67
67
#if arch_sizeof_long > arch_sizeof_int
68
68
if (bits_per_row > max_uint * 7L)
69
return ERRC; /****** WRONG ******/
69
return ERRC; /****** WRONG ******/
71
71
ss->row_count = (uint) ((bits_per_row + 7) >> 3);
72
72
ss->end_mask = (1 << (-bits_per_row & 7)) - 1;
74
74
if (ss->Colors > s_PNG_max_Colors)
75
return ERRC; /* Too many colorants */
75
return ERRC; /* Too many colorants */
77
77
ss->bpp = (bits_per_pixel + 7) >> 3;
79
prev_row = gs_alloc_bytes(st->memory, ss->bpp + ss->row_count,
80
"PNGPredictor prev row");
82
return ERRC; /****** WRONG ******/
83
memset(prev_row, 0, ss->bpp);
79
prev_row = gs_alloc_bytes(st->memory, ss->bpp + ss->row_count,
80
"PNGPredictor prev row");
82
return ERRC; /****** WRONG ******/
83
memset(prev_row, 0, ss->bpp);
85
85
ss->prev_row = prev_row;
86
86
/* case_index is only preset for encoding */
128
128
/* The definitions of ac and bc are correct, not a typo. */
129
129
int ac = b - c, bc = a - c, abcc = ac + bc;
130
130
int pa = (ac < 0 ? -ac : ac), pb = (bc < 0 ? -bc : bc),
131
pc = (abcc < 0 ? -abcc : abcc);
131
pc = (abcc < 0 ? -abcc : abcc);
133
133
return (pa <= pb && pa <= pc ? a : pb <= pc ? b : c);
136
136
s_pngp_process(stream_state * st, stream_cursor_write * pw,
137
const byte * dprev, stream_cursor_read * pr,
138
const byte * upprev, const byte * up, uint count)
137
const byte * dprev, stream_cursor_read * pr,
138
const byte * upprev, const byte * up, uint count)
140
140
stream_PNGP_state *const ss = (stream_PNGP_state *) st;
141
141
byte *q = pw->ptr + 1;
145
145
pw->ptr += count;
146
146
ss->row_left -= count;
147
147
switch (ss->case_index) {
148
case cEncode + cNone:
149
case cDecode + cNone:
153
for (; count; ++q, ++dprev, ++p, --count)
154
*q = (byte) (*p - *dprev);
157
for (; count; ++q, ++dprev, ++p, --count)
158
*q = (byte) (*p + *dprev);
161
for (; count; ++q, ++up, ++p, --count)
162
*q = (byte) (*p - *up);
165
for (; count; ++q, ++up, ++p, --count)
166
*q = (byte) (*p + *up);
168
case cEncode + cAverage:
169
for (; count; ++q, ++dprev, ++up, ++p, --count)
170
*q = (byte) (*p - arith_rshift_1((int)*dprev + (int)*up));
172
case cDecode + cAverage:
173
for (; count; ++q, ++dprev, ++up, ++p, --count)
174
*q = (byte) (*p + arith_rshift_1((int)*dprev + (int)*up));
176
case cEncode + cPaeth:
177
for (; count; ++q, ++dprev, ++up, ++upprev, ++p, --count)
178
*q = (byte) (*p - paeth_predictor(*dprev, *up, *upprev));
180
case cDecode + cPaeth:
181
for (; count; ++q, ++dprev, ++up, ++upprev, ++p, --count)
182
*q = (byte) (*p + paeth_predictor(*dprev, *up, *upprev));
148
case cEncode + cNone:
149
case cDecode + cNone:
153
for (; count; ++q, ++dprev, ++p, --count)
154
*q = (byte) (*p - *dprev);
157
for (; count; ++q, ++dprev, ++p, --count)
158
*q = (byte) (*p + *dprev);
161
for (; count; ++q, ++up, ++p, --count)
162
*q = (byte) (*p - *up);
165
for (; count; ++q, ++up, ++p, --count)
166
*q = (byte) (*p + *up);
168
case cEncode + cAverage:
169
for (; count; ++q, ++dprev, ++up, ++p, --count)
170
*q = (byte) (*p - arith_rshift_1((int)*dprev + (int)*up));
172
case cDecode + cAverage:
173
for (; count; ++q, ++dprev, ++up, ++p, --count)
174
*q = (byte) (*p + arith_rshift_1((int)*dprev + (int)*up));
176
case cEncode + cPaeth:
177
for (; count; ++q, ++dprev, ++up, ++upprev, ++p, --count)
178
*q = (byte) (*p - paeth_predictor(*dprev, *up, *upprev));
180
case cDecode + cPaeth:
181
for (; count; ++q, ++dprev, ++up, ++upprev, ++p, --count)
182
*q = (byte) (*p + paeth_predictor(*dprev, *up, *upprev));
226
226
s_PNGPE_process(stream_state * st, stream_cursor_read * pr,
227
stream_cursor_write * pw, bool last)
227
stream_cursor_write * pw, bool last)
229
229
stream_PNGP_state *const ss = (stream_PNGP_state *) st;
230
230
int bpp = ss->bpp;
233
233
while (pr->ptr < pr->limit) {
236
if (ss->row_left == 0) {
237
/* Beginning of row, write algorithm byte. */
240
if (pw->ptr >= pw->limit) {
245
(ss->Predictor == cOptimum ?
246
optimum_predictor(st, pr) :
248
*++(pw->ptr) = (byte) predictor - cNone;
249
ss->case_index = predictor + cEncode;
250
ss->row_left = ss->row_count;
251
memset(ss->prev, 0, bpp);
254
count = s_pngp_count(st, pr, pw);
256
/* We know we have input, so output must be full. */
260
byte *up = ss->prev_row + bpp + ss->row_count - ss->row_left;
261
uint n = min(count, bpp);
263
/* Process bytes whose predecessors are in prev. */
264
s_pngp_process(st, pw, ss->prev, pr, up - bpp, up, n);
265
if (ss->row_left == 0) {
267
memcpy(up - bpp, ss->prev, bpp);
268
memcpy(up, pr->ptr - (n - 1), n);
273
memcpy(up - bpp, ss->prev, n);
276
* We didn't have both enough input data and enough output
277
* space to use up all of prev. Shift more data into prev
280
int prev_left = bpp - n;
282
memmove(ss->prev, ss->prev + n, prev_left);
283
memcpy(ss->prev + prev_left, pr->ptr - (n - 1), n);
284
if (pw->ptr >= pw->limit && pr->ptr < pr->limit)
288
/* Process bytes whose predecessors are in the input. */
289
/* We know we have at least bpp input and output bytes, */
290
/* and that n = bpp. */
292
s_pngp_process(st, pw, pr->ptr - (bpp - 1), pr,
293
up, up + bpp, count);
294
memcpy(ss->prev, pr->ptr - (bpp - 1), bpp);
296
memcpy(up, pr->ptr - (bpp + count - 1), count);
297
if (ss->row_left == 0)
298
memcpy(up + count, ss->prev, bpp);
236
if (ss->row_left == 0) {
237
/* Beginning of row, write algorithm byte. */
240
if (pw->ptr >= pw->limit) {
245
(ss->Predictor == cOptimum ?
246
optimum_predictor(st, pr) :
248
*++(pw->ptr) = (byte) predictor - cNone;
249
ss->case_index = predictor + cEncode;
250
ss->row_left = ss->row_count;
251
memset(ss->prev, 0, bpp);
254
count = s_pngp_count(st, pr, pw);
256
/* We know we have input, so output must be full. */
260
byte *up = ss->prev_row + bpp + ss->row_count - ss->row_left;
261
uint n = min(count, bpp);
263
/* Process bytes whose predecessors are in prev. */
264
s_pngp_process(st, pw, ss->prev, pr, up - bpp, up, n);
265
if (ss->row_left == 0) {
267
memcpy(up - bpp, ss->prev, bpp);
268
memcpy(up, pr->ptr - (n - 1), n);
273
memcpy(up - bpp, ss->prev, n);
276
* We didn't have both enough input data and enough output
277
* space to use up all of prev. Shift more data into prev
280
int prev_left = bpp - n;
282
memmove(ss->prev, ss->prev + n, prev_left);
283
memcpy(ss->prev + prev_left, pr->ptr - (n - 1), n);
284
if (pw->ptr >= pw->limit && pr->ptr < pr->limit)
288
/* Process bytes whose predecessors are in the input. */
289
/* We know we have at least bpp input and output bytes, */
290
/* and that n = bpp. */
292
s_pngp_process(st, pw, pr->ptr - (bpp - 1), pr,
293
up, up + bpp, count);
294
memcpy(ss->prev, pr->ptr - (bpp - 1), bpp);
296
memcpy(up, pr->ptr - (bpp + count - 1), count);
297
if (ss->row_left == 0)
298
memcpy(up + count, ss->prev, bpp);
320
320
s_PNGPD_process(stream_state * st, stream_cursor_read * pr,
321
stream_cursor_write * pw, bool last)
321
stream_cursor_write * pw, bool last)
323
323
stream_PNGP_state *const ss = (stream_PNGP_state *) st;
324
324
int bpp = ss->bpp;
327
327
while (pr->ptr < pr->limit) {
330
if (ss->row_left == 0) {
331
/* Beginning of row, read algorithm byte. */
332
int predictor = pr->ptr[1];
334
if (predictor >= cOptimum - cNone) {
339
ss->case_index = predictor + cNone + cDecode;
340
ss->row_left = ss->row_count;
341
memset(ss->prev, 0, bpp);
344
count = s_pngp_count(st, pr, pw);
346
/* We know we have input, so output must be full. */
350
byte *up = ss->prev_row + bpp + ss->row_count - ss->row_left;
351
uint n = min(count, bpp);
353
/* Process bytes whose predecessors are in prev. */
354
s_pngp_process(st, pw, ss->prev, pr, up - bpp, up, n);
355
if (ss->row_left == 0) {
357
memcpy(up - bpp, ss->prev, bpp);
358
memcpy(up, pw->ptr - (n - 1), n);
363
memcpy(up - bpp, ss->prev, n);
366
* We didn't have both enough input data and enough output
367
* space to use up all of prev. Shift more data into prev
370
int prev_left = bpp - n;
372
memmove(ss->prev, ss->prev + n, prev_left);
373
memcpy(ss->prev + prev_left, pw->ptr - (n - 1), n);
374
if (pw->ptr >= pw->limit && pr->ptr < pr->limit)
378
/* Process bytes whose predecessors are in the output. */
379
/* We know we have at least bpp input and output bytes, */
380
/* and that n = bpp. */
382
s_pngp_process(st, pw, pw->ptr - (bpp - 1), pr,
383
up, up + bpp, count);
384
memcpy(ss->prev, pw->ptr - (bpp - 1), bpp);
386
memcpy(up, pw->ptr - (bpp + count - 1), count);
387
if (ss->row_left == 0)
388
memcpy(up + count, ss->prev, bpp);
330
if (ss->row_left == 0) {
331
/* Beginning of row, read algorithm byte. */
332
int predictor = pr->ptr[1];
334
if (predictor >= cOptimum - cNone) {
339
ss->case_index = predictor + cNone + cDecode;
340
ss->row_left = ss->row_count;
341
memset(ss->prev, 0, bpp);
344
count = s_pngp_count(st, pr, pw);
346
/* We know we have input, so output must be full. */
350
byte *up = ss->prev_row + bpp + ss->row_count - ss->row_left;
351
uint n = min(count, bpp);
353
/* Process bytes whose predecessors are in prev. */
354
s_pngp_process(st, pw, ss->prev, pr, up - bpp, up, n);
355
if (ss->row_left == 0) {
357
memcpy(up - bpp, ss->prev, bpp);
358
memcpy(up, pw->ptr - (n - 1), n);
363
memcpy(up - bpp, ss->prev, n);
366
* We didn't have both enough input data and enough output
367
* space to use up all of prev. Shift more data into prev
370
int prev_left = bpp - n;
372
memmove(ss->prev, ss->prev + n, prev_left);
373
memcpy(ss->prev + prev_left, pw->ptr - (n - 1), n);
374
if (pw->ptr >= pw->limit && pr->ptr < pr->limit)
378
/* Process bytes whose predecessors are in the output. */
379
/* We know we have at least bpp input and output bytes, */
380
/* and that n = bpp. */
382
s_pngp_process(st, pw, pw->ptr - (bpp - 1), pr,
383
up, up + bpp, count);
384
memcpy(ss->prev, pw->ptr - (bpp - 1), bpp);
386
memcpy(up, pw->ptr - (bpp + count - 1), count);
387
if (ss->row_left == 0)
388
memcpy(up + count, ss->prev, bpp);