blob: 89743d7501151069bdbf336314962a6c9f5673c5 [file] [log] [blame]
Guy Schalnat0d580581995-07-20 02:43:20 -05001
2/* pngwutil.c - utilities to write a png file
3
4 libpng 1.0 beta 1 - version 0.71
5 For conditions of distribution and use, see copyright notice in png.h
6 Copyright (c) 1995 Guy Eric Schalnat, Group 42, Inc.
7 June 26, 1995
8 */
9#define PNG_INTERNAL
10#include "png.h"
11
12/* place a 32 bit number into a buffer in png byte order. We work
13 with unsigned numbers for convenience, you may have to cast
14 signed numbers (if you use any, most png data is unsigned). */
15void
16png_save_uint_32(png_byte *buf, png_uint_32 i)
17{
18 buf[0] = (png_byte)((i >> 24) & 0xff);
19 buf[1] = (png_byte)((i >> 16) & 0xff);
20 buf[2] = (png_byte)((i >> 8) & 0xff);
21 buf[3] = (png_byte)(i & 0xff);
22}
23
24/* place a 16 bit number into a buffer in png byte order */
25void
26png_save_uint_16(png_byte *buf, png_uint_16 i)
27{
28 buf[0] = (png_byte)((i >> 8) & 0xff);
29 buf[1] = (png_byte)(i & 0xff);
30}
31
32/* write a 32 bit number */
33void
34png_write_uint_32(png_struct *png_ptr, png_uint_32 i)
35{
36 png_byte buf[4];
37
38 buf[0] = (png_byte)((i >> 24) & 0xff);
39 buf[1] = (png_byte)((i >> 16) & 0xff);
40 buf[2] = (png_byte)((i >> 8) & 0xff);
41 buf[3] = (png_byte)(i & 0xff);
42 png_write_data(png_ptr, buf, 4);
43}
44
45/* write a 16 bit number */
46void
47png_write_uint_16(png_struct *png_ptr, png_uint_16 i)
48{
49 png_byte buf[2];
50
51 buf[0] = (png_byte)((i >> 8) & 0xff);
52 buf[1] = (png_byte)(i & 0xff);
53 png_write_data(png_ptr, buf, 2);
54}
55
56/* Write a png chunk all at once. The type is an array of ASCII characters
57 representing the chunk name. The array must be at least 4 bytes in
58 length, and does not need to be null terminated. To be safe, pass the
59 pre-defined chunk names here, and if you need a new one, define it
60 where the others are defined. The length is the length of the data.
61 All the data must be present. If that is not possible, use the
62 png_write_chunk_start(), png_write_chunk_data(), and png_write_chunk_end()
63 functions instead. */
64void
65png_write_chunk(png_struct *png_ptr, png_byte *type,
66 png_byte *data, png_uint_32 length)
67{
68 /* write length */
69 png_write_uint_32(png_ptr, length);
70 /* write chunk name */
71 png_write_data(png_ptr, type, (png_uint_32)4);
72 /* reset the crc and run the chunk name over it */
73 png_reset_crc(png_ptr);
74 png_calculate_crc(png_ptr, type, (png_uint_32)4);
75 /* write the data and update the crc */
76 if (length)
77 {
78 png_calculate_crc(png_ptr, data, length);
79 png_write_data(png_ptr, data, length);
80 }
81 /* write the crc */
82 png_write_uint_32(png_ptr, ~png_ptr->crc);
83}
84
85/* Write the start of a png chunk. The type is the chunk type.
86 The total_length is the sum of the lengths of all the data you will be
87 passing in png_write_chunk_data() */
88void
89png_write_chunk_start(png_struct *png_ptr, png_byte *type,
90 png_uint_32 total_length)
91{
92 /* write the length */
93 png_write_uint_32(png_ptr, total_length);
94 /* write the chunk name */
95 png_write_data(png_ptr, type, (png_uint_32)4);
96 /* reset the crc and run it over the chunk name */
97 png_reset_crc(png_ptr);
98 png_calculate_crc(png_ptr, type, (png_uint_32)4);
99}
100
101/* write the data of a png chunk started with png_write_chunk_start().
102 Note that multiple calls to this function are allowed, and that the
103 sum of the lengths from these calls *must* add up to the total_length
104 given to png_write_chunk_start() */
105void
106png_write_chunk_data(png_struct *png_ptr, png_byte *data, png_uint_32 length)
107{
108 /* write the data, and run the crc over it */
109 if (length)
110 {
111 png_calculate_crc(png_ptr, data, length);
112 png_write_data(png_ptr, data, length);
113 }
114}
115
116/* finish a chunk started with png_write_chunk_start() */
117void
118png_write_chunk_end(png_struct *png_ptr)
119{
120 /* write the crc */
121 png_write_uint_32(png_ptr, ~png_ptr->crc);
122}
123
124/* simple function to write the signature */
125void
126png_write_sig(png_struct *png_ptr)
127{
128 /* write the 8 byte signature */
129 png_write_data(png_ptr, png_sig, (png_uint_32)8);
130}
131
132/* Write the IHDR chunk, and update the png_struct with the necessary
133 information. Note that the rest of this code depends upon this
134 information being correct. */
135void
136png_write_IHDR(png_struct *png_ptr, png_uint_32 width, png_uint_32 height,
137 int bit_depth, int color_type, int compression_type, int filter_type,
138 int interlace_type)
139{
140 png_byte buf[13]; /* buffer to store the IHDR info */
141
142 /* pack the header information into the buffer */
143 png_save_uint_32(buf, width);
144 png_save_uint_32(buf + 4, height);
145 buf[8] = bit_depth;
146 buf[9] = color_type;
147 buf[10] = compression_type;
148 buf[11] = filter_type;
149 buf[12] = interlace_type;
150 /* save off the relevent information */
151 png_ptr->bit_depth = bit_depth;
152 png_ptr->color_type = color_type;
153 png_ptr->interlaced = interlace_type;
154 png_ptr->width = width;
155 png_ptr->height = height;
156
157 switch (color_type)
158 {
159 case 0:
160 case 3:
161 png_ptr->channels = 1;
162 break;
163 case 2:
164 png_ptr->channels = 3;
165 break;
166 case 4:
167 png_ptr->channels = 2;
168 break;
169 case 6:
170 png_ptr->channels = 4;
171 break;
172 }
173 png_ptr->pixel_depth = bit_depth * png_ptr->channels;
174 png_ptr->rowbytes = ((width * (png_uint_32)png_ptr->pixel_depth + 7) >> 3);
175 /* set the usr info, so any transformations can modify it */
176 png_ptr->usr_width = png_ptr->width;
177 png_ptr->usr_bit_depth = png_ptr->bit_depth;
178 png_ptr->usr_channels = png_ptr->channels;
179
180 /* write the chunk */
181 png_write_chunk(png_ptr, png_IHDR, buf, (png_uint_32)13);
182}
183
184/* write the palette. We are careful not to trust png_color to be in the
185 correct order for PNG, so people can redefine it to any convient
186 structure. */
187void
188png_write_PLTE(png_struct *png_ptr, png_color *palette, int number)
189{
190 int i;
191 png_color *pal_ptr;
192 png_byte buf[3];
193
194 png_write_chunk_start(png_ptr, png_PLTE, number * 3);
195 for (i = 0, pal_ptr = palette;
196 i < number;
197 i++, pal_ptr++)
198 {
199 buf[0] = pal_ptr->red;
200 buf[1] = pal_ptr->green;
201 buf[2] = pal_ptr->blue;
202 png_write_chunk_data(png_ptr, buf, (png_uint_32)3);
203 }
204 png_write_chunk_end(png_ptr);
205}
206
207/* write an IDAT chunk */
208void
209png_write_IDAT(png_struct *png_ptr, png_byte *data, png_uint_32 length)
210{
211#ifdef zlibinout
212/* temp zlib problem */
213{
214 extern FILE *fpzlibout;
215
216 fwrite(data, 1, length, fpzlibout);
217}
218/* end temp zlib problem */
219#endif
220
221 png_write_chunk(png_ptr, png_IDAT, data, length);
222}
223
224/* write an IEND chunk */
225void
226png_write_IEND(png_struct *png_ptr)
227{
228 png_write_chunk(png_ptr, png_IEND, NULL, (png_uint_32)0);
229}
230
231/* write a gAMA chunk */
232void
233png_write_gAMA(png_struct *png_ptr, float gamma)
234{
235 png_uint_32 igamma;
236 png_byte buf[4];
237
238 /* gamma is saved in 1/100,000ths */
239 igamma = (png_uint_32)(gamma * 100000.0 + 0.5);
240 png_save_uint_32(buf, igamma);
241 png_write_chunk(png_ptr, png_gAMA, buf, (png_uint_32)4);
242}
243
244/* write the sBIT chunk */
245void
246png_write_sBIT(png_struct *png_ptr, png_color_8 *sbit, int color_type)
247{
248 png_byte buf[4];
249 int size;
250
251 /* make sure we don't depend upon the order of png_color_8 */
252 if (color_type & PNG_COLOR_MASK_COLOR)
253 {
254 buf[0] = sbit->red;
255 buf[1] = sbit->green;
256 buf[2] = sbit->blue;
257 size = 3;
258 }
259 else
260 {
261 buf[0] = sbit->gray;
262 size = 1;
263 }
264
265 if (color_type & PNG_COLOR_MASK_ALPHA)
266 {
267 buf[size++] = sbit->alpha;
268 }
269
270 png_write_chunk(png_ptr, png_sBIT, buf, (png_uint_32)size);
271}
272
273/* write the cHRM chunk */
274void
275png_write_cHRM(png_struct *png_ptr, float white_x, float white_y,
276 float red_x, float red_y, float green_x, float green_y,
277 float blue_x, float blue_y)
278{
279 png_uint_32 itemp;
280 png_byte buf[32];
281
282 /* each value is saved int 1/100,000ths */
283 itemp = (png_uint_32)(white_x * 100000.0 + 0.5);
284 png_save_uint_32(buf, itemp);
285 itemp = (png_uint_32)(white_y * 100000.0 + 0.5);
286 png_save_uint_32(buf + 4, itemp);
287 itemp = (png_uint_32)(red_x * 100000.0 + 0.5);
288 png_save_uint_32(buf + 8, itemp);
289 itemp = (png_uint_32)(red_y * 100000.0 + 0.5);
290 png_save_uint_32(buf + 12, itemp);
291 itemp = (png_uint_32)(green_x * 100000.0 + 0.5);
292 png_save_uint_32(buf + 16, itemp);
293 itemp = (png_uint_32)(green_y * 100000.0 + 0.5);
294 png_save_uint_32(buf + 20, itemp);
295 itemp = (png_uint_32)(blue_x * 100000.0 + 0.5);
296 png_save_uint_32(buf + 24, itemp);
297 itemp = (png_uint_32)(blue_y * 100000.0 + 0.5);
298 png_save_uint_32(buf + 28, itemp);
299 png_write_chunk(png_ptr, png_cHRM, buf, (png_uint_32)32);
300}
301
302/* write the tRNS chunk */
303void
304png_write_tRNS(png_struct *png_ptr, png_byte *trans, png_color_16 *tran,
305 int num_trans, int color_type)
306{
307 png_byte buf[6];
308
309 if (color_type == PNG_COLOR_TYPE_PALETTE)
310 {
311 /* write the chunk out as it is */
312 png_write_chunk(png_ptr, png_tRNS, trans, (png_uint_32)num_trans);
313 }
314 else if (color_type == PNG_COLOR_TYPE_GRAY)
315 {
316 /* one 16 bit value */
317 png_save_uint_16(buf, tran->gray);
318 png_write_chunk(png_ptr, png_tRNS, buf, (png_uint_32)2);
319 }
320 else if (color_type == PNG_COLOR_TYPE_RGB)
321 {
322 /* three 16 bit values */
323 png_save_uint_16(buf, tran->red);
324 png_save_uint_16(buf + 2, tran->green);
325 png_save_uint_16(buf + 4, tran->blue);
326 png_write_chunk(png_ptr, png_tRNS, buf, (png_uint_32)6);
327 }
328}
329
330/* write the background chunk */
331void
332png_write_bKGD(png_struct *png_ptr, png_color_16 *back, int color_type)
333{
334 png_byte buf[6];
335
336 if (color_type == PNG_COLOR_TYPE_PALETTE)
337 {
338 buf[0] = back->index;
339 png_write_chunk(png_ptr, png_bKGD, buf, (png_uint_32)1);
340 }
341 else if (color_type & PNG_COLOR_MASK_COLOR)
342 {
343 png_save_uint_16(buf, back->red);
344 png_save_uint_16(buf + 2, back->green);
345 png_save_uint_16(buf + 4, back->blue);
346 png_write_chunk(png_ptr, png_bKGD, buf, (png_uint_32)6);
347 }
348 else
349 {
350 png_save_uint_16(buf, back->gray);
351 png_write_chunk(png_ptr, png_bKGD, buf, (png_uint_32)2);
352 }
353}
354
355/* write the histogram */
356void
357png_write_hIST(png_struct *png_ptr, png_uint_16 *hist, int number)
358{
359 int i;
360 png_byte buf[3];
361
362 png_write_chunk_start(png_ptr, png_hIST, (png_uint_32)(number * 2));
363 for (i = 0; i < number; i++)
364 {
365 png_save_uint_16(buf, hist[i]);
366 png_write_chunk_data(png_ptr, buf, (png_uint_32)2);
367 }
368 png_write_chunk_end(png_ptr);
369}
370
371/* write a tEXt chunk */
372void
373png_write_tEXt(png_struct *png_ptr, char *key, char *text,
374 png_uint_32 text_len)
375{
376 int key_len;
377
378 key_len = strlen(key);
379 /* make sure we count the 0 after the key */
380 png_write_chunk_start(png_ptr, png_tEXt,
381 (png_uint_32)(key_len + text_len + 1));
382 /* key has an 0 at the end. How nice */
383 png_write_chunk_data(png_ptr, (png_byte *)key, (png_uint_32)(key_len + 1));
384 if (text && text_len)
385 png_write_chunk_data(png_ptr, (png_byte *)text, (png_uint_32)text_len);
386 png_write_chunk_end(png_ptr);
387}
388
389/* write a compressed chunk */
390void
391png_write_zTXt(png_struct *png_ptr, char *key, char *text,
392 png_uint_32 text_len, int compression)
393{
394 int key_len;
395 char buf[1];
396 int i, ret;
397 char **output_ptr = NULL; /* array of pointers to output */
398 int num_output_ptr = 0; /* number of output pointers used */
399 int max_output_ptr = 0; /* size of output_ptr */
400
401 key_len = strlen(key);
402
403 /* we can't write the chunk until we find out how much data we have,
404 which means we need to run the compresser first, and save the
405 output. This shouldn't be a problem, as the vast majority of
406 comments should be reasonable, but we will set up an array of
407 malloced pointers to be sure. */
408
409 /* set up the compression buffers */
410 png_ptr->zstream->avail_in = (uInt)text_len;
411 png_ptr->zstream->next_in = (Byte *)text;
412 png_ptr->zstream->avail_out = (uInt)png_ptr->zbuf_size;
413 png_ptr->zstream->next_out = (Byte *)png_ptr->zbuf;
414
415 /* this is the same compression loop as in png_write_row() */
416 do
417 {
418 /* compress the data */
419 ret = deflate(png_ptr->zstream, Z_NO_FLUSH);
420 if (ret != Z_OK)
421 {
422 /* error */
423 if (png_ptr->zstream->msg)
424 png_error(png_ptr, png_ptr->zstream->msg);
425 else
426 png_error(png_ptr, "zlib error");
427 }
428 /* check to see if we need more room */
429 if (!png_ptr->zstream->avail_out && png_ptr->zstream->avail_in)
430 {
431 /* make sure the output array has room */
432 if (num_output_ptr >= max_output_ptr)
433 {
434 max_output_ptr = num_output_ptr + 4;
435 if (output_ptr)
436 output_ptr = png_realloc(png_ptr, output_ptr,
437 max_output_ptr * sizeof (char *));
438 else
439 output_ptr = png_malloc(png_ptr,
440 max_output_ptr * sizeof (char *));
441 }
442
443 /* save the data */
444 output_ptr[num_output_ptr] = png_large_malloc(png_ptr,
445 png_ptr->zbuf_size);
446 memcpy(output_ptr[num_output_ptr], png_ptr->zbuf,
447 (png_size_t)png_ptr->zbuf_size);
448 num_output_ptr++;
449
450 /* and reset the buffer */
451 png_ptr->zstream->avail_out = (uInt)png_ptr->zbuf_size;
452 png_ptr->zstream->next_out = png_ptr->zbuf;
453 }
454 /* continue until we don't have anymore to compress */
455 } while (png_ptr->zstream->avail_in);
456
457 /* finish the compression */
458 do
459 {
460 /* tell zlib we are finished */
461 ret = deflate(png_ptr->zstream, Z_FINISH);
462 if (ret != Z_OK && ret != Z_STREAM_END)
463 {
464 /* we got an error */
465 if (png_ptr->zstream->msg)
466 png_error(png_ptr, png_ptr->zstream->msg);
467 else
468 png_error(png_ptr, "zlib error");
469 }
470
471 /* check to see if we need more room */
472 if (!png_ptr->zstream->avail_out && ret == Z_OK)
473 {
474 /* check to make sure our output array has room */
475 if (num_output_ptr >= max_output_ptr)
476 {
477 max_output_ptr = num_output_ptr + 4;
478 if (output_ptr)
479 output_ptr = png_realloc(png_ptr, output_ptr,
480 max_output_ptr * sizeof (char *));
481 else
482 output_ptr = png_malloc(png_ptr,
483 max_output_ptr * sizeof (char *));
484 }
485
486 /* save off the data */
487 output_ptr[num_output_ptr] = png_large_malloc(png_ptr,
488 png_ptr->zbuf_size);
489 memcpy(output_ptr[num_output_ptr], png_ptr->zbuf,
490 (png_size_t)png_ptr->zbuf_size);
491 num_output_ptr++;
492
493 /* and reset the buffer pointers */
494 png_ptr->zstream->avail_out = (uInt)png_ptr->zbuf_size;
495 png_ptr->zstream->next_out = png_ptr->zbuf;
496 }
497 } while (ret != Z_STREAM_END);
498
499 /* text length is number of buffers plus last buffer */
500 text_len = png_ptr->zbuf_size * num_output_ptr;
501 if (png_ptr->zstream->avail_out < png_ptr->zbuf_size)
502 text_len += (png_uint_32)(png_ptr->zbuf_size -
503 png_ptr->zstream->avail_out);
504
505 /* write start of chunk */
506 png_write_chunk_start(png_ptr, png_zTXt,
507 (png_uint_32)(key_len + text_len + 2));
508 /* write key */
509 png_write_chunk_data(png_ptr, (png_byte *)key, (png_uint_32)(key_len + 1));
510 buf[0] = compression;
511 /* write compression */
512 png_write_chunk_data(png_ptr, (png_byte *)buf, (png_uint_32)1);
513
514 /* write saved output buffers, if any */
515 for (i = 0; i < num_output_ptr; i++)
516 {
517 png_write_chunk_data(png_ptr, (png_byte *)output_ptr[i], png_ptr->zbuf_size);
518 png_large_free(png_ptr, output_ptr[i]);
519 }
520 if (max_output_ptr)
521 png_free(png_ptr, output_ptr);
522 /* write anything left in zbuf */
523 if (png_ptr->zstream->avail_out < png_ptr->zbuf_size)
524 png_write_chunk_data(png_ptr, png_ptr->zbuf,
525 png_ptr->zbuf_size - png_ptr->zstream->avail_out);
526 /* close the chunk */
527 png_write_chunk_end(png_ptr);
528
529 /* reset zlib for another zTXt or the image data */
530/* deflateReset(png_ptr->zstream); */
531 deflateEnd(png_ptr->zstream);
532 deflateInit(png_ptr->zstream, -1);
533}
534
535/* write the pHYs chunk */
536void
537png_write_pHYs(png_struct *png_ptr, png_uint_32 x_pixels_per_unit,
538 png_uint_32 y_pixels_per_unit,
539 int unit_type)
540{
541 png_byte buf[9];
542
543 png_save_uint_32(buf, x_pixels_per_unit);
544 png_save_uint_32(buf + 4, y_pixels_per_unit);
545 buf[8] = unit_type;
546
547 png_write_chunk(png_ptr, png_pHYs, buf, (png_uint_32)9);
548}
549
550/* write the oFFs chunk */
551void
552png_write_oFFs(png_struct *png_ptr, png_uint_32 x_offset,
553 png_uint_32 y_offset,
554 int unit_type)
555{
556 png_byte buf[9];
557
558 png_save_uint_32(buf, x_offset);
559 png_save_uint_32(buf + 4, y_offset);
560 buf[8] = unit_type;
561
562 png_write_chunk(png_ptr, png_oFFs, buf, (png_uint_32)9);
563}
564
565/* two time chunks are given. This chunk assumes you have a gmtime()
566 function. If you don't have that, use the other tIME function */
567void
568png_write_tIME(png_struct *png_ptr, png_time *mod_time)
569{
570 png_byte buf[7];
571
572 png_save_uint_16(buf, mod_time->year);
573 buf[2] = mod_time->month;
574 buf[3] = mod_time->day;
575 buf[4] = mod_time->hour;
576 buf[5] = mod_time->minute;
577 buf[6] = mod_time->second;
578
579 png_write_chunk(png_ptr, png_tIME, buf, (png_uint_32)7);
580}
581
582/* initializes the row writing capability of libpng */
583void
584png_write_start_row(png_struct *png_ptr)
585{
586 /* set up row buffer */
587 png_ptr->row_buf = (png_byte *)png_large_malloc(png_ptr,
588 (((png_uint_32)png_ptr->usr_channels *
589 (png_uint_32)png_ptr->usr_bit_depth *
590 png_ptr->width) >> 3) + 1);
591 /* set up filtering buffers, if filtering */
592 if (png_ptr->bit_depth >= 8 && png_ptr->color_type != 3)
593 {
594 png_ptr->prev_row = (png_byte *)png_large_malloc(png_ptr,
595 png_ptr->rowbytes + 1);
596 memset(png_ptr->prev_row, 0, (png_size_t)png_ptr->rowbytes + 1);
597 png_ptr->save_row = (png_byte *)png_large_malloc(png_ptr,
598 png_ptr->rowbytes + 1);
599 memset(png_ptr->save_row, 0, (png_size_t)png_ptr->rowbytes + 1);
600 }
601
602 /* if interlaced, we need to set up width and height of pass */
603 if (png_ptr->interlaced)
604 {
605 if (!(png_ptr->transformations & PNG_INTERLACE))
606 {
607 png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
608 png_pass_ystart[0]) / png_pass_yinc[0];
609 png_ptr->usr_width = (png_ptr->width +
610 png_pass_inc[0] - 1 -
611 png_pass_start[0]) /
612 png_pass_inc[0];
613 }
614 else
615 {
616 png_ptr->num_rows = png_ptr->height;
617 png_ptr->usr_width = png_ptr->width;
618 }
619 }
620 else
621 {
622 png_ptr->num_rows = png_ptr->height;
623 png_ptr->usr_width = png_ptr->width;
624 }
625 png_ptr->zstream->avail_out = (uInt)png_ptr->zbuf_size;
626 png_ptr->zstream->next_out = png_ptr->zbuf;
627}
628
629/* Internal use only. Called when finished processing a row of data */
630void
631png_write_finish_row(png_struct *png_ptr)
632{
633 int ret;
634
635 /* next row */
636 png_ptr->row_number++;
637 /* see if we are done */
638 if (png_ptr->row_number < png_ptr->num_rows)
639 return;
640
641 /* if interlaced, go to next pass */
642 if (png_ptr->interlaced)
643 {
644 png_ptr->row_number = 0;
645 if (png_ptr->transformations & PNG_INTERLACE)
646 {
647 png_ptr->pass++;
648 }
649 else
650 {
651 /* loop until we find a non-zero width or height pass */
652 do
653 {
654 png_ptr->pass++;
655 if (png_ptr->pass >= 7)
656 break;
657 png_ptr->usr_width = (png_ptr->width +
658 png_pass_inc[png_ptr->pass] - 1 -
659 png_pass_start[png_ptr->pass]) /
660 png_pass_inc[png_ptr->pass];
661 png_ptr->num_rows = (png_ptr->height +
662 png_pass_yinc[png_ptr->pass] - 1 -
663 png_pass_ystart[png_ptr->pass]) /
664 png_pass_yinc[png_ptr->pass];
665 } while (png_ptr->usr_width == 0 || png_ptr->num_rows == 0);
666
667 }
668
669 /* reset filter row */
670 if (png_ptr->prev_row)
671 memset(png_ptr->prev_row, 0, (png_size_t)png_ptr->rowbytes + 1);
672 /* if we have more data to get, go get it */
673 if (png_ptr->pass < 7)
674 return;
675 }
676
677 /* if we get here, we've just written the last row, so we need
678 to flush the compressor */
679 do
680 {
681 /* tell the compressor we are done */
682 ret = deflate(png_ptr->zstream, Z_FINISH);
683 /* check for an error */
684 if (ret != Z_OK && ret != Z_STREAM_END)
685 {
686 if (png_ptr->zstream->msg)
687 png_error(png_ptr, png_ptr->zstream->msg);
688 else
689 png_error(png_ptr, "zlib error");
690 }
691 /* check to see if we need more room */
692 if (!png_ptr->zstream->avail_out && ret == Z_OK)
693 {
694 png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
695 png_ptr->zstream->next_out = png_ptr->zbuf;
696 png_ptr->zstream->avail_out = (uInt)png_ptr->zbuf_size;
697 }
698 } while (ret != Z_STREAM_END);
699
700 /* write any extra space */
701 if (png_ptr->zstream->avail_out < png_ptr->zbuf_size)
702 {
703 png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size -
704 png_ptr->zstream->avail_out);
705 }
706
707/* deflateReset(png_ptr->zstream); */
708 deflateEnd(png_ptr->zstream);
709 deflateInit(png_ptr->zstream, -1);
710
711}
712
713/* pick out the correct pixels for the interlace pass.
714
715 The basic idea here is to go through the row with a source
716 pointer and a destination pointer (sp and dp), and copy the
717 correct pixels for the pass. As the row gets compacted,
718 sp will always be >= dp, so we should never overwrite anything.
719 See the default: case for the easiest code to understand.
720 */
721void
722png_do_write_interlace(png_row_info *row_info, png_byte *row, int pass)
723{
724 /* we don't have to do anything on the last pass (6) */
725 if (row && row_info && pass < 6)
726 {
727 /* each pixel depth is handled seperately */
728 switch (row_info->pixel_depth)
729 {
730 case 1:
731 {
732 png_byte *sp;
733 png_byte *dp;
734 int shift;
735 int d;
736 int value;
737 png_uint_32 i;
738
739 dp = row;
740 d = 0;
741 shift = 7;
742 for (i = png_pass_start[pass];
743 i < row_info->width;
744 i += png_pass_inc[pass])
745 {
746 sp = row + (png_size_t)(i >> 3);
747 value = (int)(*sp >> (7 - (int)(i & 7))) & 0x1;
748 d |= (value << shift);
749
750 if (shift == 0)
751 {
752 shift = 7;
753 *dp++ = d;
754 d = 0;
755 }
756 else
757 shift--;
758
759 }
760 if (shift != 7)
761 *dp = d;
762 break;
763 }
764 case 2:
765 {
766 png_byte *sp;
767 png_byte *dp;
768 int shift;
769 int d;
770 int value;
771 png_uint_32 i;
772
773 dp = row;
774 shift = 6;
775 d = 0;
776 for (i = png_pass_start[pass];
777 i < row_info->width;
778 i += png_pass_inc[pass])
779 {
780 sp = row + (png_size_t)(i >> 2);
781 value = (*sp >> ((3 - (int)(i & 3)) << 1)) & 0x3;
782 d |= (value << shift);
783
784 if (shift == 0)
785 {
786 shift = 6;
787 *dp++ = d;
788 d = 0;
789 }
790 else
791 shift -= 2;
792 }
793 if (shift != 6)
794 *dp = d;
795 break;
796 }
797 case 4:
798 {
799 png_byte *sp;
800 png_byte *dp;
801 int shift;
802 int d;
803 int value;
804 png_uint_32 i;
805
806 dp = row;
807 shift = 4;
808 d = 0;
809 for (i = png_pass_start[pass];
810 i < row_info->width;
811 i += png_pass_inc[pass])
812 {
813 sp = row + (png_size_t)(i >> 1);
814 value = (*sp >> ((1 - (int)(i & 1)) << 2)) & 0xf;
815 d |= (value << shift);
816
817 if (shift == 0)
818 {
819 shift = 4;
820 *dp++ = d;
821 d = 0;
822 }
823 else
824 shift -= 4;
825 }
826 if (shift != 4)
827 *dp = d;
828 break;
829 }
830 default:
831 {
832 png_byte *sp;
833 png_byte *dp;
834 png_uint_32 i;
835 int pixel_bytes;
836
837 /* start at the beginning */
838 dp = row;
839 /* find out how many bytes each pixel takes up */
840 pixel_bytes = (row_info->pixel_depth >> 3);
841 /* loop through the row, only looking at the pixels that
842 matter */
843 for (i = png_pass_start[pass];
844 i < row_info->width;
845 i += png_pass_inc[pass])
846 {
847 /* find out where the original pixel is */
848 sp = row + (png_size_t)(i * pixel_bytes);
849 /* move the pixel */
850 if (dp != sp)
851 memcpy(dp, sp, pixel_bytes);
852 /* next pixel */
853 dp += pixel_bytes;
854 }
855 break;
856 }
857 }
858 /* set new row width */
859 row_info->width = (row_info->width +
860 png_pass_inc[pass] - 1 -
861 png_pass_start[pass]) /
862 png_pass_inc[pass];
863 row_info->rowbytes = ((row_info->width *
864 row_info->pixel_depth + 7) >> 3);
865
866 }
867}
868
869/* this filters the row. Both row and prev_row have space at the
870 first byte for the filter byte. */
871void
872png_write_filter_row(png_row_info *row_info, png_byte *row,
873 png_byte *prev_row)
874{
875 int minf, bpp;
876 png_uint_32 i, v;
877 png_uint_32 s, mins;
878 png_byte *rp, *pp, *cp, *lp;
879
880 /* find out how many bytes offset each pixel is */
881 bpp = (row_info->pixel_depth + 7) / 8;
882 if (bpp < 1)
883 bpp = 1;
884
885 /* the prediction method we use is to find which method provides
886 the smallest value when summing the abs of the distances from
887 zero using anything >= 128 as negitive numbers. */
888 for (i = 0, s = 0, rp = row + 1; i < row_info->rowbytes; i++, rp++)
889 {
890 v = *rp;
891 if (v < 128)
892 s += v;
893 else
894 s += 256 - (png_int_32)v;
895 }
896
897 mins = s;
898 minf = 0;
899
900 /* check sub filter */
901 for (i = 0, s = 0, rp = row + 1, lp = row + 1 - bpp;
902 i < row_info->rowbytes; i++, rp++, lp++)
903 {
904 if (i >= bpp)
905 v = (png_byte)(((int)*rp - (int)*lp) & 0xff);
906 else
907 v = *rp;
908
909 if (v < 128)
910 s += v;
911 else
912 s += 256 - v;
913 }
914
915 if (s < mins)
916 {
917 mins = s;
918 minf = 1;
919 }
920
921 /* check up filter */
922 for (i = 0, s = 0, rp = row + 1, pp = prev_row + 1;
923 i < row_info->rowbytes; i++, rp++, pp++)
924 {
925 v = (png_byte)(((int)*rp - (int)*pp) & 0xff);
926
927 if (v < 128)
928 s += v;
929 else
930 s += 256 - v;
931 }
932
933 if (s < mins)
934 {
935 mins = s;
936 minf = 2;
937 }
938
939 /* check avg filter */
940 for (i = 0, s = 0, rp = row + 1, pp = prev_row + 1, lp = row + 1 - bpp;
941 i < row_info->rowbytes; i++, rp++, pp++, lp++)
942 {
943 if (i >= bpp)
944 v = (png_byte)(((int)*rp - (((int)*pp + (int)*lp) / 2)) & 0xff);
945 else
946 v = (png_byte)(((int)*rp - ((int)*pp / 2)) & 0xff);
947
948 if (v < 128)
949 s += v;
950 else
951 s += 256 - v;
952 }
953
954 if (s < mins)
955 {
956 mins = s;
957 minf = 3;
958 }
959
960 /* check paeth filter */
961 for (i = 0, s = 0, rp = row + 1, pp = prev_row + 1, lp = row + 1 - bpp,
962 cp = prev_row + 1 - bpp;
963 i < row_info->rowbytes; i++, rp++, pp++, lp++, cp++)
964 {
965 int a, b, c, pa, pb, pc, p;
966
967 b = *pp;
968 if (i >= bpp)
969 {
970 c = *cp;
971 a = *lp;
972 }
973 else
974 {
975 a = c = 0;
976 }
977 p = a + b - c;
978 pa = abs(p - a);
979 pb = abs(p - b);
980 pc = abs(p - c);
981
982 if (pa <= pb && pa <= pc)
983 p = a;
984 else if (pb <= pc)
985 p = b;
986 else
987 p = c;
988
989 v = (png_byte)(((int)*rp - p) & 0xff);
990
991 if (v < 128)
992 s += v;
993 else
994 s += 256 - v;
995 }
996
997 if (s < mins)
998 {
999 mins = s;
1000 minf = 4;
1001 }
1002
1003 /* set filter byte */
1004 row[0] = minf;
1005
1006 /* do filter */
1007 switch (minf)
1008 {
1009 /* sub filter */
1010 case 1:
1011 for (i = bpp, rp = row + (png_size_t)row_info->rowbytes,
1012 lp = row + (png_size_t)row_info->rowbytes - bpp;
1013 i < row_info->rowbytes; i++, rp--, lp--)
1014 {
1015 *rp = (png_byte)(((int)*rp - (int)*lp) & 0xff);
1016 }
1017 break;
1018 /* up filter */
1019 case 2:
1020 for (i = 0, rp = row + (png_size_t)row_info->rowbytes,
1021 pp = prev_row + (png_size_t)row_info->rowbytes;
1022 i < row_info->rowbytes; i++, rp--, pp--)
1023 {
1024 *rp = (png_byte)(((int)*rp - (int)*pp) & 0xff);
1025 }
1026 break;
1027 /* avg filter */
1028 case 3:
1029 for (i = row_info->rowbytes,
1030 rp = row + (png_size_t)row_info->rowbytes,
1031 pp = prev_row + (png_size_t)row_info->rowbytes,
1032 lp = row + (png_size_t)row_info->rowbytes - bpp;
1033 i > bpp; i--, rp--, lp--, pp--)
1034 {
1035 *rp = (png_byte)(((int)*rp - (((int)*lp + (int)*pp) /
1036 2)) & 0xff);
1037 }
1038 for (; i > 0; i--, rp--, pp--)
1039 {
1040 *rp = (png_byte)(((int)*rp - ((int)*pp / 2)) & 0xff);
1041 }
1042 break;
1043 /* paeth filter */
1044 case 4:
1045 for (i = row_info->rowbytes,
1046 rp = row + (png_size_t)row_info->rowbytes,
1047 pp = prev_row + (png_size_t)row_info->rowbytes,
1048 lp = row + (png_size_t)row_info->rowbytes - bpp,
1049 cp = prev_row + (png_size_t)row_info->rowbytes - bpp;
1050 i > 0; i--, rp--, lp--, pp--, cp--)
1051 {
1052 int a, b, c, pa, pb, pc, p;
1053
1054 b = *pp;
1055 if (i > bpp)
1056 {
1057 c = *cp;
1058 a = *lp;
1059 }
1060 else
1061 {
1062 a = c = 0;
1063 }
1064 p = a + b - c;
1065 pa = abs(p - a);
1066 pb = abs(p - b);
1067 pc = abs(p - c);
1068
1069 if (pa <= pb && pa <= pc)
1070 p = a;
1071 else if (pb <= pc)
1072 p = b;
1073 else
1074 p = c;
1075
1076 *rp = (png_byte)(((int)*rp - p) & 0xff);
1077 }
1078 break;
1079 }
1080}