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