aboutsummaryrefslogtreecommitdiff
path: root/system/pdp_imageproc_mmx.c
diff options
context:
space:
mode:
Diffstat (limited to 'system/pdp_imageproc_mmx.c')
-rw-r--r--system/pdp_imageproc_mmx.c584
1 files changed, 0 insertions, 584 deletions
diff --git a/system/pdp_imageproc_mmx.c b/system/pdp_imageproc_mmx.c
deleted file mode 100644
index fde790f..0000000
--- a/system/pdp_imageproc_mmx.c
+++ /dev/null
@@ -1,584 +0,0 @@
-/*
- * Pure Data Packet. c wrapper for mmx image processing routines.
- * Copyright (c) by Tom Schouten <pdp@zzz.kotnet.org>
- *
- * 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 is a c wrapper around platform specific (mmx) code */
-#include <stdlib.h>
-#include <math.h>
-#include "pdp_mmx.h"
-#include "pdp_imageproc.h"
-#include "m_pd.h"
-
-/* round image dims to next multiple of 8 */
-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;
-}
-
-// utility stuff
-inline static s16 float2fixed(float f)
-{
- if (f > 1) f = 1;
- if (f < -1) f = -1;
- f *= 0x7fff;
- return (s16)f;
-}
-
-inline static void setvec(s16 *v, float f)
-{
- s16 a = float2fixed(f);
- v[0] = a;
- v[1] = a;
- v[2] = a;
- v[3] = a;
-}
-
-
-
-// add two images
-void pdp_imageproc_add_process(s16 *image, s16 *image2, u32 width, u32 height)
-{
- unsigned int totalnbpixels = width * height;
- pixel_add_s16(image, image2, totalnbpixels>>2);
-}
-
-// mul two images
-void pdp_imageproc_mul_process(s16 *image, s16 *image2, u32 width, u32 height)
-{
- unsigned int totalnbpixels = width * height;
- pixel_mul_s16(image, image2, totalnbpixels>>2);
-}
-
-// mix 2 images
-void *pdp_imageproc_mix_new(void){return malloc(8*sizeof(s16));}
-void pdp_imageproc_mix_delete(void *x) {free (x);}
-void pdp_imageproc_mix_setleftgain(void *x, float gain){setvec((s16 *)x, gain);}
-void pdp_imageproc_mix_setrightgain(void *x, float gain){setvec((s16 *)x + 4, gain);}
-void pdp_imageproc_mix_process(void *x, s16 *image, s16 *image2, u32 width, u32 height)
-{
- s16 *d = (s16 *)x;
- unsigned int totalnbpixels = width * height;
- pixel_mix_s16(image, image2, totalnbpixels>>2, d, d+4);
-}
-
-
-// random mix 2 images
-void *pdp_imageproc_randmix_new(void){return malloc(8*sizeof(s16));}
-void pdp_imageproc_randmix_delete(void *x) {free (x);}
-void pdp_imageproc_randmix_setthreshold(void *x, float threshold){setvec((s16 *)x, 2*threshold-1);}
-void pdp_imageproc_randmix_setseed(void *x, float seed)
-{
- s16 *d = (s16 *)x;
- srandom((u32)seed);
- d[4] = (s16)random();
- d[5] = (s16)random();
- d[6] = (s16)random();
- d[7] = (s16)random();
-
-}
-void pdp_imageproc_randmix_process(void *x, s16 *image, s16 *image2, u32 width, u32 height)
-{
- s16 *d = (s16 *)x;
- unsigned int totalnbpixels = width * height;
- pixel_randmix_s16(image, image2, totalnbpixels>>2, d+4, d);
-}
-
-// affine transformation (applies gain + adds offset)
-void *pdp_imageproc_affine_new(void){return malloc(8*sizeof(s16));}
-void pdp_imageproc_affine_delete(void *x){free(x);}
-void pdp_imageproc_affine_setgain(void *x, float gain){setvec((s16 *)x, gain);}
-void pdp_imageproc_affine_setoffset(void *x, float offset){setvec((s16 *)x+4, offset);}
-void pdp_imageproc_affine_process(void *x, s16 *image, u32 width, u32 height)
-{
- s16 *d = (s16 *)x;
- pixel_affine_s16(image, (width*height)>>2, d, d+4);
-}
-
-// 3x1 or 1x3 in place convolution
-// orientation
-void *pdp_imageproc_conv_new(void){return(malloc(16*sizeof(s16)));}
-void pdp_imageproc_conv_delete(void *x){free(x);}
-void pdp_imageproc_conv_setmin1(void *x, float val){setvec((s16 *)x, val);}
-void pdp_imageproc_conv_setzero(void *x, float val){setvec((s16 *)x+4, val);}
-void pdp_imageproc_conv_setplus1(void *x, float val){setvec((s16 *)x+8, val);}
-void pdp_imageproc_conv_setbordercolor(void *x, float val){setvec((s16 *)x+12, val);}
-void pdp_imageproc_conv_process(void *x, s16 *image, u32 width, u32 height, u32 orientation, u32 nbp)
-{
- s16 *d = (s16 *)x;
- u32 i,j;
-
- if (orientation == PDP_IMAGEPROC_CONV_HORIZONTAL)
- {
- for(i=0; i<width*height; i+=width)
- for (j=0; j<nbp; j++)
- pixel_conv_hor_s16(image+i, width>>2, d+12, d);
- }
-
- else
- {
- for (j=0; j<nbp; j++)
- for(i=0; i<width; i +=4) pixel_conv_ver_s16(image+i, height, width, d+12, d);
- }
-
-
-
-}
-
-// apply a gain to an image
-void *pdp_imageproc_gain_new(void){return(malloc(8*sizeof(s16)));}
-void pdp_imageproc_gain_delete(void *x){free(x);}
-void pdp_imageproc_gain_setgain(void *x, float gain)
-{
- /* convert float to s16 + shift */
- s16 *d = (s16 *)x;
- s16 g;
- int i;
- float sign;
- int shift = 0;
-
- sign = (gain < 0) ? -1 : 1;
- gain *= sign;
-
- /* max shift = 16 */
- for(i=0; i<=16; i++){
- if (gain < 0x4000){
- gain *= 2;
- shift++;
- }
- else break;
- }
-
- gain *= sign;
- g = (s16) gain;
-
- //g = 0x4000;
- //shift = 14;
-
- d[0]=g;
- d[1]=g;
- d[2]=g;
- d[3]=g;
- d[4]=(s16)shift;
- d[5]=0;
- d[6]=0;
- d[7]=0;
-}
-void pdp_imageproc_gain_process(void *x, s16 *image, u32 width, u32 height)
-{
- s16 *d = (s16 *)x;
- pixel_gain_s16(image, (width*height)>>2, d, (u64 *)(d+4));
-}
-
-// colour rotation for 2 colour planes
-void *pdp_imageproc_crot2d_new(void){return malloc(16*sizeof(s16));}
-void pdp_imageproc_crot2d_delete(void *x){free(x);}
-void pdp_imageproc_crot2d_setmatrix(void *x, float *matrix)
-{
- s16 *d = (s16 *)x;
- setvec(d, matrix[0]);
- setvec(d+4, matrix[1]);
- setvec(d+8, matrix[2]);
- setvec(d+12, matrix[3]);
-}
-void pdp_imageproc_crot2d_process(void *x, s16 *image, u32 width, u32 height)
-{
- s16 *d = (s16 *)x;
- pixel_crot2d_s16(image, width*height >> 2, d);
-}
-
-// biquad and biquad time
-void *pdp_imageproc_bq_new(void){return malloc((5+2+2)*4*sizeof(s16));}//5xcoef, 2xstate, 2xsavestate
-void pdp_imageproc_bq_delete(void *x){free(x);}
-void pdp_imageproc_bq_setcoef(void *x, float *coef) // a0,-a1,-a2,b0,b1,b2,u0,u1
-{
- s16 *d = (s16 *)x;
- float ia0 = 1.0f / coef[0];
-
- /* all coefs are s1.14 fixed point */
- /* representing values -2 < x < 2 */
- /* so scale down before using the ordinary s0.15 float->fixed routine */
-
- ia0 *= 0.5f;
-
- // coef
- setvec(d, ia0*coef[1]);
- setvec(d+4, ia0*coef[2]);
- setvec(d+8, ia0*coef[3]);
- setvec(d+12, ia0*coef[4]);
- setvec(d+16, ia0*coef[5]);
-
- // state to reset too
- setvec(d+28, coef[6]);
- setvec(d+32, coef[7]);
-
-}
-void pdp_imageproc_bqt_process(void *x, s16 *image, s16 *state0, s16 *state1, u32 width, u32 height)
-{
- s16 *d = (s16 *)x;
- pixel_biquad_time_s16(image, state0, state1, d, (width*height)>>2);
-}
-
-void pdp_imageproc_bq_process(void *x, s16 *image, u32 width, u32 height, u32 direction, u32 nbp)
-{
- s16 *d = (s16 *)x;
- unsigned int i,j;
-
-
-
- /* VERTICAL */
-
- if ((direction & PDP_IMAGEPROC_BIQUAD_TOP2BOTTOM)
- && (direction & PDP_IMAGEPROC_BIQUAD_BOTTOM2TOP)){
-
- for(i=0; i<width; i +=4){
- for (j=0; j<nbp; j++){
- pixel_biquad_vertb_s16(image+i, height>>2, width, d, d + (5*4));
- pixel_biquad_verbt_s16(image+i, height>>2, width, d, d + (5*4));
- }
- }
- }
-
- else if (direction & PDP_IMAGEPROC_BIQUAD_TOP2BOTTOM){
- for(i=0; i<width; i +=4){
- for (j=0; j<nbp; j++){
- pixel_biquad_vertb_s16(image+i, height>>2, width, d, d + (5*4));
- }
- }
- }
-
- else if (direction & PDP_IMAGEPROC_BIQUAD_BOTTOM2TOP){
- for(i=0; i<width; i +=4){
- for (j=0; j<nbp; j++){
- pixel_biquad_verbt_s16(image+i, height>>2, width, d, d + (5*4));
- }
- }
- }
-
- /* HORIZONTAL */
-
- if ((direction & PDP_IMAGEPROC_BIQUAD_LEFT2RIGHT)
- && (direction & PDP_IMAGEPROC_BIQUAD_RIGHT2LEFT)){
-
- for(i=0; i<(width*height); i +=(width<<2)){
- for (j=0; j<nbp; j++){
- pixel_biquad_horlr_s16(image+i, width>>2, width, d, d + (5*4));
- pixel_biquad_horrl_s16(image+i, width>>2, width, d, d + (5*4));
- }
- }
- }
-
- else if (direction & PDP_IMAGEPROC_BIQUAD_LEFT2RIGHT){
- for(i=0; i<(width*height); i +=(width<<2)){
- for (j=0; j<nbp; j++){
- pixel_biquad_horlr_s16(image+i, width>>2, width, d, d + (5*4));
- }
- }
- }
-
- else if (direction & PDP_IMAGEPROC_BIQUAD_RIGHT2LEFT){
- for(i=0; i<(width*height); i +=(width<<2)){
- for (j=0; j<nbp; j++){
- pixel_biquad_horrl_s16(image+i, width>>2, width, d, d + (5*4));
- }
- }
- }
-
-}
-
-// produce a random image
-// note: random number generator can be platform specific
-// however, it should be seeded. (same seed produces the same result)
-void *pdp_imageproc_random_new(void){return malloc(4*sizeof(s16));}
-void pdp_imageproc_random_delete(void *x){free(x);}
-void pdp_imageproc_random_setseed(void *x, float seed)
-{
- s16 *d = (s16 *)x;
- srandom((u32)seed);
- d[0] = (s16)random();
- d[1] = (s16)random();
- d[2] = (s16)random();
- d[3] = (s16)random();
-
-}
-void pdp_imageproc_random_process(void *x, s16 *image, u32 width, u32 height)
-{
- s16 *d = (s16 *)x;
- unsigned int totalnbpixels = width * height;
- pixel_rand_s16(image, totalnbpixels>>2, d);
-}
-
-
-/* resampling stuff
- this is quite a zoo of data structures
- the major point is this: the resampler mmx code is shared for all resampling code
- it uses data specified in t_resample_cbrd (Cooked Bilinear Resampler Data)
-
- then the there are several feeder algorithms. one is the linear mapper. it's
- data is specified in t_resample_clrd (Cooked Linear Remapper Data)
-
- for each feeder algorithm, there are several high level algorithms. like zoom,
- rotate, ...
-*/
-
-typedef struct
-{
- u32 lineoffset;
- s16 *image;
- u32 width;
- u32 height;
-
-} t_resample_id; // Image Data
-
-/* initialize image meta data (dimensions + location) */
-static void pdp_imageproc_resample_init_id(t_resample_id *x, u32 offset, s16* image, u32 w, u32 h)
-{
- x->lineoffset = offset;
- x->image = image;
- x->width = w;
- x->height = h;
-}
-
-// mmx resampling source image resampling data + coefs
-typedef struct
-{
- // vector data for resampling routine (resampling computation)
- u8 reserved[0x60]; //internal data
- s16 *address[2]; //64 bit splatted offset address
- s16 twowidthm1[4]; //64 bit splatted 2*(width-1)
- s16 twoheightm1[4]; //64 bit splatted 2*(height-1)
- s16 lineoffset[4]; //64 bit splatted line offset in pixels
-
-} t_resample_cid; // Cooked Image Data
-
-/* convert image meta data into a cooked format used by the resampler routine */
-static void pdp_imageproc_resample_init_cid(t_resample_cid *r, t_resample_id *i)
-{
- u32 twowm1 = (i->width-1)<<1;
- u32 twohm1 = (i->height-1)<<1;
- r->address[0] = i->image;
- r->address[1] = i->image;
- r->twowidthm1[0] = twowm1;
- r->twowidthm1[1] = twowm1;
- r->twowidthm1[2] = twowm1;
- r->twowidthm1[3] = twowm1;
- r->twoheightm1[0] = twohm1;
- r->twoheightm1[1] = twohm1;
- r->twoheightm1[2] = twohm1;
- r->twoheightm1[3] = twohm1;
- r->lineoffset[0] = i->lineoffset;
- r->lineoffset[1] = i->lineoffset;
- r->lineoffset[2] = i->lineoffset;
- r->lineoffset[3] = i->lineoffset;
-}
-
-// linear mapping data struct (zoom, scale, rotate, shear, ...)
-typedef struct
-{
- s32 rowstatex[2]; // row state x coord
- s32 rowstatey[2]; // row state y coord
- s32 colstatex[2]; // column state x coord
- s32 colstatey[2]; // column state y coord
- s32 rowincx[2]; // row inc vector x coord
- s32 rowincy[2]; // row inc vector y coord
- s32 colincx[2]; // column inc vector x coord
- s32 colincy[2]; // column inc vector y coord
-} t_resample_clmd; // Cooked Linear Mapping Data
-
-/* convert incremental linear remapping vectors to internal cooked format */
-static void pdp_imageproc_resample_cookedlinmap_init(t_resample_clmd *l, s32 sx, s32 sy, s32 rix, s32 riy, s32 cix, s32 ciy)
-{
- l->colstatex[0] = l->rowstatex[0] = sx;
- l->colstatex[1] = l->rowstatex[1] = sx + rix;
- l->colstatey[0] = l->rowstatey[0] = sy;
- l->colstatey[1] = l->rowstatey[1] = sy + riy;
- l->rowincx[0] = rix << 1;
- l->rowincx[1] = rix << 1;
- l->rowincy[0] = riy << 1;
- l->rowincy[1] = riy << 1;
- l->colincx[0] = cix;
- l->colincx[1] = cix;
- l->colincy[0] = ciy;
- l->colincy[1] = ciy;
-}
-
-
-/* this struct contains all the data necessary for
- bilin interpolation from src -> dst image
- (src can be == dst) */
-typedef struct
-{
- t_resample_cid csrc; //cooked src image meta data for bilinear interpolator
- t_resample_id src; //src image meta
- t_resample_id dst; //dst image meta
-} t_resample_cbrd; //Bilinear Resampler Data
-
-
-/* this struct contains high level zoom parameters,
- all image relative */
-typedef struct
-{
- float centerx;
- float centery;
- float zoomx;
- float zoomy;
- float angle;
-} t_resample_zrd;
-
-
-/* convert floating point center and zoom data to incremental linear remapping vectors */
-static void pdp_imageproc_resample_clmd_init_from_id_zrd(t_resample_clmd *l, t_resample_id *i, t_resample_zrd *z)
-{
- double izx = 1.0f / (z->zoomx);
- double izy = 1.0f / (z->zoomy);
- double scale = (double)0xffffffff;
- double scalew = scale / ((double)(i->width - 1));
- double scaleh = scale / ((double)(i->height - 1));
- double cx = ((double)z->centerx) * ((double)(i->width - 1));
- double cy = ((double)z->centery) * ((double)(i->height - 1));
- double angle = z->angle * (-M_PI / 180.0);
- double c = cos(angle);
- double s = sin(angle);
-
- /* affine x, y mappings in screen coordinates */
- double mapx(double x, double y){return cx + izx * ( c * (x-cx) + s * (y-cy));}
- double mapy(double x, double y){return cy + izy * (-s * (x-cx) + c * (y-cy));}
-
- u32 tl_x = (u32)(scalew * mapx(0,0));
- u32 tl_y = (u32)(scaleh * mapy(0,0));
-
-
- u32 row_inc_x = (u32)(scalew * (mapx(1,0)-mapx(0,0)));
- u32 row_inc_y = (u32)(scaleh * (mapy(1,0)-mapy(0,0)));
- u32 col_inc_x = (u32)(scalew * (mapx(0,1)-mapx(0,0)));
- u32 col_inc_y = (u32)(scaleh * (mapy(0,1)-mapy(0,0)));
-
-
- pdp_imageproc_resample_cookedlinmap_init(l, tl_x, tl_y, row_inc_x, row_inc_y, col_inc_x, col_inc_y);
-}
-
-/* this struct contains all data for the zoom object */
-typedef struct
-{
- t_resample_cbrd cbrd; // Bilinear Resampler Data
- t_resample_clmd clmd; // Cooked Linear Mapping data
- t_resample_zrd zrd; // Zoom / Rotate Data
-} t_resample_zoom_rotate;
-
-// zoom + rotate
-void *pdp_imageproc_resample_affinemap_new(void)
-{
- t_resample_zoom_rotate *z = (t_resample_zoom_rotate *)malloc(sizeof(t_resample_zoom_rotate));
- z->zrd.centerx = 0.5;
- z->zrd.centery = 0.5;
- z->zrd.zoomx = 1.0;
- z->zrd.zoomy = 1.0;
- z->zrd.angle = 0.0f;
- return (void *)z;
-}
-void pdp_imageproc_resample_affinemap_delete(void *x){free(x);}
-void pdp_imageproc_resample_affinemap_setcenterx(void *x, float f){((t_resample_zoom_rotate *)x)->zrd.centerx = f;}
-void pdp_imageproc_resample_affinemap_setcentery(void *x, float f){((t_resample_zoom_rotate *)x)->zrd.centery = f;}
-void pdp_imageproc_resample_affinemap_setzoomx(void *x, float f){((t_resample_zoom_rotate *)x)->zrd.zoomx = f;}
-void pdp_imageproc_resample_affinemap_setzoomy(void *x, float f){((t_resample_zoom_rotate *)x)->zrd.zoomy = f;}
-void pdp_imageproc_resample_affinemap_setangle(void *x, float f){((t_resample_zoom_rotate *)x)->zrd.angle = f;}
-void pdp_imageproc_resample_affinemap_process(void *x, s16 *srcimage, s16 *dstimage, u32 width, u32 height)
-{
- t_resample_zoom_rotate *z = (t_resample_zoom_rotate *)x;
-
- /* setup resampler image meta data */
- pdp_imageproc_resample_init_id(&(z->cbrd.src), width, srcimage, width, height);
- pdp_imageproc_resample_init_id(&(z->cbrd.dst), width, dstimage, width, height);
- pdp_imageproc_resample_init_cid(&(z->cbrd.csrc),&(z->cbrd.src));
-
- /* setup linmap data from zoom_rotate parameters */
- pdp_imageproc_resample_clmd_init_from_id_zrd(&(z->clmd), &(z->cbrd.src), &(z->zrd));
-
-
- /* call assembler routine */
- pixel_resample_linmap_s16(z);
-}
-
-
-
-// polynomials
-
-
-typedef struct
-{
- u32 order;
- u8 pad[4];
- s16 coefs[0];
-} t_cheby;
-
-void *pdp_imageproc_cheby_new(int order)
-{
- t_cheby *z;
- int i;
- if (order < 2) order = 2;
- z = (t_cheby *)malloc(sizeof(t_cheby) + (order + 1) * sizeof(s16[4]));
- z->order = order;
- setvec(z->coefs + 0*4, 0);
- setvec(z->coefs + 1*4, 0.25);
- for (i=2; i<=order; i++) setvec(z->coefs + i*4, 0);
-
- return z;
-}
-void pdp_imageproc_cheby_delete(void *x){free(x);}
-void pdp_imageproc_cheby_setcoef(void *x, u32 n, float f)
-{
- t_cheby *z = (t_cheby *)x;
- if (n <= z->order){
- setvec(z->coefs + n*4, f * 0.25); // coefs are in s2.13 format
- }
-}
-void pdp_imageproc_cheby_process(void *x, s16 *image, u32 width, u32 height, u32 iterations)
-{
- t_cheby *z = (t_cheby *)x;
- u32 i,j;
- for (j=0; j < (height*width); j += width)
- for (i=0; i<iterations; i++)
- pixel_cheby_s16_3plus(image+j, width>>2, z->order+1, z->coefs);
-
- //pixel_cheby_s16_3plus(image, (width*height)>>2, z->order+1, z->coefs);
-}