pngwutil.c 78.7 KB
Newer Older
G
Guy Schalnat 已提交
1

A
Andreas Dilger 已提交
2
/* pngwutil.c - utilities to write a PNG file
3
 *
4
 * Last changed in libpng 1.6.26 [October 20, 2016]
5
 * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson
6 7
 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
8
 *
9
 * This code is released under the libpng license.
10
 * For conditions of distribution and use, see the disclaimer
11
 * and license in png.h
12
 */
A
Andreas Dilger 已提交
13

14
#include "pngpriv.h"
G
Guy Schalnat 已提交
15

16 17
#ifdef PNG_WRITE_SUPPORTED

18
#ifdef PNG_WRITE_INT_FUNCTIONS_SUPPORTED
A
Andreas Dilger 已提交
19 20 21 22
/* Place a 32-bit number into a buffer in PNG byte order.  We work
 * with unsigned numbers for convenience, although one supported
 * ancillary chunk uses signed (two's complement) numbers.
 */
23
void PNGAPI
G
Guy Schalnat 已提交
24
png_save_uint_32(png_bytep buf, png_uint_32 i)
G
Guy Schalnat 已提交
25
{
26 27 28 29
   buf[0] = (png_byte)((i >> 24) & 0xffU);
   buf[1] = (png_byte)((i >> 16) & 0xffU);
   buf[2] = (png_byte)((i >>  8) & 0xffU);
   buf[3] = (png_byte)( i        & 0xffU);
G
Guy Schalnat 已提交
30 31
}

32 33 34 35
/* Place a 16-bit number into a buffer in PNG byte order.
 * The parameter is declared unsigned int, not png_uint_16,
 * just to avoid potential problems on pre-ANSI C compilers.
 */
36
void PNGAPI
37
png_save_uint_16(png_bytep buf, unsigned int i)
G
Guy Schalnat 已提交
38
{
39 40
   buf[0] = (png_byte)((i >> 8) & 0xffU);
   buf[1] = (png_byte)( i       & 0xffU);
G
Guy Schalnat 已提交
41
}
42
#endif
G
Guy Schalnat 已提交
43

44 45 46 47 48 49
/* Simple function to write the signature.  If we have already written
 * the magic bytes of the signature, or more likely, the PNG stream is
 * being embedded into another stream and doesn't need its own signature,
 * we should call png_set_sig_bytes() to tell libpng how many of the
 * bytes have already been written.
 */
50
void PNGAPI
51
png_write_sig(png_structrp png_ptr)
52 53
{
   png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
54

55 56 57 58 59
#ifdef PNG_IO_STATE_SUPPORTED
   /* Inform the I/O callback that the signature is being written */
   png_ptr->io_state = PNG_IO_WRITING | PNG_IO_SIGNATURE;
#endif

60
   /* Write the rest of the 8 byte signature */
61
   png_write_data(png_ptr, &png_signature[png_ptr->sig_bytes],
62
       (png_size_t)(8 - png_ptr->sig_bytes));
63

64
   if (png_ptr->sig_bytes < 3)
65 66 67
      png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE;
}

A
Andreas Dilger 已提交
68
/* Write the start of a PNG chunk.  The type is the chunk type.
69 70 71
 * The total_length is the sum of the lengths of all the data you will be
 * passing in png_write_chunk_data().
 */
72
static void
73
png_write_chunk_header(png_structrp png_ptr, png_uint_32 chunk_name,
74
    png_uint_32 length)
G
Guy Schalnat 已提交
75
{
76 77
   png_byte buf[8];

78
#if defined(PNG_DEBUG) && (PNG_DEBUG > 0)
79 80 81
   PNG_CSTRING_FROM_CHUNK(buf, chunk_name);
   png_debug2(0, "Writing %s chunk, length = %lu", buf, (unsigned long)length);
#endif
82 83 84 85

   if (png_ptr == NULL)
      return;

86 87 88 89 90 91 92
#ifdef PNG_IO_STATE_SUPPORTED
   /* Inform the I/O callback that the chunk header is being written.
    * PNG_IO_CHUNK_HDR requires a single I/O call.
    */
   png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_HDR;
#endif

93
   /* Write the length and the chunk name */
A
Andreas Dilger 已提交
94
   png_save_uint_32(buf, length);
95 96
   png_save_uint_32(buf + 4, chunk_name);
   png_write_data(png_ptr, buf, 8);
97

98
   /* Put the chunk name into png_ptr->chunk_name */
99
   png_ptr->chunk_name = chunk_name;
100

101
   /* Reset the crc and run it over the chunk name */
G
Guy Schalnat 已提交
102
   png_reset_crc(png_ptr);
103

104
   png_calculate_crc(png_ptr, buf + 4, 4);
105 106 107 108 109 110 111

#ifdef PNG_IO_STATE_SUPPORTED
   /* Inform the I/O callback that chunk data will (possibly) be written.
    * PNG_IO_CHUNK_DATA does NOT require a specific number of I/O calls.
    */
   png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_DATA;
#endif
G
Guy Schalnat 已提交
112 113
}

114
void PNGAPI
115
png_write_chunk_start(png_structrp png_ptr, png_const_bytep chunk_string,
116 117 118 119 120 121
    png_uint_32 length)
{
   png_write_chunk_header(png_ptr, PNG_CHUNK_FROM_STRING(chunk_string), length);
}

/* Write the data of a PNG chunk started with png_write_chunk_header().
122 123
 * Note that multiple calls to this function are allowed, and that the
 * sum of the lengths from these calls *must* add up to the total_length
124
 * given to png_write_chunk_header().
125
 */
126
void PNGAPI
127
png_write_chunk_data(png_structrp png_ptr, png_const_bytep data,
128
    png_size_t length)
G
Guy Schalnat 已提交
129
{
130 131 132
   /* Write the data, and run the CRC over it */
   if (png_ptr == NULL)
      return;
133

A
Andreas Dilger 已提交
134
   if (data != NULL && length > 0)
G
Guy Schalnat 已提交
135
   {
G
Guy Schalnat 已提交
136
      png_write_data(png_ptr, data, length);
137

138
      /* Update the CRC after writing the data,
139
       * in case the user I/O routine alters it.
140 141
       */
      png_calculate_crc(png_ptr, data, length);
G
Guy Schalnat 已提交
142 143 144
   }
}

145
/* Finish a chunk started with png_write_chunk_header(). */
146
void PNGAPI
147
png_write_chunk_end(png_structrp png_ptr)
G
Guy Schalnat 已提交
148
{
A
Andreas Dilger 已提交
149 150
   png_byte buf[4];

151 152
   if (png_ptr == NULL) return;

153 154 155 156 157 158 159
#ifdef PNG_IO_STATE_SUPPORTED
   /* Inform the I/O callback that the chunk CRC is being written.
    * PNG_IO_CHUNK_CRC requires a single I/O function call.
    */
   png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_CRC;
#endif

160
   /* Write the crc in a single operation */
A
Andreas Dilger 已提交
161 162
   png_save_uint_32(buf, png_ptr->crc);

163
   png_write_data(png_ptr, buf, (png_size_t)4);
G
Guy Schalnat 已提交
164 165
}

166 167 168 169 170 171 172 173 174 175
/* Write a PNG chunk all at once.  The type is an array of ASCII characters
 * representing the chunk name.  The array must be at least 4 bytes in
 * length, and does not need to be null terminated.  To be safe, pass the
 * pre-defined chunk names here, and if you need a new one, define it
 * where the others are defined.  The length is the length of the data.
 * All the data must be present.  If that is not possible, use the
 * png_write_chunk_start(), png_write_chunk_data(), and png_write_chunk_end()
 * functions instead.
 */
static void
176
png_write_complete_chunk(png_structrp png_ptr, png_uint_32 chunk_name,
177
    png_const_bytep data, png_size_t length)
178 179 180 181
{
   if (png_ptr == NULL)
      return;

182
   /* On 64-bit architectures 'length' may not fit in a png_uint_32. */
183
   if (length > PNG_UINT_31_MAX)
184
      png_error(png_ptr, "length exceeds PNG maximum");
185 186 187 188 189 190 191 192

   png_write_chunk_header(png_ptr, chunk_name, (png_uint_32)length);
   png_write_chunk_data(png_ptr, data, length);
   png_write_chunk_end(png_ptr);
}

/* This is the API that calls the internal function above. */
void PNGAPI
193
png_write_chunk(png_structrp png_ptr, png_const_bytep chunk_string,
194
    png_const_bytep data, png_size_t length)
195 196
{
   png_write_complete_chunk(png_ptr, PNG_CHUNK_FROM_STRING(chunk_string), data,
197
       length);
198 199
}

200 201 202 203 204 205
/* This is used below to find the size of an image to pass to png_deflate_claim,
 * so it only needs to be accurate if the size is less than 16384 bytes (the
 * point at which a lower LZ window size can be used.)
 */
static png_alloc_size_t
png_image_size(png_structrp png_ptr)
206
{
207
   /* Only return sizes up to the maximum of a png_uint_32; do this by limiting
208 209 210 211 212
    * the width and height used to 15 bits.
    */
   png_uint_32 h = png_ptr->height;

   if (png_ptr->rowbytes < 32768 && h < 32768)
213
   {
214
      if (png_ptr->interlaced != 0)
215
      {
216 217 218 219 220 221 222
         /* Interlacing makes the image larger because of the replication of
          * both the filter byte and the padding to a byte boundary.
          */
         png_uint_32 w = png_ptr->width;
         unsigned int pd = png_ptr->pixel_depth;
         png_alloc_size_t cb_base;
         int pass;
223

224
         for (cb_base=0, pass=0; pass<=6; ++pass)
225
         {
226
            png_uint_32 pw = PNG_PASS_COLS(w, pass);
227

228 229
            if (pw > 0)
               cb_base += (PNG_ROWBYTES(pd, pw)+1) * PNG_PASS_ROWS(h, pass);
230 231
         }

232 233
         return cb_base;
      }
234

235 236 237
      else
         return (png_ptr->rowbytes+1) * h;
   }
238

239
   else
240
      return 0xffffffffU;
241
}
242

243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258
#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED
   /* This is the code to hack the first two bytes of the deflate stream (the
    * deflate header) to correct the windowBits value to match the actual data
    * size.  Note that the second argument is the *uncompressed* size but the
    * first argument is the *compressed* data (and it must be deflate
    * compressed.)
    */
static void
optimize_cmf(png_bytep data, png_alloc_size_t data_size)
{
   /* Optimize the CMF field in the zlib stream.  The resultant zlib stream is
    * still compliant to the stream specification.
    */
   if (data_size <= 16384) /* else windowBits must be 15 */
   {
      unsigned int z_cmf = data[0];  /* zlib compression method and flags */
259

260 261 262 263
      if ((z_cmf & 0x0f) == 8 && (z_cmf & 0xf0) <= 0x70)
      {
         unsigned int z_cinfo;
         unsigned int half_z_window_size;
264

265 266
         z_cinfo = z_cmf >> 4;
         half_z_window_size = 1U << (z_cinfo + 7);
267

268 269 270 271 272 273 274 275
         if (data_size <= half_z_window_size) /* else no change */
         {
            unsigned int tmp;

            do
            {
               half_z_window_size >>= 1;
               --z_cinfo;
276
            }
277
            while (z_cinfo > 0 && data_size <= half_z_window_size);
278

279 280
            z_cmf = (z_cmf & 0x0f) | (z_cinfo << 4);

281
            data[0] = (png_byte)z_cmf;
282 283
            tmp = data[1] & 0xe0;
            tmp += 0x1f - ((z_cmf << 8) + tmp) % 0x1f;
284
            data[1] = (png_byte)tmp;
285 286
         }
      }
287 288
   }
}
289
#endif /* WRITE_OPTIMIZE_CMF */
290

291 292 293
/* Initialize the compressor for the appropriate type of compression. */
static int
png_deflate_claim(png_structrp png_ptr, png_uint_32 owner,
294
    png_alloc_size_t data_size)
