2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
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)
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
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
23 /* $XConsortium: iltruegray.c /main/3 1995/10/23 16:02:03 rswiston $ */
24 /**---------------------------------------------------------------------
26 *** (c)Copyright 1991 Hewlett-Packard Co.
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).
38 ***-------------------------------------------------------------------*/
40 /* ======================================================================================
41 /ilc/iltruegray.c : Image Library conversion routines fron RGB to grayscale
42 =================================================================================== */
46 #include "ilpipelem.h"
47 #include "ilconvert.h"
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;
61 /* =============================================================================================================================
62 ilInitRGBToGray - Init() function.
63 NOTE: also used for Gray to RGB conversion below !
64 ============================================================================================================================= */
67 static ilError ilInitRGBGrayConversions (
68 ilRGBToGrayRecPtr pPriv,
69 ilImageInfo *pSrcImage,
70 ilImageInfo *pDstImage
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;
83 /* =============================================================================================================================
84 ilAddElementRGBGrayConversions - AddElement() function
85 Called only for RGB->gray conversion: init RGB lookup/multiply tables in pPriv
86 ============================================================================================================================= */
88 static ilError ilAddElementRGBGrayConversions (
89 ilRGBToGrayRecPtr pPriv,
90 unsigned short *pPalette, /* not used */
91 void *pOptionData /* not used */
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.
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;
114 /* =============================================================================================================================
115 ilExecuteRGBToGray - Execute() function: convert the given # of src lines.
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.
121 ============================================================================================================================= */
123 static ilError ilExecuteRGBToGray (
124 ilExecuteData *pData,
129 register ilRGBToGrayRecPtr pPriv;
130 long srcnbytes, dstnbytes;
131 register ilPtr psrcline, pdstline;
132 register ilPtr psrc, pdst;
133 register long nLines, nPixels;
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;
144 if (pPriv->nPixels < 0) return;
147 if (nLines <= 0) return;
149 while ( nLines-- > 0 ) {
153 nPixels = pPriv->nPixels;
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++];
163 psrcline += srcnbytes;
164 pdstline += dstnbytes;
172 /* =============================================================================================================================
173 ilRGBToGray - Table exported to ilConvert(), declared in /ilc/ilconvert.h
174 ============================================================================================================================= */
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() */
190 /* =====================================================================================
192 Convert byte/pixel gray to 3byte/pixel rgb.
194 ==================================================================================== */
196 static ilError ilExecuteGrayToRGB (
197 ilExecuteData *pData,
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;
209 pPriv = (ilRGBToGrayRecPtr)pData->pPrivate;
210 nPixelsM1Init = pPriv->nPixels - 1;
211 nLinesM1 = *pNLines - 1;
212 if ((nLinesM1 < 0) || (nPixelsM1Init < 0))
215 srcRowBytes = pPriv->srcRowBytes;
216 pSrcLine = pPriv->pSrcPixels + pData->srcLine * srcRowBytes;
217 dstRowBytes = pPriv->dstRowBytes;
218 pDstLine = pPriv->pDstPixels + dstLine * dstRowBytes;
220 /* Simply replicate each gray byte 3 times to form RGB - tough, eh?
221 However if black not zero must invert the gray byte.
223 if (pData->pSrcImage->pDes->blackIsZero) {
226 pSrcLine += srcRowBytes;
228 pDstLine += dstRowBytes;
229 nPixelsM1 = nPixelsM1Init;
235 } while (--nPixelsM1 >= 0);
236 } while (--nLinesM1 >= 0);
241 pSrcLine += srcRowBytes;
243 pDstLine += dstRowBytes;
244 nPixelsM1 = nPixelsM1Init;
250 } while (--nPixelsM1 >= 0);
251 } while (--nLinesM1 >= 0);
258 /* =====================================================================================
259 ilGrayToRGB - Table exported to ilConvert(), declared in /ilc/ilconvert.h
260 ==================================================================================== */
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() */