1 /* libhpojip -- HP OfficeJet image-processing library. */
3 /* Copyright (C) 1995-2002 Hewlett-Packard Company
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of the
8 * License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful, but
11 * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied
12 * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and
13 * NON-INFRINGEMENT. See the GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
20 * In addition, as a special exception, Hewlett-Packard Company
21 * gives permission to link the code of this program with any
22 * version of the OpenSSL library which is distributed under a
23 * license identical to that listed in the included LICENSE.OpenSSL
24 * file, and distribute linked combinations including the two.
25 * You must obey the GNU General Public License in all respects
26 * for all of the code used other than OpenSSL. If you modify
27 * this file, you may extend this exception to your version of the
28 * file, but you are not obligated to do so. If you do not wish to
29 * do so, delete this exception statement from your version.
32 /* Original author: Mark Overton and others.
34 * Ported to Linux by David Paschal.
37 /******************************************************************************\
39 * xyxtract.c - Y-extract - Extracts Y-component from YCC color data
41 ******************************************************************************
43 * Name of Global Jump-Table:
47 * Items in aXformInfo array passed into setXformSpec:
49 * xXformInfo[IP_Y_EXTRACT_COLOR_SPACE] tells us something about the color-space
50 * of input data: See the enum IP_Y_EXTRACT_WHICH_SPACE:
51 * IP_Y_EXTRACT_LUM_CHROME = luminance-chrominance, we merely fetch 1st component,
52 * IP_Y_EXTRACT_RGB = input is RGB,
53 * IP_Y_EXTRACT_BGR = input is BGR.
55 * Capabilities and Limitations:
57 * Inputs rows of 24-bit color data, and outputs rows of 8-bit gray
58 * consisting of the first component of the color data.
60 * Default Input Traits, and Output Traits:
62 * trait default input output
63 * ------------------- --------------------- ------------------------
64 * iPixelsPerRow * passed into output same as default input
65 * iBitsPerPixel * must be 24 8
66 * iComponentsPerPixel * must be 3 1
67 * lHorizDPI passed into output same as default input
68 * lVertDPI passed into output same as default input
69 * lNumRows passed into output same as default input
70 * iNumPages passed into output same as default input
71 * iPageNum passed into output same as default input
73 * Above, a "*" by an item indicates it must be valid (not negative).
75 * Jan 1998 Mark Overton -- wrote code
77 \******************************************************************************/
81 #include "string.h" /* for memset and memcpy */
88 #define PRINT(msg,arg1,arg2) \
89 _ftprintf(stderr, msg, (int)arg1, (int)arg2)
91 #define PRINT(msg,arg1,arg2)
94 #define CHECK_VALUE 0x1ce5ca7e
97 IP_IMAGE_TRAITS inTraits; /* traits of the input image */
98 IP_Y_EXTRACT_WHICH_SPACE eInputType; /* type of input data */
99 DWORD dwRowsDone; /* number of rows converted so far */
100 DWORD dwInNextPos; /* file pos for subsequent input */
101 DWORD dwOutNextPos; /* file pos for subsequent output */
102 DWORD dwValidChk; /* struct validity check value */
103 } YEX_INST, *PYEX_INST;
107 /*****************************************************************************\
109 * yXtract_openXform - Creates a new instance of the transformer
111 *****************************************************************************
113 * This returns a handle for the new instance to be passed into
114 * all subsequent calls.
116 * Return value: IP_DONE=success; IP_FATAL_ERROR=misc error.
118 \*****************************************************************************/
120 static WORD yXtract_openXform (
121 IP_XFORM_HANDLE *pXform) /* out: returned handle */
125 INSURE (pXform != NULL);
126 IP_MEM_ALLOC (sizeof(YEX_INST), g);
128 memset (g, 0, sizeof(YEX_INST));
129 g->dwValidChk = CHECK_VALUE;
133 return IP_FATAL_ERROR;
138 /*****************************************************************************\
140 * yXtract_setDefaultInputTraits - Specifies default input image traits
142 *****************************************************************************
144 * The header of the file-type handled by the transform probably does
145 * not include *all* the image traits we'd like to know. Those not
146 * specified in the file-header are filled in from info provided by
149 * Return value: IP_DONE=success; IP_FATAL_ERROR=misc error.
151 \*****************************************************************************/
153 static WORD yXtract_setDefaultInputTraits (
154 IP_XFORM_HANDLE hXform, /* in: handle for xform */
155 PIP_IMAGE_TRAITS pTraits) /* in: default image traits */
159 HANDLE_TO_PTR (hXform, g);
161 /* Insure that values we care about are correct */
162 INSURE (pTraits->iBitsPerPixel == 24);
163 INSURE (pTraits->iComponentsPerPixel == 3);
164 INSURE (pTraits->iPixelsPerRow > 0);
166 g->inTraits = *pTraits; /* a structure copy */
170 return IP_FATAL_ERROR;
175 /*****************************************************************************\
177 * yXtract_setXformSpec - Provides xform-specific information
179 \*****************************************************************************/
181 static WORD yXtract_setXformSpec (
182 IP_XFORM_HANDLE hXform, /* in: handle for xform */
183 DWORD_OR_PVOID aXformInfo[]) /* in: xform information */
186 HANDLE_TO_PTR (hXform, g);
187 g->eInputType = (IP_Y_EXTRACT_WHICH_SPACE)aXformInfo[IP_Y_EXTRACT_COLOR_SPACE].dword;
191 return IP_FATAL_ERROR;
196 /*****************************************************************************\
198 * yXtract_getHeaderBufSize- Returns size of input buf needed to hold header
200 \*****************************************************************************/
202 static WORD yXtract_getHeaderBufSize (
203 IP_XFORM_HANDLE hXform, /* in: handle for xform */
204 DWORD *pdwInBufLen) /* out: buf size for parsing header */
206 /* since input is raw pixels, there is no header, so set it to zero */
213 /*****************************************************************************\
215 * yXtract_getActualTraits - Parses header, and returns input & output traits
217 \*****************************************************************************/
219 static WORD yXtract_getActualTraits (
220 IP_XFORM_HANDLE hXform, /* in: handle for xform */
221 DWORD dwInputAvail, /* in: # avail bytes in input buf */
222 PBYTE pbInputBuf, /* in: ptr to input buffer */
223 PDWORD pdwInputUsed, /* out: # bytes used from input buf */
224 PDWORD pdwInputNextPos,/* out: file-pos to read from next */
225 PIP_IMAGE_TRAITS pInTraits, /* out: input image traits */
226 PIP_IMAGE_TRAITS pOutTraits) /* out: output image traits */
230 HANDLE_TO_PTR (hXform, g);
232 /* Since there is no header, we'll report no usage of input */
234 *pdwInputNextPos = 0;
236 *pInTraits = g->inTraits;
237 *pOutTraits = g->inTraits;
238 pOutTraits->iBitsPerPixel = 8;
239 pOutTraits->iComponentsPerPixel = 1;
241 return IP_DONE | IP_READY_FOR_DATA;
244 return IP_FATAL_ERROR;
249 /****************************************************************************\
251 * yXtract_getActualBufSizes - Returns buf sizes needed for remainder of job
253 \****************************************************************************/
255 static WORD yXtract_getActualBufSizes (
256 IP_XFORM_HANDLE hXform, /* in: handle for xform */
257 PDWORD pdwMinInBufLen, /* out: min input buf size */
258 PDWORD pdwMinOutBufLen) /* out: min output buf size */
262 HANDLE_TO_PTR (hXform, g);
263 *pdwMinInBufLen = 3 * g->inTraits.iPixelsPerRow;
264 *pdwMinOutBufLen = g->inTraits.iPixelsPerRow;
269 return IP_FATAL_ERROR;
274 /*****************************************************************************\
276 * yXtract_convert - Converts one row
278 \*****************************************************************************/
280 static WORD yXtract_convert (
281 IP_XFORM_HANDLE hXform,
282 DWORD dwInputAvail, /* in: # avail bytes in in-buf */
283 PBYTE pbInputBuf, /* in: ptr to in-buffer */
284 PDWORD pdwInputUsed, /* out: # bytes used from in-buf */
285 PDWORD pdwInputNextPos, /* out: file-pos to read from next */
286 DWORD dwOutputAvail, /* in: # avail bytes in out-buf */
287 PBYTE pbOutputBuf, /* in: ptr to out-buffer */
288 PDWORD pdwOutputUsed, /* out: # bytes written in out-buf */
289 PDWORD pdwOutputThisPos) /* out: file-pos to write the data */
292 int inBytes, outBytes;
293 PBYTE pIn, pOut, pOutAfter;
296 HANDLE_TO_PTR (hXform, g);
298 /**** Check if we were told to flush ****/
300 if (pbInputBuf == NULL) {
301 PRINT (_T("yXtract_convert: Told to flush.\n"), 0, 0);
302 *pdwInputUsed = *pdwOutputUsed = 0;
303 *pdwInputNextPos = g->dwInNextPos;
304 *pdwOutputThisPos = g->dwOutNextPos;
308 /**** Output a Row ****/
310 outBytes = g->inTraits.iPixelsPerRow;
311 inBytes = 3 * outBytes;
312 INSURE (dwInputAvail >= (DWORD)inBytes );
313 INSURE (dwOutputAvail >= (DWORD)outBytes);
317 pOutAfter = pOut + outBytes;
319 switch (g->eInputType) {
320 case IP_Y_EXTRACT_LUM_CHROME:
321 while (pOut < pOutAfter) {
327 case IP_Y_EXTRACT_RGB:
328 while (pOut < pOutAfter) {
329 red = (UINT)(*pIn++);
330 grn = (UINT)(*pIn++);
331 blu = (UINT)(*pIn++);
332 /* the formula below is: Y = (5*R + 9*G + 2*B) / 16 */
334 (BYTE)((((red<<2)+red) + ((grn<<3)+grn) + (blu<<1) + 8) >> 4);
338 case IP_Y_EXTRACT_BGR:
339 while (pOut < pOutAfter) {
340 blu = (UINT)(*pIn++);
341 grn = (UINT)(*pIn++);
342 red = (UINT)(*pIn++);
343 /* the formula below is: Y = (5*R + 9*G + 2*B) / 16 */
345 (BYTE)((((red<<2)+red) + ((grn<<3)+grn) + (blu<<1) + 8) >> 4);
353 *pdwInputUsed = inBytes;
354 g->dwInNextPos += inBytes;
355 *pdwInputNextPos = g->dwInNextPos;
357 *pdwOutputUsed = outBytes;
358 *pdwOutputThisPos = g->dwOutNextPos;
359 g->dwOutNextPos += outBytes;
363 return IP_CONSUMED_ROW | IP_PRODUCED_ROW | IP_READY_FOR_DATA;
366 return IP_FATAL_ERROR;
371 /*****************************************************************************\
373 * yXtract_insertedData - client inserted into our output stream
375 \*****************************************************************************/
377 static WORD yXtract_insertedData (
378 IP_XFORM_HANDLE hXform,
382 return IP_FATAL_ERROR; /* must never be called (can't insert data) */
387 /*****************************************************************************\
389 * yXtract_newPage - Tells us to flush this page, and start a new page
391 \*****************************************************************************/
393 static WORD yXtract_newPage (
394 IP_XFORM_HANDLE hXform)
398 HANDLE_TO_PTR (hXform, g);
399 /* todo: return fatal error if convert is called again? */
400 return IP_DONE; /* can't insert page-breaks, so ignore this call */
403 return IP_FATAL_ERROR;
409 /*****************************************************************************\
411 * yXtract_closeXform - Destroys this instance
413 \*****************************************************************************/
415 static WORD yXtract_closeXform (IP_XFORM_HANDLE hXform)
419 HANDLE_TO_PTR (hXform, g);
422 IP_MEM_FREE (g); /* free memory for the instance */
427 return IP_FATAL_ERROR;
432 /*****************************************************************************\
434 * yXtractTbl - Jump-table for encoder
436 \*****************************************************************************/
438 IP_XFORM_TBL yXtractTbl = {
440 yXtract_setDefaultInputTraits,
441 yXtract_setXformSpec,
442 yXtract_getHeaderBufSize,
443 yXtract_getActualTraits,
444 yXtract_getActualBufSizes,
447 yXtract_insertedData,