295
{
296
   if (png_ptr->zowner != 0)
297
   {
298
#if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_ERROR_TEXT_SUPPORTED)
299
      char msg[64];
300

301 302 303 304 305 306 307 308 309
      PNG_STRING_FROM_CHUNK(msg, owner);
      msg[4] = ':';
      msg[5] = ' ';
      PNG_STRING_FROM_CHUNK(msg+6, png_ptr->zowner);
      /* So the message that results is "<chunk> using zstream"; this is an
       * internal error, but is very useful for debugging.  i18n requirements
       * are minimal.
       */
      (void)png_safecat(msg, (sizeof msg), 10, " using zstream");
310
#endif
311
#if PNG_RELEASE_BUILD
312 313 314 315 316 317 318 319 320 321
         png_warning(png_ptr, msg);

         /* Attempt sane error recovery */
         if (png_ptr->zowner == png_IDAT) /* don't steal from IDAT */
         {
            png_ptr->zstream.msg = PNGZ_MSG_CAST("in use by IDAT");
            return Z_STREAM_ERROR;
         }

         png_ptr->zowner = 0;
322
#else
323
         png_error(png_ptr, msg);
324
#endif
325 326 327 328 329 330 331 332 333
   }

   {
      int level = png_ptr->zlib_level;
      int method = png_ptr->zlib_method;
      int windowBits = png_ptr->zlib_window_bits;
      int memLevel = png_ptr->zlib_mem_level;
      int strategy; /* set below */
      int ret; /* zlib return code */
334

335
      if (owner == png_IDAT)
336
      {
337
         if ((png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_STRATEGY) != 0)
338
            strategy = png_ptr->zlib_strategy;
339

340 341
         else if (png_ptr->do_filter != PNG_FILTER_NONE)
            strategy = PNG_Z_DEFAULT_STRATEGY;
342

343 344 345
         else
            strategy = PNG_Z_DEFAULT_NOFILTER_STRATEGY;
      }
346

347 348
      else
      {
349
#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
350 351 352 353 354
            level = png_ptr->zlib_text_level;
            method = png_ptr->zlib_text_method;
            windowBits = png_ptr->zlib_text_window_bits;
            memLevel = png_ptr->zlib_text_mem_level;
            strategy = png_ptr->zlib_text_strategy;
355
#else
356 357 358 359 360 361
            /* If customization is not supported the values all come from the
             * IDAT values except for the strategy, which is fixed to the
             * default.  (This is the pre-1.6.0 behavior too, although it was
             * implemented in a very different way.)
             */
            strategy = Z_DEFAULT_STRATEGY;
362
#endif
363
      }
364

365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384
      /* Adjust 'windowBits' down if larger than 'data_size'; to stop this
       * happening just pass 32768 as the data_size parameter.  Notice that zlib
       * requires an extra 262 bytes in the window in addition to the data to be
       * able to see the whole of the data, so if data_size+262 takes us to the
       * next windowBits size we need to fix up the value later.  (Because even
       * though deflate needs the extra window, inflate does not!)
       */
      if (data_size <= 16384)
      {
         /* IMPLEMENTATION NOTE: this 'half_window_size' stuff is only here to
          * work round a Microsoft Visual C misbehavior which, contrary to C-90,
          * widens the result of the following shift to 64-bits if (and,
          * apparently, only if) it is used in a test.
          */
         unsigned int half_window_size = 1U << (windowBits-1);

         while (data_size + 262 <= half_window_size)
         {
            half_window_size >>= 1;
            --windowBits;
385
         }
386
      }
387

388
      /* Check against the previous initialized values, if any. */
389
      if ((png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) != 0 &&
390 391 392 393 394 395 396 397
         (png_ptr->zlib_set_level != level ||
         png_ptr->zlib_set_method != method ||
         png_ptr->zlib_set_window_bits != windowBits ||
         png_ptr->zlib_set_mem_level != memLevel ||
         png_ptr->zlib_set_strategy != strategy))
      {
         if (deflateEnd(&png_ptr->zstream) != Z_OK)
            png_warning(png_ptr, "deflateEnd failed (ignored)");
398

399 400
         png_ptr->flags &= ~PNG_FLAG_ZSTREAM_INITIALIZED;
      }
401

402 403 404 405 406 407 408
      /* For safety clear out the input and output pointers (currently zlib
       * doesn't use them on Init, but it might in the future).
       */
      png_ptr->zstream.next_in = NULL;
      png_ptr->zstream.avail_in = 0;
      png_ptr->zstream.next_out = NULL;
      png_ptr->zstream.avail_out = 0;
409

410
      /* Now initialize if required, setting the new parameters, otherwise just
411
       * do a simple reset to the previous parameters.
412
       */
413
      if ((png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) != 0)
414 415 416 417 418
         ret = deflateReset(&png_ptr->zstream);

      else
      {
         ret = deflateInit2(&png_ptr->zstream, level, method, windowBits,
419
             memLevel, strategy);
420 421 422

         if (ret == Z_OK)
            png_ptr->flags |= PNG_FLAG_ZSTREAM_INITIALIZED;
423
      }
424 425 426 427 428 429 430 431 432 433 434

      /* The return code is from either deflateReset or deflateInit2; they have
       * pretty much the same set of error codes.
       */
      if (ret == Z_OK)
         png_ptr->zowner = owner;

      else
         png_zstream_error(png_ptr, ret);

      return ret;
435
   }
436
}
437

438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456
/* Clean up (or trim) a linked list of compression buffers. */
void /* PRIVATE */
png_free_buffer_list(png_structrp png_ptr, png_compression_bufferp *listp)
{
   png_compression_bufferp list = *listp;

   if (list != NULL)
   {
      *listp = NULL;

      do
      {
         png_compression_bufferp next = list->next;

         png_free(png_ptr, list);
         list = next;
      }
      while (list != NULL);
   }
457 458
}

459
#ifdef PNG_WRITE_COMPRESSED_TEXT_SUPPORTED
460
/* This pair of functions encapsulates the operation of (a) compressing a
461 462
 * text string, and (b) issuing it later as a series of chunk data writes.
 * The compression_state structure is shared context for these functions
463 464 465 466 467 468
 * set up by the caller to allow access to the relevant local variables.
 *
 * compression_buffer (new in 1.6.0) is just a linked list of zbuffer_size
 * temporary buffers.  From 1.6.0 it is retained in png_struct so that it will
 * be correctly freed in the event of a write error (previous implementations
 * just leaked memory.)
469 470 471
 */
typedef struct
{
472 473 474 475
   png_const_bytep      input;        /* The uncompressed input data */
   png_alloc_size_t     input_len;    /* Its length */
   png_uint_32          output_len;   /* Final compressed length */
   png_byte             output[1024]; /* First block of output */
476 477
} compression_state;

478 479
static void
png_text_compress_init(compression_state *comp, png_const_bytep input,
480
    png_alloc_size_t input_len)
481
{
482 483 484 485
   comp->input = input;
   comp->input_len = input_len;
   comp->output_len = 0;
}
486

487 488 489
/* Compress the data in the compression state input */
static int
png_text_compress(png_structrp png_ptr, png_uint_32 chunk_name,
490
    compression_state *comp, png_uint_32 prefix_len)
491 492
{
   int ret;
493

494
   /* To find the length of the output it is necessary to first compress the
495
    * input. The result is buffered rather than using the two-pass algorithm
496 497
    * that is used on the inflate side; deflate is assumed to be slower and a
    * PNG writer is assumed to have more memory available than a PNG reader.
498
    *
499 500 501 502
    * IMPLEMENTATION NOTE: the zlib API deflateBound() can be used to find an
    * upper limit on the output size, but it is always bigger than the input
    * size so it is likely to be more efficient to use this linked-list
    * approach.
503
    */
504
   ret = png_deflate_claim(png_ptr, chunk_name, comp->input_len);
505

506 507
   if (ret != Z_OK)
      return ret;
508

509 510 511 512 513 514
   /* Set up the compression buffers, we need a loop here to avoid overflowing a
    * uInt.  Use ZLIB_IO_MAX to limit the input.  The output is always limited
    * by the output buffer size, so there is no need to check that.  Since this
    * is ANSI-C we know that an 'int', hence a uInt, is always at least 16 bits
    * in size.
    */
515
   {
516 517 518
      png_compression_bufferp *end = &png_ptr->zbuffer_list;
      png_alloc_size_t input_len = comp->input_len; /* may be zero! */
      png_uint_32 output_len;
519

520 521 522 523 524
      /* zlib updates these for us: */
      png_ptr->zstream.next_in = PNGZ_INPUT_CAST(comp->input);
      png_ptr->zstream.avail_in = 0; /* Set below */
      png_ptr->zstream.next_out = comp->output;
      png_ptr->zstream.avail_out = (sizeof comp->output);
525

526
      output_len = png_ptr->zstream.avail_out;
527

528
      do
529
      {
530
         uInt avail_in = ZLIB_IO_MAX;
531

532 533
         if (avail_in > input_len)
            avail_in = (uInt)input_len;
534

535
         input_len -= avail_in;
536

537
         png_ptr->zstream.avail_in = avail_in;
538

539 540 541
         if (png_ptr->zstream.avail_out == 0)
         {
            png_compression_buffer *next;
542

543 544 545 546 547 548 549
            /* Chunk data is limited to 2^31 bytes in length, so the prefix
             * length must be counted here.
             */
            if (output_len + prefix_len > PNG_UINT_31_MAX)
            {
               ret = Z_MEM_ERROR;
               break;
550 551
            }

552 553 554 555 556
            /* Need a new (malloc'ed) buffer, but there may be one present
             * already.
             */
            next = *end;
            if (next == NULL)
557
            {
558 559
               next = png_voidcast(png_compression_bufferp, png_malloc_base
                  (png_ptr, PNG_COMPRESSION_BUFFER_SIZE(png_ptr)));
560

561
               if (next == NULL)
562
               {
563 564
                  ret = Z_MEM_ERROR;
                  break;
565 566
               }

567 568 569
               /* Link in this buffer (so that it will be freed later) */
               next->next = NULL;
               *end = next;
570 571
            }

572 573 574
            png_ptr->zstream.next_out = next->output;
            png_ptr->zstream.avail_out = png_ptr->zbuffer_size;
            output_len += png_ptr->zstream.avail_out;
575

576 577 578
            /* Move 'end' to the next buffer pointer. */
            end = &next->next;
         }
579

580 581
         /* Compress the data */
         ret = deflate(&png_ptr->zstream,
582
             input_len > 0 ? Z_NO_FLUSH : Z_FINISH);
583

584 585 586 587 588
         /* Claw back input data that was not consumed (because avail_in is
          * reset above every time round the loop).
          */
         input_len += png_ptr->zstream.avail_in;
         png_ptr->zstream.avail_in = 0; /* safety */
589
      }
590
      while (ret == Z_OK);
591

592
      /* There may be some space left in the last output buffer. This needs to
593 594 595 596 597 598 599 600 601 602 603 604 605 606
       * be subtracted from output_len.
       */
      output_len -= png_ptr->zstream.avail_out;
      png_ptr->zstream.avail_out = 0; /* safety */
      comp->output_len = output_len;

      /* Now double check the output length, put in a custom message if it is
       * too long.  Otherwise ensure the z_stream::msg pointer is set to
       * something.
       */
      if (output_len + prefix_len >= PNG_UINT_31_MAX)
      {
         png_ptr->zstream.msg = PNGZ_MSG_CAST("compressed data too long");
         ret = Z_MEM_ERROR;
607 608
      }

609 610
      else
         png_zstream_error(png_ptr, ret);
611

612 613
      /* Reset zlib for another zTXt/iTXt or image data */
      png_ptr->zowner = 0;
614

615
      /* The only success case is Z_STREAM_END, input_len must be 0; if not this
616 617 618 619
       * is an internal error.
       */
      if (ret == Z_STREAM_END && input_len == 0)
      {
620
#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED
621 622
         /* Fix up the deflate header, if required */
         optimize_cmf(comp->output, comp->input_len);
623
#endif
624 625 626 627 628 629 630 631 632 633
         /* But Z_OK is returned, not Z_STREAM_END; this allows the claim
          * function above to return Z_STREAM_END on an error (though it never
          * does in the current versions of zlib.)
          */
         return Z_OK;
      }

      else
         return ret;
   }
634 635
}

636
/* Ship the compressed text out via chunk writes */
637
static void
638
png_write_compressed_data_out(png_structrp png_ptr, compression_state *comp)
639
{
640 641 642 643
   png_uint_32 output_len = comp->output_len;
   png_const_bytep output = comp->output;
   png_uint_32 avail = (sizeof comp->output);
   png_compression_buffer *next = png_ptr->zbuffer_list;
644

645
   for (;;)
646
   {
647 648
      if (avail > output_len)
         avail = output_len;
649

650
      png_write_chunk_data(png_ptr, output, avail);
651

652
      output_len -= avail;
653

654 655
      if (output_len == 0 || next == NULL)
         break;
656

657 658 659 660
      avail = png_ptr->zbuffer_size;
      output = next->output;
      next = next->next;
   }
661

662 663 664 665
   /* This is an internal error; 'next' must have been NULL! */
   if (output_len > 0)
      png_error(png_ptr, "error writing ancillary chunked compressed data");
}
666
#endif /* WRITE_COMPRESSED_TEXT */
667

G
Guy Schalnat 已提交
668
/* Write the IHDR chunk, and update the png_struct with the necessary
669 670 671
 * information.  Note that the rest of this code depends upon this
 * information being correct.
 */
672
void /* PRIVATE */
673
png_write_IHDR(png_structrp png_ptr, png_uint_32 width, png_uint_32 height,
674 675
    int bit_depth, int color_type, int compression_type, int filter_type,
    int interlace_type)
G
Guy Schalnat 已提交
676
{
677
   png_byte buf[13]; /* Buffer to store the IHDR info */
678
   int is_invalid_depth;
G
Guy Schalnat 已提交
679

680
   png_debug(1, "in png_write_IHDR");
681

G
Guy Schalnat 已提交
682
   /* Check that we have valid input data from the application info */
G
Guy Schalnat 已提交
683 684
   switch (color_type)
   {
A
Andreas Dilger 已提交
685
      case PNG_COLOR_TYPE_GRAY:
G
Guy Schalnat 已提交
686 687 688 689 690 691
         switch (bit_depth)
         {
            case 1:
            case 2:
            case 4:
            case 8:
692
#ifdef PNG_WRITE_16BIT_SUPPORTED
693
            case 16:
694
#endif
695
               png_ptr->channels = 1; break;
696

697 698 699
            default:
               png_error(png_ptr,
                   "Invalid bit depth for grayscale image");
G
Guy Schalnat 已提交
700
         }
G
Guy Schalnat 已提交
701
         break;
702

A
Andreas Dilger 已提交
703
      case PNG_COLOR_TYPE_RGB:
704
         is_invalid_depth = (bit_depth != 8);
705
#ifdef PNG_WRITE_16BIT_SUPPORTED
706
         is_invalid_depth = (is_invalid_depth && bit_depth != 16);
707
#endif
708
         if (is_invalid_depth)
G
Guy Schalnat 已提交
709
            png_error(png_ptr, "Invalid bit depth for RGB image");
710

G
Guy Schalnat 已提交
711 712
         png_ptr->channels = 3;
         break;
713

A
Andreas Dilger 已提交
714
      case PNG_COLOR_TYPE_PALETTE:
G
Guy Schalnat 已提交
715 716 717 718 719
         switch (bit_depth)
         {
            case 1:
            case 2:
            case 4:
720 721 722
            case 8:
               png_ptr->channels = 1;
               break;
723

724 725
            default:
               png_error(png_ptr, "Invalid bit depth for paletted image");
G
Guy Schalnat 已提交
726 727
         }
         break;
728

A
Andreas Dilger 已提交
729
      case PNG_COLOR_TYPE_GRAY_ALPHA:
730 731 732 733 734
         is_invalid_depth = (bit_depth != 8);
#ifdef PNG_WRITE_16BIT_SUPPORTED
         is_invalid_depth = (is_invalid_depth && bit_depth != 16);
#endif
         if (is_invalid_depth)
G
Guy Schalnat 已提交
735
            png_error(png_ptr, "Invalid bit depth for grayscale+alpha image");
736

G
Guy Schalnat 已提交
737 738
         png_ptr->channels = 2;
         break;
739

A
Andreas Dilger 已提交
740
      case PNG_COLOR_TYPE_RGB_ALPHA:
741
         is_invalid_depth = (bit_depth != 8);
742
#ifdef PNG_WRITE_16BIT_SUPPORTED
743
         is_invalid_depth = (is_invalid_depth && bit_depth != 16);
744
#endif
745
         if (is_invalid_depth)
G
Guy Schalnat 已提交
746
            png_error(png_ptr, "Invalid bit depth for RGBA image");
747

G
Guy Schalnat 已提交
748 749
         png_ptr->channels = 4;
         break;
750

G
Guy Schalnat 已提交
751 752 753 754
      default:
         png_error(png_ptr, "Invalid image color type specified");
   }

A
Andreas Dilger 已提交
755
   if (compression_type != PNG_COMPRESSION_TYPE_BASE)
G
Guy Schalnat 已提交
756 757
   {
      png_warning(png_ptr, "Invalid compression type specified");
A
Andreas Dilger 已提交
758
      compression_type = PNG_COMPRESSION_TYPE_BASE;
G
Guy Schalnat 已提交
759 760
   }

761 762 763 764 765 766 767 768 769
   /* Write filter_method 64 (intrapixel differencing) only if
    * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and
    * 2. Libpng did not write a PNG signature (this filter_method is only
    *    used in PNG datastreams that are embedded in MNG datastreams) and
    * 3. The application called png_permit_mng_features with a mask that
    *    included PNG_FLAG_MNG_FILTER_64 and
    * 4. The filter_method is 64 and
    * 5. The color_type is RGB or RGBA
    */
770
   if (
771
#ifdef PNG_MNG_FEATURES_SUPPORTED
772 773
       !((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 &&
       ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) == 0) &&
774 775 776
       (color_type == PNG_COLOR_TYPE_RGB ||
        color_type == PNG_COLOR_TYPE_RGB_ALPHA) &&
       (filter_type == PNG_INTRAPIXEL_DIFFERENCING)) &&
777
#endif
778
       filter_type != PNG_FILTER_TYPE_BASE)
