2 |
- |
1 |
/* Copyright (C) 1998, 1999 Aladdin Enterprises. All rights reserved.
|
|
|
2 |
|
|
|
3 |
This software is provided AS-IS with no warranty, either express or
|
|
|
4 |
implied.
|
|
|
5 |
|
|
|
6 |
This software is distributed under license and may not be copied,
|
|
|
7 |
modified or distributed except as expressly authorized under the terms
|
|
|
8 |
of the license contained in the file LICENSE in this distribution.
|
|
|
9 |
|
|
|
10 |
For more information about licensing, please refer to
|
|
|
11 |
http://www.ghostscript.com/licensing/. For information on
|
|
|
12 |
commercial licensing, go to http://www.artifex.com/licensing/ or
|
|
|
13 |
contact Artifex Software, Inc., 101 Lucas Valley Road #110,
|
|
|
14 |
San Rafael, CA 94903, U.S.A., +1(415)492-9861.
|
|
|
15 |
*/
|
|
|
16 |
|
|
|
17 |
/* $Id: gximage.c,v 1.7 2004/08/04 19:36:12 stefan Exp $ */
|
|
|
18 |
/* Generic image support */
|
|
|
19 |
#include "memory_.h"
|
|
|
20 |
#include "gx.h"
|
|
|
21 |
#include "gscspace.h"
|
|
|
22 |
#include "gserrors.h"
|
|
|
23 |
#include "gsmatrix.h"
|
|
|
24 |
#include "gsutil.h"
|
|
|
25 |
#include "gxcolor2.h" /* for lookup map */
|
|
|
26 |
#include "gxiparam.h"
|
|
|
27 |
#include "stream.h"
|
|
|
28 |
|
|
|
29 |
/* ---------------- Generic image support ---------------- */
|
|
|
30 |
|
|
|
31 |
/* Structure descriptors */
|
|
|
32 |
public_st_gs_image_common();
|
|
|
33 |
public_st_gs_data_image();
|
|
|
34 |
public_st_gs_pixel_image();
|
|
|
35 |
|
|
|
36 |
/* Initialize the common parts of image structures. */
|
|
|
37 |
void
|
|
|
38 |
gs_image_common_t_init(gs_image_common_t * pic)
|
|
|
39 |
{
|
|
|
40 |
gs_make_identity(&pic->ImageMatrix);
|
|
|
41 |
}
|
|
|
42 |
void
|
|
|
43 |
gs_data_image_t_init(gs_data_image_t * pim, int num_components)
|
|
|
44 |
{
|
|
|
45 |
int i;
|
|
|
46 |
|
|
|
47 |
gs_image_common_t_init((gs_image_common_t *) pim);
|
|
|
48 |
pim->Width = pim->Height = 0;
|
|
|
49 |
pim->BitsPerComponent = 1;
|
|
|
50 |
if (num_components >= 0) {
|
|
|
51 |
for (i = 0; i < num_components * 2; i += 2)
|
|
|
52 |
pim->Decode[i] = 0, pim->Decode[i + 1] = 1;
|
|
|
53 |
} else {
|
|
|
54 |
for (i = 0; i < num_components * -2; i += 2)
|
|
|
55 |
pim->Decode[i] = 1, pim->Decode[i + 1] = 0;
|
|
|
56 |
}
|
|
|
57 |
pim->Interpolate = false;
|
|
|
58 |
}
|
|
|
59 |
void
|
|
|
60 |
gs_pixel_image_t_init(gs_pixel_image_t * pim,
|
|
|
61 |
const gs_color_space * color_space)
|
|
|
62 |
{
|
|
|
63 |
int num_components;
|
|
|
64 |
|
|
|
65 |
if (color_space == 0 ||
|
|
|
66 |
(num_components =
|
|
|
67 |
gs_color_space_num_components(color_space)) < 0
|
|
|
68 |
)
|
|
|
69 |
num_components = 0;
|
|
|
70 |
gs_data_image_t_init((gs_data_image_t *) pim, num_components);
|
|
|
71 |
pim->format = gs_image_format_chunky;
|
|
|
72 |
pim->ColorSpace = color_space;
|
|
|
73 |
pim->CombineWithColor = false;
|
|
|
74 |
}
|
|
|
75 |
|
|
|
76 |
/* Initialize the common part of an image-processing enumerator. */
|
|
|
77 |
int
|
|
|
78 |
gx_image_enum_common_init(gx_image_enum_common_t * piec,
|
|
|
79 |
const gs_data_image_t * pic,
|
|
|
80 |
const gx_image_enum_procs_t * piep,
|
|
|
81 |
gx_device * dev, int num_components,
|
|
|
82 |
gs_image_format_t format)
|
|
|
83 |
{
|
|
|
84 |
int bpc = pic->BitsPerComponent;
|
|
|
85 |
int i;
|
|
|
86 |
|
|
|
87 |
piec->image_type = pic->type;
|
|
|
88 |
piec->procs = piep;
|
|
|
89 |
piec->dev = dev;
|
|
|
90 |
piec->id = gs_next_ids(dev->memory, 1);
|
|
|
91 |
switch (format) {
|
|
|
92 |
case gs_image_format_chunky:
|
|
|
93 |
piec->num_planes = 1;
|
|
|
94 |
piec->plane_depths[0] = bpc * num_components;
|
|
|
95 |
break;
|
|
|
96 |
case gs_image_format_component_planar:
|
|
|
97 |
piec->num_planes = num_components;
|
|
|
98 |
for (i = 0; i < num_components; ++i)
|
|
|
99 |
piec->plane_depths[i] = bpc;
|
|
|
100 |
break;
|
|
|
101 |
case gs_image_format_bit_planar:
|
|
|
102 |
piec->num_planes = bpc * num_components;
|
|
|
103 |
for (i = 0; i < piec->num_planes; ++i)
|
|
|
104 |
piec->plane_depths[i] = 1;
|
|
|
105 |
break;
|
|
|
106 |
default:
|
|
|
107 |
return_error(gs_error_rangecheck);
|
|
|
108 |
}
|
|
|
109 |
for (i = 0; i < piec->num_planes; ++i)
|
|
|
110 |
piec->plane_widths[i] = pic->Width;
|
|
|
111 |
return 0;
|
|
|
112 |
}
|
|
|
113 |
|
|
|
114 |
/* Compute the source size of an ordinary image with explicit data. */
|
|
|
115 |
int
|
|
|
116 |
gx_data_image_source_size(const gs_imager_state * pis,
|
|
|
117 |
const gs_image_common_t * pim, gs_int_point * psize)
|
|
|
118 |
{
|
|
|
119 |
const gs_data_image_t *pdi = (const gs_data_image_t *)pim;
|
|
|
120 |
|
|
|
121 |
psize->x = pdi->Width;
|
|
|
122 |
psize->y = pdi->Height;
|
|
|
123 |
return 0;
|
|
|
124 |
}
|
|
|
125 |
|
|
|
126 |
/* Process the next piece of an image with no source data. */
|
|
|
127 |
/* This procedure should never be called. */
|
|
|
128 |
int
|
|
|
129 |
gx_no_plane_data(gx_image_enum_common_t * info,
|
|
|
130 |
const gx_image_plane_t * planes, int height,
|
|
|
131 |
int *height_used)
|
|
|
132 |
{
|
|
|
133 |
return_error(gs_error_Fatal);
|
|
|
134 |
}
|
|
|
135 |
|
|
|
136 |
/* Clean up after processing an image with no source data. */
|
|
|
137 |
/* This procedure may be called, but should do nothing. */
|
|
|
138 |
int
|
|
|
139 |
gx_ignore_end_image(gx_image_enum_common_t * info, bool draw_last)
|
|
|
140 |
{
|
|
|
141 |
return 0;
|
|
|
142 |
}
|
|
|
143 |
|
|
|
144 |
/* ---------------- Client procedures ---------------- */
|
|
|
145 |
|
|
|
146 |
int
|
|
|
147 |
gx_image_data(gx_image_enum_common_t * info, const byte ** plane_data,
|
|
|
148 |
int data_x, uint raster, int height)
|
|
|
149 |
{
|
|
|
150 |
int num_planes = info->num_planes;
|
|
|
151 |
gx_image_plane_t planes[gs_image_max_planes];
|
|
|
152 |
int i;
|
|
|
153 |
|
|
|
154 |
#ifdef DEBUG
|
|
|
155 |
if (num_planes > gs_image_max_planes) {
|
|
|
156 |
lprintf2("num_planes=%d > gs_image_max_planes=%d!\n",
|
|
|
157 |
num_planes, gs_image_max_planes);
|
|
|
158 |
return_error(gs_error_Fatal);
|
|
|
159 |
}
|
|
|
160 |
#endif
|
|
|
161 |
for (i = 0; i < num_planes; ++i) {
|
|
|
162 |
planes[i].data = plane_data[i];
|
|
|
163 |
planes[i].data_x = data_x;
|
|
|
164 |
planes[i].raster = raster;
|
|
|
165 |
}
|
|
|
166 |
return gx_image_plane_data(info, planes, height);
|
|
|
167 |
}
|
|
|
168 |
|
|
|
169 |
int
|
|
|
170 |
gx_image_plane_data(gx_image_enum_common_t * info,
|
|
|
171 |
const gx_image_plane_t * planes, int height)
|
|
|
172 |
{
|
|
|
173 |
int ignore_rows_used;
|
|
|
174 |
|
|
|
175 |
return gx_image_plane_data_rows(info, planes, height, &ignore_rows_used);
|
|
|
176 |
}
|
|
|
177 |
|
|
|
178 |
int
|
|
|
179 |
gx_image_plane_data_rows(gx_image_enum_common_t * info,
|
|
|
180 |
const gx_image_plane_t * planes, int height,
|
|
|
181 |
int *rows_used)
|
|
|
182 |
{
|
|
|
183 |
return info->procs->plane_data(info, planes, height, rows_used);
|
|
|
184 |
}
|
|
|
185 |
|
|
|
186 |
int
|
|
|
187 |
gx_image_flush(gx_image_enum_common_t * info)
|
|
|
188 |
{
|
|
|
189 |
int (*flush)(gx_image_enum_common_t *) = info->procs->flush;
|
|
|
190 |
|
|
|
191 |
return (flush ? flush(info) : 0);
|
|
|
192 |
}
|
|
|
193 |
|
|
|
194 |
bool
|
|
|
195 |
gx_image_planes_wanted(const gx_image_enum_common_t *info, byte *wanted)
|
|
|
196 |
{
|
|
|
197 |
bool (*planes_wanted)(const gx_image_enum_common_t *, byte *) =
|
|
|
198 |
info->procs->planes_wanted;
|
|
|
199 |
|
|
|
200 |
if (planes_wanted)
|
|
|
201 |
return planes_wanted(info, wanted);
|
|
|
202 |
else {
|
|
|
203 |
memset(wanted, 0xff, info->num_planes);
|
|
|
204 |
return true;
|
|
|
205 |
}
|
|
|
206 |
}
|
|
|
207 |
|
|
|
208 |
int
|
|
|
209 |
gx_image_end(gx_image_enum_common_t * info, bool draw_last)
|
|
|
210 |
{
|
|
|
211 |
return info->procs->end_image(info, draw_last);
|
|
|
212 |
}
|
|
|
213 |
|
|
|
214 |
/* ---------------- Serialization ---------------- */
|
|
|
215 |
|
|
|
216 |
/*
|
|
|
217 |
* Define dummy sput/sget/release procedures for image types that don't
|
|
|
218 |
* implement these functions.
|
|
|
219 |
*/
|
|
|
220 |
|
|
|
221 |
int
|
|
|
222 |
gx_image_no_sput(const gs_image_common_t *pic, stream *s,
|
|
|
223 |
const gs_color_space **ppcs)
|
|
|
224 |
{
|
|
|
225 |
return_error(gs_error_rangecheck);
|
|
|
226 |
}
|
|
|
227 |
|
|
|
228 |
int
|
|
|
229 |
gx_image_no_sget(gs_image_common_t *pic, stream *s,
|
|
|
230 |
const gs_color_space *pcs)
|
|
|
231 |
{
|
|
|
232 |
return_error(gs_error_rangecheck);
|
|
|
233 |
}
|
|
|
234 |
|
|
|
235 |
void
|
|
|
236 |
gx_image_default_release(gs_image_common_t *pic, gs_memory_t *mem)
|
|
|
237 |
{
|
|
|
238 |
gs_free_object(mem, pic, "gx_image_default_release");
|
|
|
239 |
}
|
|
|
240 |
|
|
|
241 |
#ifdef DEBUG
|
|
|
242 |
private void
|
|
|
243 |
debug_b_print_matrix(const gs_pixel_image_t *pim)
|
|
|
244 |
{
|
|
|
245 |
if_debug6('b', " ImageMatrix=[%g %g %g %g %g %g]\n",
|
|
|
246 |
pim->ImageMatrix.xx, pim->ImageMatrix.xy,
|
|
|
247 |
pim->ImageMatrix.yx, pim->ImageMatrix.yy,
|
|
|
248 |
pim->ImageMatrix.tx, pim->ImageMatrix.ty);
|
|
|
249 |
}
|
|
|
250 |
private void
|
|
|
251 |
debug_b_print_decode(const gs_pixel_image_t *pim, int num_decode)
|
|
|
252 |
{
|
|
|
253 |
if (gs_debug_c('b')) {
|
|
|
254 |
const char *str = " Decode=[";
|
|
|
255 |
int i;
|
|
|
256 |
|
|
|
257 |
for (i = 0; i < num_decode; str = " ", ++i)
|
|
|
258 |
dprintf2("%s%g", str, pim->Decode[i]);
|
|
|
259 |
dputs("]\n");
|
|
|
260 |
}
|
|
|
261 |
}
|
|
|
262 |
#else
|
|
|
263 |
# define debug_b_print_matrix(pim) DO_NOTHING
|
|
|
264 |
# define debug_b_print_decode(pim, num_decode) DO_NOTHING
|
|
|
265 |
#endif
|
|
|
266 |
|
|
|
267 |
/* Test whether an image has a default ImageMatrix. */
|
|
|
268 |
bool
|
|
|
269 |
gx_image_matrix_is_default(const gs_data_image_t *pid)
|
|
|
270 |
{
|
|
|
271 |
return (is_xxyy(&pid->ImageMatrix) &&
|
|
|
272 |
pid->ImageMatrix.xx == pid->Width &&
|
|
|
273 |
pid->ImageMatrix.yy == -pid->Height &&
|
|
|
274 |
is_fzero(pid->ImageMatrix.tx) &&
|
|
|
275 |
pid->ImageMatrix.ty == pid->Height);
|
|
|
276 |
}
|
|
|
277 |
|
|
|
278 |
/* Put a variable-length uint on a stream. */
|
|
|
279 |
void
|
|
|
280 |
sput_variable_uint(stream *s, uint w)
|
|
|
281 |
{
|
|
|
282 |
for (; w > 0x7f; w >>= 7)
|
|
|
283 |
sputc(s, (byte)(w | 0x80));
|
|
|
284 |
sputc(s, (byte)w);
|
|
|
285 |
}
|
|
|
286 |
|
|
|
287 |
/*
|
|
|
288 |
* Write generic pixel image parameters. The format is the following,
|
|
|
289 |
* encoded as a variable-length uint in the usual way:
|
|
|
290 |
* xxxFEDCCBBBBA
|
|
|
291 |
* A = 0 if standard ImageMatrix, 1 if explicit ImageMatrix
|
|
|
292 |
* BBBB = BitsPerComponent - 1
|
|
|
293 |
* CC = format
|
|
|
294 |
* D = 0 if standard (0..1) Decode, 1 if explicit Decode
|
|
|
295 |
* E = Interpolate
|
|
|
296 |
* F = CombineWithColor
|
|
|
297 |
* xxx = extra information from caller
|
|
|
298 |
*/
|
|
|
299 |
#define PI_ImageMatrix 0x001
|
|
|
300 |
#define PI_BPC_SHIFT 1
|
|
|
301 |
#define PI_BPC_MASK 0xf
|
|
|
302 |
#define PI_FORMAT_SHIFT 5
|
|
|
303 |
#define PI_FORMAT_MASK 0x3
|
|
|
304 |
#define PI_Decode 0x080
|
|
|
305 |
#define PI_Interpolate 0x100
|
|
|
306 |
#define PI_CombineWithColor 0x200
|
|
|
307 |
#define PI_BITS 10
|
|
|
308 |
/*
|
|
|
309 |
* Width, encoded as a variable-length uint
|
|
|
310 |
* Height, encoded ditto
|
|
|
311 |
* ImageMatrix (if A = 1), per gs_matrix_store/fetch
|
|
|
312 |
* Decode (if D = 1): blocks of up to 4 components
|
|
|
313 |
* aabbccdd, where each xx is decoded as:
|
|
|
314 |
* 00 = default, 01 = swapped default,
|
|
|
315 |
* 10 = (0,V), 11 = (U,V)
|
|
|
316 |
* non-defaulted components (up to 8 floats)
|
|
|
317 |
*/
|
|
|
318 |
int
|
|
|
319 |
gx_pixel_image_sput(const gs_pixel_image_t *pim, stream *s,
|
|
|
320 |
const gs_color_space **ppcs, int extra)
|
|
|
321 |
{
|
|
|
322 |
const gs_color_space *pcs = pim->ColorSpace;
|
|
|
323 |
int bpc = pim->BitsPerComponent;
|
|
|
324 |
int num_components = gs_color_space_num_components(pcs);
|
|
|
325 |
int num_decode;
|
|
|
326 |
uint control = extra << PI_BITS;
|
|
|
327 |
float decode_default_1 = 1;
|
|
|
328 |
int i;
|
|
|
329 |
uint ignore;
|
|
|
330 |
|
|
|
331 |
/* Construct the control word. */
|
|
|
332 |
|
|
|
333 |
if (!gx_image_matrix_is_default((const gs_data_image_t *)pim))
|
|
|
334 |
control |= PI_ImageMatrix;
|
|
|
335 |
switch (pim->format) {
|
|
|
336 |
case gs_image_format_chunky:
|
|
|
337 |
case gs_image_format_component_planar:
|
|
|
338 |
switch (bpc) {
|
|
|
339 |
case 1: case 2: case 4: case 8: case 12: break;
|
|
|
340 |
default: return_error(gs_error_rangecheck);
|
|
|
341 |
}
|
|
|
342 |
break;
|
|
|
343 |
case gs_image_format_bit_planar:
|
|
|
344 |
if (bpc < 1 || bpc > 8)
|
|
|
345 |
return_error(gs_error_rangecheck);
|
|
|
346 |
}
|
|
|
347 |
control |= (bpc - 1) << PI_BPC_SHIFT;
|
|
|
348 |
control |= pim->format << PI_FORMAT_SHIFT;
|
|
|
349 |
num_decode = num_components * 2;
|
|
|
350 |
if (gs_color_space_get_index(pcs) == gs_color_space_index_Indexed)
|
|
|
351 |
decode_default_1 = (float)pcs->params.indexed.hival;
|
|
|
352 |
for (i = 0; i < num_decode; ++i)
|
|
|
353 |
if (pim->Decode[i] != DECODE_DEFAULT(i, decode_default_1)) {
|
|
|
354 |
control |= PI_Decode;
|
|
|
355 |
break;
|
|
|
356 |
}
|
|
|
357 |
if (pim->Interpolate)
|
|
|
358 |
control |= PI_Interpolate;
|
|
|
359 |
if (pim->CombineWithColor)
|
|
|
360 |
control |= PI_CombineWithColor;
|
|
|
361 |
|
|
|
362 |
/* Write the encoding on the stream. */
|
|
|
363 |
|
|
|
364 |
if_debug3('b', "[b]put control=0x%x, Width=%d, Height=%d\n",
|
|
|
365 |
control, pim->Width, pim->Height);
|
|
|
366 |
sput_variable_uint(s, control);
|
|
|
367 |
sput_variable_uint(s, (uint)pim->Width);
|
|
|
368 |
sput_variable_uint(s, (uint)pim->Height);
|
|
|
369 |
if (control & PI_ImageMatrix) {
|
|
|
370 |
debug_b_print_matrix(pim);
|
|
|
371 |
sput_matrix(s, &pim->ImageMatrix);
|
|
|
372 |
}
|
|
|
373 |
if (control & PI_Decode) {
|
|
|
374 |
int i;
|
|
|
375 |
uint dflags = 1;
|
|
|
376 |
float decode[8];
|
|
|
377 |
int di = 0;
|
|
|
378 |
|
|
|
379 |
debug_b_print_decode(pim, num_decode);
|
|
|
380 |
for (i = 0; i < num_decode; i += 2) {
|
|
|
381 |
float u = pim->Decode[i], v = pim->Decode[i + 1];
|
|
|
382 |
float dv = DECODE_DEFAULT(i + 1, decode_default_1);
|
|
|
383 |
|
|
|
384 |
if (dflags >= 0x100) {
|
|
|
385 |
sputc(s, (byte)(dflags & 0xff));
|
|
|
386 |
sputs(s, (const byte *)decode, di * sizeof(float), &ignore);
|
|
|
387 |
dflags = 1;
|
|
|
388 |
di = 0;
|
|
|
389 |
}
|
|
|
390 |
dflags <<= 2;
|
|
|
391 |
if (u == 0 && v == dv)
|
|
|
392 |
DO_NOTHING;
|
|
|
393 |
else if (u == dv && v == 0)
|
|
|
394 |
dflags += 1;
|
|
|
395 |
else {
|
|
|
396 |
if (u != 0) {
|
|
|
397 |
dflags++;
|
|
|
398 |
decode[di++] = u;
|
|
|
399 |
}
|
|
|
400 |
dflags += 2;
|
|
|
401 |
decode[di++] = v;
|
|
|
402 |
}
|
|
|
403 |
}
|
|
|
404 |
sputc(s, (byte)((dflags << (8 - num_decode)) & 0xff));
|
|
|
405 |
sputs(s, (const byte *)decode, di * sizeof(float), &ignore);
|
|
|
406 |
}
|
|
|
407 |
*ppcs = pcs;
|
|
|
408 |
return 0;
|
|
|
409 |
}
|
|
|
410 |
|
|
|
411 |
/* Set an image's ImageMatrix to the default. */
|
|
|
412 |
void
|
|
|
413 |
gx_image_matrix_set_default(gs_data_image_t *pid)
|
|
|
414 |
{
|
|
|
415 |
pid->ImageMatrix.xx = (float)pid->Width;
|
|
|
416 |
pid->ImageMatrix.xy = 0;
|
|
|
417 |
pid->ImageMatrix.yx = 0;
|
|
|
418 |
pid->ImageMatrix.yy = (float)-pid->Height;
|
|
|
419 |
pid->ImageMatrix.tx = 0;
|
|
|
420 |
pid->ImageMatrix.ty = (float)pid->Height;
|
|
|
421 |
}
|
|
|
422 |
|
|
|
423 |
/* Get a variable-length uint from a stream. */
|
|
|
424 |
int
|
|
|
425 |
sget_variable_uint(stream *s, uint *pw)
|
|
|
426 |
{
|
|
|
427 |
uint w = 0;
|
|
|
428 |
int shift = 0;
|
|
|
429 |
int ch;
|
|
|
430 |
|
|
|
431 |
for (; (ch = sgetc(s)) >= 0x80; shift += 7)
|
|
|
432 |
w += (ch & 0x7f) << shift;
|
|
|
433 |
if (ch < 0)
|
|
|
434 |
return_error(gs_error_ioerror);
|
|
|
435 |
*pw = w + (ch << shift);
|
|
|
436 |
return 0;
|
|
|
437 |
}
|
|
|
438 |
|
|
|
439 |
/*
|
|
|
440 |
* Read generic pixel image parameters.
|
|
|
441 |
*/
|
|
|
442 |
int
|
|
|
443 |
gx_pixel_image_sget(gs_pixel_image_t *pim, stream *s,
|
|
|
444 |
const gs_color_space *pcs)
|
|
|
445 |
{
|
|
|
446 |
uint control;
|
|
|
447 |
float decode_default_1 = 1;
|
|
|
448 |
int num_components, num_decode;
|
|
|
449 |
int i;
|
|
|
450 |
int code;
|
|
|
451 |
uint ignore;
|
|
|
452 |
|
|
|
453 |
if ((code = sget_variable_uint(s, &control)) < 0 ||
|
|
|
454 |
(code = sget_variable_uint(s, (uint *)&pim->Width)) < 0 ||
|
|
|
455 |
(code = sget_variable_uint(s, (uint *)&pim->Height)) < 0
|
|
|
456 |
)
|
|
|
457 |
return code;
|
|
|
458 |
if_debug3('b', "[b]get control=0x%x, Width=%d, Height=%d\n",
|
|
|
459 |
control, pim->Width, pim->Height);
|
|
|
460 |
if (control & PI_ImageMatrix) {
|
|
|
461 |
if ((code = sget_matrix(s, &pim->ImageMatrix)) < 0)
|
|
|
462 |
return code;
|
|
|
463 |
debug_b_print_matrix(pim);
|
|
|
464 |
} else
|
|
|
465 |
gx_image_matrix_set_default((gs_data_image_t *)pim);
|
|
|
466 |
pim->BitsPerComponent = ((control >> PI_BPC_SHIFT) & PI_BPC_MASK) + 1;
|
|
|
467 |
pim->format = (control >> PI_FORMAT_SHIFT) & PI_FORMAT_MASK;
|
|
|
468 |
pim->ColorSpace = pcs;
|
|
|
469 |
num_components = gs_color_space_num_components(pcs);
|
|
|
470 |
num_decode = num_components * 2;
|
|
|
471 |
if (gs_color_space_get_index(pcs) == gs_color_space_index_Indexed)
|
|
|
472 |
decode_default_1 = (float)pcs->params.indexed.hival;
|
|
|
473 |
if (control & PI_Decode) {
|
|
|
474 |
uint dflags = 0x10000;
|
|
|
475 |
float *dp = pim->Decode;
|
|
|
476 |
|
|
|
477 |
for (i = 0; i < num_decode; i += 2, dp += 2, dflags <<= 2) {
|
|
|
478 |
if (dflags >= 0x10000) {
|
|
|
479 |
dflags = sgetc(s) + 0x100;
|
|
|
480 |
if (dflags < 0x100)
|
|
|
481 |
return_error(gs_error_ioerror);
|
|
|
482 |
}
|
|
|
483 |
switch (dflags & 0xc0) {
|
|
|
484 |
case 0x00:
|
|
|
485 |
dp[0] = 0, dp[1] = DECODE_DEFAULT(i + 1, decode_default_1);
|
|
|
486 |
break;
|
|
|
487 |
case 0x40:
|
|
|
488 |
dp[0] = DECODE_DEFAULT(i + 1, decode_default_1), dp[1] = 0;
|
|
|
489 |
break;
|
|
|
490 |
case 0x80:
|
|
|
491 |
dp[0] = 0;
|
|
|
492 |
if (sgets(s, (byte *)(dp + 1), sizeof(float), &ignore) < 0)
|
|
|
493 |
return_error(gs_error_ioerror);
|
|
|
494 |
break;
|
|
|
495 |
case 0xc0:
|
|
|
496 |
if (sgets(s, (byte *)dp, sizeof(float) * 2, &ignore) < 0)
|
|
|
497 |
return_error(gs_error_ioerror);
|
|
|
498 |
break;
|
|
|
499 |
}
|
|
|
500 |
}
|
|
|
501 |
debug_b_print_decode(pim, num_decode);
|
|
|
502 |
} else {
|
|
|
503 |
for (i = 0; i < num_decode; ++i)
|
|
|
504 |
pim->Decode[i] = DECODE_DEFAULT(i, decode_default_1);
|
|
|
505 |
}
|
|
|
506 |
pim->Interpolate = (control & PI_Interpolate) != 0;
|
|
|
507 |
pim->CombineWithColor = (control & PI_CombineWithColor) != 0;
|
|
|
508 |
return control >> PI_BITS;
|
|
|
509 |
}
|
|
|
510 |
|
|
|
511 |
/*
|
|
|
512 |
* Release a pixel image object. Currently this just frees the object.
|
|
|
513 |
*/
|
|
|
514 |
void
|
|
|
515 |
gx_pixel_image_release(gs_pixel_image_t *pic, gs_memory_t *mem)
|
|
|
516 |
{
|
|
|
517 |
gx_image_default_release((gs_image_common_t *)pic, mem);
|
|
|
518 |
}
|