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 * xgrayOut.c - Grays out everything outside the given rectangle.
41 * "Graying out" means changing pixels toward a middle gray value. Everything
42 * outside the given rectangle is grayed-out by this xform. This is useful for
43 * displaying a selected-area in an image (the rectangle).
45 ******************************************************************************
47 * Name of Global Jump-Table:
51 * Items in aXformInfo array passed into setXformSpec:
53 * aXformInfo[IP_GRAYOUT_LEFT ] = left
54 * aXformInfo[IP_GRAYOUT_RIGHT ] = right
55 * aXformInfo[IP_GRAYOUT_TOP ] = top
56 * aXformInfo[IP_GRAYOUT_BOTTOM] = bottom
58 * The four numbers above give the locations of the sides of the rectangle
59 * which is *not* to be grayed-out. Everything outside these boundaries
60 * will be grayed-out. If these coordinates are outside the image, this
61 * xform will behave sensibly.
63 * Capabilities and Limitations:
65 * 24-bit, 3-component data only.
67 * Default Input Traits, and Output Traits:
69 * Describe what you do with the default input traits, and how the
70 * output traits are determined.
72 * trait default input output
73 * ------------------- --------------------- ------------------------
74 * iPixelsPerRow * passed into output same as default input
75 * iBitsPerPixel * must be 24 24
76 * iComponentsPerPixel * must be 3 3
77 * lHorizDPI passed into output same as default input
78 * lVertDPI passed into output same as default input
79 * lNumRows passed into output same as default input
80 * iNumPages passed into output same as default input
81 * iPageNum passed into output same as default input
83 * Above, a "*" by an item indicates it must be valid (not negative).
85 \******************************************************************************/
88 #define TARGET_GRAY 0xB0 /* grayed pixels are pushed toward this gray-level */
90 // Use the #define below if this transform will exist in a dll outside of the
91 // image pipeline. This will allow the functions to be exported.
92 // #define EXPORT_TRANFORM 1
96 #include "string.h" /* for memset and memcpy */
102 #define PRINT(msg,arg1,arg2) \
103 _ftprintf(stderr, msg, (int)arg1, (int)arg2)
105 #define PRINT(msg,arg1,arg2)
108 #define CHECK_VALUE 0x4ba1dace
110 #ifdef EXPORT_TRANSFORM
111 #define FUNC_STATUS __declspec (dllexport)
113 #define FUNC_STATUS static
117 IP_IMAGE_TRAITS traits; /* traits of the input and output image */
118 DWORD dwBytesPerRow; /* # of bytes in each row */
119 int iLeft, iRight; /* the rectangle to not gray-out */
121 DWORD dwRowsDone; /* number of rows converted so far */
122 DWORD dwInNextPos; /* file pos for subsequent input */
123 DWORD dwOutNextPos; /* file pos for subsequent output */
124 DWORD dwValidChk; /* struct validity check value */
125 } GRAYOUT_INST, *PGRAYOUT_INST;
129 /*****************************************************************************\
131 * grayOut_openXform - Creates a new instance of the transformer
133 *****************************************************************************
135 * This returns a handle for the new instance to be passed into
136 * all subsequent calls.
138 * Return value: IP_DONE=success; IP_FATAL_ERROR=misc error.
140 \*****************************************************************************/
142 FUNC_STATUS WORD grayOut_openXform (
143 IP_XFORM_HANDLE *pXform) /* out: returned handle */
147 INSURE (pXform != NULL);
148 IP_MEM_ALLOC (sizeof(GRAYOUT_INST), g);
150 memset (g, 0, sizeof(GRAYOUT_INST));
151 g->dwValidChk = CHECK_VALUE;
153 g->iBottom = 1000000;
157 return IP_FATAL_ERROR;
162 /*****************************************************************************\
164 * grayOut_setDefaultInputTraits - Specifies default input image traits
166 *****************************************************************************
168 * The header of the file-type handled by the transform probably does
169 * not include *all* the image traits we'd like to know. Those not
170 * specified in the file-header are filled in from info provided by
173 * Return value: IP_DONE=success; IP_FATAL_ERROR=misc error.
175 \*****************************************************************************/
177 FUNC_STATUS WORD grayOut_setDefaultInputTraits (
178 IP_XFORM_HANDLE hXform, /* in: handle for xform */
179 PIP_IMAGE_TRAITS pTraits) /* in: default image traits */
183 HANDLE_TO_PTR (hXform, g);
185 /* insure that traits we care about are known */
186 INSURE (pTraits->iPixelsPerRow > 0 &&
187 pTraits->iBitsPerPixel == 24 &&
188 pTraits->iComponentsPerPixel == 3);
189 g->traits = *pTraits; /* a structure copy */
190 g->dwBytesPerRow = (g->traits.iPixelsPerRow*g->traits.iBitsPerPixel + 7) / 8;
194 return IP_FATAL_ERROR;
199 /*****************************************************************************\
201 * grayOut_setXformSpec - Provides xform-specific information
203 \*****************************************************************************/
205 FUNC_STATUS WORD grayOut_setXformSpec (
206 IP_XFORM_HANDLE hXform, /* in: handle for xform */
207 DWORD_OR_PVOID aXformInfo[]) /* in: xform information */
211 HANDLE_TO_PTR (hXform, g);
212 g->iLeft = aXformInfo[IP_GRAYOUT_LEFT ].dword;
213 g->iRight = aXformInfo[IP_GRAYOUT_RIGHT ].dword;
214 g->iTop = aXformInfo[IP_GRAYOUT_TOP ].dword;
215 g->iBottom = aXformInfo[IP_GRAYOUT_BOTTOM].dword;
219 return IP_FATAL_ERROR;
224 /*****************************************************************************\
226 * grayOut_getHeaderBufSize- Returns size of input buf needed to hold header
228 \*****************************************************************************/
230 FUNC_STATUS WORD grayOut_getHeaderBufSize (
231 IP_XFORM_HANDLE hXform, /* in: handle for xform */
232 DWORD *pdwInBufLen) /* out: buf size for parsing header */
234 /* since input is raw pixels, there is no header, so set it to zero */
241 /*****************************************************************************\
243 * grayOut_getActualTraits - Parses header, and returns input & output traits
245 \*****************************************************************************/
247 FUNC_STATUS WORD grayOut_getActualTraits (
248 IP_XFORM_HANDLE hXform, /* in: handle for xform */
249 DWORD dwInputAvail, /* in: # avail bytes in input buf */
250 PBYTE pbInputBuf, /* in: ptr to input buffer */
251 PDWORD pdwInputUsed, /* out: # bytes used from input buf */
252 PDWORD pdwInputNextPos,/* out: file-pos to read from next */
253 PIP_IMAGE_TRAITS pIntraits, /* out: input image traits */
254 PIP_IMAGE_TRAITS pOutTraits) /* out: output image traits */
258 HANDLE_TO_PTR (hXform, g);
260 /* Since there is no header, we'll report no usage of input */
262 *pdwInputNextPos = 0;
264 *pIntraits = g->traits; /* structure copies */
265 *pOutTraits = g->traits;
267 return IP_DONE | IP_READY_FOR_DATA;
270 return IP_FATAL_ERROR;
275 /****************************************************************************\
277 * grayOut_getActualBufSizes - Returns buf sizes needed for remainder of job
279 \****************************************************************************/
281 FUNC_STATUS WORD grayOut_getActualBufSizes (
282 IP_XFORM_HANDLE hXform, /* in: handle for xform */
283 PDWORD pdwMinInBufLen, /* out: min input buf size */
284 PDWORD pdwMinOutBufLen) /* out: min output buf size */
288 HANDLE_TO_PTR (hXform, g);
289 *pdwMinInBufLen = *pdwMinOutBufLen = g->dwBytesPerRow;
293 return IP_FATAL_ERROR;
298 /*****************************************************************************\
300 * grayOut_convert - Converts one row
302 \*****************************************************************************/
304 FUNC_STATUS WORD grayOut_convert (
305 IP_XFORM_HANDLE hXform,
306 DWORD dwInputAvail, /* in: # avail bytes in in-buf */
307 PBYTE pbInputBuf, /* in: ptr to in-buffer */
308 PDWORD pdwInputUsed, /* out: # bytes used from in-buf */
309 PDWORD pdwInputNextPos, /* out: file-pos to read from next */
310 DWORD dwOutputAvail, /* in: # avail bytes in out-buf */
311 PBYTE pbOutputBuf, /* in: ptr to out-buffer */
312 PDWORD pdwOutputUsed, /* out: # bytes written in out-buf */
313 PDWORD pdwOutputThisPos) /* out: file-pos to write the data */
317 PBYTE pIn, pInAfter, pOut, pLeft, pRight;
319 #define GRAYOUT_PIXEL \
320 *pOut++ = (BYTE)(((int)(*pIn++)+TARGET_GRAY) >> 1); /* R */ \
321 *pOut++ = (BYTE)(((int)(*pIn++)+TARGET_GRAY) >> 1); /* G */ \
322 *pOut++ = (BYTE)(((int)(*pIn++)+TARGET_GRAY) >> 1); /* B */
324 HANDLE_TO_PTR (hXform, g);
326 /**** Check if we were told to flush ****/
328 if (pbInputBuf == NULL) {
329 PRINT (_T("grayOut_convert: Told to flush.\n"), 0, 0);
330 *pdwInputUsed = *pdwOutputUsed = 0;
331 *pdwInputNextPos = g->dwInNextPos;
332 *pdwOutputThisPos = g->dwOutNextPos;
336 /**** Output a Row ****/
338 nBytes = g->dwBytesPerRow;
339 INSURE (dwInputAvail >= (DWORD)nBytes );
340 INSURE (dwOutputAvail >= (DWORD)nBytes);
344 pInAfter = pIn + nBytes;
346 if ((int)g->dwRowsDone<g->iTop || (int)g->dwRowsDone>g->iBottom) {
347 /* Gray-out the entire row */
348 while (pIn < pInAfter) {
352 /* Gray-out portion of row between iLeft and iRight */
353 pLeft = pIn + 3*g->iLeft;
354 pRight = pIn + 3*g->iRight;
356 if (pLeft >= pInAfter)
357 pLeft = pInAfter - 3; /* clamp to rightmost pixel */
358 if (pRight >= pInAfter)
359 pRight = pInAfter - 3; /* clamp to rightmost pixel */
361 while (pIn < pLeft) { /* gray-out left portion */
364 while (pIn <= pRight) { /* copy portion within rect */
369 while (pIn < pInAfter) { /* gray-out right portion */
374 *pdwInputUsed = nBytes;
375 g->dwInNextPos += nBytes;
376 *pdwInputNextPos = g->dwInNextPos;
378 *pdwOutputUsed = nBytes;
379 *pdwOutputThisPos = g->dwOutNextPos;
380 g->dwOutNextPos += nBytes;
384 return IP_CONSUMED_ROW | IP_PRODUCED_ROW | IP_READY_FOR_DATA;
387 return IP_FATAL_ERROR;
392 /*****************************************************************************\
394 * grayOut_insertedData - client inserted into our output stream
396 \*****************************************************************************/
398 FUNC_STATUS WORD grayOut_insertedData (
399 IP_XFORM_HANDLE hXform,
403 return IP_FATAL_ERROR; /* must never be called (can't insert data) */
408 /*****************************************************************************\
410 * grayOut_newPage - Tells us to flush this page, and start a new page
412 \*****************************************************************************/
414 FUNC_STATUS WORD grayOut_newPage (
415 IP_XFORM_HANDLE hXform)
419 HANDLE_TO_PTR (hXform, g);
420 /* todo: return fatal error if convert is called again? */
421 return IP_DONE; /* can't insert page-breaks, so ignore this call */
424 return IP_FATAL_ERROR;
430 /*****************************************************************************\
432 * grayOut_closeXform - Destroys this instance
434 \*****************************************************************************/
436 FUNC_STATUS WORD grayOut_closeXform (IP_XFORM_HANDLE hXform)
440 HANDLE_TO_PTR (hXform, g);
443 IP_MEM_FREE (g); /* free memory for the instance */
448 return IP_FATAL_ERROR;
453 /*****************************************************************************\
455 * grayOutTbl - Jump-table for transform driver
457 \*****************************************************************************/
458 #ifdef EXPORT_TRANSFORM
459 __declspec (dllexport)
461 IP_XFORM_TBL grayOutTbl = {
463 grayOut_setDefaultInputTraits,
464 grayOut_setXformSpec,
465 grayOut_getHeaderBufSize,
466 grayOut_getActualTraits,
467 grayOut_getActualBufSizes,
470 grayOut_insertedData,
477 /*****************************************************************************\
479 * ipGetXformTable - Returns pointer to the jump table
481 \*****************************************************************************/
483 #ifdef EXPORT_TRANSFORM
484 EXPORT(WORD) ipGetXformTable (LPIP_XFORM_TBL pXform)
491 wRet = IP_FATAL_ERROR;