G
Guy Schalnat 已提交
779 780
   {
      png_warning(png_ptr, "Invalid filter type specified");
A
Andreas Dilger 已提交
781
      filter_type = PNG_FILTER_TYPE_BASE;
G
Guy Schalnat 已提交
782 783
   }

784
#ifdef PNG_WRITE_INTERLACING_SUPPORTED
A
Andreas Dilger 已提交
785
   if (interlace_type != PNG_INTERLACE_NONE &&
786
       interlace_type != PNG_INTERLACE_ADAM7)
G
Guy Schalnat 已提交
787 788
   {
      png_warning(png_ptr, "Invalid interlace type specified");
A
Andreas Dilger 已提交
789
      interlace_type = PNG_INTERLACE_ADAM7;
G
Guy Schalnat 已提交
790
   }
791 792 793
#else
   interlace_type=PNG_INTERLACE_NONE;
#endif
G
Guy Schalnat 已提交
794

795
   /* Save the relevant information */
796 797 798
   png_ptr->bit_depth = (png_byte)bit_depth;
   png_ptr->color_type = (png_byte)color_type;
   png_ptr->interlaced = (png_byte)interlace_type;
799
#ifdef PNG_MNG_FEATURES_SUPPORTED
800
   png_ptr->filter_type = (png_byte)filter_type;
801
#endif
802
   png_ptr->compression_type = (png_byte)compression_type;
G
Guy Schalnat 已提交
803 804 805
   png_ptr->width = width;
   png_ptr->height = height;

806
   png_ptr->pixel_depth = (png_byte)(bit_depth * png_ptr->channels);
807
   png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, width);
808
   /* Set the usr info, so any transformations can modify it */
G
Guy Schalnat 已提交
809 810
   png_ptr->usr_width = png_ptr->width;
   png_ptr->usr_bit_depth = png_ptr->bit_depth;
G
Guy Schalnat 已提交
811 812
   png_ptr->usr_channels = png_ptr->channels;

813
   /* Pack the header information into the buffer */
G
Guy Schalnat 已提交
814 815
   png_save_uint_32(buf, width);
   png_save_uint_32(buf + 4, height);
816 817 818 819 820
   buf[8] = (png_byte)bit_depth;
   buf[9] = (png_byte)color_type;
   buf[10] = (png_byte)compression_type;
   buf[11] = (png_byte)filter_type;
   buf[12] = (png_byte)interlace_type;
G
Guy Schalnat 已提交
821

822
   /* Write the chunk */
823
   png_write_complete_chunk(png_ptr, png_IHDR, buf, (png_size_t)13);
G
Guy Schalnat 已提交
824

825
   if ((png_ptr->do_filter) == PNG_NO_FILTERS)
G
Guy Schalnat 已提交
826
   {
A
Andreas Dilger 已提交
827
      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE ||
828
          png_ptr->bit_depth < 8)
G
Guy Schalnat 已提交
829
         png_ptr->do_filter = PNG_FILTER_NONE;
830

G
Guy Schalnat 已提交
831
      else
G
Guy Schalnat 已提交
832
         png_ptr->do_filter = PNG_ALL_FILTERS;
G
Guy Schalnat 已提交
833
   }
834

835
   png_ptr->mode = PNG_HAVE_IHDR; /* not READY_FOR_ZTXT */
G
Guy Schalnat 已提交
836 837
}

838
/* Write the palette.  We are careful not to trust png_color to be in the
839
 * correct order for PNG, so people can redefine it to any convenient
840 841
 * structure.
 */
842
void /* PRIVATE */
843
png_write_PLTE(png_structrp png_ptr, png_const_colorp palette,
844
    png_uint_32 num_pal)
G
Guy Schalnat 已提交
845
{
846
   png_uint_32 max_palette_length, i;
847
   png_const_colorp pal_ptr;
G
Guy Schalnat 已提交
848 849
   png_byte buf[3];

850
   png_debug(1, "in png_write_PLTE");
851

852
   max_palette_length = (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ?
853 854
      (1 << png_ptr->bit_depth) : PNG_MAX_PALETTE_LENGTH;

855
   if ((
856
#ifdef PNG_MNG_FEATURES_SUPPORTED
857
       (png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) == 0 &&
858
#endif
859
       num_pal == 0) || num_pal > max_palette_length)
860
   {
861 862 863 864
      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
      {
         png_error(png_ptr, "Invalid number of colors in palette");
      }
865

866 867 868 869 870
      else
      {
         png_warning(png_ptr, "Invalid number of colors in palette");
         return;
      }
871 872
   }

873
   if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0)
874 875
   {
      png_warning(png_ptr,
876
          "Ignoring request to write a PLTE chunk in grayscale PNG");
877

878
      return;
G
Guy Schalnat 已提交
879 880
   }

A
Andreas Dilger 已提交
881
   png_ptr->num_palette = (png_uint_16)num_pal;
882
   png_debug1(3, "num_palette = %d", png_ptr->num_palette);
G
Guy Schalnat 已提交
883

884
   png_write_chunk_header(png_ptr, png_PLTE, (png_uint_32)(num_pal * 3));
885
#ifdef PNG_POINTER_INDEXING_SUPPORTED
886

A
Andreas Dilger 已提交
887
   for (i = 0, pal_ptr = palette; i < num_pal; i++, pal_ptr++)
G
Guy Schalnat 已提交
888 889 890 891
   {
      buf[0] = pal_ptr->red;
      buf[1] = pal_ptr->green;
      buf[2] = pal_ptr->blue;
892
      png_write_chunk_data(png_ptr, buf, (png_size_t)3);
G
Guy Schalnat 已提交
893
   }
894

895
#else
896 897 898
   /* This is a little slower but some buggy compilers need to do this
    * instead
    */
899
   pal_ptr=palette;
900

901 902 903 904 905
   for (i = 0; i < num_pal; i++)
   {
      buf[0] = pal_ptr[i].red;
      buf[1] = pal_ptr[i].green;
      buf[2] = pal_ptr[i].blue;
906
      png_write_chunk_data(png_ptr, buf, (png_size_t)3);
907
   }
908

909
#endif
G
Guy Schalnat 已提交
910
   png_write_chunk_end(png_ptr);
G
Guy Schalnat 已提交
911
   png_ptr->mode |= PNG_HAVE_PLTE;
G
Guy Schalnat 已提交
912 913
}

914 915 916 917 918 919 920 921 922 923 924 925 926 927
/* This is similar to png_text_compress, above, except that it does not require
 * all of the data at once and, instead of buffering the compressed result,
 * writes it as IDAT chunks.  Unlike png_text_compress it *can* png_error out
 * because it calls the write interface.  As a result it does its own error
 * reporting and does not return an error code.  In the event of error it will
 * just call png_error.  The input data length may exceed 32-bits.  The 'flush'
 * parameter is exactly the same as that to deflate, with the following
 * meanings:
 *
 * Z_NO_FLUSH: normal incremental output of compressed data
 * Z_SYNC_FLUSH: do a SYNC_FLUSH, used by png_write_flush
 * Z_FINISH: this is the end of the input, do a Z_FINISH and clean up
 *
 * The routine manages the acquire and release of the png_ptr->zstream by
928
 * checking and (at the end) clearing png_ptr->zowner; it does some sanity
929 930
 * checks on the 'mode' flags while doing this.
 */
931
void /* PRIVATE */
932
png_compress_IDAT(png_structrp png_ptr, png_const_bytep input,
933
    png_alloc_size_t input_len, int flush)
G
Guy Schalnat 已提交
934
{
935 936 937 938 939 940 941 942 943 944
   if (png_ptr->zowner != png_IDAT)
   {
      /* First time.   Ensure we have a temporary buffer for compression and
       * trim the buffer list if it has more than one entry to free memory.
       * If 'WRITE_COMPRESSED_TEXT' is not set the list will never have been
       * created at this point, but the check here is quick and safe.
       */
      if (png_ptr->zbuffer_list == NULL)
      {
         png_ptr->zbuffer_list = png_voidcast(png_compression_bufferp,
945
             png_malloc(png_ptr, PNG_COMPRESSION_BUFFER_SIZE(png_ptr)));
946 947
         png_ptr->zbuffer_list->next = NULL;
      }
948

949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969
      else
         png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list->next);

      /* It is a terminal error if we can't claim the zstream. */
      if (png_deflate_claim(png_ptr, png_IDAT, png_image_size(png_ptr)) != Z_OK)
         png_error(png_ptr, png_ptr->zstream.msg);

      /* The output state is maintained in png_ptr->zstream, so it must be
       * initialized here after the claim.
       */
      png_ptr->zstream.next_out = png_ptr->zbuffer_list->output;
      png_ptr->zstream.avail_out = png_ptr->zbuffer_size;
   }

   /* Now loop reading and writing until all the input is consumed or an error
    * terminates the operation.  The _out values are maintained across calls to
    * this function, but the input must be reset each time.
    */
   png_ptr->zstream.next_in = PNGZ_INPUT_CAST(input);
   png_ptr->zstream.avail_in = 0; /* set below */
   for (;;)
970
   {
971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987
      int ret;

      /* INPUT: from the row data */
      uInt avail = ZLIB_IO_MAX;

      if (avail > input_len)
         avail = (uInt)input_len; /* safe because of the check */

      png_ptr->zstream.avail_in = avail;
      input_len -= avail;

      ret = deflate(&png_ptr->zstream, input_len > 0 ? Z_NO_FLUSH : flush);

      /* Include as-yet unconsumed input */
      input_len += png_ptr->zstream.avail_in;
      png_ptr->zstream.avail_in = 0;

988
      /* OUTPUT: write complete IDAT chunks when avail_out drops to zero. Note
989 990
       * that these two zstream fields are preserved across the calls, therefore
       * there is no need to set these up on entry to the loop.
991
       */
992 993 994 995
      if (png_ptr->zstream.avail_out == 0)
      {
         png_bytep data = png_ptr->zbuffer_list->output;
         uInt size = png_ptr->zbuffer_size;
996

997 998 999
         /* Write an IDAT containing the data then reset the buffer.  The
          * first IDAT may need deflate header optimization.
          */
1000 1001 1002
#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED
            if ((png_ptr->mode & PNG_HAVE_IDAT) == 0 &&
                png_ptr->compression_type == PNG_COMPRESSION_TYPE_BASE)
1003
               optimize_cmf(data, png_image_size(png_ptr));
1004
#endif
1005

1006
         if (size > 0)
1007
            png_write_complete_chunk(png_ptr, png_IDAT, data, size);
1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020
         png_ptr->mode |= PNG_HAVE_IDAT;

         png_ptr->zstream.next_out = data;
         png_ptr->zstream.avail_out = size;

         /* For SYNC_FLUSH or FINISH it is essential to keep calling zlib with
          * the same flush parameter until it has finished output, for NO_FLUSH
          * it doesn't matter.
          */
         if (ret == Z_OK && flush != Z_NO_FLUSH)
            continue;
      }

1021
      /* The order of these checks doesn't matter much; it just affects which
1022 1023 1024
       * possible error might be detected if multiple things go wrong at once.
       */
      if (ret == Z_OK) /* most likely return code! */
1025
      {
1026 1027 1028
         /* If all the input has been consumed then just return.  If Z_FINISH
          * was used as the flush parameter something has gone wrong if we get
          * here.
1029
          */
1030
         if (input_len == 0)
1031
         {
1032 1033
            if (flush == Z_FINISH)
               png_error(png_ptr, "Z_OK on Z_FINISH with output space");
1034

1035 1036 1037
            return;
         }
      }
1038

1039 1040 1041 1042 1043 1044 1045
      else if (ret == Z_STREAM_END && flush == Z_FINISH)
      {
         /* This is the end of the IDAT data; any pending output must be
          * flushed.  For small PNG files we may still be at the beginning.
          */
         png_bytep data = png_ptr->zbuffer_list->output;
         uInt size = png_ptr->zbuffer_size - png_ptr->zstream.avail_out;
1046

1047 1048 1049 1050 1051
#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED
         if ((png_ptr->mode & PNG_HAVE_IDAT) == 0 &&
             png_ptr->compression_type == PNG_COMPRESSION_TYPE_BASE)
            optimize_cmf(data, png_image_size(png_ptr));
#endif
1052

1053
         if (size > 0)
1054
            png_write_complete_chunk(png_ptr, png_IDAT, data, size);
1055 1056 1057
         png_ptr->zstream.avail_out = 0;
         png_ptr->zstream.next_out = NULL;
         png_ptr->mode |= PNG_HAVE_IDAT | PNG_AFTER_IDAT;
1058

1059 1060
         png_ptr->zowner = 0; /* Release the stream */
         return;
1061
      }
1062

1063
      else
1064 1065 1066 1067 1068
      {
         /* This is an error condition. */
         png_zstream_error(png_ptr, ret);
         png_error(png_ptr, png_ptr->zstream.msg);
      }
1069
   }
G
Guy Schalnat 已提交
1070 1071
}

