From 599a8e20c02fa48bab5102d15fab79dd6b631c95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20Mart=C3=ADn?= Date: Sun, 7 Sep 2003 21:39:37 +0000 Subject: Updating to last version of pdp 0.12.2 svn path=/trunk/externals/pdp/; revision=940 --- system/image/pdp_imageproc_common.c | 596 ++++++++++++++++++++++++++++++++++++ 1 file changed, 596 insertions(+) create mode 100644 system/image/pdp_imageproc_common.c (limited to 'system/image/pdp_imageproc_common.c') diff --git a/system/image/pdp_imageproc_common.c b/system/image/pdp_imageproc_common.c new file mode 100644 index 0000000..bc34b79 --- /dev/null +++ b/system/image/pdp_imageproc_common.c @@ -0,0 +1,596 @@ +/* + * Pure Data Packet. common image processing routines. + * Copyright (c) by Tom Schouten + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + + +/* + This file contains common code for (portable) low level image processing objects + pdp_imageproc_* methods + The rest is int pdp_imageproc_.c + + There are also highlevel dispatcher methods that operate on packets: + pdp_imageproc_dispatch_* methods + +*/ + +#include +#include +#include +#include "pdp.h" + +#define CLAMP16(x) (((x) > 0x7fff) ? 0x7fff : (((x) < -0x7fff) ? -0x7fff : (x))) + +u32 pdp_imageproc_legalwidth(int i) +{ + if (i>1024) return 1024; + if (i>0) return ((((i-1)>>3)+1)<<3); + return 8; + +} + +u32 pdp_imageproc_legalheight(int i) +{ + if (i>1024) return 1024; + if (i>0) return ((((i-1)>>3)+1)<<3); + return 8; +} +u32 pdp_imageproc_legalwidth_round_down(int i) +{ + if (i>1024) return 1024; + if (i>8) return ((i>>3)<<3); + return 8; + +} + +u32 pdp_imageproc_legalheight_round_down(int i) +{ + if (i>1024) return 1024; + if (i>8) return ((i>>3)<<3); + return 8; +} + + + +/* some operations */ + +/* logic operators */ + +void pdp_imageproc_xor_process(void *x, u32 width, u32 height, s16 *image, s16 *image2) +{ + u32 *plane = (u32 *)image; + u32 *plane2 = (u32 *)image2; + int count = (width * height) >> 1; + int i; + + for (i=0; i> 1; + int i; + + for (i=0; i> 1; + int i; + + for (i=0; i> 1; + int i; + + for (i=0; i> 1; + int i; + + mask = (mask & 0xffff) | (mask << 16); + + for (i=0; i> 1) + (two >> 1) + ((scale * _rand_s16()) >> 16)); + //return (one >> 1) + (two >> 1); +} + +void *pdp_imageproc_plasma_new(void){return pdp_alloc(sizeof(t_plasma));} +void pdp_imageproc_plasma_delete(void *x){pdp_dealloc(x);} +void pdp_imageproc_plasma_setseed(void *x, float seed) +{ + *((float *)x) = seed; +} +void pdp_imageproc_plasma_setturbulence(void *x, float f) +{ + ((t_plasma *)x)->scale = CLAMP16(f * ((float)0x7fff)); +} + +static void _plasma_subdiv(u32 w, u32 h, u32 s, s16 *image, int calc_left, int calc_top, s32 scale) +{ + int w0 = ((w-1)>>1); // width of left segments + int h0 = ((h-1)>>1); // heigth of top segments + int w1 = w - w0; + int h1 = h - h0; + + /* conditions: w0 <= w1, h0 <= h1 */ + + /* original coordinates */ + int topleft = 0; + int topright = w-1; + int bottomleft = s * (h-1); + int bottomright = bottomleft + topright; + + /* new subdivision coordinates */ + int top = w0; + int left = s * h0; + int bottom = bottomleft + w0; + int right = topright + left; + int center = left + top; + + if (w0 && h0){ /* left-right and top-bottom subdivide */ + + /* calculate corner pixel colours */ + if (calc_top) image[top] = _new_color(image[topleft], image[topright], scale); + if (calc_left) image[left] = _new_color(image[topleft], image[bottomleft], scale); + image[right] = _new_color(image[topright], image[bottomright], scale); + image[bottom] = _new_color(image[bottomleft], image[bottomright], scale); + image[center] = (_new_color(image[top], image[bottom], scale) >> 1) + +(_new_color(image[left], image[right], scale) >> 1); + + + /* subdivide (with overlap) */ + _plasma_subdiv(w0+1, h0+1, s, &image[topleft], 1, 1, scale); + _plasma_subdiv(w1, h0+1, s, &image[top], 0, 1, scale); + _plasma_subdiv(w0+1, h1, s, &image[left], 1, 0, scale); + _plasma_subdiv(w1, h1, s, &image[center], 0, 0, scale); + + } + + + else if(h0) { /* top-bottom subdivide */ + + //post("h:%d", h); + + /* calculate corner pixel colours */ + if(calc_left) image[left] = _new_color(image[topleft], image[bottomleft], scale); + image[right] = _new_color(image[topright], image[bottomright], scale); + + /* subdivide (without overlap) */ + _plasma_subdiv(w, h0+1, s, &image[topleft], 1, 0, scale); + _plasma_subdiv(w, h1, s, &image[left], 1, 0, scale); + + } + + else if (w0){ /* left-right subdivide */ + + /* calculate corner pixel colours */ + if (calc_top) image[top] = _new_color(image[topleft], image[topright], scale); + image[bottom] = _new_color(image[bottomleft], image[bottomright],scale); + + /* subdivide with overlap */ + _plasma_subdiv(w0+1, h, s, &image[topleft], 0, 1, scale); + _plasma_subdiv(w1, h, s, &image[top], 0, 1, scale); + + } + +} + +void pdp_imageproc_plasma_process(void *x, u32 width, u32 height, s16 *image) +{ + s32 scale = (((t_plasma *)x)->scale); + srandom (((t_plasma *)x)->seed); + + /* set initial border colours */ + image[0] = _rand_s16(); + image[width-1] = _rand_s16(); + image[width * (height-1)] = _rand_s16(); + image[width * height - 1] = _rand_s16(); + + /* subdivide */ + _plasma_subdiv(width, height, width, image, 1, 1, scale); + + ((t_plasma *)x)->seed = random(); + +} + + + +void pdp_imageproc_zero_process(void *x, u32 width, u32 height, s16 *image) +{ + int bytesize = (width * height) << 1; + memset(image, 0, bytesize); +} + +void pdp_imageproc_constant_process(void *x, u32 width, u32 height, s16 *image) +{ + int i; + u32 value = (u32)x; + u32 *plane = (u32 *)image; + int wordsize = (width * height) >> 1; + value = (value & 0xffff) | (value << 16); + for (i=0; i>= 15; /* shift sign bit into top word */ + mask_bot >>= 15; + ((u32)mask_bot) >>=16; /* shift top word into bottom word */ + return mask_top |mask_bot; +} + +/* clear the least significant bit of the top word + to ensure a decoupled vector add */ +static inline void _decouple(s32 *invec) +{ + *invec &= 0xfffeffff; +} + +void pdp_imageproc_abs_process(void *x, u32 width, u32 height, s16 *image) +{ + int i; + s32 *wimage = (s32 *)image; + int wsize = (width * height) >> 1; + for (i=0; i= 0) ? (c) : (~c) */ + /* not is used instead of neg to prevent overflow on 0x8000 */ + /* this maps both 0 and -1 to 0 */ + + wimage[i] ^= _sign(wimage[i]); + + } +} + +void pdp_imageproc_zthresh_process(void *x, u32 width, u32 height, s16 *image) +{ + int i; + s32 *wimage = (s32 *)image; + int wsize = (width * height) >> 1; + for (i=0; i= 0) ? (c) : (0) */ + wimage[i] &= ~_sign(wimage[i]); + } +} + +/* hard thresholding: x contains a positive unsigned short int */ +void pdp_imageproc_hardthresh_process(void *x, u32 width, u32 height, s16 *image) +{ + int i; + s32 thresh = (s32)x; + s32 sign1, isign2, a; + s32 *wimage = (s32 *)image; + int wsize = (width * height) >> 1; + thresh |= (thresh << 16); + for (i=0; i> 1; + thresh |= thresh << 16; + for (i=0; i> 1; + for (i=0; i> 1; + for (i=0; i right */ +void pdp_imageproc_flip_lr_process(void *dummy, u32 width, u32 height, s16 *image) +{ + u32 y; + s16 tmp, *l, *r; + for (y=0; ywidth; + h = image0->height; + d = image0->depth; + plane_size = w*h; + + if (image0->chanmask) chanmask = image0->chanmask; + image0->chanmask = 0; + + + switch(image0->encoding){ + case PDP_IMAGE_GREY: + if (chanmask & 1) (*process_routine)(x, w, h, idata0); + break; + case PDP_IMAGE_YV12: + if (chanmask & 1) (*process_routine)(x, w, h, idata0); + idata0 += plane_size; + plane_size >>= 2; + w >>= 1; + h >>= 1; + if (chanmask & 2) (*process_routine)(x, w, h, idata0); + idata0 += plane_size; + if (chanmask & 4) (*process_routine)(x, w, h, idata0); + break; + case PDP_IMAGE_MCHP: + mask = 1; + while (d--){ + if (chanmask & mask) (*process_routine)(x, w, h, idata0); + idata0 += plane_size; + mask <<= 1; + } + break; + default: + break; + } +} + + +void pdp_imageproc_dispatch_2buf(void (*process_routine)(void*, u32, u32, s16*, s16 *), void *x, u32 chanmask, int packet0, int packet1) +{ + t_pdp *header0; + t_image *image0; + s16 *idata0, *idata1; + unsigned int w,h,d,plane_size,mask; + + /* if packets are not compatible images, return without doing anything */ + if (!(pdp_packet_image_compat(packet0, packet1))) return; + + header0 = pdp_packet_header(packet0); + image0 = pdp_packet_image_info(packet0); + idata0 = pdp_packet_data (packet0); + idata1 = pdp_packet_data (packet1); + + w = image0->width; + h = image0->height; + d = image0->depth; + plane_size = w*h; + + if (image0->chanmask) chanmask = image0->chanmask; + image0->chanmask = 0; + + switch(image0->encoding){ + case PDP_IMAGE_GREY: + if (chanmask & 1) (*process_routine)(x, w, h, idata0, idata1); + break; + case PDP_IMAGE_YV12: + if (chanmask & 1) (*process_routine)(x, w, h, idata0, idata1); + idata0 += plane_size; + idata1 += plane_size; + plane_size >>= 2; + w >>= 1; + h >>= 1; + if (chanmask & 2) (*process_routine)(x, w, h, idata0, idata1); + idata0 += plane_size; + idata1 += plane_size; + if (chanmask & 4) (*process_routine)(x, w, h, idata0, idata1); + break; + case PDP_IMAGE_MCHP: + mask = 1; + while (d--){ + if (chanmask & mask) (*process_routine)(x, w, h, idata0, idata1); + idata0 += plane_size; + idata1 += plane_size; + mask <<= 1; + } + break; + default: + break; + } +} +void pdp_imageproc_dispatch_3buf(void (*process_routine)(void*, u32, u32, s16*, s16 *, s16 *), void *x, u32 chanmask, int packet0, int packet1, int packet2) +{ + t_pdp *header0; + t_image *image0; + s16 *idata0, *idata1, *idata2; + unsigned int w,h,d,plane_size, mask; + + /* if packets are not compatible images, return without doing anything */ + if (!((pdp_packet_image_compat(packet0, packet1)) + &&(pdp_packet_image_compat(packet0, packet1)))) return; + + header0 = pdp_packet_header(packet0); + image0 = pdp_packet_image_info(packet0); + idata0 = pdp_packet_data (packet0); + idata1 = pdp_packet_data (packet1); + idata2 = pdp_packet_data (packet2); + + w = image0->width; + h = image0->height; + d = image0->depth; + plane_size = w*h; + + if (image0->chanmask) chanmask = image0->chanmask; + image0->chanmask = 0; + + switch(image0->encoding){ + case PDP_IMAGE_GREY: + if (chanmask & 1)(*process_routine)(x, w, h, idata0, idata1, idata2); + break; + case PDP_IMAGE_YV12: + if (chanmask & 1)(*process_routine)(x, w, h, idata0, idata1, idata2); + idata0 += plane_size; + idata1 += plane_size; + idata2 += plane_size; + plane_size >>= 2; + w >>= 1; + h >>= 1; + if (chanmask & 2)(*process_routine)(x, w, h, idata0, idata1, idata2); + idata0 += plane_size; + idata1 += plane_size; + idata2 += plane_size; + if (chanmask & 4)(*process_routine)(x, w, h, idata0, idata1, idata2); + break; + case PDP_IMAGE_MCHP: + mask = 1; + while (d--){ + if (chanmask & mask) (*process_routine)(x, w, h, idata0, idata1, idata2); + idata0 += plane_size; + idata1 += plane_size; + idata2 += plane_size; + mask <<= 1; + } + break; + default: + break; + } +} -- cgit v1.2.1