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 * xbi2gray.c - Converts bilevel into gray (8-bit gray or 24-bit gray)
41 ******************************************************************************
43 * Name of Global Jump-Table:
47 * Items in aXformInfo array passed into setXformSpec:
49 * aXformInfo[IP_BI_2_GRAY_OUTPUT_BPP] = format of output:
50 * 8 = output 8-bit gray,
51 * 24 = output 24-bit gray.
52 * aXformInfo[IP_BI_2_GRAY_WHITE_PIXEL] =
53 * an RGBQUAD representing a white output pixel.
54 * aXformInfo[IP_BI_2_GRAY_BLACK_PIXEL] =
55 * an RGBQUAD representing a black output pixel.
57 * Each bilevel pixel is output as a full white or full black pixel.
58 * This xform needs to know what values to use for those white and
59 * black output pixels. Hence the two RGBQUAD items above.
60 * For 8-bit gray output, only the rgbRed field is used in each.
62 * Capabilities and Limitations:
64 * Translates each white or black bilevel input pixel into an 8-bit
65 * or 24-bit output white or black output pixel.
67 * Default Input Traits, and Output Traits:
69 * trait default input output
70 * ------------------- --------------------- ------------------------
71 * iPixelsPerRow * passed into output same as default input
72 * iBitsPerPixel * must be 1 8 or 24
73 * iComponentsPerPixel * must be 1 1 or 3
74 * lHorizDPI passed into output same as default input
75 * lVertDPI passed into output same as default input
76 * lNumRows passed into output same as default input
77 * iNumPages passed into output same as default input
78 * iPageNum passed into output same as default input
80 * Above, a "*" by an item indicates it must be valid (not negative).
82 * Mar 1998 Mark Overton -- wrote code
84 \******************************************************************************/
88 #include "string.h" /* for memset and memcpy */
95 #define PRINT(msg,arg1,arg2) \
96 _ftprintf(stderr, msg, (int)arg1, (int)arg2)
98 #define PRINT(msg,arg1,arg2)
101 #define CHECK_VALUE 0x1ce5ca7e
104 IP_IMAGE_TRAITS inTraits; /* traits of the input image */
105 UINT uRowsDone; /* number of rows converted so far */
106 WORD wOutBitsPerPixel; /* bits/pixel to output (8 or 24) */
107 RGBQUAD rgbWhite; /* value of an output white */
108 RGBQUAD rgbBlack; /* value of an output black */
109 DWORD dwInRowBytes; /* # bytes per input row */
110 DWORD dwOutRowBytes; /* # bytes per output row */
111 DWORD dwInNextPos; /* file pos for subsequent input */
112 DWORD dwOutNextPos; /* file pos for subsequent output */
113 DWORD dwValidChk; /* struct validity check value */
114 } B2G_INST, *PB2G_INST;
118 /*****************************************************************************\
120 * bi2gray_openXform - Creates a new instance of the transformer
122 *****************************************************************************
124 * This returns a handle for the new instance to be passed into
125 * all subsequent calls.
127 * Return value: IP_DONE=success; IP_FATAL_ERROR=misc error.
129 \*****************************************************************************/
131 static WORD bi2gray_openXform (
132 IP_XFORM_HANDLE *pXform) /* out: returned handle */
136 INSURE (pXform != NULL);
137 IP_MEM_ALLOC (sizeof(B2G_INST), g);
139 memset (g, 0, sizeof(B2G_INST));
140 g->dwValidChk = CHECK_VALUE;
144 return IP_FATAL_ERROR;
149 /*****************************************************************************\
151 * bi2gray_setDefaultInputTraits - Specifies default input image traits
153 *****************************************************************************
155 * The header of the file-type handled by the transform probably does
156 * not include *all* the image traits we'd like to know. Those not
157 * specified in the file-header are filled in from info provided by
160 * Return value: IP_DONE=success; IP_FATAL_ERROR=misc error.
162 \*****************************************************************************/
164 static WORD bi2gray_setDefaultInputTraits (
165 IP_XFORM_HANDLE hXform, /* in: handle for xform */
166 PIP_IMAGE_TRAITS pTraits) /* in: default image traits */
170 HANDLE_TO_PTR (hXform, g);
172 /* Insure that values we care about are correct */
173 INSURE (pTraits->iBitsPerPixel == 1);
174 INSURE (pTraits->iComponentsPerPixel == 1);
175 INSURE (pTraits->iPixelsPerRow > 0);
177 g->inTraits = *pTraits; /* a structure copy */
181 return IP_FATAL_ERROR;
186 /*****************************************************************************\
188 * bi2gray_setXformSpec - Provides xform-specific information
190 \*****************************************************************************/
192 static WORD bi2gray_setXformSpec (
193 IP_XFORM_HANDLE hXform, /* in: handle for xform */
194 DWORD_OR_PVOID aXformInfo[]) /* in: xform information */
199 HANDLE_TO_PTR (hXform, g);
200 nBits = aXformInfo[IP_BI_2_GRAY_OUTPUT_BPP].dword;
201 INSURE (nBits==8 || nBits==24);
202 g->wOutBitsPerPixel = (WORD)nBits;
203 g->rgbWhite = aXformInfo[IP_BI_2_GRAY_WHITE_PIXEL].rgbquad;
204 g->rgbBlack = aXformInfo[IP_BI_2_GRAY_BLACK_PIXEL].rgbquad;
208 return IP_FATAL_ERROR;
213 /*****************************************************************************\
215 * bi2gray_getHeaderBufSize- Returns size of input buf needed to hold header
217 \*****************************************************************************/
219 static WORD bi2gray_getHeaderBufSize (
220 IP_XFORM_HANDLE hXform, /* in: handle for xform */
221 DWORD *pdwInBufLen) /* out: buf size for parsing header */
223 /* since input is raw pixels, there is no header, so set it to zero */
230 /*****************************************************************************\
232 * bi2gray_getActualTraits - Parses header, and returns input & output traits
234 \*****************************************************************************/
236 static WORD bi2gray_getActualTraits (
237 IP_XFORM_HANDLE hXform, /* in: handle for xform */
238 DWORD dwInputAvail, /* in: # avail bytes in input buf */
239 PBYTE pbInputBuf, /* in: ptr to input buffer */
240 PDWORD pdwInputUsed, /* out: # bytes used from input buf */
241 PDWORD pdwInputNextPos,/* out: file-pos to read from next */
242 PIP_IMAGE_TRAITS pInTraits, /* out: input image traits */
243 PIP_IMAGE_TRAITS pOutTraits) /* out: output image traits */
247 HANDLE_TO_PTR (hXform, g);
249 /* Since there is no header, we'll report no usage of input */
251 *pdwInputNextPos = 0;
253 *pInTraits = g->inTraits; /* structure copies */
254 *pOutTraits = g->inTraits;
255 pOutTraits->iBitsPerPixel = g->wOutBitsPerPixel;
256 pOutTraits->iComponentsPerPixel = g->wOutBitsPerPixel==8 ? 1 : 3;
258 g->dwInRowBytes = (g->inTraits.iPixelsPerRow+7) / 8;
259 g->dwOutRowBytes = g->inTraits.iPixelsPerRow * pOutTraits->iComponentsPerPixel;
261 return IP_DONE | IP_READY_FOR_DATA;
264 return IP_FATAL_ERROR;
269 /****************************************************************************\
271 * bi2gray_getActualBufSizes - Returns buf sizes needed for remainder of job
273 \****************************************************************************/
275 static WORD bi2gray_getActualBufSizes (
276 IP_XFORM_HANDLE hXform, /* in: handle for xform */
277 PDWORD pdwMinInBufLen, /* out: min input buf size */
278 PDWORD pdwMinOutBufLen) /* out: min output buf size */
282 HANDLE_TO_PTR (hXform, g);
283 *pdwMinInBufLen = g->dwInRowBytes;
284 *pdwMinOutBufLen = g->dwOutRowBytes;
289 return IP_FATAL_ERROR;
294 /*****************************************************************************\
296 * bi2gray_convert - Converts one row
298 \*****************************************************************************/
300 static WORD bi2gray_convert (
301 IP_XFORM_HANDLE hXform,
302 DWORD dwInputAvail, /* in: # avail bytes in in-buf */
303 PBYTE pbInputBuf, /* in: ptr to in-buffer */
304 PDWORD pdwInputUsed, /* out: # bytes used from in-buf */
305 PDWORD pdwInputNextPos, /* out: file-pos to read from next */
306 DWORD dwOutputAvail, /* in: # avail bytes in out-buf */
307 PBYTE pbOutputBuf, /* in: ptr to out-buffer */
308 PDWORD pdwOutputUsed, /* out: # bytes written in out-buf */
309 PDWORD pdwOutputThisPos) /* out: file-pos to write the data */
312 PBYTE pIn, pOut, pInAfter;
313 BYTE bMask, bBilevel;
315 HANDLE_TO_PTR (hXform, g);
317 /**** Check if we were told to flush ****/
319 if (pbInputBuf == NULL) {
320 PRINT (_T("bi2gray_convert: Told to flush.\n"), 0, 0);
321 *pdwInputUsed = *pdwOutputUsed = 0;
322 *pdwInputNextPos = g->dwInNextPos;
323 *pdwOutputThisPos = g->dwOutNextPos;
327 /**** Output a Row ****/
329 INSURE (dwInputAvail >= g->dwInRowBytes );
330 INSURE (dwOutputAvail >= g->dwOutRowBytes);
334 pInAfter = pIn + g->dwInRowBytes;
336 while (pIn < pInAfter) {
339 if (g->wOutBitsPerPixel == 24) {
340 for (bMask=0x80u; bMask!=0; bMask>>=1) {
341 *(RGBQUAD*)pOut = (bMask & bBilevel)
346 } else { /* 8 bits per output pixel */
347 for (bMask=0x80u; bMask!=0; bMask>>=1) {
348 *pOut++ = (bMask & bBilevel)
350 : g->rgbWhite.rgbRed;
355 *pdwInputUsed = g->dwInRowBytes;
356 g->dwInNextPos += g->dwInRowBytes;
357 *pdwInputNextPos = g->dwInNextPos;
359 *pdwOutputUsed = g->dwOutRowBytes;
360 *pdwOutputThisPos = g->dwOutNextPos;
361 g->dwOutNextPos += g->dwOutRowBytes;
365 return IP_CONSUMED_ROW | IP_PRODUCED_ROW | IP_READY_FOR_DATA;
368 return IP_FATAL_ERROR;
373 /*****************************************************************************\
375 * bi2gray_insertedData - client inserted into our output stream
377 \*****************************************************************************/
379 static WORD bi2gray_insertedData (
380 IP_XFORM_HANDLE hXform,
384 return IP_FATAL_ERROR; /* must never be called (can't insert data) */
389 /*****************************************************************************\
391 * bi2gray_newPage - Tells us to flush this page, and start a new page
393 \*****************************************************************************/
395 static WORD bi2gray_newPage (
396 IP_XFORM_HANDLE hXform)
400 HANDLE_TO_PTR (hXform, g);
401 /* todo: return fatal error if convert is called again? */
402 return IP_DONE; /* can't insert page-breaks, so ignore this call */
405 return IP_FATAL_ERROR;
411 /*****************************************************************************\
413 * bi2gray_closeXform - Destroys this instance
415 \*****************************************************************************/
417 static WORD bi2gray_closeXform (IP_XFORM_HANDLE hXform)
421 HANDLE_TO_PTR (hXform, g);
424 IP_MEM_FREE (g); /* free memory for the instance */
429 return IP_FATAL_ERROR;
434 /*****************************************************************************\
436 * bi2grayTbl - Jump-table for encoder
438 \*****************************************************************************/
440 IP_XFORM_TBL bi2grayTbl = {
442 bi2gray_setDefaultInputTraits,
443 bi2gray_setXformSpec,
444 bi2gray_getHeaderBufSize,
445 bi2gray_getActualTraits,
446 bi2gray_getActualBufSizes,
449 bi2gray_insertedData,