1
/* libhpojip -- HP OfficeJet image-processing library. */
3
/* Copyright (C) 1995-2002 HP 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, HP 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,