Tizen 2.1 base
[platform/upstream/hplip.git] / ip / xgrayout.c
1 /* libhpojip -- HP OfficeJet image-processing library. */
2
3 /* Copyright (C) 1995-2002 Hewlett-Packard Company
4  *
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.
9  *
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.
14  *
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,
18  * MA 02111-1307, USA.
19  *
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.
30  */
31
32 /* Original author: Mark Overton and others.
33  *
34  * Ported to Linux by David Paschal.
35  */
36
37 /******************************************************************************\
38  *
39  * xgrayOut.c - Grays out everything outside the given rectangle.
40  *
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).
44  *
45  ******************************************************************************
46  *
47  * Name of Global Jump-Table:
48  *
49  *    grayOutTbl
50  *
51  * Items in aXformInfo array passed into setXformSpec:
52  *
53  *    aXformInfo[IP_GRAYOUT_LEFT  ] = left
54  *    aXformInfo[IP_GRAYOUT_RIGHT ] = right
55  *    aXformInfo[IP_GRAYOUT_TOP   ] = top
56  *    aXformInfo[IP_GRAYOUT_BOTTOM] = bottom
57  *
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.
62  *
63  * Capabilities and Limitations:
64  *
65  *    24-bit, 3-component data only.
66  *
67  * Default Input Traits, and Output Traits:
68  *
69  *    Describe what you do with the default input traits, and how the
70  *    output traits are determined.
71  *
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
82  *
83  *    Above, a "*" by an item indicates it must be valid (not negative).
84  *
85 \******************************************************************************/
86
87
88 #define TARGET_GRAY  0xB0  /* grayed pixels are pushed toward this gray-level */
89
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
93
94 #include "hpip.h"
95 #include "ipdefs.h"
96 #include "string.h"    /* for memset and memcpy */
97
98
99 #if 0
100     #include "stdio.h"
101     #include <tchar.h>
102     #define PRINT(msg,arg1,arg2) \
103         _ftprintf(stderr, msg, (int)arg1, (int)arg2)
104 #else
105     #define PRINT(msg,arg1,arg2)
106 #endif
107
108 #define CHECK_VALUE 0x4ba1dace
109
110 #ifdef EXPORT_TRANSFORM
111 #define FUNC_STATUS __declspec (dllexport)
112 #else
113 #define FUNC_STATUS static
114 #endif
115
116 typedef struct {
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 */
120     int      iTop, iBottom;
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;
126
127
128
129 /*****************************************************************************\
130  *
131  * grayOut_openXform - Creates a new instance of the transformer
132  *
133  *****************************************************************************
134  *
135  * This returns a handle for the new instance to be passed into
136  * all subsequent calls.
137  *
138  * Return value: IP_DONE=success; IP_FATAL_ERROR=misc error.
139  *
140 \*****************************************************************************/
141
142 FUNC_STATUS WORD grayOut_openXform (
143     IP_XFORM_HANDLE *pXform)   /* out: returned handle */
144 {
145     PGRAYOUT_INST g;
146
147     INSURE (pXform != NULL);
148     IP_MEM_ALLOC (sizeof(GRAYOUT_INST), g);
149     *pXform = g;
150     memset (g, 0, sizeof(GRAYOUT_INST));
151     g->dwValidChk = CHECK_VALUE;
152     g->iRight  = 1000000;
153     g->iBottom = 1000000;
154     return IP_DONE;
155
156     fatal_error:
157     return IP_FATAL_ERROR;
158 }
159
160
161
162 /*****************************************************************************\
163  *
164  * grayOut_setDefaultInputTraits - Specifies default input image traits
165  *
166  *****************************************************************************
167  *
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
171  * this routine.
172  *
173  * Return value: IP_DONE=success; IP_FATAL_ERROR=misc error.
174  *
175 \*****************************************************************************/
176
177 FUNC_STATUS WORD grayOut_setDefaultInputTraits (
178     IP_XFORM_HANDLE  hXform,     /* in: handle for xform */
179     PIP_IMAGE_TRAITS pTraits)    /* in: default image traits */
180 {
181     PGRAYOUT_INST g;
182
183     HANDLE_TO_PTR (hXform, g);
184
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;
191     return IP_DONE;
192
193     fatal_error:
194     return IP_FATAL_ERROR;
195 }
196
197
198
199 /*****************************************************************************\
200  *
201  * grayOut_setXformSpec - Provides xform-specific information
202  *
203 \*****************************************************************************/
204
205 FUNC_STATUS WORD grayOut_setXformSpec (
206     IP_XFORM_HANDLE hXform,         /* in: handle for xform */
207     DWORD_OR_PVOID  aXformInfo[])   /* in: xform information */
208 {
209     PGRAYOUT_INST g;
210
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;
216     return IP_DONE;
217
218     fatal_error:
219     return IP_FATAL_ERROR;
220 }
221
222
223
224 /*****************************************************************************\
225  *
226  * grayOut_getHeaderBufSize- Returns size of input buf needed to hold header
227  *
228 \*****************************************************************************/
229
230 FUNC_STATUS WORD grayOut_getHeaderBufSize (
231     IP_XFORM_HANDLE  hXform,         /* in:  handle for xform */
232     DWORD           *pdwInBufLen)    /* out: buf size for parsing header */
233 {
234     /* since input is raw pixels, there is no header, so set it to zero */
235     *pdwInBufLen = 0;
236     return IP_DONE;
237 }
238
239
240
241 /*****************************************************************************\
242  *
243  * grayOut_getActualTraits - Parses header, and returns input & output traits
244  *
245 \*****************************************************************************/
246
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 */
255 {
256     PGRAYOUT_INST g;
257
258     HANDLE_TO_PTR (hXform, g);
259
260     /* Since there is no header, we'll report no usage of input */
261     *pdwInputUsed    = 0;
262     *pdwInputNextPos = 0;
263
264     *pIntraits  = g->traits;   /* structure copies */
265     *pOutTraits = g->traits;
266
267     return IP_DONE | IP_READY_FOR_DATA;
268
269     fatal_error:
270     return IP_FATAL_ERROR;
271 }
272
273
274
275 /****************************************************************************\
276  *
277  * grayOut_getActualBufSizes - Returns buf sizes needed for remainder of job
278  *
279 \****************************************************************************/
280
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 */
285 {
286     PGRAYOUT_INST g;
287
288     HANDLE_TO_PTR (hXform, g);
289     *pdwMinInBufLen = *pdwMinOutBufLen = g->dwBytesPerRow;
290     return IP_DONE;
291
292     fatal_error:
293     return IP_FATAL_ERROR;
294 }
295
296
297
298 /*****************************************************************************\
299  *
300  * grayOut_convert - Converts one row
301  *
302 \*****************************************************************************/
303
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 */
314 {
315     PGRAYOUT_INST g;
316     int       nBytes;
317     PBYTE     pIn, pInAfter, pOut, pLeft, pRight;
318
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 */
323
324     HANDLE_TO_PTR (hXform, g);
325
326     /**** Check if we were told to flush ****/
327
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;
333         return IP_DONE;
334     }
335
336     /**** Output a Row ****/
337
338     nBytes = g->dwBytesPerRow;
339     INSURE (dwInputAvail  >= (DWORD)nBytes );
340     INSURE (dwOutputAvail >= (DWORD)nBytes);
341
342     pIn  = pbInputBuf;
343     pOut = pbOutputBuf;
344     pInAfter = pIn + nBytes;
345
346     if ((int)g->dwRowsDone<g->iTop || (int)g->dwRowsDone>g->iBottom) {
347         /* Gray-out the entire row */
348         while (pIn < pInAfter) {
349             GRAYOUT_PIXEL
350         }
351     } else {
352         /* Gray-out portion of row between iLeft and iRight */
353         pLeft  = pIn + 3*g->iLeft;
354         pRight = pIn + 3*g->iRight;
355
356         if (pLeft >= pInAfter)
357             pLeft  = pInAfter - 3;  /* clamp to rightmost pixel */
358         if (pRight >= pInAfter)
359             pRight = pInAfter - 3;  /* clamp to rightmost pixel */
360
361         while (pIn < pLeft) {   /* gray-out left portion */
362             GRAYOUT_PIXEL
363         }
364         while (pIn <= pRight) {   /* copy portion within rect */
365             *pOut++ = *pIn++;
366             *pOut++ = *pIn++;
367             *pOut++ = *pIn++;
368         }
369         while (pIn < pInAfter) {   /* gray-out right portion */
370             GRAYOUT_PIXEL
371         }
372     }
373
374     *pdwInputUsed     = nBytes;
375     g->dwInNextPos   += nBytes;
376     *pdwInputNextPos  = g->dwInNextPos;
377
378     *pdwOutputUsed    = nBytes;
379     *pdwOutputThisPos = g->dwOutNextPos;
380     g->dwOutNextPos  += nBytes;
381
382     g->dwRowsDone += 1;
383
384     return IP_CONSUMED_ROW | IP_PRODUCED_ROW | IP_READY_FOR_DATA;
385
386     fatal_error:
387     return IP_FATAL_ERROR;
388 }
389
390
391
392 /*****************************************************************************\
393  *
394  * grayOut_insertedData - client inserted into our output stream
395  *
396 \*****************************************************************************/
397
398 FUNC_STATUS WORD grayOut_insertedData (
399     IP_XFORM_HANDLE hXform,
400     DWORD           dwNumBytes)
401 {
402     fatalBreakPoint ();
403     return IP_FATAL_ERROR;   /* must never be called (can't insert data) */
404 }
405
406
407
408 /*****************************************************************************\
409  *
410  * grayOut_newPage - Tells us to flush this page, and start a new page
411  *
412 \*****************************************************************************/
413
414 FUNC_STATUS WORD grayOut_newPage (
415     IP_XFORM_HANDLE hXform)
416 {
417     PGRAYOUT_INST g;
418
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 */
422
423     fatal_error:
424     return IP_FATAL_ERROR;
425
426 }
427
428
429
430 /*****************************************************************************\
431  *
432  * grayOut_closeXform - Destroys this instance
433  *
434 \*****************************************************************************/
435
436 FUNC_STATUS WORD grayOut_closeXform (IP_XFORM_HANDLE hXform)
437 {
438     PGRAYOUT_INST g;
439
440     HANDLE_TO_PTR (hXform, g);
441
442     g->dwValidChk = 0;
443     IP_MEM_FREE (g);       /* free memory for the instance */
444
445     return IP_DONE;
446
447     fatal_error:
448     return IP_FATAL_ERROR;
449 }
450
451
452
453 /*****************************************************************************\
454  *
455  * grayOutTbl - Jump-table for transform driver
456  *
457 \*****************************************************************************/
458 #ifdef EXPORT_TRANSFORM
459 __declspec (dllexport)
460 #endif
461 IP_XFORM_TBL grayOutTbl = {
462     grayOut_openXform,
463     grayOut_setDefaultInputTraits,
464     grayOut_setXformSpec,
465     grayOut_getHeaderBufSize,
466     grayOut_getActualTraits,
467     grayOut_getActualBufSizes,
468     grayOut_convert,
469     grayOut_newPage,
470     grayOut_insertedData,
471     grayOut_closeXform
472 };
473
474 /* End of File */
475
476
477 /*****************************************************************************\
478  *
479  * ipGetXformTable - Returns pointer to the jump table
480  *
481 \*****************************************************************************/
482
483 #ifdef EXPORT_TRANSFORM
484 EXPORT(WORD) ipGetXformTable (LPIP_XFORM_TBL pXform)
485 {
486     WORD wRet = IP_DONE;
487
488     if (pXform)
489         *pXform = clrmapTbl;
490     else
491         wRet = IP_FATAL_ERROR;
492
493     return wRet;
494 }
495 #endif