~kamalmostafa/ubuntu/lucid/pdp/fix-504941-ftbfs

« back to all changes in this revision

Viewing changes to system/image/pdp_imageproc_common.c

  • Committer: Bazaar Package Importer
  • Author(s): Guenter Geiger (Debian/GNU)
  • Date: 2005-03-15 22:21:05 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20050315222105-1q287rsihmd9j1tb
Tags: 1:0.12.4-2
* fixed the hardcoded depends
* added 3dp library

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 *   Pure Data Packet. common image processing routines.
3
 
 *   Copyright (c) by Tom Schouten <pdp@zzz.kotnet.org>
4
 
 *
5
 
 *   This program is free software; you can redistribute it and/or modify
6
 
 *   it under the terms of the GNU General Public License as published by
7
 
 *   the Free Software Foundation; either version 2 of the License, or
8
 
 *   (at your option) any later version.
9
 
 *
10
 
 *   This program is distributed in the hope that it will be useful,
11
 
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
 *   GNU General Public License for more details.
14
 
 *
15
 
 *   You should have received a copy of the GNU General Public License
16
 
 *   along with this program; if not, write to the Free Software
17
 
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18
 
 *
19
 
 */
20
 
 
21
 
 
22
 
/*
23
 
  This file contains common code for (portable) low level image processing objects
24
 
  pdp_imageproc_* methods
25
 
  The rest is int pdp_imageproc_<platform>.c
26
 
 
27
 
  There are also highlevel dispatcher methods that operate on packets:
28
 
  pdp_imageproc_dispatch_* methods
29
 
 
30
 
*/
31
 
 
32
 
#include <stdlib.h>
33
 
#include <string.h>
34
 
#include <math.h>
35
 
#include "pdp_imageproc.h"
36
 
#include "pdp_image.h"
37
 
#include "pdp_mem.h"
38
 
#include "pdp_packet.h"
39
 
 
40
 
#define CLAMP16(x) (((x) > 0x7fff) ? 0x7fff : (((x) < -0x7fff) ? -0x7fff : (x)))
41
 
 
42
 
u32 pdp_imageproc_legalwidth(int i)
43
 
{
44
 
    if (i>1024) return 1024;
45
 
    if (i>0) return  ((((i-1)>>3)+1)<<3);
46
 
    return 8;
47
 
    
48
 
}
49
 
 
50
 
u32 pdp_imageproc_legalheight(int i)
51
 
{
52
 
    if (i>1024) return 1024;
53
 
    if (i>0) return  ((((i-1)>>3)+1)<<3);
54
 
    return 8;
55
 
}
56
 
u32 pdp_imageproc_legalwidth_round_down(int i)
57
 
{
58
 
    if (i>1024) return 1024;
59
 
    if (i>8) return  ((i>>3)<<3);
60
 
    return 8;
61
 
    
62
 
}
63
 
 
64
 
u32 pdp_imageproc_legalheight_round_down(int i)
65
 
{
66
 
    if (i>1024) return 1024;
67
 
    if (i>8) return  ((i>>3)<<3);
68
 
    return 8;
69
 
}
70
 
 
71
 
 
72
 
/* check if two packets are allocated and of the same type */
73
 
bool pdp_packet_compat(int packet0, int packet1)
74
 
{
75
 
 
76
 
    t_pdp *header0 = pdp_packet_header(packet0);
77
 
    t_pdp *header1 = pdp_packet_header(packet1);
78
 
    if (!(header1)) return 0;
79
 
    if (!(header0)) return 0;
80
 
    if (header0->type != header1->type) return 0;
81
 
    return 1;
82
 
}
83
 
 
84
 
/* some operations */
85
 
 
86
 
/* logic operators */
87
 
 
88
 
void pdp_imageproc_xor_process(void *x, u32 width, u32 height, s16 *image, s16 *image2)
89
 
{
90
 
    u32 *plane = (u32 *)image;
91
 
    u32 *plane2 = (u32 *)image2;
92
 
    int count = (width * height) >> 1;
93
 
    int i;
94
 
 
95
 
    for (i=0; i<count; i++){
96
 
        plane[i] ^= plane2[i];
97
 
    }
98
 
}
99
 
 
100
 
void pdp_imageproc_and_process(void *x, u32 width, u32 height, s16 *image, s16 *image2)
101
 