1072
/* Write an IEND chunk */
1073
void /* PRIVATE */
1074
png_write_IEND(png_structrp png_ptr)
G
Guy Schalnat 已提交
1075
{
1076
   png_debug(1, "in png_write_IEND");
1077

1078
   png_write_complete_chunk(png_ptr, png_IEND, NULL, (png_size_t)0);
A
Andreas Dilger 已提交
1079
   png_ptr->mode |= PNG_HAVE_IEND;
G
Guy Schalnat 已提交
1080 1081
}

1082
#ifdef PNG_WRITE_gAMA_SUPPORTED
1083
/* Write a gAMA chunk */
1084
void /* PRIVATE */
1085
png_write_gAMA_fixed(png_structrp png_ptr, png_fixed_point file_gamma)
1086 1087 1088
{
   png_byte buf[4];

1089
   png_debug(1, "in png_write_gAMA");
1090

1091
   /* file_gamma is saved in 1/100,000ths */
1092
   png_save_uint_32(buf, (png_uint_32)file_gamma);
1093
   png_write_complete_chunk(png_ptr, png_gAMA, buf, (png_size_t)4);
1094 1095
}
#endif
G
Guy Schalnat 已提交
1096

1097
#ifdef PNG_WRITE_sRGB_SUPPORTED
1098
/* Write a sRGB chunk */
1099
void /* PRIVATE */
1100
png_write_sRGB(png_structrp png_ptr, int srgb_intent)
1101 1102 1103
{
   png_byte buf[1];

1104
   png_debug(1, "in png_write_sRGB");
1105

1106
   if (srgb_intent >= PNG_sRGB_INTENT_LAST)
1107 1108
      png_warning(png_ptr,
          "Invalid sRGB rendering intent specified");
1109

1110
   buf[0]=(png_byte)srgb_intent;
1111
   png_write_complete_chunk(png_ptr, png_sRGB, buf, (png_size_t)1);
1112 1113 1114
}
#endif

1115
#ifdef PNG_WRITE_iCCP_SUPPORTED
1116
/* Write an iCCP chunk */
1117
void /* PRIVATE */
1118 1119
png_write_iCCP(png_structrp png_ptr, png_const_charp name,
    png_const_bytep profile)
1120
{
1121 1122 1123
   png_uint_32 name_len;
   png_uint_32 profile_len;
   png_byte new_name[81]; /* 1 byte for the compression byte */
1124
   compression_state comp;
1125
   png_uint_32 temp;
1126

1127
   png_debug(1, "in png_write_iCCP");
1128

1129 1130 1131
   /* These are all internal problems: the profile should have been checked
    * before when it was stored.
    */
1132
   if (profile == NULL)
1133
      png_error(png_ptr, "No profile for iCCP chunk"); /* internal error */
1134

1135
   profile_len = png_get_uint_32(profile);
1136

1137 1138
   if (profile_len < 132)
      png_error(png_ptr, "ICC profile too short");
1139

1140 1141
   temp = (png_uint_32) (*(profile+8));
   if (temp > 3 && (profile_len & 0x03))
1142
      png_error(png_ptr, "ICC profile length invalid (not a multiple of 4)");
1143

1144
   {
1145
      png_uint_32 embedded_profile_len = png_get_uint_32(profile);
1146

1147 1148
      if (profile_len != embedded_profile_len)
         png_error(png_ptr, "Profile length does not match profile");
1149
   }
1150

1151
   name_len = png_check_keyword(png_ptr, name, new_name);
1152

1153 1154
   if (name_len == 0)
      png_error(png_ptr, "iCCP: invalid keyword");
1155

1156
   new_name[++name_len] = PNG_COMPRESSION_TYPE_BASE;
1157

1158
   /* Make sure we include the NULL after the name and the compression type */
1159
   ++name_len;
1160

1161
   png_text_compress_init(&comp, profile, profile_len);
1162

1163 1164 1165
   /* Allow for keyword terminator and compression byte */
   if (png_text_compress(png_ptr, png_iCCP, &comp, name_len) != Z_OK)
      png_error(png_ptr, png_ptr->zstream.msg);
1166

1167 1168 1169 1170 1171
   png_write_chunk_header(png_ptr, png_iCCP, name_len + comp.output_len);

   png_write_chunk_data(png_ptr, new_name, name_len);

   png_write_compressed_data_out(png_ptr, &comp);
1172 1173 1174 1175 1176

   png_write_chunk_end(png_ptr);
}
#endif

1177
#ifdef PNG_WRITE_sPLT_SUPPORTED
1178
/* Write a sPLT chunk */
1179
void /* PRIVATE */
1180
png_write_sPLT(png_structrp png_ptr, png_const_sPLT_tp spalette)
1181
{
1182 1183
   png_uint_32 name_len;
   png_byte new_name[80];
1184
   png_byte entrybuf[10];
1185
   png_size_t entry_size = (spalette->depth == 8 ? 6 : 10);
1186
   png_size_t palette_size = entry_size * (png_size_t)spalette->nentries;
1187
   png_sPLT_entryp ep;
1188
#ifndef PNG_POINTER_INDEXING_SUPPORTED
1189 1190
   int i;
#endif
1191

1192
   png_debug(1, "in png_write_sPLT");
1193

1194 1195 1196 1197
   name_len = png_check_keyword(png_ptr, spalette->name, new_name);

   if (name_len == 0)
      png_error(png_ptr, "sPLT: invalid keyword");
1198

1199
   /* Make sure we include the NULL after the name */
1200
   png_write_chunk_header(png_ptr, png_sPLT,
1201
       (png_uint_32)(name_len + 2 + palette_size));
1202

1203
   png_write_chunk_data(png_ptr, (png_bytep)new_name,
1204
       (png_size_t)(name_len + 1));
1205

1206
   png_write_chunk_data(png_ptr, &spalette->depth, (png_size_t)1);
1207

1208
   /* Loop through each palette entry, writing appropriately */
1209
#ifdef PNG_POINTER_INDEXING_SUPPORTED
1210
   for (ep = spalette->entries; ep<spalette->entries + spalette->nentries; ep++)
1211
   {
1212 1213
      if (spalette->depth == 8)
      {
1214 1215 1216 1217
         entrybuf[0] = (png_byte)ep->red;
         entrybuf[1] = (png_byte)ep->green;
         entrybuf[2] = (png_byte)ep->blue;
         entrybuf[3] = (png_byte)ep->alpha;
1218
         png_save_uint_16(entrybuf + 4, ep->frequency);
1219
      }
1220

1221 1222
      else
      {
1223 1224 1225 1226 1227
         png_save_uint_16(entrybuf + 0, ep->red);
         png_save_uint_16(entrybuf + 2, ep->green);
         png_save_uint_16(entrybuf + 4, ep->blue);
         png_save_uint_16(entrybuf + 6, ep->alpha);
         png_save_uint_16(entrybuf + 8, ep->frequency);
1228
      }
1229

1230
      png_write_chunk_data(png_ptr, entrybuf, entry_size);
1231
   }
1232 1233
#else
   ep=spalette->entries;
1234
   for (i = 0; i>spalette->nentries; i++)
1235
   {
1236 1237
      if (spalette->depth == 8)
      {
1238 1239 1240 1241
         entrybuf[0] = (png_byte)ep[i].red;
         entrybuf[1] = (png_byte)ep[i].green;
         entrybuf[2] = (png_byte)ep[i].blue;
         entrybuf[3] = (png_byte)ep[i].alpha;
1242
         png_save_uint_16(entrybuf + 4, ep[i].frequency);
1243
      }
1244

1245 1246
      else
      {
1247 1248 1249 1250 1251
         png_save_uint_16(entrybuf + 0, ep[i].red);
         png_save_uint_16(entrybuf + 2, ep[i].green);
         png_save_uint_16(entrybuf + 4, ep[i].blue);
         png_save_uint_16(entrybuf + 6, ep[i].alpha);
         png_save_uint_16(entrybuf + 8, ep[i].frequency);
1252
      }
1253

1254
      png_write_chunk_data(png_ptr, entrybuf, entry_size);
1255 1256
   }
#endif
1257 1258 1259 1260 1261

   png_write_chunk_end(png_ptr);
}
#endif

1262
#ifdef PNG_WRITE_sBIT_SUPPORTED
1263
/* Write the sBIT chunk */
1264
void /* PRIVATE */
1265
png_write_sBIT(png_structrp png_ptr, png_const_color_8p sbit, int color_type)
G
Guy Schalnat 已提交
1266 1267
{
   png_byte buf[4];
A
Andreas Dilger 已提交
1268
   png_size_t size;
G
Guy Schalnat 已提交
1269

1270
   png_debug(1, "in png_write_sBIT");
1271

1272
   /* Make sure we don't depend upon the order of PNG_COLOR_8 */
1273
   if ((color_type & PNG_COLOR_MASK_COLOR) != 0)
G
Guy Schalnat 已提交
1274
   {
1275
      png_byte maxbits;
G
Guy Schalnat 已提交
1276

1277 1278
      maxbits = (png_byte)(color_type==PNG_COLOR_TYPE_PALETTE ? 8 :
          png_ptr->usr_bit_depth);
1279

1280 1281
      if (sbit->red == 0 || sbit->red > maxbits ||
          sbit->green == 0 || sbit->green > maxbits ||
G
Guy Schalnat 已提交
1282 1283 1284 1285 1286
          sbit->blue == 0 || sbit->blue > maxbits)
      {
         png_warning(png_ptr, "Invalid sBIT depth specified");
         return;
      }
1287

G
Guy Schalnat 已提交
1288 1289 1290 1291 1292
      buf[0] = sbit->red;
      buf[1] = sbit->green;
      buf[2] = sbit->blue;
      size = 3;
   }
1293

G
Guy Schalnat 已提交
1294 1295
   else
   {
G
Guy Schalnat 已提交
1296 1297 1298 1299 1300
      if (sbit->gray == 0 || sbit->gray > png_ptr->usr_bit_depth)
      {
         png_warning(png_ptr, "Invalid sBIT depth specified");
         return;
      }
1301

G
Guy Schalnat 已提交
1302 1303 1304 1305
      buf[0] = sbit->gray;
      size = 1;
   }

1306
   if ((color_type & PNG_COLOR_MASK_ALPHA) != 0)
G
Guy Schalnat 已提交
1307
   {
G
Guy Schalnat 已提交
1308 1309 1310 1311 1312
      if (sbit->alpha == 0 || sbit->alpha > png_ptr->usr_bit_depth)
      {
         png_warning(png_ptr, "Invalid sBIT depth specified");
         return;
      }
1313

G
Guy Schalnat 已提交
1314 1315 1316
      buf[size++] = sbit->alpha;
   }

1317
   png_write_complete_chunk(png_ptr, png_sBIT, buf, size);
G
Guy Schalnat 已提交
1318
}
G
Guy Schalnat 已提交
1319
#endif
G
Guy Schalnat 已提交
1320

1321
#ifdef PNG_WRITE_cHRM_SUPPORTED
1322
/* Write the cHRM chunk */
1323
void /* PRIVATE */
1324
png_write_cHRM_fixed(png_structrp png_ptr, const png_xy *xy)
1325 1326 1327
{
   png_byte buf[32];

1328
   png_debug(1, "in png_write_cHRM");
1329

1330
   /* Each value is saved in 1/100,000ths */
1331 1332
   png_save_int_32(buf,      xy->whitex);
   png_save_int_32(buf +  4, xy->whitey);
1333

1334 1335
   png_save_int_32(buf +  8, xy->redx);
   png_save_int_32(buf + 12, xy->redy);
1336

1337 1338
   png_save_int_32(buf + 16, xy->greenx);
   png_save_int_32(buf + 20, xy->greeny);
1339

1340 1341
   png_save_int_32(buf + 24, xy->bluex);
   png_save_int_32(buf + 28, xy->bluey);
1342

1343
   png_write_complete_chunk(png_ptr, png_cHRM, buf, 32);
1344 1345
}
#endif
G
Guy Schalnat 已提交
1346

1347
#ifdef PNG_WRITE_tRNS_SUPPORTED
1348
/* Write the tRNS chunk */
1349
void /* PRIVATE */
1350
png_write_tRNS(png_structrp png_ptr, png_const_bytep trans_alpha,
1351
    png_const_color_16p tran, int num_trans, int color_type)
G
Guy Schalnat 已提交
1352 1353 1354
{
   png_byte buf[6];

1355
   png_debug(1, "in png_write_tRNS");
1356

G
Guy Schalnat 已提交
1357 1358
   if (color_type == PNG_COLOR_TYPE_PALETTE)
   {
1359
      if (num_trans <= 0 || num_trans > (int)png_ptr->num_palette)
G
Guy Schalnat 已提交
1360
      {
1361 1362
         png_app_warning(png_ptr,
             "Invalid number of transparent colors specified");
G
Guy Schalnat 已提交
1363 1364
         return;
      }
1365

1366
      /* Write the chunk out as it is */
1367
      png_write_complete_chunk(png_ptr, png_tRNS, trans_alpha,
1368
          (png_size_t)num_trans);
G
Guy Schalnat 已提交
1369
   }
1370

G
Guy Schalnat 已提交
1371 1372
   else if (color_type == PNG_COLOR_TYPE_GRAY)
   {
1373
      /* One 16-bit value */
1374
      if (tran->gray >= (1 << png_ptr->bit_depth))
1375
      {
1376
         png_app_warning(png_ptr,
1377
             "Ignoring attempt to write tRNS chunk out-of-range for bit_depth");
1378

1379 1380
         return;
      }
1381

G
Guy Schalnat 已提交
1382
      png_save_uint_16(buf, tran->gray);
1383
      png_write_complete_chunk(png_ptr, png_tRNS, buf, (png_size_t)2);
G
Guy Schalnat 已提交
1384
   }
1385

G
Guy Schalnat 已提交
1386 1387
   else if (color_type == PNG_COLOR_TYPE_RGB)
   {
1388
      /* Three 16-bit values */
G
Guy Schalnat 已提交
1389 1390 1391
      png_save_uint_16(buf, tran->red);
      png_save_uint_16(buf + 2, tran->green);
      png_save_uint_16(buf + 4, tran->blue);
1392
#ifdef PNG_WRITE_16BIT_SUPPORTED
1393
      if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4]) != 0)
1394
#else
1395
      if ((buf[0] | buf[2] | buf[4]) != 0)
1396
#endif
1397
      {
1398
         png_app_warning(png_ptr,
1399
             "Ignoring attempt to write 16-bit tRNS chunk when bit_depth is 8");
1400 1401
         return;
      }
1402

1403
      png_write_complete_chunk(png_ptr, png_tRNS, buf, (png_size_t)6);
G
Guy Schalnat 已提交
1404
   }
1405

