7936e05a5056d1d941a06c1769cee31030449996
[oweals/cde.git] / cde / lib / DtHelp / il / iltruegray.c
1 /* $XConsortium: iltruegray.c /main/3 1995/10/23 16:02:03 rswiston $ */
2 /**---------------------------------------------------------------------
3 ***     
4 ***    (c)Copyright 1991 Hewlett-Packard Co.
5 ***    
6 ***                             RESTRICTED RIGHTS LEGEND
7 ***    Use, duplication, or disclosure by the U.S. Government is subject to
8 ***    restrictions as set forth in sub-paragraph (c)(1)(ii) of the Rights in
9 ***    Technical Data and Computer Software clause in DFARS 252.227-7013.
10 ***                             Hewlett-Packard Company
11 ***                             3000 Hanover Street
12 ***                             Palo Alto, CA 94304 U.S.A.
13 ***    Rights for non-DOD U.S. Government Departments and Agencies are as set
14 ***    forth in FAR 52.227-19(c)(1,2).
15 ***
16 ***-------------------------------------------------------------------*/
17
18 /* ======================================================================================
19      /ilc/iltruegray.c : Image Library conversion routines fron RGB to grayscale
20    =================================================================================== */
21
22
23 #include "ilint.h"
24 #include "ilpipelem.h"
25 #include "ilconvert.h"
26
27
28
29 typedef struct {
30     unsigned long   R[256], G[256], B[256]; /* RGB->gray multiply lookup table */
31     long            nPixels;                /* width of src/dst images */
32     long            srcRowBytes;            /* bytes/row of src image */
33     ilPtr           pSrcPixels;             /* ptr to start of src pixels */
34     long            dstRowBytes;            /* bytes/row of dst image */
35     ilPtr           pDstPixels;             /* ptr to start of dst pixels */
36     } ilRGBToGrayRec, *ilRGBToGrayRecPtr;
37
38
39 /* =============================================================================================================================
40              ilInitRGBToGray     -   Init() function.
41         NOTE: also used for Gray to RGB conversion below !
42    ============================================================================================================================= */
43
44
45 static ilError ilInitRGBGrayConversions (
46     ilRGBToGrayRecPtr  pPriv,
47     ilImageInfo        *pSrcImage,
48     ilImageInfo        *pDstImage
49     )
50 {
51
52     pPriv->nPixels = pSrcImage->width;
53     pPriv->srcRowBytes = pSrcImage->plane[0].nBytesPerRow;
54     pPriv->pSrcPixels = pSrcImage->plane[0].pPixels;
55     pPriv->dstRowBytes = pDstImage->plane[0].nBytesPerRow;
56     pPriv->pDstPixels = pDstImage->plane[0].pPixels;
57
58     return IL_OK;
59 }
60
61 /* =============================================================================================================================
62              ilAddElementRGBGrayConversions - AddElement() function
63         Called only for RGB->gray conversion: init RGB lookup/multiply tables in pPriv
64    ============================================================================================================================= */
65
66 static ilError ilAddElementRGBGrayConversions (
67     ilRGBToGrayRecPtr   pPriv,
68     unsigned short     *pPalette,           /* not used */
69     void               *pOptionData         /* not used */
70     )
71 {
72     register int        i;
73
74         /*  Init tables, index by R/G/B, which effectively multiply each component
75             (0..255) by the NTSC conversion formula: 0.30 * R + 0.587 * G + 0.114 * B,
76             except that each value is * 65536 for extra accuracy: the result is
77             shifted right by 16 before storing.
78             Note that "19660" would probably be more accurate at "19661", but the 
79             old code used 19660 and for that little difference it is silly to 
80             invalidate the old checksum tests.  Note also that if R/G/B are all = 255
81             the result is still <= 255 after the shift right.
82         */
83     for (i = 0; i < 256; i++) {
84         pPriv->R[i] = 19660 * i;
85         pPriv->G[i] = 38469 * i;
86         pPriv->B[i] = 7471 * i;
87         }
88     return IL_OK;
89 }
90
91
92 /* =============================================================================================================================
93             ilExecuteRGBToGray    -    Execute() function: convert the given # of src lines.
94
95          Converts RGB images to a grayscale with format byte per pixel.
96             Input image:   uncompressed IL_DES_RGB, IL_FORMAT_3BYTE_PIXEL
97             Output image:  uncompressed IL_GRAY, 255 levels, IL_FORMAT_BYTE.
98
99    ============================================================================================================================= */
100
101 static ilError ilExecuteRGBToGray  (
102     ilExecuteData          *pData,
103     long                    dstLine,
104     long                   *pNLines
105     )
106 {
107 register ilRGBToGrayRecPtr  pPriv;
108 long                        srcnbytes, dstnbytes;
109 register ilPtr              psrcline, pdstline;
110 register ilPtr              psrc, pdst;
111 register long               nLines, nPixels;
112 register INT32              i;
113
114
115
116     pPriv = (ilRGBToGrayRecPtr)pData->pPrivate;
117     srcnbytes = pPriv->srcRowBytes;
118     psrcline = pPriv->pSrcPixels + pData->srcLine * srcnbytes;
119     dstnbytes = pPriv->dstRowBytes;
120     pdstline = pPriv->pDstPixels + dstLine * dstnbytes;
121
122     if (pPriv->nPixels < 0)  return;
123
124     nLines = *pNLines;
125     if (nLines <= 0) return;
126
127     while ( nLines--  > 0 ) {
128
129           psrc = psrcline;
130           pdst = pdstline;
131           nPixels = pPriv->nPixels;
132
133           /*  --    grayscale from:     Y  =   0.30red  + 0.587green + 0.114blue    */
134           while ( nPixels--  >  0 ) {
135                 i = pPriv->R[*psrc++];
136                 i += pPriv->G[*psrc++];
137                 i += pPriv->B[*psrc++];
138                 *pdst++ = i >> 16;
139                 }
140
141           psrcline += srcnbytes;
142           pdstline += dstnbytes;
143     }
144
145
146     return IL_OK;
147 }
148
149
150 /* =============================================================================================================================
151           ilRGBToGray          -    Table exported to ilConvert(), declared in /ilc/ilconvert.h 
152    ============================================================================================================================= */
153
154 IL_PRIVATE ilConvertRec _ilRGBToGray = {
155     IL_NPF,                                     /* CheckFormat() */
156     IL_STD_FORMAT_3BYTE_PIXEL,                  /* srcFormatCode */
157     ilAddElementRGBGrayConversions,             /* AddElement() */
158     IL_DES_GRAY,                                /* pDstDes */
159     IL_FORMAT_BYTE,                             /* pDstFormat */
160     sizeof (ilRGBToGrayRec),                    /* nBytesPrivate */
161     ilInitRGBGrayConversions,                   /* Init() */
162     IL_NPF,                                     /* Cleanup() */
163     IL_NPF,                                     /* Destroy() */
164     ilExecuteRGBToGray                          /* Execute() */
165     };
166
167
168 /* =====================================================================================
169                                    GRAY TO RGB
170         Convert byte/pixel gray to 3byte/pixel rgb.
171
172    ==================================================================================== */
173
174 static ilError ilExecuteGrayToRGB  (
175     ilExecuteData          *pData,
176     long                    dstLine,
177     long                   *pNLines
178     )
179 {
180 ilRGBToGrayRecPtr           pPriv;
181 register long               nLinesM1, nPixelsM1;
182 long                        srcRowBytes, dstRowBytes, nPixelsM1Init;
183 ilPtr                       pSrcLine, pDstLine;
184 register ilPtr              pSrc, pDst;
185 register ilByte             byte;
186
187     pPriv = (ilRGBToGrayRecPtr)pData->pPrivate;
188     nPixelsM1Init = pPriv->nPixels - 1;
189     nLinesM1 = *pNLines - 1;
190     if ((nLinesM1 < 0) || (nPixelsM1Init < 0))
191         return IL_OK;
192
193     srcRowBytes = pPriv->srcRowBytes;
194     pSrcLine = pPriv->pSrcPixels + pData->srcLine * srcRowBytes;
195     dstRowBytes = pPriv->dstRowBytes;
196     pDstLine = pPriv->pDstPixels + dstLine * dstRowBytes;
197
198         /*  Simply replicate each gray byte 3 times to form RGB - tough, eh?
199             However if black not zero must invert the gray byte.
200         */
201     if (pData->pSrcImage->pDes->blackIsZero) {
202         do {
203             pSrc = pSrcLine;
204             pSrcLine += srcRowBytes;
205             pDst = pDstLine;
206             pDstLine += dstRowBytes;
207             nPixelsM1 = nPixelsM1Init;
208             do {
209                 byte = *pSrc++;
210                 *pDst++ = byte;
211                 *pDst++ = byte;
212                 *pDst++ = byte;
213                 } while (--nPixelsM1 >= 0);
214             } while (--nLinesM1 >= 0);
215         }
216     else {
217         do {
218             pSrc = pSrcLine;
219             pSrcLine += srcRowBytes;
220             pDst = pDstLine;
221             pDstLine += dstRowBytes;
222             nPixelsM1 = nPixelsM1Init;
223             do {
224                 byte = ~*pSrc++;
225                 *pDst++ = byte;
226                 *pDst++ = byte;
227                 *pDst++ = byte;
228                 } while (--nPixelsM1 >= 0);
229             } while (--nLinesM1 >= 0);
230         }
231
232     return IL_OK;
233 }
234
235
236 /* =====================================================================================
237           ilGrayToRGB  -    Table exported to ilConvert(), declared in /ilc/ilconvert.h 
238    ==================================================================================== */
239
240 IL_PRIVATE ilConvertRec _ilGrayToRGB = {
241     IL_NPF,                                     /* CheckFormat() */
242     IL_STD_FORMAT_BYTE,                         /* srcFormatCode */
243     IL_NPF,                                     /* AddElement() */
244     IL_DES_RGB,                                 /* pDstDes */
245     IL_FORMAT_3BYTE_PIXEL,                      /* pDstFormat */
246     sizeof (ilRGBToGrayRec),                    /* nBytesPrivate */
247     ilInitRGBGrayConversions,                   /* Init() */
248     IL_NPF,                                     /* Cleanup() */
249     IL_NPF,                                     /* Destroy() */
250     ilExecuteGrayToRGB                          /* Execute() */
251     };
252
253
254