{
102
 
    u32 *plane = (u32 *)image;
103
 
    u32 *plane2 = (u32 *)image2;
104
 
    int count = (width * height) >> 1;
105
 
    int i;
106
 
 
107
 
    for (i=0; i<count; i++){
108
 
        plane[i] &= plane2[i];
109
 
    }
110
 
}
111
 
 
112
 
void pdp_imageproc_or_process(void *x, u32 width, u32 height, s16 *image, s16 *image2)
113
 
{
114
 
    u32 *plane = (u32 *)image;
115
 
    u32 *plane2 = (u32 *)image2;
116
 
    int count = (width * height) >> 1;
117
 
    int i;
118
 
 
119
 
    for (i=0; i<count; i++){
120
 
        plane[i] |= plane2[i];
121
 
    }
122
 
}
123
 
 
124
 
void pdp_imageproc_not_process(void *x, u32 width, u32 height, s16 *image)
125
 
{
126
 
    u32 *plane = (u32 *)image;
127
 
    int count = (width * height) >> 1;
128
 
    int i;
129
 
 
130
 
    for (i=0; i<count; i++){
131
 
        plane[i] ^= 0xffffffff;
132
 
    }
133
 
}
134
 
 
135
 
void pdp_imageproc_mask_process(void *x, u32 width, u32 height, s16 *image)
136
 
{
137
 
    u32 mask = (u32)x;
138
 
    u32 *plane = (u32 *)image;
139
 
    int count = (width * height) >> 1;
140
 
    int i;
141
 
 
142
 
    mask = (mask & 0xffff) | (mask << 16);
143
 
 
144
 
    for (i=0; i<count; i++){
145
 
        plane[i] &= mask;
146
 
    }
147
 
}
148
 
 
149
 
// produce a plasma image
150
 
// note: random number generator can be platform specific
151
 
// however, it should be seeded. (same seed produces the same result)
152
 
 
153
 
typedef struct
154
 
{
155
 
    u32 seed;
156
 
    s32 scale;
157
 
} t_plasma;
158
 
 
159
 
static inline s16 _rand_s16(void)
160
 
{
161
 
  return (s16)(random()<<0);
162
 
}
163
 
 
164
 
static inline s16 _new_color(s32 one, s32 two, s32 scale)
165
 
{
166
 
  return CLAMP16((one >> 1) + (two >> 1) + ((scale * _rand_s16()) >> 16));
167
 
  //return (one >> 1) + (two >> 1);
168
 
}
169
 
 
170
 
void *pdp_imageproc_plasma_new(void){return pdp_alloc(sizeof(t_plasma));}
171
 
void pdp_imageproc_plasma_delete(void *x){pdp_dealloc(x);}
172
 
void pdp_imageproc_plasma_setseed(void *x, float seed)
173
 
{
174
 
    *((float *)x) = seed;
175
 
}
176
 
void pdp_imageproc_plasma_setturbulence(void *x, float f)
177
 
{
178
 
    ((t_plasma *)x)->scale = CLAMP16(f * ((float)0x7fff));
179
 
}
180
 
 
181
 
static void _plasma_subdiv(u32 w, u32 h, u32 s, s16 *image, int calc_left, int calc_top, s32 scale)
182
 