G
Guy Schalnat 已提交
1406 1407
   else
   {
1408
      png_app_warning(png_ptr, "Can't write tRNS with an alpha channel");
G
Guy Schalnat 已提交
1409
   }
G
Guy Schalnat 已提交
1410
}
G
Guy Schalnat 已提交
1411
#endif
G
Guy Schalnat 已提交
1412

1413
#ifdef PNG_WRITE_bKGD_SUPPORTED
1414
/* Write the background chunk */
1415
void /* PRIVATE */
1416
png_write_bKGD(png_structrp png_ptr, png_const_color_16p back, int color_type)
G
Guy Schalnat 已提交
1417 1418 1419
{
   png_byte buf[6];

1420
   png_debug(1, "in png_write_bKGD");
1421

G
Guy Schalnat 已提交
1422 1423
   if (color_type == PNG_COLOR_TYPE_PALETTE)
   {
1424
      if (
1425
#ifdef PNG_MNG_FEATURES_SUPPORTED
1426 1427
          (png_ptr->num_palette != 0 ||
          (png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) == 0) &&
1428
#endif
1429
         back->index >= png_ptr->num_palette)
G
Guy Schalnat 已提交
1430 1431 1432 1433
      {
         png_warning(png_ptr, "Invalid background palette index");
         return;
      }
1434

G
Guy Schalnat 已提交
1435
      buf[0] = back->index;
1436
      png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)1);
G
Guy Schalnat 已提交
1437
   }
1438

1439
   else if ((color_type & PNG_COLOR_MASK_COLOR) != 0)
G
Guy Schalnat 已提交
1440 1441 1442 1443
   {
      png_save_uint_16(buf, back->red);
      png_save_uint_16(buf + 2, back->green);
      png_save_uint_16(buf + 4, back->blue);
1444
#ifdef PNG_WRITE_16BIT_SUPPORTED
1445
      if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4]) != 0)
1446
#else
1447
      if ((buf[0] | buf[2] | buf[4]) != 0)
1448
#endif
1449 1450
      {
         png_warning(png_ptr,
1451 1452
             "Ignoring attempt to write 16-bit bKGD chunk "
             "when bit_depth is 8");
1453

1454 1455
         return;
      }
1456

1457
      png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)6);
G
Guy Schalnat 已提交
1458
   }
1459

G
Guy Schalnat 已提交
1460
   else
G
Guy Schalnat 已提交
1461
   {
1462
      if (back->gray >= (1 << png_ptr->bit_depth))
1463 1464
      {
         png_warning(png_ptr,
1465
             "Ignoring attempt to write bKGD chunk out-of-range for bit_depth");
1466

1467 1468
         return;
      }
1469

G
Guy Schalnat 已提交
1470
      png_save_uint_16(buf, back->gray);
1471
      png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)2);
G
Guy Schalnat 已提交
1472 1473
   }
}
G
Guy Schalnat 已提交
1474
#endif
G
Guy Schalnat 已提交
1475

1476
#ifdef PNG_WRITE_hIST_SUPPORTED
1477
/* Write the histogram */
1478
void /* PRIVATE */
1479
png_write_hIST(png_structrp png_ptr, png_const_uint_16p hist, int num_hist)
G
Guy Schalnat 已提交
1480
{
1481
   int i;
G
Guy Schalnat 已提交
1482 1483
   png_byte buf[3];

1484
   png_debug(1, "in png_write_hIST");
1485

1486
   if (num_hist > (int)png_ptr->num_palette)
G
Guy Schalnat 已提交
1487
   {
1488
      png_debug2(3, "num_hist = %d, num_palette = %d", num_hist,
1489
          png_ptr->num_palette);
1490

G
Guy Schalnat 已提交
1491 1492 1493 1494
      png_warning(png_ptr, "Invalid number of histogram entries specified");
      return;
   }

1495
   png_write_chunk_header(png_ptr, png_hIST, (png_uint_32)(num_hist * 2));
1496

A
Andreas Dilger 已提交
1497
   for (i = 0; i < num_hist; i++)
G
Guy Schalnat 已提交
1498
   {
G
Guy Schalnat 已提交
1499
      png_save_uint_16(buf, hist[i]);
1500
      png_write_chunk_data(png_ptr, buf, (png_size_t)2);
G
Guy Schalnat 已提交
1501
   }
1502

G
Guy Schalnat 已提交
1503 1504
   png_write_chunk_end(png_ptr);
}
G
Guy Schalnat 已提交
1505
#endif
G
Guy Schalnat 已提交
1506

1507
#ifdef PNG_WRITE_tEXt_SUPPORTED
1508
/* Write a tEXt chunk */
1509
void /* PRIVATE */
1510
png_write_tEXt(png_structrp png_ptr, png_const_charp key, png_const_charp text,
1511
    png_size_t text_len)
G
Guy Schalnat 已提交
1512
{
1513 1514
   png_uint_32 key_len;
   png_byte new_key[80];
A
Andreas Dilger 已提交
1515

1516
   png_debug(1, "in png_write_tEXt");
1517

1518 1519 1520 1521
   key_len = png_check_keyword(png_ptr, key, new_key);

   if (key_len == 0)
      png_error(png_ptr, "tEXt: invalid keyword");
G
Guy Schalnat 已提交
1522

A
Andreas Dilger 已提交
1523
   if (text == NULL || *text == '\0')
A
Andreas Dilger 已提交
1524
      text_len = 0;
1525

1526
   else
1527 1528 1529 1530
      text_len = strlen(text);

   if (text_len > PNG_UINT_31_MAX - (key_len+1))
      png_error(png_ptr, "tEXt: text too long");
1531

1532
   /* Make sure we include the 0 after the key */
1533
   png_write_chunk_header(png_ptr, png_tEXt,
1534
       (png_uint_32)/*checked above*/(key_len + text_len + 1));
1535 1536 1537 1538
   /*
    * We leave it to the application to meet PNG-1.0 requirements on the
    * contents of the text.  PNG-1.0 through PNG-1.2 discourage the use of
    * any non-Latin-1 characters except for NEWLINE.  ISO PNG will forbid them.
1539
    * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG.
1540
    */
1541
   png_write_chunk_data(png_ptr, new_key, key_len + 1);
1542

1543
   if (text_len != 0)
1544
      png_write_chunk_data(png_ptr, (png_const_bytep)text, text_len);
A
Andreas Dilger 已提交
1545

G
Guy Schalnat 已提交
1546 1547
   png_write_chunk_end(png_ptr);
}
G
Guy Schalnat 已提交
1548
#endif
G
Guy Schalnat 已提交
1549

1550
#ifdef PNG_WRITE_zTXt_SUPPORTED
1551
/* Write a compressed text chunk */
1552
void /* PRIVATE */
1553
png_write_zTXt(png_structrp png_ptr, png_const_charp key, png_const_charp text,
1554
    int compression)
G
Guy Schalnat 已提交
1555
{
1556 1557
   png_uint_32 key_len;
   png_byte new_key[81];
1558
   compression_state comp;
G
Guy Schalnat 已提交
1559

1560
   png_debug(1, "in png_write_zTXt");
A
Andreas Dilger 已提交
1561

1562
   if (compression == PNG_TEXT_COMPRESSION_NONE)
A
Andreas Dilger 已提交
1563
   {
1564
      png_write_tEXt(png_ptr, key, text, 0);
G
Guy Schalnat 已提交
1565
      return;
A
Andreas Dilger 已提交
1566
   }
A
Andreas Dilger 已提交
1567

1568 1569
   if (compression != PNG_TEXT_COMPRESSION_zTXt)
      png_error(png_ptr, "zTXt: invalid compression type");
G
Guy Schalnat 已提交
1570

1571
   key_len = png_check_keyword(png_ptr, key, new_key);
1572

1573 1574
   if (key_len == 0)
      png_error(png_ptr, "zTXt: invalid keyword");
1575

1576 1577 1578
   /* Add the compression method and 1 for the keyword separator. */
   new_key[++key_len] = PNG_COMPRESSION_TYPE_BASE;
   ++key_len;
1579

1580 1581
   /* Compute the compressed data; do it now for the length */
   png_text_compress_init(&comp, (png_const_bytep)text,
1582
       text == NULL ? 0 : strlen(text));
1583

1584 1585
   if (png_text_compress(png_ptr, png_zTXt, &comp, key_len) != Z_OK)
      png_error(png_ptr, png_ptr->zstream.msg);
1586

1587 1588
   /* Write start of chunk */
   png_write_chunk_header(png_ptr, png_zTXt, key_len + comp.output_len);
1589

1590 1591
   /* Write key */
   png_write_chunk_data(png_ptr, new_key, key_len);
1592

1593
   /* Write the compressed data */
1594
   png_write_compressed_data_out(png_ptr, &comp);
G
Guy Schalnat 已提交
1595

1596
   /* Close the chunk */
1597 1598 1599
   png_write_chunk_end(png_ptr);
}
#endif
G
Guy Schalnat 已提交
1600

1601
#ifdef PNG_WRITE_iTXt_SUPPORTED
1602
/* Write an iTXt chunk */
1603
void /* PRIVATE */
1604
png_write_iTXt(png_structrp png_ptr, int compression, png_const_charp key,
1605
    png_const_charp lang, png_const_charp lang_key, png_const_charp text)
1606
{
1607 1608 1609
   png_uint_32 key_len, prefix_len;
   png_size_t lang_len, lang_key_len;
   png_byte new_key[82];
1610
   compression_state comp;
G
Guy Schalnat 已提交
1611

1612
   png_debug(1, "in png_write_iTXt");
G
Guy Schalnat 已提交
1613

1614
   key_len = png_check_keyword(png_ptr, key, new_key);
1615

1616 1617
   if (key_len == 0)
      png_error(png_ptr, "iTXt: invalid keyword");
1618

1619 1620
   /* Set the compression flag */
   switch (compression)
1621
   {
1622 1623 1624 1625
      case PNG_ITXT_COMPRESSION_NONE:
      case PNG_TEXT_COMPRESSION_NONE:
         compression = new_key[++key_len] = 0; /* no compression */
         break;
1626

1627 1628 1629 1630
      case PNG_TEXT_COMPRESSION_zTXt:
      case PNG_ITXT_COMPRESSION_zTXt:
         compression = new_key[++key_len] = 1; /* compressed */
         break;
1631

1632 1633 1634
      default:
         png_error(png_ptr, "iTXt: invalid compression");
   }
1635

1636 1637
   new_key[++key_len] = PNG_COMPRESSION_TYPE_BASE;
   ++key_len; /* for the keywod separator */
1638

1639 1640
   /* We leave it to the application to meet PNG-1.0 requirements on the
    * contents of the text.  PNG-1.0 through PNG-1.2 discourage the use of
1641 1642 1643 1644
    * any non-Latin-1 characters except for NEWLINE.  ISO PNG, however,
    * specifies that the text is UTF-8 and this really doesn't require any
    * checking.
    *
1645
    * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG.
1646 1647
    *
    * TODO: validate the language tag correctly (see the spec.)
1648
    */
1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659
   if (lang == NULL) lang = ""; /* empty language is valid */
   lang_len = strlen(lang)+1;
   if (lang_key == NULL) lang_key = ""; /* may be empty */
   lang_key_len = strlen(lang_key)+1;
   if (text == NULL) text = ""; /* may be empty */

   prefix_len = key_len;
   if (lang_len > PNG_UINT_31_MAX-prefix_len)
      prefix_len = PNG_UINT_31_MAX;
   else
      prefix_len = (png_uint_32)(prefix_len + lang_len);
1660

1661 1662 1663 1664
   if (lang_key_len > PNG_UINT_31_MAX-prefix_len)
      prefix_len = PNG_UINT_31_MAX;
   else
      prefix_len = (png_uint_32)(prefix_len + lang_key_len);
G
Guy Schalnat 已提交
1665

1666
   png_text_compress_init(&comp, (png_const_bytep)text, strlen(text));
1667

1668
   if (compression != 0)
1669 1670 1671 1672
   {
      if (png_text_compress(png_ptr, png_iTXt, &comp, prefix_len) != Z_OK)
         png_error(png_ptr, png_ptr->zstream.msg);
   }
1673

1674 1675 1676 1677
   else
   {
      if (comp.input_len > PNG_UINT_31_MAX-prefix_len)
         png_error(png_ptr, "iTXt: uncompressed text too long");
1678 1679 1680

      /* So the string will fit in a chunk: */
      comp.output_len = (png_uint_32)/*SAFE*/comp.input_len;
1681
   }
1682

1683 1684
   png_write_chunk_header(png_ptr, png_iTXt, comp.output_len + prefix_len);

1685
   png_write_chunk_data(png_ptr, new_key, key_len);
1686

1687
   png_write_chunk_data(png_ptr, (png_const_bytep)lang, lang_len);
1688

1689
   png_write_chunk_data(png_ptr, (png_const_bytep)lang_key, lang_key_len);
1690

1691
   if (compression != 0)
1692 1693 1694
      png_write_compressed_data_out(png_ptr, &comp);

   else
1695
      png_write_chunk_data(png_ptr, (png_const_bytep)text, comp.output_len);
1696 1697

   png_write_chunk_end(png_ptr);
G
Guy Schalnat 已提交
1698
}
G
Guy Schalnat 已提交
1699
#endif
G
Guy Schalnat 已提交
1700

1701
#ifdef PNG_WRITE_oFFs_SUPPORTED
1702
/* Write the oFFs chunk */
1703
void /* PRIVATE */
1704
png_write_oFFs(png_structrp png_ptr, png_int_32 x_offset, png_int_32 y_offset,
1705
    int unit_type)
G
Guy Schalnat 已提交
1706 1707 1708
{
   png_byte buf[9];

1709
   png_debug(1, "in png_write_oFFs");
1710

A
Andreas Dilger 已提交
1711 1712
   if (unit_type >= PNG_OFFSET_LAST)
      png_warning(png_ptr, "Unrecognized unit type for oFFs chunk");
G
Guy Schalnat 已提交
1713

1714 1715
   png_save_int_32(buf, x_offset);
   png_save_int_32(buf + 4, y_offset);
1716
   buf[8] = (png_byte)unit_type;
G
Guy Schalnat 已提交
1717

1718
   png_write_complete_chunk(png_ptr, png_oFFs, buf, (png_size_t)9);
G
Guy Schalnat 已提交
1719
}
G
Guy Schalnat 已提交
1720
#endif
1721
#ifdef PNG_WRITE_pCAL_SUPPORTED
1722
/* Write the pCAL chunk (described in the PNG extensions document) */
1723
void /* PRIVATE */
1724
png_write_pCAL(png_structrp png_ptr, png_charp purpose, png_int_32 X0,
1725 1726
    png_int_32 X1, int type, int nparams, png_const_charp units,
    png_charpp params)
