lib/DtHelp/il: remove register keyword
[oweals/cde.git] / cde / lib / DtHelp / il / ilmirror.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these libraries and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* $XConsortium: ilmirror.c /main/4 1996/01/08 12:16:48 lehors $ */
24 /* =============================================================================================================================
25
26      /ilc/ilmirror.c : Images Library mirror routines.   
27
28
29
30         Date        Mail-ID     Description
31         --------    ----------- -------------------------------------------------------------------
32         07/11/91    larsson     Initial Coding.
33
34         
35
36    ============================================================================================================================= */
37
38 #include "ilint.h"
39 #include "ilpipelem.h"
40 #include "ilerrors.h"
41
42 #define LONGSZ        4
43 #define WORDPOS       32
44 #define BYTESIZE      8
45 #define LEFT_BIT_ON   0x80000000
46
47
48     /*  Table of bytes with equivalent bits flipped, in /ilc/ilrotate.c */
49 extern const unsigned char ilBitReverseTable [];
50
51
52  typedef struct {
53         int    illinecount;          /* running line count as pipe strips are executed */
54         int    ilMirrorheight;       /* src height value saved to avoid strip sizes  */
55  }  ilMirrorPriv,  *ilMirrorPrivptr;
56
57
58
59 /* =============================================================================================================================
60    ============================================================================================================================= */
61
62
63 static ilError ilMirrorInit(
64     ilMirrorPrivptr  pPrivate,
65     ilImageInfo     *pSrcImage,
66     ilImageInfo     *pDstImage
67     )
68
69 {
70  unsigned char  *pdstline;
71  ilImagePlaneInfo           *pplane;
72
73
74    /* Initialize counters */
75
76    pPrivate->illinecount =  1;
77             
78    /* Zero out destination memory for bitonal format handling */
79    pplane   = &pDstImage->plane[0];
80    pdstline =  (unsigned char *) (pplane->pPixels);
81
82    bzero((char *)pdstline, (pplane->nBytesPerRow * pPrivate->ilMirrorheight) );
83
84    return IL_OK;
85 }
86
87
88 /* =============================================================================================================================
89
90       ilMirrorXBitonalExecute  -  Vertical mirroring for images with bit per pixel format .
91
92    ============================================================================================================================= */
93 static ilError ilMirrorXBitonalExecute (
94     ilExecuteData  *pData,
95     unsigned long           dstLine,
96     unsigned long          *pNLines
97     )
98 {
99                         
100
101 unsigned char     *psrc, *pdst, *psrcline, *pdstline;
102 ilImagePlaneInfo           *pplane;
103 int               x, y, lastcount, srcnbytes, dstnbytes;
104 ilMirrorPrivptr   pPriv;
105
106
107
108    if (*pNLines <= 0)  return IL_OK;
109
110    pplane                  =  &pData->pSrcImage->plane[0];
111    srcnbytes               =  pplane->nBytesPerRow;
112    psrcline                =  (unsigned char *) (pplane->pPixels) +  pData->srcLine * srcnbytes;
113
114    pplane                  =  &pData->pDstImage->plane[0];
115    dstnbytes               =  pplane->nBytesPerRow;
116    pdstline                =  (unsigned char *) (pplane->pPixels)  +  dstLine * dstnbytes;
117    pPriv                   =  (ilMirrorPrivptr) pData->pPrivate;
118
119
120
121    /* Mirror vertically  map (x,y) to (x, -y) about its center  [ x,  height-y ]  */
122
123    lastcount = pPriv->illinecount - 1;
124    for (y = pPriv->illinecount;   y <= (lastcount + *pNLines);  y++, pPriv->illinecount++ )  {
125
126       psrc = psrcline;
127       pdst = pdstline + (dstnbytes * (pPriv->ilMirrorheight - y));
128       for ( x = 0;   x < srcnbytes;  x++)  *pdst++  = *psrc++;
129       psrcline += srcnbytes;
130
131    }
132
133
134    /* No. of lines written is the destination height */
135    if  ( pPriv->illinecount <= pPriv->ilMirrorheight ) *pNLines = 0;
136    else   *pNLines = pPriv->ilMirrorheight;
137    
138    return IL_OK;
139 }
140
141
142
143 /* =============================================================================================================================
144
145       ilMirrorYBitonalExecute  -  Horizontal mirroring for images with bit per pixel format .
146
147    ============================================================================================================================= */
148 static ilError ilMirrorYBitonalExecute (
149     ilExecuteData  *pData,
150     unsigned long           dstLine,
151     unsigned long          *pNLines
152     )
153 {
154                         
155
156 unsigned char     *psrc, *pdst, *psrcline, *psrcbefore, *pdstline;
157 unsigned char     srcbyte;
158 ilImagePlaneInfo           *pplane;
159 int               x, y, lastcount, loffset, roffset;
160 int               srcnbytes, dstnbytes, widthbytes;
161 ilMirrorPrivptr   pPriv;
162
163
164    if (*pNLines <= 0)  return IL_OK;
165
166    pplane                  =  &pData->pSrcImage->plane[0];
167    srcnbytes               =  pplane->nBytesPerRow;
168    psrcline                =  (unsigned char *) (pplane->pPixels) +  pData->srcLine * srcnbytes;
169
170    pplane                  =  &pData->pDstImage->plane[0];
171    dstnbytes               =  pplane->nBytesPerRow;
172    pdstline                =  (unsigned char *) (pplane->pPixels)  +  dstLine * dstnbytes;
173    pPriv                   =  (ilMirrorPrivptr) pData->pPrivate;
174
175
176    loffset    = pData->pSrcImage->width % BYTESIZE;
177    roffset    = BYTESIZE - loffset;
178    widthbytes = pData->pSrcImage->width / BYTESIZE;
179    if ( loffset > 0 ) widthbytes++;
180
181
182    /* Mirror horizontally  map (x,y) to (-x, y) about its center  [ width-x,  y ]  */
183
184    lastcount = pPriv->illinecount - 1;
185    for (y = lastcount;   y < (lastcount + *pNLines);  y++, pPriv->illinecount++ )  {
186
187       psrc       = psrcline + widthbytes - 1;
188       psrcbefore = psrc - 1;
189
190       pdst = pdstline + (dstnbytes * y);
191
192       if ( loffset == 0 ) 
193            for ( x = 0;  x < widthbytes;  x++)   *pdst++ = ilBitReverseTable[ *psrc-- ];
194       else  { 
195            for ( x = 0;   x < widthbytes;  x++) {
196
197                    if ( psrcbefore < psrcline )    srcbyte = (*psrc >> roffset);
198                    else       srcbyte = (*psrcbefore << loffset) | (*psrc >> roffset);
199
200                    *pdst++  =  ilBitReverseTable[srcbyte];
201                    psrc--;
202                    psrcbefore--;
203            }
204       }
205
206       psrcline += srcnbytes;
207    }
208
209
210    /* No. of lines written is the destination height */
211    if  ( pPriv->illinecount <= pPriv->ilMirrorheight ) *pNLines = 0;
212    else   *pNLines = pPriv->ilMirrorheight;
213    
214    return IL_OK;
215 }
216
217 /* =============================================================================================================================
218
219       ilMirrorX3ByteExecute  -  Vertical mirroring for images with 24 bits per pixel format .
220
221    ============================================================================================================================= */
222 static ilError ilMirrorX3ByteExecute (
223     ilExecuteData   *pData,
224     unsigned long           dstLine,
225     unsigned long          *pNLines
226     )
227 {
228
229
230 unsigned char     *psrc, *pdst, *psrcline, *pdstline;
231 unsigned long     srcnbytes, dstnbytes;
232 ilImagePlaneInfo           *pplane;
233 int               x, y, lastcount;
234 ilMirrorPrivptr   pPriv;
235
236
237    if (*pNLines <= 0)  return IL_OK;
238
239    pplane                  =  &pData->pSrcImage->plane[0];
240    srcnbytes               =  pplane->nBytesPerRow;
241    psrcline                =  (unsigned char *) (pplane->pPixels) +  pData->srcLine * srcnbytes;
242
243    pplane                  =  &pData->pDstImage->plane[0];
244    dstnbytes               =  pplane->nBytesPerRow;
245    pdstline                =  (unsigned char *) (pplane->pPixels)  +  dstLine * dstnbytes;
246    pPriv                   =  (ilMirrorPrivptr) pData->pPrivate;
247
248
249
250    /* Mirror vertically  map (x,y) to (x, -y) about its center  [ x,  height-y ]  */
251
252    lastcount = pPriv->illinecount - 1;
253    for (y = pPriv->illinecount;   y <= (lastcount + *pNLines);  y++, pPriv->illinecount++ )  {
254
255       psrc = psrcline;
256
257       pdst = pdstline + (dstnbytes * (pPriv->ilMirrorheight - y));
258       for ( x = 0;   x < pData->pSrcImage->width;  x++) {
259            *pdst++  =  *psrc++;
260            *pdst++  =  *psrc++;
261            *pdst++  =  *psrc++;
262       }
263       psrcline += srcnbytes;
264
265    }
266
267
268    /* No. of lines written is the destination height */
269    if  ( pPriv->illinecount <= pPriv->ilMirrorheight ) *pNLines = 0;
270    else   *pNLines = pPriv->ilMirrorheight;
271    
272    return IL_OK;
273 }
274
275
276 /* =============================================================================================================================
277
278       ilMirrorY3ByteExecute  -  Horizontal mirroring for images with 24 bits per pixel format .
279
280    ============================================================================================================================= */
281 static ilError ilMirrorY3ByteExecute (
282     ilExecuteData   *pData,
283     unsigned long           dstLine,
284     unsigned long          *pNLines
285     )
286 {
287
288
289 unsigned char     *psrc, *pdst, *psrcline, *pdstline;
290 unsigned long     srcnbytes, dstnbytes;
291 ilImagePlaneInfo           *pplane;
292 int               x, y, xoffset, lastcount;
293 ilMirrorPrivptr   pPriv;
294
295
296    if (*pNLines <= 0)  return IL_OK;
297
298    pplane                  =  &pData->pSrcImage->plane[0];
299    srcnbytes               =  pplane->nBytesPerRow;
300    psrcline                =  (unsigned char *) (pplane->pPixels) +  pData->srcLine * srcnbytes;
301
302    pplane                  =  &pData->pDstImage->plane[0];
303    dstnbytes               =  pplane->nBytesPerRow;
304    pdstline                =  (unsigned char *) (pplane->pPixels)  +  dstLine * dstnbytes;
305    pPriv                   =  (ilMirrorPrivptr) pData->pPrivate;
306
307
308
309    /* Mirror horizontally  map (x,y) to (-x, y) about its center  [ width-x,  y ]  */
310
311    xoffset = pData->pSrcImage->width * 3;
312
313    lastcount = pPriv->illinecount - 1;
314    for (y = lastcount;   y < (lastcount + *pNLines);  y++, pPriv->illinecount++ )  {
315
316       psrc = psrcline + 2;
317
318       pdst = pdstline + (dstnbytes * y) + xoffset - 1;
319       for ( x = 0;   x < pData->pSrcImage->width;  x++,  psrc += 5) {
320                 *pdst--  =  *psrc--;
321                 *pdst--  =  *psrc--;
322                 *pdst--  =  *psrc;
323       }
324       psrcline += srcnbytes;
325       
326    }
327
328
329    /* No. of lines written is the destination height */
330    if  ( pPriv->illinecount <= pPriv->ilMirrorheight ) *pNLines = 0;
331    else   *pNLines = pPriv->ilMirrorheight;
332    
333    return IL_OK;
334 }
335
336
337 /* =============================================================================================================================
338
339       ilMirrorXByteExecute  -  Vertical mirroring for images with byte per pixel format .
340
341    ============================================================================================================================= */
342 static ilError ilMirrorXByteExecute (
343     ilExecuteData   *pData,
344     unsigned long           dstLine,
345     unsigned long          *pNLines
346     )
347 {
348
349
350 unsigned char     *psrc, *pdst, *psrcline, *pdstline;
351 unsigned long     srcnbytes, dstnbytes;
352 ilImagePlaneInfo           *pplane;
353 int               x, y, lastcount;
354 ilMirrorPrivptr   pPriv;
355
356
357    if (*pNLines <= 0)  return IL_OK;
358
359    pplane                  =  &pData->pSrcImage->plane[0];
360    srcnbytes               =  pplane->nBytesPerRow;
361    psrcline                =  (unsigned char *) (pplane->pPixels) +  pData->srcLine * srcnbytes;
362
363    pplane                  =  &pData->pDstImage->plane[0];
364    dstnbytes               =  pplane->nBytesPerRow;
365    pdstline                =  (unsigned char *) (pplane->pPixels)  +  dstLine * dstnbytes;
366    pPriv                   =  (ilMirrorPrivptr) pData->pPrivate;
367
368
369
370
371    /* Mirror vertically  map (x,y) to (x, -y) about its center  [ x,  height-y ]  */
372
373    lastcount = pPriv->illinecount - 1;
374    for (y = pPriv->illinecount;   y <= (lastcount + *pNLines);  y++, pPriv->illinecount++ )  {
375
376       psrc = psrcline;
377       pdst = pdstline + (dstnbytes * (pPriv->ilMirrorheight - y));
378       for ( x = 0;   x < pData->pSrcImage->width;  x++) *pdst++  =  *psrc++;
379       psrcline += srcnbytes;
380
381    }
382
383
384    /* No. of lines written is the destination height */
385    if  ( pPriv->illinecount <= pPriv->ilMirrorheight ) *pNLines = 0;
386    else   *pNLines = pPriv->ilMirrorheight;
387    
388    return IL_OK;
389 }                       
390
391
392 /* =============================================================================================================================
393
394       ilMirrorYByteExecute  -  Horizontal mirroring for images with byte per pixel format .
395
396    ============================================================================================================================= */
397 static ilError ilMirrorYByteExecute (
398     ilExecuteData   *pData,
399     unsigned long           dstLine,
400     unsigned long          *pNLines
401     )
402 {
403
404
405 unsigned char     *psrc, *pdst, *psrcline, *pdstline;
406 unsigned long     srcnbytes, dstnbytes;
407 ilImagePlaneInfo           *pplane;
408 int               x, y, lastcount;
409 ilMirrorPrivptr   pPriv;
410
411
412    if (*pNLines <= 0)  return IL_OK;
413
414    pplane                  =  &pData->pSrcImage->plane[0];
415    srcnbytes               =  pplane->nBytesPerRow;
416    psrcline                =  (unsigned char *) (pplane->pPixels) +  pData->srcLine * srcnbytes;
417
418    pplane                  =  &pData->pDstImage->plane[0];
419    dstnbytes               =  pplane->nBytesPerRow;
420    pdstline                =  (unsigned char *) (pplane->pPixels)  +  dstLine * dstnbytes;
421    pPriv                   =  (ilMirrorPrivptr) pData->pPrivate;
422
423
424
425
426    /* Mirror horizontally  map (x,y) to (-x, y) about its center  [ width-x,  y ]  */
427
428    lastcount = pPriv->illinecount - 1;
429    for (y = lastcount;   y < (lastcount + *pNLines);  y++, pPriv->illinecount++ )  {
430
431       psrc = psrcline;
432       pdst = pdstline + (dstnbytes * y) + srcnbytes - 1;
433       for ( x = 0;   x < pData->pSrcImage->width;  x++) *pdst--  =  *psrc++;
434       psrcline += srcnbytes;
435
436    }
437
438
439    /* No. of lines written is the destination height */
440    if  ( pPriv->illinecount <= pPriv->ilMirrorheight ) *pNLines = 0;
441    else   *pNLines = pPriv->ilMirrorheight;
442    
443    return IL_OK;
444 }
445
446 /* =============================================================================================================================
447
448       ilMirror -  Add a mirror filter to an existing pipe  - checking for format types 
449                   and doing an explicit conversion if necessary.  Direction parameter
450                   specifies verticle (MIRRORX) or horizontal (MIRRORY).
451                   
452
453    ============================================================================================================================= */
454
455 ilBool ilMirror (
456     ilPipe              pipe,
457     int                 direction
458     )
459
460 {
461 unsigned int              state;
462 ilPipeInfo                info;
463 ilMirrorPrivptr  pPriv;
464 ilDstElementData          dstdata;
465 ilImageDes                imdes;
466 ilImageFormat             imformat;
467 ilBool                    convert;
468 ilBool                    bitonal;
469 ilBool                    cw;
470 unsigned int              rtype;
471
472
473        /* Get ptr to pipe info and check state */
474
475        state = ilGetPipeInfo(pipe, TRUE, &info, &imdes, &imformat);
476        if(state != IL_PIPE_FORMING) {
477          if (!pipe->context->error)
478              ilDeclarePipeInvalid(pipe, IL_ERROR_PIPE_STATE);
479          return FALSE;
480        }
481
482
483        bitonal = FALSE;
484
485        /* Check for valid Formats */
486        convert = FALSE;
487        switch (imdes.nSamplesPerPixel)  {
488             case  3: /* RGB or YUV */  
489                      if(imformat.sampleOrder != IL_SAMPLE_PIXELS)  { 
490                            imformat.sampleOrder = IL_SAMPLE_PIXELS;
491                            convert = TRUE;
492                      }
493
494                      if((imformat.nBitsPerSample[0] != 8) ||
495                         (imformat.nBitsPerSample[1] != 8) ||
496                         (imformat.nBitsPerSample[2] != 8))  {
497
498                           imformat.nBitsPerSample[0] = 8;
499                           imformat.nBitsPerSample[1] = 8;
500                           imformat.nBitsPerSample[2] = 8;
501                           convert = TRUE;
502                      }
503                      break;
504
505             case  1:
506                      switch (imformat.nBitsPerSample[0]) {
507                              case 8:  /* Byte per pixel */
508                                       break;
509
510                              case 1:  /* Bitonal */
511                                       bitonal = TRUE; 
512                                       if (imformat.rowBitAlign != 32) {
513                                          imformat.rowBitAlign = 32;
514                                          convert = TRUE;
515                                       }
516                                       break;
517
518                              default: /* something other than 1 - try 8 */
519                                       imformat.nBitsPerSample[0] = 8;
520                                       convert = TRUE;
521                      }  
522                      break;
523
524             default:
525                       return ilDeclarePipeInvalid(pipe, IL_ERROR_NOT_IMPLEMENTED);
526        }
527
528
529        if(convert) {
530             if (!ilConvert(pipe, &imdes, &imformat, 0, NULL))
531                 return FALSE;
532             ilGetPipeInfo (pipe, FALSE, &info, (ilImageDes *)NULL, (ilImageFormat *)NULL);
533        }
534          
535
536        /* if invalid direction flag as an error */
537        if ((direction != IL_MIRRORX) && (direction != IL_MIRRORY))
538             return ilDeclarePipeInvalid(pipe, IL_ERROR_INVALID_OPTION);
539
540        dstdata.producerObject = (ilObject) NULL;
541        dstdata.pDes           = (ilImageDes *) NULL;
542        dstdata.pFormat        = (ilImageFormat *) NULL;
543        dstdata.pPalette       = info.pPalette;
544
545        dstdata.width          = info.width;
546        dstdata.height         = info.height;
547
548        /* set output strip height */
549        dstdata.stripHeight    = dstdata.height;
550        dstdata.constantStrip  = TRUE;
551
552
553        switch (imdes.nSamplesPerPixel) {
554             case 3:            
555                       switch (direction) {
556                         case IL_MIRRORX:
557                                pPriv = (ilMirrorPrivptr) ilAddPipeElement(pipe, IL_FILTER, sizeof(ilMirrorPriv), 0, (ilSrcElementData *) NULL,
558                                                                           &dstdata, ilMirrorInit, IL_NPF, IL_NPF, ilMirrorX3ByteExecute, 0);
559                                break;
560                         case IL_MIRRORY:
561                                pPriv = (ilMirrorPrivptr) ilAddPipeElement(pipe, IL_FILTER, sizeof(ilMirrorPriv), 0, (ilSrcElementData *) NULL,
562                                                                           &dstdata, ilMirrorInit, IL_NPF, IL_NPF, ilMirrorY3ByteExecute, 0);
563                       }
564                       break;
565
566             case 1:  
567                  if(bitonal) {
568                       switch (direction) {
569                         case IL_MIRRORX:
570                                pPriv = (ilMirrorPrivptr) ilAddPipeElement(pipe, IL_FILTER, sizeof(ilMirrorPriv), 0, (ilSrcElementData *) NULL,
571                                                                           &dstdata, ilMirrorInit, IL_NPF, IL_NPF, ilMirrorXBitonalExecute, 0);
572                                break;
573                         case IL_MIRRORY:
574                                pPriv = (ilMirrorPrivptr) ilAddPipeElement(pipe, IL_FILTER, sizeof(ilMirrorPriv), 0, (ilSrcElementData *) NULL,
575                                                                           &dstdata, ilMirrorInit, IL_NPF, IL_NPF, ilMirrorYBitonalExecute, 0);
576                       }
577                  }
578                  else {
579                       switch (direction) {
580                         case IL_MIRRORX:
581                                pPriv = (ilMirrorPrivptr) ilAddPipeElement(pipe, IL_FILTER, sizeof(ilMirrorPriv), 0, (ilSrcElementData *) NULL,
582                                                                           &dstdata, ilMirrorInit, IL_NPF, IL_NPF, ilMirrorXByteExecute, 0);
583                                break;
584                         case IL_MIRRORY:
585                                pPriv = (ilMirrorPrivptr) ilAddPipeElement(pipe, IL_FILTER, sizeof(ilMirrorPriv), 0, (ilSrcElementData *) NULL,
586                                                                           &dstdata, ilMirrorInit, IL_NPF, IL_NPF, ilMirrorYByteExecute, 0);
587                       }
588                  }
589
590        }
591
592        if(!pPriv)
593             return FALSE;
594
595        /* Save away true height */
596        pPriv->ilMirrorheight = info.height;   
597
598        pipe->context->error = IL_OK;
599        return TRUE;
600 }
601
602