{
183
 
  int w0 = ((w-1)>>1);  // width of left segments
184
 
  int h0 = ((h-1)>>1);  // heigth of top segments
185
 
  int w1 = w - w0;
186
 
  int h1 = h - h0;
187
 
 
188
 
  /* conditions: w0 <= w1, h0 <= h1 */
189
 
 
190
 
  /* original coordinates */
191
 
  int topleft = 0;
192
 
  int topright = w-1;
193
 
  int bottomleft = s * (h-1);
194
 
  int bottomright = bottomleft + topright;
195
 
 
196
 
  /* new subdivision coordinates */
197
 
  int top = w0;
198
 
  int left = s * h0;
199
 
  int bottom = bottomleft + w0;
200
 
  int right = topright + left;
201
 
  int center = left + top;
202
 
 
203
 
  if (w0 && h0){ /* left-right and top-bottom subdivide */
204
 
 
205
 
    /* calculate corner pixel colours */
206
 
    if (calc_top)  image[top]    = _new_color(image[topleft], image[topright], scale);
207
 
    if (calc_left) image[left]   = _new_color(image[topleft], image[bottomleft], scale);
208
 
    image[right]  = _new_color(image[topright], image[bottomright], scale);
209
 
    image[bottom] = _new_color(image[bottomleft], image[bottomright], scale);
210
 
    image[center] = (_new_color(image[top], image[bottom], scale) >> 1)
211
 
        +(_new_color(image[left], image[right], scale) >> 1);
212
 
 
213
 
 
214
 
    /* subdivide (with overlap) */
215
 
    _plasma_subdiv(w0+1, h0+1, s, &image[topleft], 1, 1, scale);
216
 
    _plasma_subdiv(w1, h0+1, s, &image[top], 0, 1, scale);
217
 
    _plasma_subdiv(w0+1, h1, s, &image[left], 1, 0, scale);
218
 
    _plasma_subdiv(w1, h1, s, &image[center], 0, 0, scale);
219
 
    
220
 
  }
221
 
  
222
 
 
223
 
  else if(h0) { /* top-bottom subdivide */
224
 
 
225
 
      //post("h:%d", h);
226
 
 
227
 
    /* calculate corner pixel colours */
228
 
    if(calc_left) image[left]   = _new_color(image[topleft], image[bottomleft], scale);
229
 
    image[right]  = _new_color(image[topright], image[bottomright], scale);
230
 
 
231
 
    /* subdivide (without overlap) */
232
 
    _plasma_subdiv(w, h0+1, s, &image[topleft], 1, 0, scale);
233
 
    _plasma_subdiv(w, h1, s, &image[left], 1, 0, scale);
234
 
    
235
 
  }
236
 
  
237
 
  else if (w0){ /* left-right subdivide */
238
 
 
239
 
    /* calculate corner pixel colours */
240
 
    if (calc_top) image[top]    = _new_color(image[topleft], image[topright], scale);
241
 
    image[bottom] = _new_color(image[bottomleft], image[bottomright],scale);
242
 
 
243
 
    /* subdivide with overlap */
244
 
    _plasma_subdiv(w0+1, h, s, &image[topleft], 0, 1, scale);
245
 
    _plasma_subdiv(w1, h, s, &image[top], 0, 1, scale);
246
 
 
247
 
  }
248
 
 
249
 
}
250
 
 
251
 
void pdp_imageproc_plasma_process(void *x, u32 width, u32 height, s16 *image)
252
 
{
253
 
    s32 scale = (((t_plasma *)x)->scale);
254
 
    srandom (((t_plasma *)x)->seed);
255
 
 
256
 
    /* set initial border colours */
257
 
    image[0]                  = _rand_s16();
258
 
    image[width-1]            = _rand_s16();
259
 
    image[width * (height-1)] = _rand_s16();
260
 
    image[width * height - 1] = _rand_s16();
261
 
 
262
 
    /* subdivide */
263
 
    _plasma_subdiv(width, height, width, image, 1, 1, scale);
264
 
 
265
 
    ((t_plasma *)x)->seed = random();
266
 
 
267
 
}
268
 
  
269
 
 
270
 
 
271
 
void pdp_imageproc_zero_process(void *x, u32 width, u32 height, s16 *image)
272
 
{
273
 
    int bytesize = (width * height) << 1;
274
 
    memset(image, 0, bytesize);
275
 
}
276
 
 
277
 
void pdp_imageproc_constant_process(void *x, u32 width, u32 height, s16 *image)
278
 
{
279
 
    int i;
280
 
    u32 value = (u32)x;
281
 
    u32 *plane = (u32 *)image;
282
 
    int wordsize = (width * height) >> 1;
283
 
    value = (value & 0xffff) | (value << 16);
284
 
    for (i=0; i<wordsize; i++){
285
 
        plane[i] = value;
286
 
    }
287
 
}
288
 
 
289
 
 
290
 
/* other stateless operators */
291
 
 
292
 
/* some 2x16bit vector ops */
293
 
 
294
 
/* some bit shuffling to ensure 32 bit accesses 
295
 
   get the sign bit extended as a mask: - : 0xffff +: 0x0000 */
296
 
static inline u32 _sign(s32 invec)
297
 
{
298
 
    s32 mask_top = invec;
299
 
    s32 mask_bot = invec;
300
 
 
301
 
    mask_top &= 0x80000000; /* isolate top sign bit */
302
 
    mask_bot <<= 16;        /* shift bottom word to top word */
303
 
    mask_bot &= 0x80000000; /* isolate bottom sign bit */
304
 
    mask_top >>= 15;        /* shift sign bit into top word */
305
 
    mask_bot >>= 15;
306
 
    ((u32)mask_bot) >>=16;  /* shift top word into bottom word */
307
 
    return mask_top |mask_bot;    
308
 
}
309
 
 
310
 