A
Andreas Dilger 已提交
1727
{
1728 1729
   png_uint_32 purpose_len;
   png_size_t units_len, total_len;
1730
   png_size_tp params_len;
A
Andreas Dilger 已提交
1731
   png_byte buf[10];
1732
   png_byte new_purpose[80];
A
Andreas Dilger 已提交
1733 1734
   int i;

1735
   png_debug1(1, "in png_write_pCAL (%d parameters)", nparams);
1736

A
Andreas Dilger 已提交
1737
   if (type >= PNG_EQUATION_LAST)
1738 1739 1740 1741 1742 1743 1744 1745
      png_error(png_ptr, "Unrecognized equation type for pCAL chunk");

   purpose_len = png_check_keyword(png_ptr, purpose, new_purpose);

   if (purpose_len == 0)
      png_error(png_ptr, "pCAL: invalid keyword");

   ++purpose_len; /* terminator */
A
Andreas Dilger 已提交
1746

1747
   png_debug1(3, "pCAL purpose length = %d", (int)purpose_len);
1748
   units_len = strlen(units) + (nparams == 0 ? 0 : 1);
1749
   png_debug1(3, "pCAL units length = %d", (int)units_len);
A
Andreas Dilger 已提交
1750 1751
   total_len = purpose_len + units_len + 10;

1752
   params_len = (png_size_tp)png_malloc(png_ptr,
1753
       (png_alloc_size_t)((png_alloc_size_t)nparams * (sizeof (png_size_t))));
A
Andreas Dilger 已提交
1754 1755

   /* Find the length of each parameter, making sure we don't count the
1756 1757
    * null terminator for the last parameter.
    */
A
Andreas Dilger 已提交
1758 1759
   for (i = 0; i < nparams; i++)
   {
1760
      params_len[i] = strlen(params[i]) + (i == nparams - 1 ? 0 : 1);
1761
      png_debug2(3, "pCAL parameter %d length = %lu", i,
1762
          (unsigned long)params_len[i]);
1763
      total_len += params_len[i];
A
Andreas Dilger 已提交
1764 1765
   }

1766
   png_debug1(3, "pCAL total length = %d", (int)total_len);
1767
   png_write_chunk_header(png_ptr, png_pCAL, (png_uint_32)total_len);
1768
   png_write_chunk_data(png_ptr, new_purpose, purpose_len);
A
Andreas Dilger 已提交
1769 1770
   png_save_int_32(buf, X0);
   png_save_int_32(buf + 4, X1);
1771 1772
   buf[8] = (png_byte)type;
   buf[9] = (png_byte)nparams;
1773
   png_write_chunk_data(png_ptr, buf, (png_size_t)10);
1774
   png_write_chunk_data(png_ptr, (png_const_bytep)units, (png_size_t)units_len);
A
Andreas Dilger 已提交
1775 1776 1777

   for (i = 0; i < nparams; i++)
   {
1778
      png_write_chunk_data(png_ptr, (png_const_bytep)params[i], params_len[i]);
A
Andreas Dilger 已提交
1779 1780
   }

1781
   png_free(png_ptr, params_len);
A
Andreas Dilger 已提交
1782 1783 1784 1785
   png_write_chunk_end(png_ptr);
}
#endif

1786
#ifdef PNG_WRITE_sCAL_SUPPORTED
1787
/* Write the sCAL chunk */
1788
void /* PRIVATE */
1789
png_write_sCAL_s(png_structrp png_ptr, int unit, png_const_charp width,
1790
    png_const_charp height)
1791
{
1792 1793
   png_byte buf[64];
   png_size_t wlen, hlen, total_len;
1794

1795
   png_debug(1, "in png_write_sCAL_s");
1796

1797 1798
   wlen = strlen(width);
   hlen = strlen(height);
1799
   total_len = wlen + hlen + 2;
1800

1801 1802 1803 1804 1805
   if (total_len > 64)
   {
      png_warning(png_ptr, "Can't write sCAL (buffer too small)");
      return;
   }
1806

1807
   buf[0] = (png_byte)unit;
1808 1809
   memcpy(buf + 1, width, wlen + 1);      /* Append the '\0' here */
   memcpy(buf + wlen + 2, height, hlen);  /* Do NOT append the '\0' here */
1810

1811
   png_debug1(3, "sCAL total length = %u", (unsigned int)total_len);
1812
   png_write_complete_chunk(png_ptr, png_sCAL, buf, total_len);
1813 1814 1815
}
#endif

1816
#ifdef PNG_WRITE_pHYs_SUPPORTED
1817
/* Write the pHYs chunk */
1818
void /* PRIVATE */
1819
png_write_pHYs(png_structrp png_ptr, png_uint_32 x_pixels_per_unit,
1820 1821
    png_uint_32 y_pixels_per_unit,
    int unit_type)
G
Guy Schalnat 已提交
1822 1823 1824
{
   png_byte buf[9];

1825
   png_debug(1, "in png_write_pHYs");
1826

A
Andreas Dilger 已提交
1827 1828
   if (unit_type >= PNG_RESOLUTION_LAST)
      png_warning(png_ptr, "Unrecognized unit type for pHYs chunk");
G
Guy Schalnat 已提交
1829

A
Andreas Dilger 已提交
1830 1831
   png_save_uint_32(buf, x_pixels_per_unit);
   png_save_uint_32(buf + 4, y_pixels_per_unit);
1832
   buf[8] = (png_byte)unit_type;
G
Guy Schalnat 已提交
1833

1834
   png_write_complete_chunk(png_ptr, png_pHYs, buf, (png_size_t)9);
G
Guy Schalnat 已提交
1835
}
G
Guy Schalnat 已提交
1836
#endif
G
Guy Schalnat 已提交
1837

1838
#ifdef PNG_WRITE_tIME_SUPPORTED
1839 1840 1841
/* Write the tIME chunk.  Use either png_convert_from_struct_tm()
 * or png_convert_from_time_t(), or fill in the structure yourself.
 */
1842
void /* PRIVATE */
1843
png_write_tIME(png_structrp png_ptr, png_const_timep mod_time)
G
Guy Schalnat 已提交
1844 1845 1846
{
   png_byte buf[7];

1847
   png_debug(1, "in png_write_tIME");
1848

G
Guy Schalnat 已提交
1849 1850 1851 1852 1853 1854 1855 1856
   if (mod_time->month  > 12 || mod_time->month  < 1 ||
       mod_time->day    > 31 || mod_time->day    < 1 ||
       mod_time->hour   > 23 || mod_time->second > 60)
   {
      png_warning(png_ptr, "Invalid time specified for tIME chunk");
      return;
   }

G
Guy Schalnat 已提交
1857 1858 1859 1860 1861 1862 1863
   png_save_uint_16(buf, mod_time->year);
   buf[2] = mod_time->month;
   buf[3] = mod_time->day;
   buf[4] = mod_time->hour;
   buf[5] = mod_time->minute;
   buf[6] = mod_time->second;

1864
   png_write_complete_chunk(png_ptr, png_tIME, buf, (png_size_t)7);
G
Guy Schalnat 已提交
1865
}
G
Guy Schalnat 已提交
1866
#endif
G
Guy Schalnat 已提交
1867

1868
/* Initializes the row writing capability of libpng */
1869
void /* PRIVATE */
1870
png_write_start_row(png_structrp png_ptr)
G
Guy Schalnat 已提交
1871
{
1872
#ifdef PNG_WRITE_INTERLACING_SUPPORTED
1873
   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
1874

1875
   /* Start of interlace block */
1876
   static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
1877

1878
   /* Offset to next interlace block */
1879
   static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
1880

1881
   /* Start of interlace block in the y direction */
1882
   static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
1883

1884
   /* Offset to next interlace block in the y direction */
1885
   static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
1886
#endif
1887

1888 1889
   png_alloc_size_t buf_size;
   int usr_pixel_depth;
A
Andreas Dilger 已提交
1890

1891
#ifdef PNG_WRITE_FILTER_SUPPORTED
1892
   png_byte filters;
1893 1894
#endif

1895
   png_debug(1, "in png_write_start_row");
1896

1897 1898 1899 1900 1901
   usr_pixel_depth = png_ptr->usr_channels * png_ptr->usr_bit_depth;
   buf_size = PNG_ROWBYTES(usr_pixel_depth, png_ptr->width) + 1;

   /* 1.5.6: added to allow checking in the row write code. */
   png_ptr->transformed_pixel_depth = png_ptr->pixel_depth;
1902
   png_ptr->maximum_pixel_depth = (png_byte)usr_pixel_depth;
A
Andreas Dilger 已提交
1903

1904
   /* Set up row buffer */
1905
   png_ptr->row_buf = png_voidcast(png_bytep, png_malloc(png_ptr, buf_size));
1906

A
Andreas Dilger 已提交
1907
   png_ptr->row_buf[0] = PNG_FILTER_VALUE_NONE;
G
Guy Schalnat 已提交
1908

1909
#ifdef PNG_WRITE_FILTER_SUPPORTED
1910
   filters = png_ptr->do_filter;
1911

1912
   if (png_ptr->height == 1)
1913
      filters &= 0xff & ~(PNG_FILTER_UP|PNG_FILTER_AVG|PNG_FILTER_PAETH);
G
Guy Schalnat 已提交
1914

1915
   if (png_ptr->width == 1)
1916
      filters &= 0xff & ~(PNG_FILTER_SUB|PNG_FILTER_AVG|PNG_FILTER_PAETH);
1917 1918 1919 1920 1921 1922 1923 1924

   if (filters == 0)
      filters = PNG_FILTER_NONE;

   png_ptr->do_filter = filters;

   if (((filters & (PNG_FILTER_SUB | PNG_FILTER_UP | PNG_FILTER_AVG |
       PNG_FILTER_PAETH)) != 0) && png_ptr->try_row == NULL)
G
Guy Schalnat 已提交
1925
   {
1926
      int num_filters = 0;
G
Guy Schalnat 已提交
1927

1928
      png_ptr->try_row = png_voidcast(png_bytep, png_malloc(png_ptr, buf_size));
1929

1930 1931
      if (filters & PNG_FILTER_SUB)
         num_filters++;
G
Guy Schalnat 已提交
1932

1933 1934
      if (filters & PNG_FILTER_UP)
         num_filters++;
1935

1936 1937
      if (filters & PNG_FILTER_AVG)
         num_filters++;
G
Guy Schalnat 已提交
1938

1939 1940
      if (filters & PNG_FILTER_PAETH)
         num_filters++;
1941

1942 1943 1944
      if (num_filters > 1)
         png_ptr->tst_row = png_voidcast(png_bytep, png_malloc(png_ptr,
             buf_size));
G
Guy Schalnat 已提交
1945
   }
1946 1947 1948 1949 1950

   /* We only need to keep the previous row if we are using one of the following
    * filters.
    */
   if ((filters & (PNG_FILTER_AVG | PNG_FILTER_UP | PNG_FILTER_PAETH)) != 0)
J
John Bowler 已提交
1951
      png_ptr->prev_row = png_voidcast(png_bytep,
1952
          png_calloc(png_ptr, buf_size));
1953
#endif /* WRITE_FILTER */
G
Guy Schalnat 已提交
1954

1955
#ifdef PNG_WRITE_INTERLACING_SUPPORTED
1956
   /* If interlaced, we need to set up width and height of pass */
1957
   if (png_ptr->interlaced != 0)
G
Guy Schalnat 已提交
1958
   {
1959
      if ((png_ptr->transformations & PNG_INTERLACE) == 0)
G
Guy Schalnat 已提交
1960 1961
      {
         png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
1962
             png_pass_ystart[0]) / png_pass_yinc[0];
1963

A
Andreas Dilger 已提交
1964
         png_ptr->usr_width = (png_ptr->width + png_pass_inc[0] - 1 -
1965
             png_pass_start[0]) / png_pass_inc[0];
G
Guy Schalnat 已提交
1966
      }
1967

G
Guy Schalnat 已提交
1968 1969 1970 1971 1972 1973
      else
      {
         png_ptr->num_rows = png_ptr->height;
         png_ptr->usr_width = png_ptr->width;
      }
   }
1974

G
Guy Schalnat 已提交
1975
   else
1976
#endif
G
Guy Schalnat 已提交
1977
   {
G
Guy Schalnat 已提交
1978 1979 1980 1981 1982
      png_ptr->num_rows = png_ptr->height;
      png_ptr->usr_width = png_ptr->width;
   }
}

