1 /* $XConsortium: iltruegray.c /main/3 1995/10/23 16:02:03 rswiston $ */
2 /**---------------------------------------------------------------------
4 *** (c)Copyright 1991 Hewlett-Packard Co.
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).
16 ***-------------------------------------------------------------------*/
18 /* ======================================================================================
19 /ilc/iltruegray.c : Image Library conversion routines fron RGB to grayscale
20 =================================================================================== */
24 #include "ilpipelem.h"
25 #include "ilconvert.h"
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;
39 /* =============================================================================================================================
40 ilInitRGBToGray - Init() function.
41 NOTE: also used for Gray to RGB conversion below !
42 ============================================================================================================================= */
45 static ilError ilInitRGBGrayConversions (
46 ilRGBToGrayRecPtr pPriv,
47 ilImageInfo *pSrcImage,
48 ilImageInfo *pDstImage
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;
61 /* =============================================================================================================================
62 ilAddElementRGBGrayConversions - AddElement() function
63 Called only for RGB->gray conversion: init RGB lookup/multiply tables in pPriv
64 ============================================================================================================================= */
66 static ilError ilAddElementRGBGrayConversions (
67 ilRGBToGrayRecPtr pPriv,
68 unsigned short *pPalette, /* not used */
69 void *pOptionData /* not used */
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.
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;
92 /* =============================================================================================================================
93 ilExecuteRGBToGray - Execute() function: convert the given # of src lines.
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.
99 ============================================================================================================================= */
101 static ilError ilExecuteRGBToGray (
102 ilExecuteData *pData,
107 register ilRGBToGrayRecPtr pPriv;
108 long srcnbytes, dstnbytes;
109 register ilPtr psrcline, pdstline;
110 register ilPtr psrc, pdst;
111 register long nLines, nPixels;
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;
122 if (pPriv->nPixels < 0) return;
125 if (nLines <= 0) return;
127 while ( nLines-- > 0 ) {
131 nPixels = pPriv->nPixels;
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++];
141 psrcline += srcnbytes;
142 pdstline += dstnbytes;
150 /* =============================================================================================================================
151 ilRGBToGray - Table exported to ilConvert(), declared in /ilc/ilconvert.h
152 ============================================================================================================================= */
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() */
168 /* =====================================================================================
170 Convert byte/pixel gray to 3byte/pixel rgb.
172 ==================================================================================== */
174 static ilError ilExecuteGrayToRGB (
175 ilExecuteData *pData,
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;
187 pPriv = (ilRGBToGrayRecPtr)pData->pPrivate;
188 nPixelsM1Init = pPriv->nPixels - 1;
189 nLinesM1 = *pNLines - 1;
190 if ((nLinesM1 < 0) || (nPixelsM1Init < 0))
193 srcRowBytes = pPriv->srcRowBytes;
194 pSrcLine = pPriv->pSrcPixels + pData->srcLine * srcRowBytes;
195 dstRowBytes = pPriv->dstRowBytes;
196 pDstLine = pPriv->pDstPixels + dstLine * dstRowBytes;
198 /* Simply replicate each gray byte 3 times to form RGB - tough, eh?
199 However if black not zero must invert the gray byte.
201 if (pData->pSrcImage->pDes->blackIsZero) {
204 pSrcLine += srcRowBytes;
206 pDstLine += dstRowBytes;
207 nPixelsM1 = nPixelsM1Init;
213 } while (--nPixelsM1 >= 0);
214 } while (--nLinesM1 >= 0);
219 pSrcLine += srcRowBytes;
221 pDstLine += dstRowBytes;
222 nPixelsM1 = nPixelsM1Init;
228 } while (--nPixelsM1 >= 0);
229 } while (--nLinesM1 >= 0);
236 /* =====================================================================================
237 ilGrayToRGB - Table exported to ilConvert(), declared in /ilc/ilconvert.h
238 ==================================================================================== */
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() */