/* clear the least significant bit of the top word
311
 
   to ensure a decoupled vector add */
312
 
static inline void _decouple(s32 *invec)
313
 
{
314
 
    *invec &= 0xfffeffff;
315
 
}
316
 
 
317
 
void pdp_imageproc_abs_process(void *x, u32 width, u32 height, s16 *image)
318
 
{
319
 
    int i;
320
 
    s32 *wimage = (s32 *)image;
321
 
    int wsize = (width * height) >> 1;
322
 
    for (i=0; i<wsize; i++){
323
 
        /* this computes  c = (c >= 0) ? (c) : (~c) */
324
 
        /* not is used instead of neg to prevent overflow on 0x8000 */
325
 
        /* this maps both 0 and -1 to 0 */
326
 
 
327
 
        wimage[i] ^= _sign(wimage[i]);
328
 
        
329
 
    }
330
 
}
331
 
 
332
 
void pdp_imageproc_zthresh_process(void *x, u32 width, u32 height, s16 *image)
333
 
{
334
 
    int i;
335
 
    s32 *wimage = (s32 *)image;
336
 
    int wsize = (width * height) >> 1;
337
 
    for (i=0; i<wsize; i++){
338
 
        /* this computes  c = (c >= 0) ? (c) : (0) */
339
 
        wimage[i] &= ~_sign(wimage[i]);
340
 
    }
341
 
}
342
 
 
343
 
/* hard thresholding: x contains a positive unsigned short int */
344
 
void pdp_imageproc_hardthresh_process(void *x, u32 width, u32 height, s16 *image)
345
 
{
346
 
    int i;
347
 
    s32 thresh = (s32)x;
348
 
    s32 sign1, isign2, a;
349
 
    s32 *wimage = (s32 *)image;
350
 
    int wsize = (width * height) >> 1;
351
 
    thresh |= (thresh << 16);
352
 
    for (i=0; i<wsize; i++){
353
 
        a = wimage[i];
354
 
        sign1 = _sign(a);   
355
 
        a ^= sign1;           /* take abs */
356
 
        _decouple(&a);
357
 
        a -= thresh;          /* subtract threshold */
358
 
        isign2 = ~ _sign(a);
359
 
        a &= isign2;          /* zero thresh */
360
 
        _decouple(&a);
361
 
        a += thresh & isign2; /* add threshold (if not zero thresholded)*/
362
 
        a ^= sign1;
363
 
        wimage[i] = a;
364
 
    }
365
 
}
366
 
 
367
 
/* soft thresholding: x contains a positive unsigned short int */
368
 
void pdp_imageproc_softthresh_process(void *x, u32 width, u32 height, s16 *image)
369
 
{
370
 
    int i;
371
 
    s32 thresh = (s32)x;
372
 
    s32 sign1, sign2, a;
373
 
    s32 *wimage = (s32 *)image;
374
 
    int wsize = (width * height) >> 1;
375
 
    thresh |= thresh << 16;
376
 
    for (i=0; i<wsize; i++){
377
 
        a = wimage[i];
378
 
        sign1 = _sign(a);   
379
 
        a ^= sign1;           /* take abs */
380
 
        _decouple(&a);
381
 
        a -= thresh;          /* subtract threshold */
382
 
        sign2 = _sign(a);
383
 
        a &= ~ sign2;         /* zero thresh */
384
 
        _decouple(&a);
385
 
        //a += thresh;        /* add threshold */
386
 
        a ^= sign1;
387
 
        wimage[i] = a;
388
 
        
389
 
    }
390
 
 
391
 
}
392
 
 
393
 
 
394
 
/* turns an image into a positive andmask */
395
 
void pdp_imageproc_ispositive_process(void *x, u32 width, u32 height, s16 *image)
396
 
{
397
 
    int i;
398
 
    s32 *wimage = (s32 *)image;
399
 
    int wsize = (width * height) >> 1;
400
 
    for (i=0; i<wsize; i++){
401
 
        wimage[i] = ~_sign(wimage[i]);
402
 
    }
403
 
 
404
 
}
405
 
 
406
 
/* get sign */
407
 
void pdp_imageproc_sign_process(void *x, u32 width, u32 height, s16 *image)
408
 