A
Andreas Dilger 已提交
1983
/* Internal use only.  Called when finished processing a row of data. */
1984
void /* PRIVATE */
1985
png_write_finish_row(png_structrp png_ptr)
G
Guy Schalnat 已提交
1986
{
1987
#ifdef PNG_WRITE_INTERLACING_SUPPORTED
1988
   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
1989

1990
   /* Start of interlace block */
1991
   static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
1992

1993
   /* Offset to next interlace block */
1994
   static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
1995

1996
   /* Start of interlace block in the y direction */
1997
   static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
1998

1999
   /* Offset to next interlace block in the y direction */
2000
   static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
2001
#endif
2002

2003
   png_debug(1, "in png_write_finish_row");
2004

2005
   /* Next row */
G
Guy Schalnat 已提交
2006
   png_ptr->row_number++;
G
Guy Schalnat 已提交
2007

2008
   /* See if we are done */
G
Guy Schalnat 已提交
2009
   if (png_ptr->row_number < png_ptr->num_rows)
G
Guy Schalnat 已提交
2010
      return;
G
Guy Schalnat 已提交
2011

2012
#ifdef PNG_WRITE_INTERLACING_SUPPORTED
2013
   /* If interlaced, go to next pass */
2014
   if (png_ptr->interlaced != 0)
G
Guy Schalnat 已提交
2015 2016
   {
      png_ptr->row_number = 0;
2017
      if ((png_ptr->transformations & PNG_INTERLACE) != 0)
G
Guy Schalnat 已提交
2018 2019 2020
      {
         png_ptr->pass++;
      }
2021

G
Guy Schalnat 已提交
2022 2023
      else
      {
2024
         /* Loop until we find a non-zero width or height pass */
G
Guy Schalnat 已提交
2025 2026 2027
         do
         {
            png_ptr->pass++;
2028

G
Guy Schalnat 已提交
2029 2030
            if (png_ptr->pass >= 7)
               break;
2031

G
Guy Schalnat 已提交
2032
            png_ptr->usr_width = (png_ptr->width +
2033 2034 2035
                png_pass_inc[png_ptr->pass] - 1 -
                png_pass_start[png_ptr->pass]) /
                png_pass_inc[png_ptr->pass];
2036

G
Guy Schalnat 已提交
2037
            png_ptr->num_rows = (png_ptr->height +
2038 2039 2040
                png_pass_yinc[png_ptr->pass] - 1 -
                png_pass_ystart[png_ptr->pass]) /
                png_pass_yinc[png_ptr->pass];
2041

2042
            if ((png_ptr->transformations & PNG_INTERLACE) != 0)
G
Guy Schalnat 已提交
2043
               break;
2044

G
Guy Schalnat 已提交
2045 2046 2047 2048
         } while (png_ptr->usr_width == 0 || png_ptr->num_rows == 0);

      }

2049
      /* Reset the row above the image for the next pass */
G
Guy Schalnat 已提交
2050
      if (png_ptr->pass < 7)
G
Guy Schalnat 已提交
2051
      {
A
Andreas Dilger 已提交
2052
         if (png_ptr->prev_row != NULL)
2053
            memset(png_ptr->prev_row, 0,
2054 2055
                (png_size_t)(PNG_ROWBYTES(png_ptr->usr_channels*
                png_ptr->usr_bit_depth, png_ptr->width)) + 1);
2056

G
Guy Schalnat 已提交
2057
         return;
G
Guy Schalnat 已提交
2058
      }
G
Guy Schalnat 已提交
2059
   }
2060
#endif
G
Guy Schalnat 已提交
2061

2062
   /* If we get here, we've just written the last row, so we need
G
Guy Schalnat 已提交
2063
      to flush the compressor */
2064
   png_compress_IDAT(png_ptr, NULL, 0, Z_FINISH);
G
Guy Schalnat 已提交
2065 2066
}

2067
#ifdef PNG_WRITE_INTERLACING_SUPPORTED
2068 2069 2070 2071 2072 2073 2074
/* Pick out the correct pixels for the interlace pass.
 * The basic idea here is to go through the row with a source
 * pointer and a destination pointer (sp and dp), and copy the
 * correct pixels for the pass.  As the row gets compacted,
 * sp will always be >= dp, so we should never overwrite anything.
 * See the default: case for the easiest code to understand.
 */
2075
void /* PRIVATE */
G
Guy Schalnat 已提交
2076
png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
G
Guy Schalnat 已提交
2077
{
2078
   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
2079

2080
   /* Start of interlace block */
2081
   static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
2082

2083
   /* Offset to next interlace block */
2084
   static PNG_CONST png_byte  png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
2085

2086
   png_debug(1, "in png_do_write_interlace");
2087

2088
   /* We don't have to do anything on the last pass (6) */
A
Andreas Dilger 已提交
2089
   if (pass < 6)
G
Guy Schalnat 已提交
2090
   {
2091
      /* Each pixel depth is handled separately */
G
Guy Schalnat 已提交
2092
      switch (row_info->pixel_depth)
G
Guy Schalnat 已提交
2093
      {
G
Guy Schalnat 已提交
2094 2095
         case 1:
         {
G
Guy Schalnat 已提交
2096 2097
            png_bytep sp;
            png_bytep dp;
2098
            unsigned int shift;
G
Guy Schalnat 已提交
2099 2100
            int d;
            int value;
2101 2102
            png_uint_32 i;
            png_uint_32 row_width = row_info->width;
G
Guy Schalnat 已提交
2103 2104 2105 2106

            dp = row;
            d = 0;
            shift = 7;
2107

2108
            for (i = png_pass_start[pass]; i < row_width;
G
Guy Schalnat 已提交
2109 2110 2111
               i += png_pass_inc[pass])
            {
               sp = row + (png_size_t)(i >> 3);
2112
               value = (int)(*sp >> (7 - (int)(i & 0x07))) & 0x01;
G
Guy Schalnat 已提交
2113 2114 2115 2116 2117
               d |= (value << shift);

               if (shift == 0)
               {
                  shift = 7;
2118
                  *dp++ = (png_byte)d;
G
Guy Schalnat 已提交
2119 2120
                  d = 0;
               }
2121

G
Guy Schalnat 已提交
2122 2123 2124 2125 2126
               else
                  shift--;

            }
            if (shift != 7)
2127
               *dp = (png_byte)d;
2128

G
Guy Schalnat 已提交
2129 2130
            break;
         }
2131

G
Guy Schalnat 已提交
2132
         case 2:
G
Guy Schalnat 已提交
2133
         {
G
Guy Schalnat 已提交
2134 2135
            png_bytep sp;
            png_bytep dp;
2136
            unsigned int shift;
G
Guy Schalnat 已提交
2137 2138
            int d;
            int value;
2139 2140
            png_uint_32 i;
            png_uint_32 row_width = row_info->width;
G
Guy Schalnat 已提交
2141 2142 2143 2144

            dp = row;
            shift = 6;
            d = 0;
2145

2146
            for (i = png_pass_start[pass]; i < row_width;
G
Guy Schalnat 已提交
2147 2148 2149
               i += png_pass_inc[pass])
            {
               sp = row + (png_size_t)(i >> 2);
2150
               value = (*sp >> ((3 - (int)(i & 0x03)) << 1)) & 0x03;
G
Guy Schalnat 已提交
2151 2152 2153 2154 2155
               d |= (value << shift);

               if (shift == 0)
               {
                  shift = 6;
2156
                  *dp++ = (png_byte)d;
G
Guy Schalnat 已提交
2157 2158
                  d = 0;
               }
2159

G
Guy Schalnat 已提交
2160 2161 2162 2163
               else
                  shift -= 2;
            }
            if (shift != 6)
2164
               *dp = (png_byte)d;
2165

G
Guy Schalnat 已提交
2166 2167
            break;
         }
2168

G
Guy Schalnat 已提交
2169 2170
         case 4:
         {
G
Guy Schalnat 已提交
2171 2172
            png_bytep sp;
            png_bytep dp;
2173
            unsigned int shift;
G
Guy Schalnat 已提交
2174 2175
            int d;
            int value;
2176 2177
            png_uint_32 i;
            png_uint_32 row_width = row_info->width;
G
Guy Schalnat 已提交
2178 2179 2180 2181

            dp = row;
            shift = 4;
            d = 0;
2182
            for (i = png_pass_start[pass]; i < row_width;
2183
                i += png_pass_inc[pass])
G
Guy Schalnat 已提交
2184 2185
            {
               sp = row + (png_size_t)(i >> 1);
2186
               value = (*sp >> ((1 - (int)(i & 0x01)) << 2)) & 0x0f;
G
Guy Schalnat 已提交
2187 2188 2189 2190
               d |= (value << shift);

               if (shift == 0)
               {
G
Guy Schalnat 已提交
2191
                  shift = 4;
2192
                  *dp++ = (png_byte)d;
G
Guy Schalnat 已提交
2193 2194
                  d = 0;
               }
2195

G
Guy Schalnat 已提交
2196 2197 2198 2199
               else
                  shift -= 4;
            }
            if (shift != 4)
2200
               *dp = (png_byte)d;
2201

G
Guy Schalnat 已提交
2202 2203
            break;
         }
2204

G
Guy Schalnat 已提交
2205 2206
         default:
         {
G
Guy Schalnat 已提交
2207 2208
            png_bytep sp;
            png_bytep dp;
2209 2210
            png_uint_32 i;
            png_uint_32 row_width = row_info->width;
A
Andreas Dilger 已提交
2211
            png_size_t pixel_bytes;
G
Guy Schalnat 已提交
2212

2213
            /* Start at the beginning */
G
Guy Schalnat 已提交
2214
            dp = row;
2215

2216
            /* Find out how many bytes each pixel takes up */
G
Guy Schalnat 已提交
2217
            pixel_bytes = (row_info->pixel_depth >> 3);
2218 2219

            /* Loop through the row, only looking at the pixels that matter */
2220
            for (i = png_pass_start[pass]; i < row_width;
G
Guy Schalnat 已提交
2221 2222
               i += png_pass_inc[pass])
            {
2223
               /* Find out where the original pixel is */
2224
               sp = row + (png_size_t)i * pixel_bytes;
2225

2226
               /* Move the pixel */
G
Guy Schalnat 已提交
2227
               if (dp != sp)
2228
                  memcpy(dp, sp, pixel_bytes);
2229

2230
               /* Next pixel */
G
Guy Schalnat 已提交
2231 2232
               dp += pixel_bytes;
            }
G
Guy Schalnat 已提交
2233
            break;
G
Guy Schalnat 已提交
2234 2235
         }
      }
2236
      /* Set new row width */
G
Guy Schalnat 已提交
2237
      row_info->width = (row_info->width +
2238 2239 2240
          png_pass_inc[pass] - 1 -
          png_pass_start[pass]) /
          png_pass_inc[pass];
2241

2242 2243
      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
          row_info->width);
G
Guy Schalnat 已提交
2244 2245
   }
}
G
Guy Schalnat 已提交
2246
#endif
G
Guy Schalnat 已提交
2247

2248

A
Andreas Dilger 已提交
2249 2250
/* This filters the row, chooses which filter to use, if it has not already
 * been specified by the application, and then writes the row out with the
2251 2252
 * chosen filter.
 */
2253
static void /* PRIVATE */
2254
png_write_filtered_row(png_structrp png_ptr, png_bytep filtered_row,
2255
    png_size_t row_bytes);
2256

2257 2258 2259 2260 2261 2262 2263 2264
#ifdef PNG_WRITE_FILTER_SUPPORTED
static png_size_t /* PRIVATE */
png_setup_sub_row(png_structrp png_ptr, const png_uint_32 bpp,
    const png_size_t row_bytes, const png_size_t lmins)
{
   png_bytep rp, dp, lp;
   png_size_t i;
   png_size_t sum = 0;
2265
   unsigned int v;
2266 2267 2268 2269 2270 2271 2272

   png_ptr->try_row[0] = PNG_FILTER_VALUE_SUB;

   for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1; i < bpp;
        i++, rp++, dp++)
   {
      v = *dp = *rp;
2273
#ifdef PNG_USE_ABS
2274
      sum += 128 - abs((int)v - 128);
2275
#else
2276
      sum += (v < 128) ? v : 256 - v;
2277
#endif
2278 2279 2280 2281 2282 2283
   }

   for (lp = png_ptr->row_buf + 1; i < row_bytes;
      i++, rp++, lp++, dp++)
   {
      v = *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff);
2284
#ifdef PNG_USE_ABS
2285
      sum += 128 - abs((int)v - 128);
2286
#else
2287
      sum += (v < 128) ? v : 256 - v;
2288
#endif
2289 2290 2291 2292 2293 2294 2295 2296

      if (sum > lmins)  /* We are already worse, don't continue. */
        break;
   }

   return (sum);
}

2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318
static void /* PRIVATE */
png_setup_sub_row_only(png_structrp png_ptr, const png_uint_32 bpp,
    const png_size_t row_bytes)
{
   png_bytep rp, dp, lp;
   png_size_t i;

   png_ptr->try_row[0] = PNG_FILTER_VALUE_SUB;

   for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1; i < bpp;
        i++, rp++, dp++)
   {
      *dp = *rp;
   }

   for (lp = png_ptr->row_buf + 1; i < row_bytes;
      i++, rp++, lp++, dp++)
   {
      *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff);
   }
}

2319 2320 2321 2322 2323 2324 2325
static png_size_t /* PRIVATE */
png_setup_up_row(png_structrp png_ptr, const png_size_t row_bytes,
    const png_size_t lmins)
{
   png_bytep rp, dp, pp;
   png_size_t i;
   png_size_t sum = 0;
2326
   unsigned int v;
2327 2328 2329 2330 2331 2332 2333 2334

   png_ptr->try_row[0] = PNG_FILTER_VALUE_UP;

   for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1,
       pp = png_ptr->prev_row + 1; i < row_bytes;
       i++, rp++, pp++, dp++)
   {
      v = *dp = (png_byte)(((int)*rp - (int)*pp) & 0xff);
2335
#ifdef PNG_USE_ABS
2336
      sum += 128 - abs((int)v - 128);
2337
#else
2338
      sum += (v < 128) ? v : 256 - v;
2339
#endif
2340 2341 2342 2343 2344 2345 2346

      if (sum > lmins)  /* We are already worse, don't continue. */
        break;
   }

   return (sum);
}
2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361
static void /* PRIVATE */
png_setup_up_row_only(png_structrp png_ptr, const png_size_t row_bytes)
{
   png_bytep rp, dp, pp;
   png_size_t i;

   png_ptr->try_row[0] = PNG_FILTER_VALUE_UP;

   for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1,
       pp = png_ptr->prev_row + 1; i < row_bytes;
       i++, rp++, pp++, dp++)
   {
      *dp = (png_byte)(((int)*rp - (int)*pp) & 0xff);
   }
}
2362 2363 2364

static png_size_t /* PRIVATE */
png_setup_avg_row(png_structrp png_ptr, const png_uint_32 bpp,
2365
    const png_size_t row_bytes, const png_size_t lmins)
2366 2367 2368 2369
{
   png_bytep rp, dp, pp, lp;
   png_uint_32 i;
   png_size_t sum = 0;
2370
   unsigned int v;
2371 2372 2373 2374

   png_ptr->try_row[0] = PNG_FILTER_VALUE_AVG;

   for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1,
2375
       pp = png_ptr->prev_row + 1; i < bpp; i++)
2376 2377 2378
   {
      v = *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff);

2379
#ifdef PNG_USE_ABS
2380
      sum += 128 - abs((int)v - 128);
2381
#else
2382
      sum += (v < 128) ? v : 256 - v;
2383
#endif
2384 2385 2386 2387 2388 2389 2390
   }

   for (lp = png_ptr->row_buf + 1; i < row_bytes; i++)
   {
      v = *dp++ = (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2))
          & 0xff);

2391
#ifdef PNG_USE_ABS
2392
      sum += 128 - abs((int)v - 128);
2393
#else
2394
      sum += (v < 128) ? v : 256 - v;
2395
#endif
2396 2397 2398 2399 2400 2401 2402

      if (sum > lmins)  /* We are already worse, don't continue. */
        break;
   }

   return (sum);
}
2403 2404
static void /* PRIVATE */
png_setup_avg_row_only(png_structrp png_ptr, const png_uint_32 bpp,
2405
    const png_size_t row_bytes)
2406 2407 2408 2409 2410 2411 2412
{
   png_bytep rp, dp, pp, lp;
   png_uint_32 i;

   png_ptr->try_row[0] = PNG_FILTER_VALUE_AVG;

   for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1,
2413
       pp = png_ptr->prev_row + 1; i < bpp; i++)
2414 2415 2416 2417 2418 2419 2420 2421 2422 2423
   {
      *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff);
   }

   for (lp = png_ptr->row_buf + 1; i < row_bytes; i++)
   {
      *dp++ = (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2))
          & 0xff);
   }
}
2424 2425 2426 2427 2428 2429 2430 2431

static png_size_t /* PRIVATE */
png_setup_paeth_row(png_structrp png_ptr, const png_uint_32 bpp,
    const png_size_t row_bytes, const png_size_t lmins)
{
   png_bytep rp, dp, pp, cp, lp;
   png_size_t i;
   png_size_t sum = 0;
2432
   unsigned int v;
2433 2434 2435 2436 2437 2438 2439 2440

   png_ptr->try_row[0] = PNG_FILTER_VALUE_PAETH;

   for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1,
       pp = png_ptr->prev_row + 1; i < bpp; i++)
   {
      v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);

2441
#ifdef PNG_USE_ABS
2442
      sum += 128 - abs((int)v - 128);
2443
#else
2444
      sum += (v < 128) ? v : 256 - v;
2445
#endif
2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473
   }

   for (lp = png_ptr->row_buf + 1, cp = png_ptr->prev_row + 1; i < row_bytes;
        i++)
   {
      int a, b, c, pa, pb, pc, p;

      b = *pp++;
      c = *cp++;
      a = *lp++;

      p = b - c;
      pc = a - c;

#ifdef PNG_USE_ABS
      pa = abs(p);
      pb = abs(pc);
      pc = abs(p + pc);
#else
      pa = p < 0 ? -p : p;
      pb = pc < 0 ? -pc : pc;
      pc = (p + pc) < 0 ? -(p + pc) : p + pc;
#endif

      p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;

      v = *dp++ = (png_byte)(((int)*rp++ - p) & 0xff);

2474
#ifdef PNG_USE_ABS
2475
      sum += 128 - abs((int)v - 128);
2476
#else
2477
      sum += (v < 128) ? v : 256 - v;
2478
#endif
2479 2480 2481 2482 2483 2484 2485

      if (sum > lmins)  /* We are already worse, don't continue. */
        break;
   }

   return (sum);
}
2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527
static void /* PRIVATE */
png_setup_paeth_row_only(png_structrp png_ptr, const png_uint_32 bpp,
    const png_size_t row_bytes)
{
   png_bytep rp, dp, pp, cp, lp;
   png_size_t i;

   png_ptr->try_row[0] = PNG_FILTER_VALUE_PAETH;

   for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1,
       pp = png_ptr->prev_row + 1; i < bpp; i++)
   {
      *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
   }

   for (lp = png_ptr->row_buf + 1, cp = png_ptr->prev_row + 1; i < row_bytes;
        i++)
   {
      int a, b, c, pa, pb, pc, p;

      b = *pp++;
      c = *cp++;
      a = *lp++;

      p = b - c;
      pc = a - c;

#ifdef PNG_USE_ABS
      pa = abs(p);
      pb = abs(pc);
      pc = abs(p + pc);
#else
      pa = p < 0 ? -p : p;
      pb = pc < 0 ? -pc : pc;
      pc = (p + pc) < 0 ? -(p + pc) : p + pc;
#endif

      p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;

      *dp++ = (png_byte)(((int)*rp++ - p) & 0xff);
   }
}
2528 2529
#endif /* WRITE_FILTER */

2530
void /* PRIVATE */
2531
png_write_find_filter(png_structrp png_ptr, png_row_infop row_info)
G
Guy Schalnat 已提交
2532
{
2533 2534 2535
#ifndef PNG_WRITE_FILTER_SUPPORTED
   png_write_filtered_row(png_ptr, png_ptr->row_buf, row_info->rowbytes+1);
#else
2536
   unsigned int filter_to_do = png_ptr->do_filter;
2537 2538 2539 2540 2541
   png_bytep row_buf;
   png_bytep best_row;
   png_uint_32 bpp;
   png_size_t mins;
   png_size_t row_bytes = row_info->rowbytes;
2542 2543 2544

   png_debug(1, "in png_write_find_filter");

2545
   /* Find out how many bytes offset each pixel is */
2546
   bpp = (row_info->pixel_depth + 7) >> 3;
G
Guy Schalnat 已提交
2547

2548 2549 2550
   row_buf = png_ptr->row_buf;
   mins = PNG_SIZE_MAX - 256/* so we can detect potential overflow of the
                               running sum */;
A
Andreas Dilger 已提交
2551 2552 2553

   /* The prediction method we use is to find which method provides the
    * smallest value when summing the absolute values of the distances
2554
    * from zero, using anything >= 128 as negative numbers.  This is known
A
Andreas Dilger 已提交
2555
    * as the "minimum sum of absolute differences" heuristic.  Other
2556
    * heuristics are the "weighted minimum sum of absolute differences"
A
Andreas Dilger 已提交
2557
    * (experimental and can in theory improve compression), and the "zlib
2558 2559 2560
    * predictive" method (not implemented yet), which does test compressions
    * of lines using different filter methods, and then chooses the
    * (series of) filter(s) that give minimum compressed data size (VERY
A
Andreas Dilger 已提交
2561
    * computationally expensive).
2562 2563
    *
    * GRR 980525:  consider also
2564
    *
2565 2566 2567
    *   (1) minimum sum of absolute differences from running average (i.e.,
    *       keep running sum of non-absolute differences & count of bytes)
    *       [track dispersion, too?  restart average if dispersion too large?]
2568
    *
2569 2570
    *  (1b) minimum sum of absolute differences from sliding average, probably
    *       with window size <= deflate window (usually 32K)
2571
    *
2572 2573
    *   (2) minimum sum of squared differences from zero or running average
    *       (i.e., ~ root-mean-square approach)
A
Andreas Dilger 已提交
2574
    */
G
Guy Schalnat 已提交
2575

2576

G
Guy Schalnat 已提交
2577
   /* We don't need to test the 'no filter' case if this is the only filter
A
Andreas Dilger 已提交
2578 2579
    * that has been chosen, as it doesn't actually do anything to the data.
    */
2580 2581
   best_row = png_ptr->row_buf;

2582 2583 2584 2585 2586
   if (PNG_SIZE_MAX/128 <= row_bytes)
   {
      /* Overflow can occur in the calculation, just select the lowest set
       * filter.
       */
2587
      filter_to_do &= 0U-filter_to_do;
2588 2589 2590
   }
   else if ((filter_to_do & PNG_FILTER_NONE) != 0 &&
         filter_to_do != PNG_FILTER_NONE)
G
Guy Schalnat 已提交
2591
   {
2592 2593 2594
      /* Overflow not possible and multiple filters in the list, including the
       * 'none' filter.
       */
G
Guy Schalnat 已提交
2595
      png_bytep rp;
2596
      png_size_t sum = 0;
2597
      png_size_t i;
2598
      unsigned int v;
G
Guy Schalnat 已提交
2599

2600 2601 2602 2603
      {
         for (i = 0, rp = row_buf + 1; i < row_bytes; i++, rp++)
         {
            v = *rp;
2604
#ifdef PNG_USE_ABS
2605
            sum += 128 - abs((int)v - 128);
2606
#else
2607
            sum += (v < 128) ? v : 256 - v;
2608
#endif
2609 2610 2611
         }
      }

G
Guy Schalnat 已提交
2612 2613
      mins = sum;
   }
G
Guy Schalnat 已提交
2614

2615
   /* Sub filter */
2616
   if (filter_to_do == PNG_FILTER_SUB)
2617
   /* It's the only filter so no testing is needed */
2618
   {
2619
      png_setup_sub_row_only(png_ptr, bpp, row_bytes);
2620
      best_row = png_ptr->try_row;
2621 2622
   }

2623
   else if ((filter_to_do & PNG_FILTER_SUB) != 0)
G
Guy Schalnat 已提交
2624
   {
2625 2626
      png_size_t sum;
      png_size_t lmins = mins;
G
Guy Schalnat 已提交
2627

2628
      sum = png_setup_sub_row(png_ptr, bpp, row_bytes, lmins);
A
Andreas Dilger 已提交
2629

G
Guy Schalnat 已提交
2630 2631 2632
      if (sum < mins)
      {
         mins = sum;
2633 2634 2635 2636 2637 2638
         best_row = png_ptr->try_row;
         if (png_ptr->tst_row != NULL)
         {
            png_ptr->try_row = png_ptr->tst_row;
            png_ptr->tst_row = best_row;
         }
G
Guy Schalnat 已提交
2639
      }
G
Guy Schalnat 已提交
2640 2641
   }

2642
   /* Up filter */
2643 2644
   if (filter_to_do == PNG_FILTER_UP)
   {
2645
      png_setup_up_row_only(png_ptr, row_bytes);
2646
      best_row = png_ptr->try_row;
2647 2648
   }

2649
   else if ((filter_to_do & PNG_FILTER_UP) != 0)
G
Guy Schalnat 已提交
2650
   {
2651 2652
      png_size_t sum;
      png_size_t lmins = mins;
G
Guy Schalnat 已提交
2653

2654
      sum = png_setup_up_row(png_ptr, row_bytes, lmins);
A
Andreas Dilger 已提交
2655

G
Guy Schalnat 已提交
2656 2657 2658
      if (sum < mins)
      {
         mins = sum;
2659 2660 2661 2662 2663 2664
         best_row = png_ptr->try_row;
         if (png_ptr->tst_row != NULL)
         {
            png_ptr->try_row = png_ptr->tst_row;
            png_ptr->tst_row = best_row;
         }
G
Guy Schalnat 已提交
2665 2666 2667
      }
   }

2668
   /* Avg filter */
2669 2670
   if (filter_to_do == PNG_FILTER_AVG)
   {
2671
      png_setup_avg_row_only(png_ptr, bpp, row_bytes);
2672
      best_row = png_ptr->try_row;
2673 2674
   }

2675
   else if ((filter_to_do & PNG_FILTER_AVG) != 0)
G
Guy Schalnat 已提交
2676
   {
2677 2678
      png_size_t sum;
      png_size_t lmins = mins;
G
Guy Schalnat 已提交
2679

2680
      sum= png_setup_avg_row(png_ptr, bpp, row_bytes, lmins);
A
Andreas Dilger 已提交
2681

G
Guy Schalnat 已提交
2682 2683 2684
      if (sum < mins)
      {
         mins = sum;
2685 2686 2687 2688 2689 2690
         best_row = png_ptr->try_row;
         if (png_ptr->tst_row != NULL)
         {
            png_ptr->try_row = png_ptr->tst_row;
            png_ptr->tst_row = best_row;
         }
G
Guy Schalnat 已提交
2691 2692
      }
   }
G
Guy Schalnat 已提交
2693

A
Andreas Dilger 已提交
2694
   /* Paeth filter */
2695
   if (filter_to_do == PNG_FILTER_PAETH)
2696
   {
2697
      png_setup_paeth_row_only(png_ptr, bpp, row_bytes);
2698
      best_row = png_ptr->try_row;
2699 2700
   }

2701
   else if ((filter_to_do & PNG_FILTER_PAETH) != 0)
G
Guy Schalnat 已提交
2702
   {
2703 2704
      png_size_t sum;
      png_size_t lmins = mins;
G
Guy Schalnat 已提交
2705

2706
      sum = png_setup_paeth_row(png_ptr, bpp, row_bytes, lmins);
A
Andreas Dilger 已提交
2707

G
Guy Schalnat 已提交
2708 2709
      if (sum < mins)
      {
2710 2711 2712 2713 2714 2715
         best_row = png_ptr->try_row;
         if (png_ptr->tst_row != NULL)
         {
            png_ptr->try_row = png_ptr->tst_row;
            png_ptr->tst_row = best_row;
         }
G
Guy Schalnat 已提交
2716
      }
G
Guy Schalnat 已提交
2717
   }
2718

2719 2720
   /* Do the actual writing of the filtered row data from the chosen filter. */
   png_write_filtered_row(png_ptr, best_row, row_info->rowbytes+1);
A
Andreas Dilger 已提交
2721

2722
#endif /* WRITE_FILTER */
G
Guy Schalnat 已提交
2723
}
G
Guy Schalnat 已提交
2724

G
Guy Schalnat 已提交
2725

A
Andreas Dilger 已提交
2726
/* Do the actual writing of a previously filtered row. */
2727
static void
2728
png_write_filtered_row(png_structrp png_ptr, png_bytep filtered_row,
2729
    png_size_t full_row_length/*includes filter byte*/)
G
Guy Schalnat 已提交
2730
{
2731
   png_debug(1, "in png_write_filtered_row");
2732

2733
   png_debug1(2, "filter = %d", filtered_row[0]);
2734

2735
   png_compress_IDAT(png_ptr, filtered_row, full_row_length, Z_NO_FLUSH);
G
Guy Schalnat 已提交
2736

2737
#ifdef PNG_WRITE_FILTER_SUPPORTED
2738
   /* Swap the current and previous rows */
A
Andreas Dilger 已提交
2739
   if (png_ptr->prev_row != NULL)
G
Guy Schalnat 已提交
2740 2741 2742 2743 2744 2745 2746
   {
      png_bytep tptr;

      tptr = png_ptr->prev_row;
      png_ptr->prev_row = png_ptr->row_buf;
      png_ptr->row_buf = tptr;
   }
2747
#endif /* WRITE_FILTER */
G
Guy Schalnat 已提交
2748

2749
   /* Finish row - updates counters and flushes zlib if last row */
G
Guy Schalnat 已提交
2750
   png_write_finish_row(png_ptr);
G
Guy Schalnat 已提交
2751

2752
#ifdef PNG_WRITE_FLUSH_SUPPORTED
G
Guy Schalnat 已提交
2753 2754 2755 2756 2757 2758
   png_ptr->flush_rows++;

   if (png_ptr->flush_dist > 0 &&
       png_ptr->flush_rows >= png_ptr->flush_dist)
   {
      png_write_flush(png_ptr);
G
Guy Schalnat 已提交
2759
   }
2760
#endif /* WRITE_FLUSH */
G
Guy Schalnat 已提交
2761
}
2762
#endif /* WRITE */