{
409
 
    int i;
410
 
    s32 *wimage = (s32 *)image;
411
 
    int wsize = (width * height) >> 1;
412
 
    for (i=0; i<wsize; i++){
413
 
        wimage[i] = _sign(wimage[i]) ^ 0x7fff7fff;
414
 
    }
415
 
 
416
 
}
417
 
 
418
 
/* flip left <-> right */
419
 
void pdp_imageproc_flip_lr_process(void *dummy, u32 width, u32 height, s16 *image)
420
 
{
421
 
    u32 y;
422
 
    s16 tmp, *l, *r;
423
 
    for (y=0; y<height; y++){
424
 
        l = image;
425
 
        r = image + width - 1;
426
 
        while (l < r){
427
 
            tmp = *l;
428
 
            *l = *r;
429
 
            *r = tmp;
430
 
            l++;
431
 
            r--;
432
 
        }
433
 
        image += width;
434
 
    }
435
 
 
436
 
}
437
 
 
438
 
void pdp_llconv_flip_top_bottom(s16 *data, int width, int height, int pixelsize);
439
 
 
440
 
void pdp_imageproc_flip_tb_process(void *dummy, u32 width, u32 height, s16 *image)
441
 
{
442
 
    pdp_llconv_flip_top_bottom(image, width, height, 2);
443
 
}
444
 
 
445
 
 
446
 
/* image processing dispatcher methods  */
447
 
/* if the first packet contains a nonzero channel mask, it will be used instead
448
 
   of the one supplied as argument to the dispatcher functions.
449
 
   the packet's channel mask will be reset to 0 */
450
 
 
451
 
void pdp_imageproc_dispatch_1buf(void (*process_routine)(void*, u32, u32, s16*), void *x, u32 chanmask, int packet0)
452
 
{
453
 
    t_pdp *header0;
454
 
    t_image *image0;
455
 
    s16  *idata0;
456
 
    unsigned int w,h,d,plane_size,mask;
457
 
 
458
 
    /* if packet is not a valid image return without doing anything */
459
 
    if (!(pdp_packet_image_isvalid(packet0))) return;
460
 
 
461
 
    header0 = pdp_packet_header(packet0);
462
 
    image0 = pdp_packet_image_info(packet0);
463
 
    idata0   = pdp_packet_data  (packet0);
464
 
 
465
 
    w = image0->width;
466
 
    h = image0->height;
467
 
    d = image0->depth;
468
 
    plane_size = w*h;
469
 
 
470
 
    if (image0->chanmask) chanmask = image0->chanmask;
471
 
    image0->chanmask = 0;
472
 
 
473
 
 
474
 
    switch(image0->encoding){
475
 
    case PDP_IMAGE_GREY:
476
 
        if (chanmask & 1) (*process_routine)(x, w, h, idata0);
477
 
        break;
478
 
    case PDP_IMAGE_YV12:
479
 
        if (chanmask & 1) (*process_routine)(x, w, h, idata0);
480
 
        idata0 += plane_size;
481
 
        plane_size >>= 2;
482
 
        w >>= 1;
483
 
        h >>= 1;
484
 
        if (chanmask & 2) (*process_routine)(x, w, h, idata0);
485
 
        idata0 += plane_size;
486
 
        if (chanmask & 4) (*process_routine)(x, w, h, idata0);
487
 
        break;
488
 
    case PDP_IMAGE_MCHP:
489
 
        mask = 1;
490
 
        while (d--){
491
 
            if (chanmask & mask) (*process_routine)(x, w, h, idata0);
492
 
            idata0 += plane_size;
493
 
            mask <<= 1;
494
 
        }
495
 
        break;
496
 
    default:
497
 
        break;
498
 
    }
499
 
}
500
 
 
501
 
 
502
 
void pdp_imageproc_dispatch_2buf(void (*process_routine)(void*, u32, u32, s16*, s16 *), void *x, u32 chanmask, int packet0, int packet1)
503
 
{
504
 
    t_pdp *header0;
505
 
    t_image *image0;
506
 
    s16  *idata0, *idata1;
507
 
    unsigned int w,h,d,plane_size,mask;
508
 
 
509
 
    /* if packets are not compatible images, return without doing anything */
510
 
    if (!(pdp_packet_image_compat(packet0, packet1))) return;
511
 
 
512
 
    header0 = pdp_packet_header(packet0);
513
 
    image0 = pdp_packet_image_info(packet0);
514
 
    idata0   = pdp_packet_data  (packet0);
515
 
    idata1   = pdp_packet_data  (packet1);
516
 
 
517
 
    w = image0->width;
518
 
    h = image0->height;
519
 
    d = image0->depth;
520
 
    plane_size = w*h;
521
 
 
522
 
    if (image0->chanmask) chanmask = image0->chanmask;
523
 
    image0->chanmask = 0;
524
 
 
525
 
    switch(image0->encoding){
526
 
    case PDP_IMAGE_GREY:
527
 
        if (chanmask & 1) (*process_routine)(x, w, h, idata0, idata1);
528
 
        break;
529
 
    case PDP_IMAGE_YV12:
530
 
        if (chanmask & 1) (*process_routine)(x, w, h, idata0, idata1);
531
 
        idata0 += plane_size;
532
 
        idata1 += plane_size;
533
 
        plane_size >>= 2;
534
 
        w >>= 1;
535
 
        h >>= 1;
536
 
        if (chanmask & 2) (*process_routine)(x, w, h, idata0, idata1);
537
 
        idata0 += plane_size;
538
 
        idata1 += plane_size;
539
 
        if (chanmask & 4) (*process_routine)(x, w, h, idata0, idata1);
540
 
        break;
541
 
    case PDP_IMAGE_MCHP:
542
 
        mask = 1;
543
 
        while (d--){
544
 
            if (chanmask & mask) (*process_routine)(x, w, h, idata0, idata1);
545
 
            idata0 += plane_size;
546
 
            idata1 += plane_size;
547
 
            mask <<= 1;
548
 
        }
549
 
        break;
550
 
    default:
551
 
        break;
552
 
    }
553
 
}
554
 
void pdp_imageproc_dispatch_3buf(void (*process_routine)(void*, u32, u32, s16*, s16 *, s16 *), void *x, u32 chanmask, int packet0, int packet1, int packet2)
555
 
{
556
 
    t_pdp *header0;
557
 
    t_image *image0;
558
 
    s16  *idata0, *idata1, *idata2;
559
 
    unsigned int w,h,d,plane_size, mask;
560
 
 
561
 
    /* if packets are not compatible images, return without doing anything */
562
 
    if (!((pdp_packet_image_compat(packet0, packet1))
563
 
          &&(pdp_packet_image_compat(packet0, packet1)))) return;
564
 
 
565
 
    header0 = pdp_packet_header(packet0);
566
 
    image0 = pdp_packet_image_info(packet0);
567
 
    idata0   = pdp_packet_data  (packet0);
568
 
    idata1   = pdp_packet_data  (packet1);
569
 
    idata2   = pdp_packet_data  (packet2);
570
 
 
571
 
    w = image0->width;
572
 
    h = image0->height;
573
 
    d = image0->depth;
574
 
    plane_size = w*h;
575
 
 
576
 
    if (image0->chanmask) chanmask = image0->chanmask;
577
 
    image0->chanmask = 0;
578
 
 
579
 
    switch(image0->encoding){
580
 
    case PDP_IMAGE_GREY:
581
 
        if (chanmask & 1)(*process_routine)(x, w, h, idata0, idata1, idata2);
582
 
        break;
583
 
    case PDP_IMAGE_YV12:
584
 
        if (chanmask & 1)(*process_routine)(x, w, h, idata0, idata1, idata2);
585
 
        idata0 += plane_size;
586
 
        idata1 += plane_size;
587
 
        idata2 += plane_size;
588
 
        plane_size >>= 2;
589
 
        w >>= 1;
590
 
        h >>= 1;
591
 
        if (chanmask & 2)(*process_routine)(x, w, h, idata0, idata1, idata2);
592
 
        idata0 += plane_size;
593
 
        idata1 += plane_size;
594
 
        idata2 += plane_size;
595
 
        if (chanmask & 4)(*process_routine)(x, w, h, idata0, idata1, idata2);
596
 
        break;
597
 
    case PDP_IMAGE_MCHP:
598
 
        mask = 1;
599
 
        while (d--){
600
 
            if (chanmask & mask) (*process_routine)(x, w, h, idata0, idata1, idata2);
601
 
            idata0 += plane_size;
602
 
            idata1 += plane_size;
603
 
            idata2 += plane_size;
604
 
            mask <<= 1;
605
 
        }
606
 
        break;
607
 
    default:
608
 
        break;
609
 
    }
610
 
}