all repos — mgba @ b03412aa38b39190f475cb89d5c8a2a5e97bc32d

mGBA Game Boy Advance Emulator

src/third-party/libpng/pngwutil.c (view raw)

   1
   2/* pngwutil.c - utilities to write a PNG file
   3 *
   4 * Last changed in libpng 1.6.17 [March 26, 2015]
   5 * Copyright (c) 1998-2015 Glenn Randers-Pehrson
   6 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
   7 * (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 */
  13
  14#include "pngpriv.h"
  15
  16#ifdef PNG_WRITE_SUPPORTED
  17
  18#ifdef PNG_WRITE_INT_FUNCTIONS_SUPPORTED
  19/* Place a 32-bit number into a buffer in PNG byte order.  We work
  20 * with unsigned numbers for convenience, although one supported
  21 * ancillary chunk uses signed (two's complement) numbers.
  22 */
  23void PNGAPI
  24png_save_uint_32(png_bytep buf, png_uint_32 i)
  25{
  26   buf[0] = (png_byte)(i >> 24);
  27   buf[1] = (png_byte)(i >> 16);
  28   buf[2] = (png_byte)(i >> 8);
  29   buf[3] = (png_byte)(i     );
  30}
  31
  32/* Place a 16-bit number into a buffer in PNG byte order.
  33 * The parameter is declared unsigned int, not png_uint_16,
  34 * just to avoid potential problems on pre-ANSI C compilers.
  35 */
  36void PNGAPI
  37png_save_uint_16(png_bytep buf, unsigned int i)
  38{
  39   buf[0] = (png_byte)(i >> 8);
  40   buf[1] = (png_byte)(i     );
  41}
  42#endif
  43
  44/* Simple function to write the signature.  If we have already written
  45 * the magic bytes of the signature, or more likely, the PNG stream is
  46 * being embedded into another stream and doesn't need its own signature,
  47 * we should call png_set_sig_bytes() to tell libpng how many of the
  48 * bytes have already been written.
  49 */
  50void PNGAPI
  51png_write_sig(png_structrp png_ptr)
  52{
  53   png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
  54
  55#ifdef PNG_IO_STATE_SUPPORTED
  56   /* Inform the I/O callback that the signature is being written */
  57   png_ptr->io_state = PNG_IO_WRITING | PNG_IO_SIGNATURE;
  58#endif
  59
  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      png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE;
  66}
  67
  68/* Write the start of a PNG chunk.  The type is the chunk type.
  69 * The total_length is the sum of the lengths of all the data you will be
  70 * passing in png_write_chunk_data().
  71 */
  72static void
  73png_write_chunk_header(png_structrp png_ptr, png_uint_32 chunk_name,
  74    png_uint_32 length)
  75{
  76   png_byte buf[8];
  77
  78#if defined(PNG_DEBUG) && (PNG_DEBUG > 0)
  79   PNG_CSTRING_FROM_CHUNK(buf, chunk_name);
  80   png_debug2(0, "Writing %s chunk, length = %lu", buf, (unsigned long)length);
  81#endif
  82
  83   if (png_ptr == NULL)
  84      return;
  85
  86#ifdef PNG_IO_STATE_SUPPORTED
  87   /* Inform the I/O callback that the chunk header is being written.
  88    * PNG_IO_CHUNK_HDR requires a single I/O call.
  89    */
  90   png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_HDR;
  91#endif
  92
  93   /* Write the length and the chunk name */
  94   png_save_uint_32(buf, length);
  95   png_save_uint_32(buf + 4, chunk_name);
  96   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 */
 102   png_reset_crc(png_ptr);
 103
 104   png_calculate_crc(png_ptr, buf + 4, 4);
 105
 106#ifdef PNG_IO_STATE_SUPPORTED
 107   /* Inform the I/O callback that chunk data will (possibly) be written.
 108    * PNG_IO_CHUNK_DATA does NOT require a specific number of I/O calls.
 109    */
 110   png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_DATA;
 111#endif
 112}
 113
 114void PNGAPI
 115png_write_chunk_start(png_structrp png_ptr, png_const_bytep chunk_string,
 116    png_uint_32 length)
 117{
 118   png_write_chunk_header(png_ptr, PNG_CHUNK_FROM_STRING(chunk_string), length);
 119}
 120
 121/* Write the data of a PNG chunk started with png_write_chunk_header().
 122 * Note that multiple calls to this function are allowed, and that the
 123 * sum of the lengths from these calls *must* add up to the total_length
 124 * given to png_write_chunk_header().
 125 */
 126void PNGAPI
 127png_write_chunk_data(png_structrp png_ptr, png_const_bytep data,
 128    png_size_t length)
 129{
 130   /* Write the data, and run the CRC over it */
 131   if (png_ptr == NULL)
 132      return;
 133
 134   if (data != NULL && length > 0)
 135   {
 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);
 142   }
 143}
 144
 145/* Finish a chunk started with png_write_chunk_header(). */
 146void PNGAPI
 147png_write_chunk_end(png_structrp png_ptr)
 148{
 149   png_byte buf[4];
 150
 151   if (png_ptr == NULL) return;
 152
 153#ifdef PNG_IO_STATE_SUPPORTED
 154   /* Inform the I/O callback that the chunk CRC is being written.
 155    * PNG_IO_CHUNK_CRC requires a single I/O function call.
 156    */
 157   png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_CRC;
 158#endif
 159
 160   /* Write the crc in a single operation */
 161   png_save_uint_32(buf, png_ptr->crc);
 162
 163   png_write_data(png_ptr, buf, (png_size_t)4);
 164}
 165
 166/* Write a PNG chunk all at once.  The type is an array of ASCII characters
 167 * representing the chunk name.  The array must be at least 4 bytes in
 168 * length, and does not need to be null terminated.  To be safe, pass the
 169 * pre-defined chunk names here, and if you need a new one, define it
 170 * where the others are defined.  The length is the length of the data.
 171 * All the data must be present.  If that is not possible, use the
 172 * png_write_chunk_start(), png_write_chunk_data(), and png_write_chunk_end()
 173 * functions instead.
 174 */
 175static void
 176png_write_complete_chunk(png_structrp png_ptr, png_uint_32 chunk_name,
 177   png_const_bytep data, png_size_t length)
 178{
 179   if (png_ptr == NULL)
 180      return;
 181
 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   png_write_chunk_header(png_ptr, chunk_name, (png_uint_32)length);
 187   png_write_chunk_data(png_ptr, data, length);
 188   png_write_chunk_end(png_ptr);
 189}
 190
 191/* This is the API that calls the internal function above. */
 192void PNGAPI
 193png_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/* This is used below to find the size of an image to pass to png_deflate_claim,
 201 * so it only needs to be accurate if the size is less than 16384 bytes (the
 202 * point at which a lower LZ window size can be used.)
 203 */
 204static png_alloc_size_t
 205png_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    * the width and height used to 15 bits.
 209    */
 210   png_uint_32 h = png_ptr->height;
 211
 212   if (png_ptr->rowbytes < 32768 && h < 32768)
 213   {
 214      if (png_ptr->interlaced != 0)
 215      {
 216         /* Interlacing makes the image larger because of the replication of
 217          * both the filter byte and the padding to a byte boundary.
 218          */
 219         png_uint_32 w = png_ptr->width;
 220         unsigned int pd = png_ptr->pixel_depth;
 221         png_alloc_size_t cb_base;
 222         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            if (pw > 0)
 229               cb_base += (PNG_ROWBYTES(pd, pw)+1) * PNG_PASS_ROWS(h, pass);
 230         }
 231
 232         return cb_base;
 233      }
 234
 235      else
 236         return (png_ptr->rowbytes+1) * h;
 237   }
 238
 239   else
 240      return 0xffffffffU;
 241}
 242
 243#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED
 244   /* This is the code to hack the first two bytes of the deflate stream (the
 245    * deflate header) to correct the windowBits value to match the actual data
 246    * size.  Note that the second argument is the *uncompressed* size but the
 247    * first argument is the *compressed* data (and it must be deflate
 248    * compressed.)
 249    */
 250static void
 251optimize_cmf(png_bytep data, png_alloc_size_t data_size)
 252{
 253   /* Optimize the CMF field in the zlib stream.  The resultant zlib stream is
 254    * still compliant to the stream specification.
 255    */
 256   if (data_size <= 16384) /* else windowBits must be 15 */
 257   {
 258      unsigned int z_cmf = data[0];  /* zlib compression method and flags */
 259
 260      if ((z_cmf & 0x0f) == 8 && (z_cmf & 0xf0) <= 0x70)
 261      {
 262         unsigned int z_cinfo;
 263         unsigned int half_z_window_size;
 264
 265         z_cinfo = z_cmf >> 4;
 266         half_z_window_size = 1U << (z_cinfo + 7);
 267
 268         if (data_size <= half_z_window_size) /* else no change */
 269         {
 270            unsigned int tmp;
 271
 272            do
 273            {
 274               half_z_window_size >>= 1;
 275               --z_cinfo;
 276            }
 277            while (z_cinfo > 0 && data_size <= half_z_window_size);
 278
 279            z_cmf = (z_cmf & 0x0f) | (z_cinfo << 4);
 280
 281            data[0] = (png_byte)z_cmf;
 282            tmp = data[1] & 0xe0;
 283            tmp += 0x1f - ((z_cmf << 8) + tmp) % 0x1f;
 284            data[1] = (png_byte)tmp;
 285         }
 286      }
 287   }
 288}
 289#endif /* WRITE_OPTIMIZE_CMF */
 290
 291/* Initialize the compressor for the appropriate type of compression. */
 292static int
 293png_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      PNG_STRING_FROM_CHUNK(msg, owner);
 302      msg[4] = ':';
 303      msg[5] = ' ';
 304      PNG_STRING_FROM_CHUNK(msg+6, png_ptr->zowner);
 305      /* So the message that results is "<chunk> using zstream"; this is an
 306       * internal error, but is very useful for debugging.  i18n requirements
 307       * are minimal.
 308       */
 309      (void)png_safecat(msg, (sizeof msg), 10, " using zstream");
 310#endif
 311#if PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC
 312         png_warning(png_ptr, msg);
 313
 314         /* Attempt sane error recovery */
 315         if (png_ptr->zowner == png_IDAT) /* don't steal from IDAT */
 316         {
 317            png_ptr->zstream.msg = PNGZ_MSG_CAST("in use by IDAT");
 318            return Z_STREAM_ERROR;
 319         }
 320
 321         png_ptr->zowner = 0;
 322#else
 323         png_error(png_ptr, msg);
 324#endif
 325   }
 326
 327   {
 328      int level = png_ptr->zlib_level;
 329      int method = png_ptr->zlib_method;
 330      int windowBits = png_ptr->zlib_window_bits;
 331      int memLevel = png_ptr->zlib_mem_level;
 332      int strategy; /* set below */
 333      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         else if (png_ptr->do_filter != PNG_FILTER_NONE)
 341            strategy = PNG_Z_DEFAULT_STRATEGY;
 342
 343         else
 344            strategy = PNG_Z_DEFAULT_NOFILTER_STRATEGY;
 345      }
 346
 347      else
 348      {
 349#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
 350            level = png_ptr->zlib_text_level;
 351            method = png_ptr->zlib_text_method;
 352            windowBits = png_ptr->zlib_text_window_bits;
 353            memLevel = png_ptr->zlib_text_mem_level;
 354            strategy = png_ptr->zlib_text_strategy;
 355#else
 356            /* If customization is not supported the values all come from the
 357             * IDAT values except for the strategy, which is fixed to the
 358             * default.  (This is the pre-1.6.0 behavior too, although it was
 359             * implemented in a very different way.)
 360             */
 361            strategy = Z_DEFAULT_STRATEGY;
 362#endif
 363      }
 364
 365      /* Adjust 'windowBits' down if larger than 'data_size'; to stop this
 366       * happening just pass 32768 as the data_size parameter.  Notice that zlib
 367       * requires an extra 262 bytes in the window in addition to the data to be
 368       * able to see the whole of the data, so if data_size+262 takes us to the
 369       * next windowBits size we need to fix up the value later.  (Because even
 370       * though deflate needs the extra window, inflate does not!)
 371       */
 372      if (data_size <= 16384)
 373      {
 374         /* IMPLEMENTATION NOTE: this 'half_window_size' stuff is only here to
 375          * work round a Microsoft Visual C misbehavior which, contrary to C-90,
 376          * widens the result of the following shift to 64-bits if (and,
 377          * apparently, only if) it is used in a test.
 378          */
 379         unsigned int half_window_size = 1U << (windowBits-1);
 380
 381         while (data_size + 262 <= half_window_size)
 382         {
 383            half_window_size >>= 1;
 384            --windowBits;
 385         }
 386      }
 387
 388      /* Check against the previous initialized values, if any. */
 389      if ((png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) != 0 &&
 390         (png_ptr->zlib_set_level != level ||
 391         png_ptr->zlib_set_method != method ||
 392         png_ptr->zlib_set_window_bits != windowBits ||
 393         png_ptr->zlib_set_mem_level != memLevel ||
 394         png_ptr->zlib_set_strategy != strategy))
 395      {
 396         if (deflateEnd(&png_ptr->zstream) != Z_OK)
 397            png_warning(png_ptr, "deflateEnd failed (ignored)");
 398
 399         png_ptr->flags &= ~PNG_FLAG_ZSTREAM_INITIALIZED;
 400      }
 401
 402      /* For safety clear out the input and output pointers (currently zlib
 403       * doesn't use them on Init, but it might in the future).
 404       */
 405      png_ptr->zstream.next_in = NULL;
 406      png_ptr->zstream.avail_in = 0;
 407      png_ptr->zstream.next_out = NULL;
 408      png_ptr->zstream.avail_out = 0;
 409
 410      /* Now initialize if required, setting the new parameters, otherwise just
 411       * to a simple reset to the previous parameters.
 412       */
 413      if ((png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) != 0)
 414         ret = deflateReset(&png_ptr->zstream);
 415
 416      else
 417      {
 418         ret = deflateInit2(&png_ptr->zstream, level, method, windowBits,
 419            memLevel, strategy);
 420
 421         if (ret == Z_OK)
 422            png_ptr->flags |= PNG_FLAG_ZSTREAM_INITIALIZED;
 423      }
 424
 425      /* The return code is from either deflateReset or deflateInit2; they have
 426       * pretty much the same set of error codes.
 427       */
 428      if (ret == Z_OK)
 429         png_ptr->zowner = owner;
 430
 431      else
 432         png_zstream_error(png_ptr, ret);
 433
 434      return ret;
 435   }
 436}
 437
 438/* Clean up (or trim) a linked list of compression buffers. */
 439void /* PRIVATE */
 440png_free_buffer_list(png_structrp png_ptr, png_compression_bufferp *listp)
 441{
 442   png_compression_bufferp list = *listp;
 443
 444   if (list != NULL)
 445   {
 446      *listp = NULL;
 447
 448      do
 449      {
 450         png_compression_bufferp next = list->next;
 451
 452         png_free(png_ptr, list);
 453         list = next;
 454      }
 455      while (list != NULL);
 456   }
 457}
 458
 459#ifdef PNG_WRITE_COMPRESSED_TEXT_SUPPORTED
 460/* This pair of functions encapsulates the operation of (a) compressing a
 461 * text string, and (b) issuing it later as a series of chunk data writes.
 462 * The compression_state structure is shared context for these functions
 463 * set up by the caller to allow access to the relevant local variables.
 464 *
 465 * compression_buffer (new in 1.6.0) is just a linked list of zbuffer_size
 466 * temporary buffers.  From 1.6.0 it is retained in png_struct so that it will
 467 * be correctly freed in the event of a write error (previous implementations
 468 * just leaked memory.)
 469 */
 470typedef struct
 471{
 472   png_const_bytep      input;        /* The uncompressed input data */
 473   png_alloc_size_t     input_len;    /* Its length */
 474   png_uint_32          output_len;   /* Final compressed length */
 475   png_byte             output[1024]; /* First block of output */
 476} compression_state;
 477
 478static void
 479png_text_compress_init(compression_state *comp, png_const_bytep input,
 480   png_alloc_size_t input_len)
 481{
 482   comp->input = input;
 483   comp->input_len = input_len;
 484   comp->output_len = 0;
 485}
 486
 487/* Compress the data in the compression state input */
 488static int
 489png_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    * that is used on the inflate side; deflate is assumed to be slower and a
 497    * PNG writer is assumed to have more memory available than a PNG reader.
 498    *
 499    * IMPLEMENTATION NOTE: the zlib API deflateBound() can be used to find an
 500    * upper limit on the output size, but it is always bigger than the input
 501    * size so it is likely to be more efficient to use this linked-list
 502    * approach.
 503    */
 504   ret = png_deflate_claim(png_ptr, chunk_name, comp->input_len);
 505
 506   if (ret != Z_OK)
 507      return ret;
 508
 509   /* Set up the compression buffers, we need a loop here to avoid overflowing a
 510    * uInt.  Use ZLIB_IO_MAX to limit the input.  The output is always limited
 511    * by the output buffer size, so there is no need to check that.  Since this
 512    * is ANSI-C we know that an 'int', hence a uInt, is always at least 16 bits
 513    * in size.
 514    */
 515   {
 516      png_compression_bufferp *end = &png_ptr->zbuffer_list;
 517      png_alloc_size_t input_len = comp->input_len; /* may be zero! */
 518      png_uint_32 output_len;
 519
 520      /* zlib updates these for us: */
 521      png_ptr->zstream.next_in = PNGZ_INPUT_CAST(comp->input);
 522      png_ptr->zstream.avail_in = 0; /* Set below */
 523      png_ptr->zstream.next_out = comp->output;
 524      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         if (avail_in > input_len)
 533            avail_in = (uInt)input_len;
 534
 535         input_len -= avail_in;
 536
 537         png_ptr->zstream.avail_in = avail_in;
 538
 539         if (png_ptr->zstream.avail_out == 0)
 540         {
 541            png_compression_buffer *next;
 542
 543            /* Chunk data is limited to 2^31 bytes in length, so the prefix
 544             * length must be counted here.
 545             */
 546            if (output_len + prefix_len > PNG_UINT_31_MAX)
 547            {
 548               ret = Z_MEM_ERROR;
 549               break;
 550            }
 551
 552            /* Need a new (malloc'ed) buffer, but there may be one present
 553             * already.
 554             */
 555            next = *end;
 556            if (next == NULL)
 557            {
 558               next = png_voidcast(png_compression_bufferp, png_malloc_base
 559                  (png_ptr, PNG_COMPRESSION_BUFFER_SIZE(png_ptr)));
 560
 561               if (next == NULL)
 562               {
 563                  ret = Z_MEM_ERROR;
 564                  break;
 565               }
 566
 567               /* Link in this buffer (so that it will be freed later) */
 568               next->next = NULL;
 569               *end = next;
 570            }
 571
 572            png_ptr->zstream.next_out = next->output;
 573            png_ptr->zstream.avail_out = png_ptr->zbuffer_size;
 574            output_len += png_ptr->zstream.avail_out;
 575
 576            /* Move 'end' to the next buffer pointer. */
 577            end = &next->next;
 578         }
 579
 580         /* Compress the data */
 581         ret = deflate(&png_ptr->zstream,
 582            input_len > 0 ? Z_NO_FLUSH : Z_FINISH);
 583
 584         /* Claw back input data that was not consumed (because avail_in is
 585          * reset above every time round the loop).
 586          */
 587         input_len += png_ptr->zstream.avail_in;
 588         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       * be subtracted from output_len.
 594       */
 595      output_len -= png_ptr->zstream.avail_out;
 596      png_ptr->zstream.avail_out = 0; /* safety */
 597      comp->output_len = output_len;
 598
 599      /* Now double check the output length, put in a custom message if it is
 600       * too long.  Otherwise ensure the z_stream::msg pointer is set to
 601       * something.
 602       */
 603      if (output_len + prefix_len >= PNG_UINT_31_MAX)
 604      {
 605         png_ptr->zstream.msg = PNGZ_MSG_CAST("compressed data too long");
 606         ret = Z_MEM_ERROR;
 607      }
 608
 609      else
 610         png_zstream_error(png_ptr, ret);
 611
 612      /* Reset zlib for another zTXt/iTXt or image data */
 613      png_ptr->zowner = 0;
 614
 615      /* The only success case is Z_STREAM_END, input_len must be 0; if not this
 616       * is an internal error.
 617       */
 618      if (ret == Z_STREAM_END && input_len == 0)
 619      {
 620#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED
 621         /* Fix up the deflate header, if required */
 622         optimize_cmf(comp->output, comp->input_len);
 623#endif
 624         /* But Z_OK is returned, not Z_STREAM_END; this allows the claim
 625          * function above to return Z_STREAM_END on an error (though it never
 626          * does in the current versions of zlib.)
 627          */
 628         return Z_OK;
 629      }
 630
 631      else
 632         return ret;
 633   }
 634}
 635
 636/* Ship the compressed text out via chunk writes */
 637static void
 638png_write_compressed_data_out(png_structrp png_ptr, compression_state *comp)
 639{
 640   png_uint_32 output_len = comp->output_len;
 641   png_const_bytep output = comp->output;
 642   png_uint_32 avail = (sizeof comp->output);
 643   png_compression_buffer *next = png_ptr->zbuffer_list;
 644
 645   for (;;)
 646   {
 647      if (avail > output_len)
 648         avail = output_len;
 649
 650      png_write_chunk_data(png_ptr, output, avail);
 651
 652      output_len -= avail;
 653
 654      if (output_len == 0 || next == NULL)
 655         break;
 656
 657      avail = png_ptr->zbuffer_size;
 658      output = next->output;
 659      next = next->next;
 660   }
 661
 662   /* This is an internal error; 'next' must have been NULL! */
 663   if (output_len > 0)
 664      png_error(png_ptr, "error writing ancillary chunked compressed data");
 665}
 666#endif /* WRITE_COMPRESSED_TEXT */
 667
 668#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) || \
 669    defined(PNG_WRITE_iCCP_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED)
 670/* Check that the tEXt or zTXt keyword is valid per PNG 1.0 specification,
 671 * and if invalid, correct the keyword rather than discarding the entire
 672 * chunk.  The PNG 1.0 specification requires keywords 1-79 characters in
 673 * length, forbids leading or trailing whitespace, multiple internal spaces,
 674 * and the non-break space (0x80) from ISO 8859-1.  Returns keyword length.
 675 *
 676 * The 'new_key' buffer must be 80 characters in size (for the keyword plus a
 677 * trailing '\0').  If this routine returns 0 then there was no keyword, or a
 678 * valid one could not be generated, and the caller must png_error.
 679 */
 680static png_uint_32
 681png_check_keyword(png_structrp png_ptr, png_const_charp key, png_bytep new_key)
 682{
 683   png_const_charp orig_key = key;
 684   png_uint_32 key_len = 0;
 685   int bad_character = 0;
 686   int space = 1;
 687
 688   png_debug(1, "in png_check_keyword");
 689
 690   if (key == NULL)
 691   {
 692      *new_key = 0;
 693      return 0;
 694   }
 695
 696   while (*key && key_len < 79)
 697   {
 698      png_byte ch = (png_byte)*key++;
 699
 700      if ((ch > 32 && ch <= 126) || (ch >= 161 /*&& ch <= 255*/))
 701         *new_key++ = ch, ++key_len, space = 0;
 702
 703      else if (space == 0)
 704      {
 705         /* A space or an invalid character when one wasn't seen immediately
 706          * before; output just a space.
 707          */
 708         *new_key++ = 32, ++key_len, space = 1;
 709
 710         /* If the character was not a space then it is invalid. */
 711         if (ch != 32)
 712            bad_character = ch;
 713      }
 714
 715      else if (bad_character == 0)
 716         bad_character = ch; /* just skip it, record the first error */
 717   }
 718
 719   if (key_len > 0 && space != 0) /* trailing space */
 720   {
 721      --key_len, --new_key;
 722      if (bad_character == 0)
 723         bad_character = 32;
 724   }
 725
 726   /* Terminate the keyword */
 727   *new_key = 0;
 728
 729   if (key_len == 0)
 730      return 0;
 731
 732#ifdef PNG_WARNINGS_SUPPORTED
 733   /* Try to only output one warning per keyword: */
 734   if (*key != 0) /* keyword too long */
 735      png_warning(png_ptr, "keyword truncated");
 736
 737   else if (bad_character != 0)
 738   {
 739      PNG_WARNING_PARAMETERS(p)
 740
 741      png_warning_parameter(p, 1, orig_key);
 742      png_warning_parameter_signed(p, 2, PNG_NUMBER_FORMAT_02x, bad_character);
 743
 744      png_formatted_warning(png_ptr, p, "keyword \"@1\": bad character '0x@2'");
 745   }
 746#endif /* WARNINGS */
 747
 748   return key_len;
 749}
 750#endif /* WRITE_TEXT || WRITE_pCAL || WRITE_iCCP || WRITE_sPLT */
 751
 752/* Write the IHDR chunk, and update the png_struct with the necessary
 753 * information.  Note that the rest of this code depends upon this
 754 * information being correct.
 755 */
 756void /* PRIVATE */
 757png_write_IHDR(png_structrp png_ptr, png_uint_32 width, png_uint_32 height,
 758    int bit_depth, int color_type, int compression_type, int filter_type,
 759    int interlace_type)
 760{
 761   png_byte buf[13]; /* Buffer to store the IHDR info */
 762
 763   png_debug(1, "in png_write_IHDR");
 764
 765   /* Check that we have valid input data from the application info */
 766   switch (color_type)
 767   {
 768      case PNG_COLOR_TYPE_GRAY:
 769         switch (bit_depth)
 770         {
 771            case 1:
 772            case 2:
 773            case 4:
 774            case 8:
 775#ifdef PNG_WRITE_16BIT_SUPPORTED
 776            case 16:
 777#endif
 778               png_ptr->channels = 1; break;
 779
 780            default:
 781               png_error(png_ptr,
 782                   "Invalid bit depth for grayscale image");
 783         }
 784         break;
 785
 786      case PNG_COLOR_TYPE_RGB:
 787#ifdef PNG_WRITE_16BIT_SUPPORTED
 788         if (bit_depth != 8 && bit_depth != 16)
 789#else
 790         if (bit_depth != 8)
 791#endif
 792            png_error(png_ptr, "Invalid bit depth for RGB image");
 793
 794         png_ptr->channels = 3;
 795         break;
 796
 797      case PNG_COLOR_TYPE_PALETTE:
 798         switch (bit_depth)
 799         {
 800            case 1:
 801            case 2:
 802            case 4:
 803            case 8:
 804               png_ptr->channels = 1;
 805               break;
 806
 807            default:
 808               png_error(png_ptr, "Invalid bit depth for paletted image");
 809         }
 810         break;
 811
 812      case PNG_COLOR_TYPE_GRAY_ALPHA:
 813         if (bit_depth != 8 && bit_depth != 16)
 814            png_error(png_ptr, "Invalid bit depth for grayscale+alpha image");
 815
 816         png_ptr->channels = 2;
 817         break;
 818
 819      case PNG_COLOR_TYPE_RGB_ALPHA:
 820#ifdef PNG_WRITE_16BIT_SUPPORTED
 821         if (bit_depth != 8 && bit_depth != 16)
 822#else
 823         if (bit_depth != 8)
 824#endif
 825            png_error(png_ptr, "Invalid bit depth for RGBA image");
 826
 827         png_ptr->channels = 4;
 828         break;
 829
 830      default:
 831         png_error(png_ptr, "Invalid image color type specified");
 832   }
 833
 834   if (compression_type != PNG_COMPRESSION_TYPE_BASE)
 835   {
 836      png_warning(png_ptr, "Invalid compression type specified");
 837      compression_type = PNG_COMPRESSION_TYPE_BASE;
 838   }
 839
 840   /* Write filter_method 64 (intrapixel differencing) only if
 841    * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and
 842    * 2. Libpng did not write a PNG signature (this filter_method is only
 843    *    used in PNG datastreams that are embedded in MNG datastreams) and
 844    * 3. The application called png_permit_mng_features with a mask that
 845    *    included PNG_FLAG_MNG_FILTER_64 and
 846    * 4. The filter_method is 64 and
 847    * 5. The color_type is RGB or RGBA
 848    */
 849   if (
 850#ifdef PNG_MNG_FEATURES_SUPPORTED
 851       !((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 &&
 852       ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) == 0) &&
 853       (color_type == PNG_COLOR_TYPE_RGB ||
 854        color_type == PNG_COLOR_TYPE_RGB_ALPHA) &&
 855       (filter_type == PNG_INTRAPIXEL_DIFFERENCING)) &&
 856#endif
 857       filter_type != PNG_FILTER_TYPE_BASE)
 858   {
 859      png_warning(png_ptr, "Invalid filter type specified");
 860      filter_type = PNG_FILTER_TYPE_BASE;
 861   }
 862
 863#ifdef PNG_WRITE_INTERLACING_SUPPORTED
 864   if (interlace_type != PNG_INTERLACE_NONE &&
 865       interlace_type != PNG_INTERLACE_ADAM7)
 866   {
 867      png_warning(png_ptr, "Invalid interlace type specified");
 868      interlace_type = PNG_INTERLACE_ADAM7;
 869   }
 870#else
 871   interlace_type=PNG_INTERLACE_NONE;
 872#endif
 873
 874   /* Save the relevant information */
 875   png_ptr->bit_depth = (png_byte)bit_depth;
 876   png_ptr->color_type = (png_byte)color_type;
 877   png_ptr->interlaced = (png_byte)interlace_type;
 878#ifdef PNG_MNG_FEATURES_SUPPORTED
 879   png_ptr->filter_type = (png_byte)filter_type;
 880#endif
 881   png_ptr->compression_type = (png_byte)compression_type;
 882   png_ptr->width = width;
 883   png_ptr->height = height;
 884
 885   png_ptr->pixel_depth = (png_byte)(bit_depth * png_ptr->channels);
 886   png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, width);
 887   /* Set the usr info, so any transformations can modify it */
 888   png_ptr->usr_width = png_ptr->width;
 889   png_ptr->usr_bit_depth = png_ptr->bit_depth;
 890   png_ptr->usr_channels = png_ptr->channels;
 891
 892   /* Pack the header information into the buffer */
 893   png_save_uint_32(buf, width);
 894   png_save_uint_32(buf + 4, height);
 895   buf[8] = (png_byte)bit_depth;
 896   buf[9] = (png_byte)color_type;
 897   buf[10] = (png_byte)compression_type;
 898   buf[11] = (png_byte)filter_type;
 899   buf[12] = (png_byte)interlace_type;
 900
 901   /* Write the chunk */
 902   png_write_complete_chunk(png_ptr, png_IHDR, buf, (png_size_t)13);
 903
 904   if ((png_ptr->do_filter) == PNG_NO_FILTERS)
 905   {
 906      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE ||
 907          png_ptr->bit_depth < 8)
 908         png_ptr->do_filter = PNG_FILTER_NONE;
 909
 910      else
 911         png_ptr->do_filter = PNG_ALL_FILTERS;
 912   }
 913
 914   png_ptr->mode = PNG_HAVE_IHDR; /* not READY_FOR_ZTXT */
 915}
 916
 917/* Write the palette.  We are careful not to trust png_color to be in the
 918 * correct order for PNG, so people can redefine it to any convenient
 919 * structure.
 920 */
 921void /* PRIVATE */
 922png_write_PLTE(png_structrp png_ptr, png_const_colorp palette,
 923    png_uint_32 num_pal)
 924{
 925   png_uint_32 i;
 926   png_const_colorp pal_ptr;
 927   png_byte buf[3];
 928
 929   png_debug(1, "in png_write_PLTE");
 930
 931   if ((
 932#ifdef PNG_MNG_FEATURES_SUPPORTED
 933       (png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) == 0 &&
 934#endif
 935       num_pal == 0) || num_pal > 256)
 936   {
 937      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
 938      {
 939         png_error(png_ptr, "Invalid number of colors in palette");
 940      }
 941
 942      else
 943      {
 944         png_warning(png_ptr, "Invalid number of colors in palette");
 945         return;
 946      }
 947   }
 948
 949   if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0)
 950   {
 951      png_warning(png_ptr,
 952          "Ignoring request to write a PLTE chunk in grayscale PNG");
 953
 954      return;
 955   }
 956
 957   png_ptr->num_palette = (png_uint_16)num_pal;
 958   png_debug1(3, "num_palette = %d", png_ptr->num_palette);
 959
 960   png_write_chunk_header(png_ptr, png_PLTE, (png_uint_32)(num_pal * 3));
 961#ifdef PNG_POINTER_INDEXING_SUPPORTED
 962
 963   for (i = 0, pal_ptr = palette; i < num_pal; i++, pal_ptr++)
 964   {
 965      buf[0] = pal_ptr->red;
 966      buf[1] = pal_ptr->green;
 967      buf[2] = pal_ptr->blue;
 968      png_write_chunk_data(png_ptr, buf, (png_size_t)3);
 969   }
 970
 971#else
 972   /* This is a little slower but some buggy compilers need to do this
 973    * instead
 974    */
 975   pal_ptr=palette;
 976
 977   for (i = 0; i < num_pal; i++)
 978   {
 979      buf[0] = pal_ptr[i].red;
 980      buf[1] = pal_ptr[i].green;
 981      buf[2] = pal_ptr[i].blue;
 982      png_write_chunk_data(png_ptr, buf, (png_size_t)3);
 983   }
 984
 985#endif
 986   png_write_chunk_end(png_ptr);
 987   png_ptr->mode |= PNG_HAVE_PLTE;
 988}
 989
 990/* This is similar to png_text_compress, above, except that it does not require
 991 * all of the data at once and, instead of buffering the compressed result,
 992 * writes it as IDAT chunks.  Unlike png_text_compress it *can* png_error out
 993 * because it calls the write interface.  As a result it does its own error
 994 * reporting and does not return an error code.  In the event of error it will
 995 * just call png_error.  The input data length may exceed 32-bits.  The 'flush'
 996 * parameter is exactly the same as that to deflate, with the following
 997 * meanings:
 998 *
 999 * Z_NO_FLUSH: normal incremental output of compressed data
1000 * Z_SYNC_FLUSH: do a SYNC_FLUSH, used by png_write_flush
1001 * Z_FINISH: this is the end of the input, do a Z_FINISH and clean up
1002 *
1003 * The routine manages the acquire and release of the png_ptr->zstream by
1004 * checking and (at the end) clearing png_ptr->zowner; it does some sanity
1005 * checks on the 'mode' flags while doing this.
1006 */
1007void /* PRIVATE */
1008png_compress_IDAT(png_structrp png_ptr, png_const_bytep input,
1009   png_alloc_size_t input_len, int flush)
1010{
1011   if (png_ptr->zowner != png_IDAT)
1012   {
1013      /* First time.   Ensure we have a temporary buffer for compression and
1014       * trim the buffer list if it has more than one entry to free memory.
1015       * If 'WRITE_COMPRESSED_TEXT' is not set the list will never have been
1016       * created at this point, but the check here is quick and safe.
1017       */
1018      if (png_ptr->zbuffer_list == NULL)
1019      {
1020         png_ptr->zbuffer_list = png_voidcast(png_compression_bufferp,
1021            png_malloc(png_ptr, PNG_COMPRESSION_BUFFER_SIZE(png_ptr)));
1022         png_ptr->zbuffer_list->next = NULL;
1023      }
1024
1025      else
1026         png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list->next);
1027
1028      /* It is a terminal error if we can't claim the zstream. */
1029      if (png_deflate_claim(png_ptr, png_IDAT, png_image_size(png_ptr)) != Z_OK)
1030         png_error(png_ptr, png_ptr->zstream.msg);
1031
1032      /* The output state is maintained in png_ptr->zstream, so it must be
1033       * initialized here after the claim.
1034       */
1035      png_ptr->zstream.next_out = png_ptr->zbuffer_list->output;
1036      png_ptr->zstream.avail_out = png_ptr->zbuffer_size;
1037   }
1038
1039   /* Now loop reading and writing until all the input is consumed or an error
1040    * terminates the operation.  The _out values are maintained across calls to
1041    * this function, but the input must be reset each time.
1042    */
1043   png_ptr->zstream.next_in = PNGZ_INPUT_CAST(input);
1044   png_ptr->zstream.avail_in = 0; /* set below */
1045   for (;;)
1046   {
1047      int ret;
1048
1049      /* INPUT: from the row data */
1050      uInt avail = ZLIB_IO_MAX;
1051
1052      if (avail > input_len)
1053         avail = (uInt)input_len; /* safe because of the check */
1054
1055      png_ptr->zstream.avail_in = avail;
1056      input_len -= avail;
1057
1058      ret = deflate(&png_ptr->zstream, input_len > 0 ? Z_NO_FLUSH : flush);
1059
1060      /* Include as-yet unconsumed input */
1061      input_len += png_ptr->zstream.avail_in;
1062      png_ptr->zstream.avail_in = 0;
1063
1064      /* OUTPUT: write complete IDAT chunks when avail_out drops to zero. Note
1065       * that these two zstream fields are preserved across the calls, therefore
1066       * there is no need to set these up on entry to the loop.
1067       */
1068      if (png_ptr->zstream.avail_out == 0)
1069      {
1070         png_bytep data = png_ptr->zbuffer_list->output;
1071         uInt size = png_ptr->zbuffer_size;
1072
1073         /* Write an IDAT containing the data then reset the buffer.  The
1074          * first IDAT may need deflate header optimization.
1075          */
1076#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED
1077            if ((png_ptr->mode & PNG_HAVE_IDAT) == 0 &&
1078                png_ptr->compression_type == PNG_COMPRESSION_TYPE_BASE)
1079               optimize_cmf(data, png_image_size(png_ptr));
1080#endif
1081
1082         png_write_complete_chunk(png_ptr, png_IDAT, data, size);
1083         png_ptr->mode |= PNG_HAVE_IDAT;
1084
1085         png_ptr->zstream.next_out = data;
1086         png_ptr->zstream.avail_out = size;
1087
1088         /* For SYNC_FLUSH or FINISH it is essential to keep calling zlib with
1089          * the same flush parameter until it has finished output, for NO_FLUSH
1090          * it doesn't matter.
1091          */
1092         if (ret == Z_OK && flush != Z_NO_FLUSH)
1093            continue;
1094      }
1095
1096      /* The order of these checks doesn't matter much; it just affects which
1097       * possible error might be detected if multiple things go wrong at once.
1098       */
1099      if (ret == Z_OK) /* most likely return code! */
1100      {
1101         /* If all the input has been consumed then just return.  If Z_FINISH
1102          * was used as the flush parameter something has gone wrong if we get
1103          * here.
1104          */
1105         if (input_len == 0)
1106         {
1107            if (flush == Z_FINISH)
1108               png_error(png_ptr, "Z_OK on Z_FINISH with output space");
1109
1110            return;
1111         }
1112      }
1113
1114      else if (ret == Z_STREAM_END && flush == Z_FINISH)
1115      {
1116         /* This is the end of the IDAT data; any pending output must be
1117          * flushed.  For small PNG files we may still be at the beginning.
1118          */
1119         png_bytep data = png_ptr->zbuffer_list->output;
1120         uInt size = png_ptr->zbuffer_size - png_ptr->zstream.avail_out;
1121
1122#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED
1123         if ((png_ptr->mode & PNG_HAVE_IDAT) == 0 &&
1124             png_ptr->compression_type == PNG_COMPRESSION_TYPE_BASE)
1125            optimize_cmf(data, png_image_size(png_ptr));
1126#endif
1127
1128         png_write_complete_chunk(png_ptr, png_IDAT, data, size);
1129         png_ptr->zstream.avail_out = 0;
1130         png_ptr->zstream.next_out = NULL;
1131         png_ptr->mode |= PNG_HAVE_IDAT | PNG_AFTER_IDAT;
1132
1133         png_ptr->zowner = 0; /* Release the stream */
1134         return;
1135      }
1136
1137      else
1138      {
1139         /* This is an error condition. */
1140         png_zstream_error(png_ptr, ret);
1141         png_error(png_ptr, png_ptr->zstream.msg);
1142      }
1143   }
1144}
1145
1146/* Write an IEND chunk */
1147void /* PRIVATE */
1148png_write_IEND(png_structrp png_ptr)
1149{
1150   png_debug(1, "in png_write_IEND");
1151
1152   png_write_complete_chunk(png_ptr, png_IEND, NULL, (png_size_t)0);
1153   png_ptr->mode |= PNG_HAVE_IEND;
1154}
1155
1156#ifdef PNG_WRITE_gAMA_SUPPORTED
1157/* Write a gAMA chunk */
1158void /* PRIVATE */
1159png_write_gAMA_fixed(png_structrp png_ptr, png_fixed_point file_gamma)
1160{
1161   png_byte buf[4];
1162
1163   png_debug(1, "in png_write_gAMA");
1164
1165   /* file_gamma is saved in 1/100,000ths */
1166   png_save_uint_32(buf, (png_uint_32)file_gamma);
1167   png_write_complete_chunk(png_ptr, png_gAMA, buf, (png_size_t)4);
1168}
1169#endif
1170
1171#ifdef PNG_WRITE_sRGB_SUPPORTED
1172/* Write a sRGB chunk */
1173void /* PRIVATE */
1174png_write_sRGB(png_structrp png_ptr, int srgb_intent)
1175{
1176   png_byte buf[1];
1177
1178   png_debug(1, "in png_write_sRGB");
1179
1180   if (srgb_intent >= PNG_sRGB_INTENT_LAST)
1181      png_warning(png_ptr,
1182          "Invalid sRGB rendering intent specified");
1183
1184   buf[0]=(png_byte)srgb_intent;
1185   png_write_complete_chunk(png_ptr, png_sRGB, buf, (png_size_t)1);
1186}
1187#endif
1188
1189#ifdef PNG_WRITE_iCCP_SUPPORTED
1190/* Write an iCCP chunk */
1191void /* PRIVATE */
1192png_write_iCCP(png_structrp png_ptr, png_const_charp name,
1193    png_const_bytep profile)
1194{
1195   png_uint_32 name_len;
1196   png_uint_32 profile_len;
1197   png_byte new_name[81]; /* 1 byte for the compression byte */
1198   compression_state comp;
1199   png_uint_32 temp;
1200
1201   png_debug(1, "in png_write_iCCP");
1202
1203   /* These are all internal problems: the profile should have been checked
1204    * before when it was stored.
1205    */
1206   if (profile == NULL)
1207      png_error(png_ptr, "No profile for iCCP chunk"); /* internal error */
1208
1209   profile_len = png_get_uint_32(profile);
1210
1211   if (profile_len < 132)
1212      png_error(png_ptr, "ICC profile too short");
1213
1214   temp = (png_uint_32) (*(profile+8));
1215   if (temp > 3 && (profile_len & 0x03))
1216      png_error(png_ptr, "ICC profile length invalid (not a multiple of 4)");
1217
1218   {
1219      png_uint_32 embedded_profile_len = png_get_uint_32(profile);
1220
1221      if (profile_len != embedded_profile_len)
1222         png_error(png_ptr, "Profile length does not match profile");
1223   }
1224
1225   name_len = png_check_keyword(png_ptr, name, new_name);
1226
1227   if (name_len == 0)
1228      png_error(png_ptr, "iCCP: invalid keyword");
1229
1230   new_name[++name_len] = PNG_COMPRESSION_TYPE_BASE;
1231
1232   /* Make sure we include the NULL after the name and the compression type */
1233   ++name_len;
1234
1235   png_text_compress_init(&comp, profile, profile_len);
1236
1237   /* Allow for keyword terminator and compression byte */
1238   if (png_text_compress(png_ptr, png_iCCP, &comp, name_len) != Z_OK)
1239      png_error(png_ptr, png_ptr->zstream.msg);
1240
1241   png_write_chunk_header(png_ptr, png_iCCP, name_len + comp.output_len);
1242
1243   png_write_chunk_data(png_ptr, new_name, name_len);
1244
1245   png_write_compressed_data_out(png_ptr, &comp);
1246
1247   png_write_chunk_end(png_ptr);
1248}
1249#endif
1250
1251#ifdef PNG_WRITE_sPLT_SUPPORTED
1252/* Write a sPLT chunk */
1253void /* PRIVATE */
1254png_write_sPLT(png_structrp png_ptr, png_const_sPLT_tp spalette)
1255{
1256   png_uint_32 name_len;
1257   png_byte new_name[80];
1258   png_byte entrybuf[10];
1259   png_size_t entry_size = (spalette->depth == 8 ? 6 : 10);
1260   png_size_t palette_size = entry_size * spalette->nentries;
1261   png_sPLT_entryp ep;
1262#ifndef PNG_POINTER_INDEXING_SUPPORTED
1263   int i;
1264#endif
1265
1266   png_debug(1, "in png_write_sPLT");
1267
1268   name_len = png_check_keyword(png_ptr, spalette->name, new_name);
1269
1270   if (name_len == 0)
1271      png_error(png_ptr, "sPLT: invalid keyword");
1272
1273   /* Make sure we include the NULL after the name */
1274   png_write_chunk_header(png_ptr, png_sPLT,
1275       (png_uint_32)(name_len + 2 + palette_size));
1276
1277   png_write_chunk_data(png_ptr, (png_bytep)new_name,
1278       (png_size_t)(name_len + 1));
1279
1280   png_write_chunk_data(png_ptr, &spalette->depth, (png_size_t)1);
1281
1282   /* Loop through each palette entry, writing appropriately */
1283#ifdef PNG_POINTER_INDEXING_SUPPORTED
1284   for (ep = spalette->entries; ep<spalette->entries + spalette->nentries; ep++)
1285   {
1286      if (spalette->depth == 8)
1287      {
1288         entrybuf[0] = (png_byte)ep->red;
1289         entrybuf[1] = (png_byte)ep->green;
1290         entrybuf[2] = (png_byte)ep->blue;
1291         entrybuf[3] = (png_byte)ep->alpha;
1292         png_save_uint_16(entrybuf + 4, ep->frequency);
1293      }
1294
1295      else
1296      {
1297         png_save_uint_16(entrybuf + 0, ep->red);
1298         png_save_uint_16(entrybuf + 2, ep->green);
1299         png_save_uint_16(entrybuf + 4, ep->blue);
1300         png_save_uint_16(entrybuf + 6, ep->alpha);
1301         png_save_uint_16(entrybuf + 8, ep->frequency);
1302      }
1303
1304      png_write_chunk_data(png_ptr, entrybuf, entry_size);
1305   }
1306#else
1307   ep=spalette->entries;
1308   for (i = 0; i>spalette->nentries; i++)
1309   {
1310      if (spalette->depth == 8)
1311      {
1312         entrybuf[0] = (png_byte)ep[i].red;
1313         entrybuf[1] = (png_byte)ep[i].green;
1314         entrybuf[2] = (png_byte)ep[i].blue;
1315         entrybuf[3] = (png_byte)ep[i].alpha;
1316         png_save_uint_16(entrybuf + 4, ep[i].frequency);
1317      }
1318
1319      else
1320      {
1321         png_save_uint_16(entrybuf + 0, ep[i].red);
1322         png_save_uint_16(entrybuf + 2, ep[i].green);
1323         png_save_uint_16(entrybuf + 4, ep[i].blue);
1324         png_save_uint_16(entrybuf + 6, ep[i].alpha);
1325         png_save_uint_16(entrybuf + 8, ep[i].frequency);
1326      }
1327
1328      png_write_chunk_data(png_ptr, entrybuf, entry_size);
1329   }
1330#endif
1331
1332   png_write_chunk_end(png_ptr);
1333}
1334#endif
1335
1336#ifdef PNG_WRITE_sBIT_SUPPORTED
1337/* Write the sBIT chunk */
1338void /* PRIVATE */
1339png_write_sBIT(png_structrp png_ptr, png_const_color_8p sbit, int color_type)
1340{
1341   png_byte buf[4];
1342   png_size_t size;
1343
1344   png_debug(1, "in png_write_sBIT");
1345
1346   /* Make sure we don't depend upon the order of PNG_COLOR_8 */
1347   if ((color_type & PNG_COLOR_MASK_COLOR) != 0)
1348   {
1349      png_byte maxbits;
1350
1351      maxbits = (png_byte)(color_type==PNG_COLOR_TYPE_PALETTE ? 8 :
1352          png_ptr->usr_bit_depth);
1353
1354      if (sbit->red == 0 || sbit->red > maxbits ||
1355          sbit->green == 0 || sbit->green > maxbits ||
1356          sbit->blue == 0 || sbit->blue > maxbits)
1357      {
1358         png_warning(png_ptr, "Invalid sBIT depth specified");
1359         return;
1360      }
1361
1362      buf[0] = sbit->red;
1363      buf[1] = sbit->green;
1364      buf[2] = sbit->blue;
1365      size = 3;
1366   }
1367
1368   else
1369   {
1370      if (sbit->gray == 0 || sbit->gray > png_ptr->usr_bit_depth)
1371      {
1372         png_warning(png_ptr, "Invalid sBIT depth specified");
1373         return;
1374      }
1375
1376      buf[0] = sbit->gray;
1377      size = 1;
1378   }
1379
1380   if ((color_type & PNG_COLOR_MASK_ALPHA) != 0)
1381   {
1382      if (sbit->alpha == 0 || sbit->alpha > png_ptr->usr_bit_depth)
1383      {
1384         png_warning(png_ptr, "Invalid sBIT depth specified");
1385         return;
1386      }
1387
1388      buf[size++] = sbit->alpha;
1389   }
1390
1391   png_write_complete_chunk(png_ptr, png_sBIT, buf, size);
1392}
1393#endif
1394
1395#ifdef PNG_WRITE_cHRM_SUPPORTED
1396/* Write the cHRM chunk */
1397void /* PRIVATE */
1398png_write_cHRM_fixed(png_structrp png_ptr, const png_xy *xy)
1399{
1400   png_byte buf[32];
1401
1402   png_debug(1, "in png_write_cHRM");
1403
1404   /* Each value is saved in 1/100,000ths */
1405   png_save_int_32(buf,      xy->whitex);
1406   png_save_int_32(buf +  4, xy->whitey);
1407
1408   png_save_int_32(buf +  8, xy->redx);
1409   png_save_int_32(buf + 12, xy->redy);
1410
1411   png_save_int_32(buf + 16, xy->greenx);
1412   png_save_int_32(buf + 20, xy->greeny);
1413
1414   png_save_int_32(buf + 24, xy->bluex);
1415   png_save_int_32(buf + 28, xy->bluey);
1416
1417   png_write_complete_chunk(png_ptr, png_cHRM, buf, 32);
1418}
1419#endif
1420
1421#ifdef PNG_WRITE_tRNS_SUPPORTED
1422/* Write the tRNS chunk */
1423void /* PRIVATE */
1424png_write_tRNS(png_structrp png_ptr, png_const_bytep trans_alpha,
1425    png_const_color_16p tran, int num_trans, int color_type)
1426{
1427   png_byte buf[6];
1428
1429   png_debug(1, "in png_write_tRNS");
1430
1431   if (color_type == PNG_COLOR_TYPE_PALETTE)
1432   {
1433      if (num_trans <= 0 || num_trans > (int)png_ptr->num_palette)
1434      {
1435         png_app_warning(png_ptr,
1436             "Invalid number of transparent colors specified");
1437         return;
1438      }
1439
1440      /* Write the chunk out as it is */
1441      png_write_complete_chunk(png_ptr, png_tRNS, trans_alpha,
1442         (png_size_t)num_trans);
1443   }
1444
1445   else if (color_type == PNG_COLOR_TYPE_GRAY)
1446   {
1447      /* One 16 bit value */
1448      if (tran->gray >= (1 << png_ptr->bit_depth))
1449      {
1450         png_app_warning(png_ptr,
1451             "Ignoring attempt to write tRNS chunk out-of-range for bit_depth");
1452
1453         return;
1454      }
1455
1456      png_save_uint_16(buf, tran->gray);
1457      png_write_complete_chunk(png_ptr, png_tRNS, buf, (png_size_t)2);
1458   }
1459
1460   else if (color_type == PNG_COLOR_TYPE_RGB)
1461   {
1462      /* Three 16 bit values */
1463      png_save_uint_16(buf, tran->red);
1464      png_save_uint_16(buf + 2, tran->green);
1465      png_save_uint_16(buf + 4, tran->blue);
1466#ifdef PNG_WRITE_16BIT_SUPPORTED
1467      if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4]) != 0)
1468#else
1469      if ((buf[0] | buf[2] | buf[4]) != 0)
1470#endif
1471      {
1472         png_app_warning(png_ptr,
1473           "Ignoring attempt to write 16-bit tRNS chunk when bit_depth is 8");
1474         return;
1475      }
1476
1477      png_write_complete_chunk(png_ptr, png_tRNS, buf, (png_size_t)6);
1478   }
1479
1480   else
1481   {
1482      png_app_warning(png_ptr, "Can't write tRNS with an alpha channel");
1483   }
1484}
1485#endif
1486
1487#ifdef PNG_WRITE_bKGD_SUPPORTED
1488/* Write the background chunk */
1489void /* PRIVATE */
1490png_write_bKGD(png_structrp png_ptr, png_const_color_16p back, int color_type)
1491{
1492   png_byte buf[6];
1493
1494   png_debug(1, "in png_write_bKGD");
1495
1496   if (color_type == PNG_COLOR_TYPE_PALETTE)
1497   {
1498      if (
1499#ifdef PNG_MNG_FEATURES_SUPPORTED
1500          (png_ptr->num_palette != 0 ||
1501          (png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) == 0) &&
1502#endif
1503         back->index >= png_ptr->num_palette)
1504      {
1505         png_warning(png_ptr, "Invalid background palette index");
1506         return;
1507      }
1508
1509      buf[0] = back->index;
1510      png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)1);
1511   }
1512
1513   else if ((color_type & PNG_COLOR_MASK_COLOR) != 0)
1514   {
1515      png_save_uint_16(buf, back->red);
1516      png_save_uint_16(buf + 2, back->green);
1517      png_save_uint_16(buf + 4, back->blue);
1518#ifdef PNG_WRITE_16BIT_SUPPORTED
1519      if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4]) != 0)
1520#else
1521      if ((buf[0] | buf[2] | buf[4]) != 0)
1522#endif
1523      {
1524         png_warning(png_ptr,
1525             "Ignoring attempt to write 16-bit bKGD chunk when bit_depth is 8");
1526
1527         return;
1528      }
1529
1530      png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)6);
1531   }
1532
1533   else
1534   {
1535      if (back->gray >= (1 << png_ptr->bit_depth))
1536      {
1537         png_warning(png_ptr,
1538             "Ignoring attempt to write bKGD chunk out-of-range for bit_depth");
1539
1540         return;
1541      }
1542
1543      png_save_uint_16(buf, back->gray);
1544      png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)2);
1545   }
1546}
1547#endif
1548
1549#ifdef PNG_WRITE_hIST_SUPPORTED
1550/* Write the histogram */
1551void /* PRIVATE */
1552png_write_hIST(png_structrp png_ptr, png_const_uint_16p hist, int num_hist)
1553{
1554   int i;
1555   png_byte buf[3];
1556
1557   png_debug(1, "in png_write_hIST");
1558
1559   if (num_hist > (int)png_ptr->num_palette)
1560   {
1561      png_debug2(3, "num_hist = %d, num_palette = %d", num_hist,
1562          png_ptr->num_palette);
1563
1564      png_warning(png_ptr, "Invalid number of histogram entries specified");
1565      return;
1566   }
1567
1568   png_write_chunk_header(png_ptr, png_hIST, (png_uint_32)(num_hist * 2));
1569
1570   for (i = 0; i < num_hist; i++)
1571   {
1572      png_save_uint_16(buf, hist[i]);
1573      png_write_chunk_data(png_ptr, buf, (png_size_t)2);
1574   }
1575
1576   png_write_chunk_end(png_ptr);
1577}
1578#endif
1579
1580#ifdef PNG_WRITE_tEXt_SUPPORTED
1581/* Write a tEXt chunk */
1582void /* PRIVATE */
1583png_write_tEXt(png_structrp png_ptr, png_const_charp key, png_const_charp text,
1584    png_size_t text_len)
1585{
1586   png_uint_32 key_len;
1587   png_byte new_key[80];
1588
1589   png_debug(1, "in png_write_tEXt");
1590
1591   key_len = png_check_keyword(png_ptr, key, new_key);
1592
1593   if (key_len == 0)
1594      png_error(png_ptr, "tEXt: invalid keyword");
1595
1596   if (text == NULL || *text == '\0')
1597      text_len = 0;
1598
1599   else
1600      text_len = strlen(text);
1601
1602   if (text_len > PNG_UINT_31_MAX - (key_len+1))
1603      png_error(png_ptr, "tEXt: text too long");
1604
1605   /* Make sure we include the 0 after the key */
1606   png_write_chunk_header(png_ptr, png_tEXt,
1607       (png_uint_32)/*checked above*/(key_len + text_len + 1));
1608   /*
1609    * We leave it to the application to meet PNG-1.0 requirements on the
1610    * contents of the text.  PNG-1.0 through PNG-1.2 discourage the use of
1611    * any non-Latin-1 characters except for NEWLINE.  ISO PNG will forbid them.
1612    * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG.
1613    */
1614   png_write_chunk_data(png_ptr, new_key, key_len + 1);
1615
1616   if (text_len != 0)
1617      png_write_chunk_data(png_ptr, (png_const_bytep)text, text_len);
1618
1619   png_write_chunk_end(png_ptr);
1620}
1621#endif
1622
1623#ifdef PNG_WRITE_zTXt_SUPPORTED
1624/* Write a compressed text chunk */
1625void /* PRIVATE */
1626png_write_zTXt(png_structrp png_ptr, png_const_charp key, png_const_charp text,
1627    int compression)
1628{
1629   png_uint_32 key_len;
1630   png_byte new_key[81];
1631   compression_state comp;
1632
1633   png_debug(1, "in png_write_zTXt");
1634
1635   if (compression == PNG_TEXT_COMPRESSION_NONE)
1636   {
1637      png_write_tEXt(png_ptr, key, text, 0);
1638      return;
1639   }
1640
1641   if (compression != PNG_TEXT_COMPRESSION_zTXt)
1642      png_error(png_ptr, "zTXt: invalid compression type");
1643
1644   key_len = png_check_keyword(png_ptr, key, new_key);
1645
1646   if (key_len == 0)
1647      png_error(png_ptr, "zTXt: invalid keyword");
1648
1649   /* Add the compression method and 1 for the keyword separator. */
1650   new_key[++key_len] = PNG_COMPRESSION_TYPE_BASE;
1651   ++key_len;
1652
1653   /* Compute the compressed data; do it now for the length */
1654   png_text_compress_init(&comp, (png_const_bytep)text,
1655      text == NULL ? 0 : strlen(text));
1656
1657   if (png_text_compress(png_ptr, png_zTXt, &comp, key_len) != Z_OK)
1658      png_error(png_ptr, png_ptr->zstream.msg);
1659
1660   /* Write start of chunk */
1661   png_write_chunk_header(png_ptr, png_zTXt, key_len + comp.output_len);
1662
1663   /* Write key */
1664   png_write_chunk_data(png_ptr, new_key, key_len);
1665
1666   /* Write the compressed data */
1667   png_write_compressed_data_out(png_ptr, &comp);
1668
1669   /* Close the chunk */
1670   png_write_chunk_end(png_ptr);
1671}
1672#endif
1673
1674#ifdef PNG_WRITE_iTXt_SUPPORTED
1675/* Write an iTXt chunk */
1676void /* PRIVATE */
1677png_write_iTXt(png_structrp png_ptr, int compression, png_const_charp key,
1678    png_const_charp lang, png_const_charp lang_key, png_const_charp text)
1679{
1680   png_uint_32 key_len, prefix_len;
1681   png_size_t lang_len, lang_key_len;
1682   png_byte new_key[82];
1683   compression_state comp;
1684
1685   png_debug(1, "in png_write_iTXt");
1686
1687   key_len = png_check_keyword(png_ptr, key, new_key);
1688
1689   if (key_len == 0)
1690      png_error(png_ptr, "iTXt: invalid keyword");
1691
1692   /* Set the compression flag */
1693   switch (compression)
1694   {
1695      case PNG_ITXT_COMPRESSION_NONE:
1696      case PNG_TEXT_COMPRESSION_NONE:
1697         compression = new_key[++key_len] = 0; /* no compression */
1698         break;
1699
1700      case PNG_TEXT_COMPRESSION_zTXt:
1701      case PNG_ITXT_COMPRESSION_zTXt:
1702         compression = new_key[++key_len] = 1; /* compressed */
1703         break;
1704
1705      default:
1706         png_error(png_ptr, "iTXt: invalid compression");
1707   }
1708
1709   new_key[++key_len] = PNG_COMPRESSION_TYPE_BASE;
1710   ++key_len; /* for the keywod separator */
1711
1712   /* We leave it to the application to meet PNG-1.0 requirements on the
1713    * contents of the text.  PNG-1.0 through PNG-1.2 discourage the use of
1714    * any non-Latin-1 characters except for NEWLINE.  ISO PNG, however,
1715    * specifies that the text is UTF-8 and this really doesn't require any
1716    * checking.
1717    *
1718    * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG.
1719    *
1720    * TODO: validate the language tag correctly (see the spec.)
1721    */
1722   if (lang == NULL) lang = ""; /* empty language is valid */
1723   lang_len = strlen(lang)+1;
1724   if (lang_key == NULL) lang_key = ""; /* may be empty */
1725   lang_key_len = strlen(lang_key)+1;
1726   if (text == NULL) text = ""; /* may be empty */
1727
1728   prefix_len = key_len;
1729   if (lang_len > PNG_UINT_31_MAX-prefix_len)
1730      prefix_len = PNG_UINT_31_MAX;
1731   else
1732      prefix_len = (png_uint_32)(prefix_len + lang_len);
1733
1734   if (lang_key_len > PNG_UINT_31_MAX-prefix_len)
1735      prefix_len = PNG_UINT_31_MAX;
1736   else
1737      prefix_len = (png_uint_32)(prefix_len + lang_key_len);
1738
1739   png_text_compress_init(&comp, (png_const_bytep)text, strlen(text));
1740
1741   if (compression != 0)
1742   {
1743      if (png_text_compress(png_ptr, png_iTXt, &comp, prefix_len) != Z_OK)
1744         png_error(png_ptr, png_ptr->zstream.msg);
1745   }
1746
1747   else
1748   {
1749      if (comp.input_len > PNG_UINT_31_MAX-prefix_len)
1750         png_error(png_ptr, "iTXt: uncompressed text too long");
1751
1752      /* So the string will fit in a chunk: */
1753      comp.output_len = (png_uint_32)/*SAFE*/comp.input_len;
1754   }
1755
1756   png_write_chunk_header(png_ptr, png_iTXt, comp.output_len + prefix_len);
1757
1758   png_write_chunk_data(png_ptr, new_key, key_len);
1759
1760   png_write_chunk_data(png_ptr, (png_const_bytep)lang, lang_len);
1761
1762   png_write_chunk_data(png_ptr, (png_const_bytep)lang_key, lang_key_len);
1763
1764   if (compression != 0)
1765      png_write_compressed_data_out(png_ptr, &comp);
1766
1767   else
1768      png_write_chunk_data(png_ptr, (png_const_bytep)text, comp.output_len);
1769
1770   png_write_chunk_end(png_ptr);
1771}
1772#endif
1773
1774#ifdef PNG_WRITE_oFFs_SUPPORTED
1775/* Write the oFFs chunk */
1776void /* PRIVATE */
1777png_write_oFFs(png_structrp png_ptr, png_int_32 x_offset, png_int_32 y_offset,
1778    int unit_type)
1779{
1780   png_byte buf[9];
1781
1782   png_debug(1, "in png_write_oFFs");
1783
1784   if (unit_type >= PNG_OFFSET_LAST)
1785      png_warning(png_ptr, "Unrecognized unit type for oFFs chunk");
1786
1787   png_save_int_32(buf, x_offset);
1788   png_save_int_32(buf + 4, y_offset);
1789   buf[8] = (png_byte)unit_type;
1790
1791   png_write_complete_chunk(png_ptr, png_oFFs, buf, (png_size_t)9);
1792}
1793#endif
1794#ifdef PNG_WRITE_pCAL_SUPPORTED
1795/* Write the pCAL chunk (described in the PNG extensions document) */
1796void /* PRIVATE */
1797png_write_pCAL(png_structrp png_ptr, png_charp purpose, png_int_32 X0,
1798    png_int_32 X1, int type, int nparams, png_const_charp units,
1799    png_charpp params)
1800{
1801   png_uint_32 purpose_len;
1802   png_size_t units_len, total_len;
1803   png_size_tp params_len;
1804   png_byte buf[10];
1805   png_byte new_purpose[80];
1806   int i;
1807
1808   png_debug1(1, "in png_write_pCAL (%d parameters)", nparams);
1809
1810   if (type >= PNG_EQUATION_LAST)
1811      png_error(png_ptr, "Unrecognized equation type for pCAL chunk");
1812
1813   purpose_len = png_check_keyword(png_ptr, purpose, new_purpose);
1814
1815   if (purpose_len == 0)
1816      png_error(png_ptr, "pCAL: invalid keyword");
1817
1818   ++purpose_len; /* terminator */
1819
1820   png_debug1(3, "pCAL purpose length = %d", (int)purpose_len);
1821   units_len = strlen(units) + (nparams == 0 ? 0 : 1);
1822   png_debug1(3, "pCAL units length = %d", (int)units_len);
1823   total_len = purpose_len + units_len + 10;
1824
1825   params_len = (png_size_tp)png_malloc(png_ptr,
1826       (png_alloc_size_t)(nparams * (sizeof (png_size_t))));
1827
1828   /* Find the length of each parameter, making sure we don't count the
1829    * null terminator for the last parameter.
1830    */
1831   for (i = 0; i < nparams; i++)
1832   {
1833      params_len[i] = strlen(params[i]) + (i == nparams - 1 ? 0 : 1);
1834      png_debug2(3, "pCAL parameter %d length = %lu", i,
1835          (unsigned long)params_len[i]);
1836      total_len += params_len[i];
1837   }
1838
1839   png_debug1(3, "pCAL total length = %d", (int)total_len);
1840   png_write_chunk_header(png_ptr, png_pCAL, (png_uint_32)total_len);
1841   png_write_chunk_data(png_ptr, new_purpose, purpose_len);
1842   png_save_int_32(buf, X0);
1843   png_save_int_32(buf + 4, X1);
1844   buf[8] = (png_byte)type;
1845   buf[9] = (png_byte)nparams;
1846   png_write_chunk_data(png_ptr, buf, (png_size_t)10);
1847   png_write_chunk_data(png_ptr, (png_const_bytep)units, (png_size_t)units_len);
1848
1849   for (i = 0; i < nparams; i++)
1850   {
1851      png_write_chunk_data(png_ptr, (png_const_bytep)params[i], params_len[i]);
1852   }
1853
1854   png_free(png_ptr, params_len);
1855   png_write_chunk_end(png_ptr);
1856}
1857#endif
1858
1859#ifdef PNG_WRITE_sCAL_SUPPORTED
1860/* Write the sCAL chunk */
1861void /* PRIVATE */
1862png_write_sCAL_s(png_structrp png_ptr, int unit, png_const_charp width,
1863    png_const_charp height)
1864{
1865   png_byte buf[64];
1866   png_size_t wlen, hlen, total_len;
1867
1868   png_debug(1, "in png_write_sCAL_s");
1869
1870   wlen = strlen(width);
1871   hlen = strlen(height);
1872   total_len = wlen + hlen + 2;
1873
1874   if (total_len > 64)
1875   {
1876      png_warning(png_ptr, "Can't write sCAL (buffer too small)");
1877      return;
1878   }
1879
1880   buf[0] = (png_byte)unit;
1881   memcpy(buf + 1, width, wlen + 1);      /* Append the '\0' here */
1882   memcpy(buf + wlen + 2, height, hlen);  /* Do NOT append the '\0' here */
1883
1884   png_debug1(3, "sCAL total length = %u", (unsigned int)total_len);
1885   png_write_complete_chunk(png_ptr, png_sCAL, buf, total_len);
1886}
1887#endif
1888
1889#ifdef PNG_WRITE_pHYs_SUPPORTED
1890/* Write the pHYs chunk */
1891void /* PRIVATE */
1892png_write_pHYs(png_structrp png_ptr, png_uint_32 x_pixels_per_unit,
1893    png_uint_32 y_pixels_per_unit,
1894    int unit_type)
1895{
1896   png_byte buf[9];
1897
1898   png_debug(1, "in png_write_pHYs");
1899
1900   if (unit_type >= PNG_RESOLUTION_LAST)
1901      png_warning(png_ptr, "Unrecognized unit type for pHYs chunk");
1902
1903   png_save_uint_32(buf, x_pixels_per_unit);
1904   png_save_uint_32(buf + 4, y_pixels_per_unit);
1905   buf[8] = (png_byte)unit_type;
1906
1907   png_write_complete_chunk(png_ptr, png_pHYs, buf, (png_size_t)9);
1908}
1909#endif
1910
1911#ifdef PNG_WRITE_tIME_SUPPORTED
1912/* Write the tIME chunk.  Use either png_convert_from_struct_tm()
1913 * or png_convert_from_time_t(), or fill in the structure yourself.
1914 */
1915void /* PRIVATE */
1916png_write_tIME(png_structrp png_ptr, png_const_timep mod_time)
1917{
1918   png_byte buf[7];
1919
1920   png_debug(1, "in png_write_tIME");
1921
1922   if (mod_time->month  > 12 || mod_time->month  < 1 ||
1923       mod_time->day    > 31 || mod_time->day    < 1 ||
1924       mod_time->hour   > 23 || mod_time->second > 60)
1925   {
1926      png_warning(png_ptr, "Invalid time specified for tIME chunk");
1927      return;
1928   }
1929
1930   png_save_uint_16(buf, mod_time->year);
1931   buf[2] = mod_time->month;
1932   buf[3] = mod_time->day;
1933   buf[4] = mod_time->hour;
1934   buf[5] = mod_time->minute;
1935   buf[6] = mod_time->second;
1936
1937   png_write_complete_chunk(png_ptr, png_tIME, buf, (png_size_t)7);
1938}
1939#endif
1940
1941/* Initializes the row writing capability of libpng */
1942void /* PRIVATE */
1943png_write_start_row(png_structrp png_ptr)
1944{
1945#ifdef PNG_WRITE_INTERLACING_SUPPORTED
1946   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
1947
1948   /* Start of interlace block */
1949   static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
1950
1951   /* Offset to next interlace block */
1952   static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
1953
1954   /* Start of interlace block in the y direction */
1955   static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
1956
1957   /* Offset to next interlace block in the y direction */
1958   static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
1959#endif
1960
1961   png_alloc_size_t buf_size;
1962   int usr_pixel_depth;
1963
1964   png_debug(1, "in png_write_start_row");
1965
1966   usr_pixel_depth = png_ptr->usr_channels * png_ptr->usr_bit_depth;
1967   buf_size = PNG_ROWBYTES(usr_pixel_depth, png_ptr->width) + 1;
1968
1969   /* 1.5.6: added to allow checking in the row write code. */
1970   png_ptr->transformed_pixel_depth = png_ptr->pixel_depth;
1971   png_ptr->maximum_pixel_depth = (png_byte)usr_pixel_depth;
1972
1973   /* Set up row buffer */
1974   png_ptr->row_buf = (png_bytep)png_malloc(png_ptr, buf_size);
1975
1976   png_ptr->row_buf[0] = PNG_FILTER_VALUE_NONE;
1977
1978#ifdef PNG_WRITE_FILTER_SUPPORTED
1979   /* Set up filtering buffer, if using this filter */
1980   if (png_ptr->do_filter & PNG_FILTER_SUB)
1981   {
1982      png_ptr->sub_row = (png_bytep)png_malloc(png_ptr, png_ptr->rowbytes + 1);
1983
1984      png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB;
1985   }
1986
1987   /* We only need to keep the previous row if we are using one of these. */
1988   if ((png_ptr->do_filter &
1989      (PNG_FILTER_AVG | PNG_FILTER_UP | PNG_FILTER_PAETH)) != 0)
1990   {
1991      /* Set up previous row buffer */
1992      png_ptr->prev_row = (png_bytep)png_calloc(png_ptr, buf_size);
1993
1994      if ((png_ptr->do_filter & PNG_FILTER_UP) != 0)
1995      {
1996         png_ptr->up_row = (png_bytep)png_malloc(png_ptr,
1997            png_ptr->rowbytes + 1);
1998
1999         png_ptr->up_row[0] = PNG_FILTER_VALUE_UP;
2000      }
2001
2002      if ((png_ptr->do_filter & PNG_FILTER_AVG) != 0)
2003      {
2004         png_ptr->avg_row = (png_bytep)png_malloc(png_ptr,
2005             png_ptr->rowbytes + 1);
2006
2007         png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG;
2008      }
2009
2010      if ((png_ptr->do_filter & PNG_FILTER_PAETH) != 0)
2011      {
2012         png_ptr->paeth_row = (png_bytep)png_malloc(png_ptr,
2013             png_ptr->rowbytes + 1);
2014
2015         png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH;
2016      }
2017   }
2018#endif /* WRITE_FILTER */
2019
2020#ifdef PNG_WRITE_INTERLACING_SUPPORTED
2021   /* If interlaced, we need to set up width and height of pass */
2022   if (png_ptr->interlaced != 0)
2023   {
2024      if ((png_ptr->transformations & PNG_INTERLACE) == 0)
2025      {
2026         png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
2027             png_pass_ystart[0]) / png_pass_yinc[0];
2028
2029         png_ptr->usr_width = (png_ptr->width + png_pass_inc[0] - 1 -
2030             png_pass_start[0]) / png_pass_inc[0];
2031      }
2032
2033      else
2034      {
2035         png_ptr->num_rows = png_ptr->height;
2036         png_ptr->usr_width = png_ptr->width;
2037      }
2038   }
2039
2040   else
2041#endif
2042   {
2043      png_ptr->num_rows = png_ptr->height;
2044      png_ptr->usr_width = png_ptr->width;
2045   }
2046}
2047
2048/* Internal use only.  Called when finished processing a row of data. */
2049void /* PRIVATE */
2050png_write_finish_row(png_structrp png_ptr)
2051{
2052#ifdef PNG_WRITE_INTERLACING_SUPPORTED
2053   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
2054
2055   /* Start of interlace block */
2056   static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
2057
2058   /* Offset to next interlace block */
2059   static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
2060
2061   /* Start of interlace block in the y direction */
2062   static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
2063
2064   /* Offset to next interlace block in the y direction */
2065   static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
2066#endif
2067
2068   png_debug(1, "in png_write_finish_row");
2069
2070   /* Next row */
2071   png_ptr->row_number++;
2072
2073   /* See if we are done */
2074   if (png_ptr->row_number < png_ptr->num_rows)
2075      return;
2076
2077#ifdef PNG_WRITE_INTERLACING_SUPPORTED
2078   /* If interlaced, go to next pass */
2079   if (png_ptr->interlaced != 0)
2080   {
2081      png_ptr->row_number = 0;
2082      if ((png_ptr->transformations & PNG_INTERLACE) != 0)
2083      {
2084         png_ptr->pass++;
2085      }
2086
2087      else
2088      {
2089         /* Loop until we find a non-zero width or height pass */
2090         do
2091         {
2092            png_ptr->pass++;
2093
2094            if (png_ptr->pass >= 7)
2095               break;
2096
2097            png_ptr->usr_width = (png_ptr->width +
2098                png_pass_inc[png_ptr->pass] - 1 -
2099                png_pass_start[png_ptr->pass]) /
2100                png_pass_inc[png_ptr->pass];
2101
2102            png_ptr->num_rows = (png_ptr->height +
2103                png_pass_yinc[png_ptr->pass] - 1 -
2104                png_pass_ystart[png_ptr->pass]) /
2105                png_pass_yinc[png_ptr->pass];
2106
2107            if ((png_ptr->transformations & PNG_INTERLACE) != 0)
2108               break;
2109
2110         } while (png_ptr->usr_width == 0 || png_ptr->num_rows == 0);
2111
2112      }
2113
2114      /* Reset the row above the image for the next pass */
2115      if (png_ptr->pass < 7)
2116      {
2117         if (png_ptr->prev_row != NULL)
2118            memset(png_ptr->prev_row, 0,
2119                (png_size_t)(PNG_ROWBYTES(png_ptr->usr_channels*
2120                png_ptr->usr_bit_depth, png_ptr->width)) + 1);
2121
2122         return;
2123      }
2124   }
2125#endif
2126
2127   /* If we get here, we've just written the last row, so we need
2128      to flush the compressor */
2129   png_compress_IDAT(png_ptr, NULL, 0, Z_FINISH);
2130}
2131
2132#ifdef PNG_WRITE_INTERLACING_SUPPORTED
2133/* Pick out the correct pixels for the interlace pass.
2134 * The basic idea here is to go through the row with a source
2135 * pointer and a destination pointer (sp and dp), and copy the
2136 * correct pixels for the pass.  As the row gets compacted,
2137 * sp will always be >= dp, so we should never overwrite anything.
2138 * See the default: case for the easiest code to understand.
2139 */
2140void /* PRIVATE */
2141png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
2142{
2143   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
2144
2145   /* Start of interlace block */
2146   static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
2147
2148   /* Offset to next interlace block */
2149   static PNG_CONST png_byte  png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
2150
2151   png_debug(1, "in png_do_write_interlace");
2152
2153   /* We don't have to do anything on the last pass (6) */
2154   if (pass < 6)
2155   {
2156      /* Each pixel depth is handled separately */
2157      switch (row_info->pixel_depth)
2158      {
2159         case 1:
2160         {
2161            png_bytep sp;
2162            png_bytep dp;
2163            int shift;
2164            int d;
2165            int value;
2166            png_uint_32 i;
2167            png_uint_32 row_width = row_info->width;
2168
2169            dp = row;
2170            d = 0;
2171            shift = 7;
2172
2173            for (i = png_pass_start[pass]; i < row_width;
2174               i += png_pass_inc[pass])
2175            {
2176               sp = row + (png_size_t)(i >> 3);
2177               value = (int)(*sp >> (7 - (int)(i & 0x07))) & 0x01;
2178               d |= (value << shift);
2179
2180               if (shift == 0)
2181               {
2182                  shift = 7;
2183                  *dp++ = (png_byte)d;
2184                  d = 0;
2185               }
2186
2187               else
2188                  shift--;
2189
2190            }
2191            if (shift != 7)
2192               *dp = (png_byte)d;
2193
2194            break;
2195         }
2196
2197         case 2:
2198         {
2199            png_bytep sp;
2200            png_bytep dp;
2201            int shift;
2202            int d;
2203            int value;
2204            png_uint_32 i;
2205            png_uint_32 row_width = row_info->width;
2206
2207            dp = row;
2208            shift = 6;
2209            d = 0;
2210
2211            for (i = png_pass_start[pass]; i < row_width;
2212               i += png_pass_inc[pass])
2213            {
2214               sp = row + (png_size_t)(i >> 2);
2215               value = (*sp >> ((3 - (int)(i & 0x03)) << 1)) & 0x03;
2216               d |= (value << shift);
2217
2218               if (shift == 0)
2219               {
2220                  shift = 6;
2221                  *dp++ = (png_byte)d;
2222                  d = 0;
2223               }
2224
2225               else
2226                  shift -= 2;
2227            }
2228            if (shift != 6)
2229               *dp = (png_byte)d;
2230
2231            break;
2232         }
2233
2234         case 4:
2235         {
2236            png_bytep sp;
2237            png_bytep dp;
2238            int shift;
2239            int d;
2240            int value;
2241            png_uint_32 i;
2242            png_uint_32 row_width = row_info->width;
2243
2244            dp = row;
2245            shift = 4;
2246            d = 0;
2247            for (i = png_pass_start[pass]; i < row_width;
2248                i += png_pass_inc[pass])
2249            {
2250               sp = row + (png_size_t)(i >> 1);
2251               value = (*sp >> ((1 - (int)(i & 0x01)) << 2)) & 0x0f;
2252               d |= (value << shift);
2253
2254               if (shift == 0)
2255               {
2256                  shift = 4;
2257                  *dp++ = (png_byte)d;
2258                  d = 0;
2259               }
2260
2261               else
2262                  shift -= 4;
2263            }
2264            if (shift != 4)
2265               *dp = (png_byte)d;
2266
2267            break;
2268         }
2269
2270         default:
2271         {
2272            png_bytep sp;
2273            png_bytep dp;
2274            png_uint_32 i;
2275            png_uint_32 row_width = row_info->width;
2276            png_size_t pixel_bytes;
2277
2278            /* Start at the beginning */
2279            dp = row;
2280
2281            /* Find out how many bytes each pixel takes up */
2282            pixel_bytes = (row_info->pixel_depth >> 3);
2283
2284            /* Loop through the row, only looking at the pixels that matter */
2285            for (i = png_pass_start[pass]; i < row_width;
2286               i += png_pass_inc[pass])
2287            {
2288               /* Find out where the original pixel is */
2289               sp = row + (png_size_t)i * pixel_bytes;
2290
2291               /* Move the pixel */
2292               if (dp != sp)
2293                  memcpy(dp, sp, pixel_bytes);
2294
2295               /* Next pixel */
2296               dp += pixel_bytes;
2297            }
2298            break;
2299         }
2300      }
2301      /* Set new row width */
2302      row_info->width = (row_info->width +
2303          png_pass_inc[pass] - 1 -
2304          png_pass_start[pass]) /
2305          png_pass_inc[pass];
2306
2307      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
2308          row_info->width);
2309   }
2310}
2311#endif
2312
2313/* This filters the row, chooses which filter to use, if it has not already
2314 * been specified by the application, and then writes the row out with the
2315 * chosen filter.
2316 */
2317static void /* PRIVATE */
2318png_write_filtered_row(png_structrp png_ptr, png_bytep filtered_row,
2319   png_size_t row_bytes);
2320
2321#define PNG_MAXSUM (((png_uint_32)(-1)) >> 1)
2322#define PNG_HISHIFT 10
2323#define PNG_LOMASK ((png_uint_32)0xffffL)
2324#define PNG_HIMASK ((png_uint_32)(~PNG_LOMASK >> PNG_HISHIFT))
2325void /* PRIVATE */
2326png_write_find_filter(png_structrp png_ptr, png_row_infop row_info)
2327{
2328   png_bytep best_row;
2329#ifdef PNG_WRITE_FILTER_SUPPORTED
2330   png_bytep prev_row, row_buf;
2331   png_uint_32 mins, bpp;
2332   png_byte filter_to_do = png_ptr->do_filter;
2333   png_size_t row_bytes = row_info->rowbytes;
2334#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
2335   int num_p_filters = png_ptr->num_prev_filters;
2336#endif
2337
2338   png_debug(1, "in png_write_find_filter");
2339
2340#ifndef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
2341  if (png_ptr->row_number == 0 && filter_to_do == PNG_ALL_FILTERS)
2342  {
2343     /* These will never be selected so we need not test them. */
2344     filter_to_do &= ~(PNG_FILTER_UP | PNG_FILTER_PAETH);
2345  }
2346#endif
2347
2348   /* Find out how many bytes offset each pixel is */
2349   bpp = (row_info->pixel_depth + 7) >> 3;
2350
2351   prev_row = png_ptr->prev_row;
2352#endif
2353   best_row = png_ptr->row_buf;
2354#ifdef PNG_WRITE_FILTER_SUPPORTED
2355   row_buf = best_row;
2356   mins = PNG_MAXSUM;
2357
2358   /* The prediction method we use is to find which method provides the
2359    * smallest value when summing the absolute values of the distances
2360    * from zero, using anything >= 128 as negative numbers.  This is known
2361    * as the "minimum sum of absolute differences" heuristic.  Other
2362    * heuristics are the "weighted minimum sum of absolute differences"
2363    * (experimental and can in theory improve compression), and the "zlib
2364    * predictive" method (not implemented yet), which does test compressions
2365    * of lines using different filter methods, and then chooses the
2366    * (series of) filter(s) that give minimum compressed data size (VERY
2367    * computationally expensive).
2368    *
2369    * GRR 980525:  consider also
2370    *
2371    *   (1) minimum sum of absolute differences from running average (i.e.,
2372    *       keep running sum of non-absolute differences & count of bytes)
2373    *       [track dispersion, too?  restart average if dispersion too large?]
2374    *
2375    *  (1b) minimum sum of absolute differences from sliding average, probably
2376    *       with window size <= deflate window (usually 32K)
2377    *
2378    *   (2) minimum sum of squared differences from zero or running average
2379    *       (i.e., ~ root-mean-square approach)
2380    */
2381
2382
2383   /* We don't need to test the 'no filter' case if this is the only filter
2384    * that has been chosen, as it doesn't actually do anything to the data.
2385    */
2386   if ((filter_to_do & PNG_FILTER_NONE) != 0 && filter_to_do != PNG_FILTER_NONE)
2387   {
2388      png_bytep rp;
2389      png_uint_32 sum = 0;
2390      png_size_t i;
2391      int v;
2392
2393      for (i = 0, rp = row_buf + 1; i < row_bytes; i++, rp++)
2394      {
2395         v = *rp;
2396         sum += (v < 128) ? v : 256 - v;
2397      }
2398
2399#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
2400      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
2401      {
2402         png_uint_32 sumhi, sumlo;
2403         int j;
2404         sumlo = sum & PNG_LOMASK;
2405         sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK; /* Gives us some footroom */
2406
2407         /* Reduce the sum if we match any of the previous rows */
2408         for (j = 0; j < num_p_filters; j++)
2409         {
2410            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_NONE)
2411            {
2412               sumlo = (sumlo * png_ptr->filter_weights[j]) >>
2413                   PNG_WEIGHT_SHIFT;
2414
2415               sumhi = (sumhi * png_ptr->filter_weights[j]) >>
2416                   PNG_WEIGHT_SHIFT;
2417            }
2418         }
2419
2420         /* Factor in the cost of this filter (this is here for completeness,
2421          * but it makes no sense to have a "cost" for the NONE filter, as
2422          * it has the minimum possible computational cost - none).
2423          */
2424         sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_NONE]) >>
2425             PNG_COST_SHIFT;
2426
2427         sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_NONE]) >>
2428             PNG_COST_SHIFT;
2429
2430         if (sumhi > PNG_HIMASK)
2431            sum = PNG_MAXSUM;
2432
2433         else
2434            sum = (sumhi << PNG_HISHIFT) + sumlo;
2435      }
2436#endif
2437      mins = sum;
2438   }
2439
2440   /* Sub filter */
2441   if (filter_to_do == PNG_FILTER_SUB)
2442   /* It's the only filter so no testing is needed */
2443   {
2444      png_bytep rp, lp, dp;
2445      png_size_t i;
2446
2447      for (i = 0, rp = row_buf + 1, dp = png_ptr->sub_row + 1; i < bpp;
2448           i++, rp++, dp++)
2449      {
2450         *dp = *rp;
2451      }
2452
2453      for (lp = row_buf + 1; i < row_bytes;
2454         i++, rp++, lp++, dp++)
2455      {
2456         *dp = (png_byte)((int)*rp - (int)*lp);
2457      }
2458
2459      best_row = png_ptr->sub_row;
2460   }
2461
2462   else if ((filter_to_do & PNG_FILTER_SUB) != 0)
2463   {
2464      png_bytep rp, dp, lp;
2465      png_uint_32 sum = 0, lmins = mins;
2466      png_size_t i;
2467      int v;
2468
2469#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
2470      /* We temporarily increase the "minimum sum" by the factor we
2471       * would reduce the sum of this filter, so that we can do the
2472       * early exit comparison without scaling the sum each time.
2473       */
2474      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
2475      {
2476         int j;
2477         png_uint_32 lmhi, lmlo;
2478         lmlo = lmins & PNG_LOMASK;
2479         lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
2480
2481         for (j = 0; j < num_p_filters; j++)
2482         {
2483            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_SUB)
2484            {
2485               lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
2486                   PNG_WEIGHT_SHIFT;
2487
2488               lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
2489                   PNG_WEIGHT_SHIFT;
2490            }
2491         }
2492
2493         lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
2494             PNG_COST_SHIFT;
2495
2496         lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
2497             PNG_COST_SHIFT;
2498
2499         if (lmhi > PNG_HIMASK)
2500            lmins = PNG_MAXSUM;
2501
2502         else
2503            lmins = (lmhi << PNG_HISHIFT) + lmlo;
2504      }
2505#endif
2506
2507      for (i = 0, rp = row_buf + 1, dp = png_ptr->sub_row + 1; i < bpp;
2508           i++, rp++, dp++)
2509      {
2510         v = *dp = *rp;
2511
2512         sum += (v < 128) ? v : 256 - v;
2513      }
2514
2515      for (lp = row_buf + 1; i < row_bytes;
2516         i++, rp++, lp++, dp++)
2517      {
2518         v = *dp = (png_byte)((int)*rp - (int)*lp);
2519
2520         sum += (v < 128) ? v : 256 - v;
2521
2522         if (sum > lmins)  /* We are already worse, don't continue. */
2523            break;
2524      }
2525
2526#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
2527      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
2528      {
2529         int j;
2530         png_uint_32 sumhi, sumlo;
2531         sumlo = sum & PNG_LOMASK;
2532         sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
2533
2534         for (j = 0; j < num_p_filters; j++)
2535         {
2536            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_SUB)
2537            {
2538               sumlo = (sumlo * png_ptr->inv_filter_weights[j]) >>
2539                   PNG_WEIGHT_SHIFT;
2540
2541               sumhi = (sumhi * png_ptr->inv_filter_weights[j]) >>
2542                   PNG_WEIGHT_SHIFT;
2543            }
2544         }
2545
2546         sumlo = (sumlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
2547             PNG_COST_SHIFT;
2548
2549         sumhi = (sumhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
2550             PNG_COST_SHIFT;
2551
2552         if (sumhi > PNG_HIMASK)
2553            sum = PNG_MAXSUM;
2554
2555         else
2556            sum = (sumhi << PNG_HISHIFT) + sumlo;
2557      }
2558#endif
2559
2560      if (sum < mins)
2561      {
2562         mins = sum;
2563         best_row = png_ptr->sub_row;
2564      }
2565   }
2566
2567   /* Up filter */
2568   if (filter_to_do == PNG_FILTER_UP)
2569   {
2570      png_bytep rp, dp, pp;
2571      png_size_t i;
2572
2573      for (i = 0, rp = row_buf + 1, dp = png_ptr->up_row + 1,
2574          pp = prev_row + 1; i < row_bytes;
2575          i++, rp++, pp++, dp++)
2576      {
2577         *dp = (png_byte)((int)*rp - (int)*pp);
2578      }
2579
2580      best_row = png_ptr->up_row;
2581   }
2582
2583   else if ((filter_to_do & PNG_FILTER_UP) != 0)
2584   {
2585      png_bytep rp, dp, pp;
2586      png_uint_32 sum = 0, lmins = mins;
2587      png_size_t i;
2588      int v;
2589
2590
2591#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
2592      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
2593      {
2594         int j;
2595         png_uint_32 lmhi, lmlo;
2596         lmlo = lmins & PNG_LOMASK;
2597         lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
2598
2599         for (j = 0; j < num_p_filters; j++)
2600         {
2601            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_UP)
2602            {
2603               lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
2604                   PNG_WEIGHT_SHIFT;
2605
2606               lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
2607                   PNG_WEIGHT_SHIFT;
2608            }
2609         }
2610
2611         lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_UP]) >>
2612             PNG_COST_SHIFT;
2613
2614         lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_UP]) >>
2615             PNG_COST_SHIFT;
2616
2617         if (lmhi > PNG_HIMASK)
2618            lmins = PNG_MAXSUM;
2619
2620         else
2621            lmins = (lmhi << PNG_HISHIFT) + lmlo;
2622      }
2623#endif
2624
2625      for (i = 0, rp = row_buf + 1, dp = png_ptr->up_row + 1,
2626          pp = prev_row + 1; i < row_bytes; i++)
2627      {
2628         v = *dp++ = (png_byte)((int)*rp++ - (int)*pp++);
2629
2630         sum += (v < 128) ? v : 256 - v;
2631
2632         if (sum > lmins)  /* We are already worse, don't continue. */
2633            break;
2634      }
2635
2636#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
2637      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
2638      {
2639         int j;
2640         png_uint_32 sumhi, sumlo;
2641         sumlo = sum & PNG_LOMASK;
2642         sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
2643
2644         for (j = 0; j < num_p_filters; j++)
2645         {
2646            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_UP)
2647            {
2648               sumlo = (sumlo * png_ptr->filter_weights[j]) >>
2649                   PNG_WEIGHT_SHIFT;
2650
2651               sumhi = (sumhi * png_ptr->filter_weights[j]) >>
2652                   PNG_WEIGHT_SHIFT;
2653            }
2654         }
2655
2656         sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_UP]) >>
2657             PNG_COST_SHIFT;
2658
2659         sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_UP]) >>
2660             PNG_COST_SHIFT;
2661
2662         if (sumhi > PNG_HIMASK)
2663            sum = PNG_MAXSUM;
2664
2665         else
2666            sum = (sumhi << PNG_HISHIFT) + sumlo;
2667      }
2668#endif
2669
2670      if (sum < mins)
2671      {
2672         mins = sum;
2673         best_row = png_ptr->up_row;
2674      }
2675   }
2676
2677   /* Avg filter */
2678   if (filter_to_do == PNG_FILTER_AVG)
2679   {
2680      png_bytep rp, dp, pp, lp;
2681      png_uint_32 i;
2682
2683      for (i = 0, rp = row_buf + 1, dp = png_ptr->avg_row + 1,
2684           pp = prev_row + 1; i < bpp; i++)
2685      {
2686         *dp++ = (png_byte)((int)*rp++ - ((int)*pp++ / 2));
2687      }
2688
2689      for (lp = row_buf + 1; i < row_bytes; i++)
2690      {
2691         *dp++ =
2692             (png_byte)((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2));
2693      }
2694      best_row = png_ptr->avg_row;
2695   }
2696
2697   else if ((filter_to_do & PNG_FILTER_AVG) != 0)
2698   {
2699      png_bytep rp, dp, pp, lp;
2700      png_uint_32 sum = 0, lmins = mins;
2701      png_size_t i;
2702      int v;
2703
2704#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
2705      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
2706      {
2707         int j;
2708         png_uint_32 lmhi, lmlo;
2709         lmlo = lmins & PNG_LOMASK;
2710         lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
2711
2712         for (j = 0; j < num_p_filters; j++)
2713         {
2714            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_AVG)
2715            {
2716               lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
2717                   PNG_WEIGHT_SHIFT;
2718
2719               lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
2720                   PNG_WEIGHT_SHIFT;
2721            }
2722         }
2723
2724         lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_AVG]) >>
2725             PNG_COST_SHIFT;
2726
2727         lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_AVG]) >>
2728             PNG_COST_SHIFT;
2729
2730         if (lmhi > PNG_HIMASK)
2731            lmins = PNG_MAXSUM;
2732
2733         else
2734            lmins = (lmhi << PNG_HISHIFT) + lmlo;
2735      }
2736#endif
2737
2738      for (i = 0, rp = row_buf + 1, dp = png_ptr->avg_row + 1,
2739           pp = prev_row + 1; i < bpp; i++)
2740      {
2741         v = *dp++ = (png_byte)((int)*rp++ - ((int)*pp++ / 2));
2742
2743         sum += (v < 128) ? v : 256 - v;
2744      }
2745
2746      for (lp = row_buf + 1; i < row_bytes; i++)
2747      {
2748         v = *dp++ =
2749             (png_byte)(((int)*rp++ - ((int)*pp++ + (int)*lp++) / 2));
2750
2751         sum += (v < 128) ? v : 256 - v;
2752
2753         if (sum > lmins)  /* We are already worse, don't continue. */
2754            break;
2755      }
2756
2757#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
2758      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
2759      {
2760         int j;
2761         png_uint_32 sumhi, sumlo;
2762         sumlo = sum & PNG_LOMASK;
2763         sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
2764
2765         for (j = 0; j < num_p_filters; j++)
2766         {
2767            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_NONE)
2768            {
2769               sumlo = (sumlo * png_ptr->filter_weights[j]) >>
2770                   PNG_WEIGHT_SHIFT;
2771
2772               sumhi = (sumhi * png_ptr->filter_weights[j]) >>
2773                   PNG_WEIGHT_SHIFT;
2774            }
2775         }
2776
2777         sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_AVG]) >>
2778             PNG_COST_SHIFT;
2779
2780         sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_AVG]) >>
2781             PNG_COST_SHIFT;
2782
2783         if (sumhi > PNG_HIMASK)
2784            sum = PNG_MAXSUM;
2785
2786         else
2787            sum = (sumhi << PNG_HISHIFT) + sumlo;
2788      }
2789#endif
2790
2791      if (sum < mins)
2792      {
2793         mins = sum;
2794         best_row = png_ptr->avg_row;
2795      }
2796   }
2797
2798   /* Paeth filter */
2799   if ((filter_to_do == PNG_FILTER_PAETH) != 0)
2800   {
2801      png_bytep rp, dp, pp, cp, lp;
2802      png_size_t i;
2803
2804      for (i = 0, rp = row_buf + 1, dp = png_ptr->paeth_row + 1,
2805          pp = prev_row + 1; i < bpp; i++)
2806      {
2807         *dp++ = (png_byte)((int)*rp++ - (int)*pp++);
2808      }
2809
2810      for (lp = row_buf + 1, cp = prev_row + 1; i < row_bytes; i++)
2811      {
2812         int a, b, c, pa, pb, pc, p;
2813
2814         b = *pp++;
2815         c = *cp++;
2816         a = *lp++;
2817
2818         p = b - c;
2819         pc = a - c;
2820
2821#ifdef PNG_USE_ABS
2822         pa = abs(p);
2823         pb = abs(pc);
2824         pc = abs(p + pc);
2825#else
2826         pa = p < 0 ? -p : p;
2827         pb = pc < 0 ? -pc : pc;
2828         pc = (p + pc) < 0 ? -(p + pc) : p + pc;
2829#endif
2830
2831         p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
2832
2833         *dp++ = (png_byte)((int)*rp++ - p);
2834      }
2835      best_row = png_ptr->paeth_row;
2836   }
2837
2838   else if ((filter_to_do & PNG_FILTER_PAETH) != 0)
2839   {
2840      png_bytep rp, dp, pp, cp, lp;
2841      png_uint_32 sum = 0, lmins = mins;
2842      png_size_t i;
2843      int v;
2844
2845#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
2846      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
2847      {
2848         int j;
2849         png_uint_32 lmhi, lmlo;
2850         lmlo = lmins & PNG_LOMASK;
2851         lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
2852
2853         for (j = 0; j < num_p_filters; j++)
2854         {
2855            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_PAETH)
2856            {
2857               lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
2858                   PNG_WEIGHT_SHIFT;
2859
2860               lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
2861                   PNG_WEIGHT_SHIFT;
2862            }
2863         }
2864
2865         lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_PAETH]) >>
2866             PNG_COST_SHIFT;
2867
2868         lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_PAETH]) >>
2869             PNG_COST_SHIFT;
2870
2871         if (lmhi > PNG_HIMASK)
2872            lmins = PNG_MAXSUM;
2873
2874         else
2875            lmins = (lmhi << PNG_HISHIFT) + lmlo;
2876      }
2877#endif
2878
2879      for (i = 0, rp = row_buf + 1, dp = png_ptr->paeth_row + 1,
2880          pp = prev_row + 1; i < bpp; i++)
2881      {
2882         v = *dp++ = (png_byte)((int)*rp++ - (int)*pp++);
2883
2884         sum += (v < 128) ? v : 256 - v;
2885      }
2886
2887      for (lp = row_buf + 1, cp = prev_row + 1; i < row_bytes; i++)
2888      {
2889         int a, b, c, pa, pb, pc, p;
2890
2891         b = *pp++;
2892         c = *cp++;
2893         a = *lp++;
2894
2895#ifndef PNG_SLOW_PAETH
2896         p = b - c;
2897         pc = a - c;
2898#ifdef PNG_USE_ABS
2899         pa = abs(p);
2900         pb = abs(pc);
2901         pc = abs(p + pc);
2902#else
2903         pa = p < 0 ? -p : p;
2904         pb = pc < 0 ? -pc : pc;
2905         pc = (p + pc) < 0 ? -(p + pc) : p + pc;
2906#endif
2907         p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
2908#else /* SLOW_PAETH */
2909         p = a + b - c;
2910         pa = abs(p - a);
2911         pb = abs(p - b);
2912         pc = abs(p - c);
2913
2914         if (pa <= pb && pa <= pc)
2915            p = a;
2916
2917         else if (pb <= pc)
2918            p = b;
2919
2920         else
2921            p = c;
2922#endif /* SLOW_PAETH */
2923
2924         v = *dp++ = (png_byte)((int)*rp++ - p);
2925
2926         sum += (v < 128) ? v : 256 - v;
2927
2928         if (sum > lmins)  /* We are already worse, don't continue. */
2929            break;
2930      }
2931
2932#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
2933      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
2934      {
2935         int j;
2936         png_uint_32 sumhi, sumlo;
2937         sumlo = sum & PNG_LOMASK;
2938         sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
2939
2940         for (j = 0; j < num_p_filters; j++)
2941         {
2942            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_PAETH)
2943            {
2944               sumlo = (sumlo * png_ptr->filter_weights[j]) >>
2945                   PNG_WEIGHT_SHIFT;
2946
2947               sumhi = (sumhi * png_ptr->filter_weights[j]) >>
2948                   PNG_WEIGHT_SHIFT;
2949            }
2950         }
2951
2952         sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_PAETH]) >>
2953             PNG_COST_SHIFT;
2954
2955         sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_PAETH]) >>
2956             PNG_COST_SHIFT;
2957
2958         if (sumhi > PNG_HIMASK)
2959            sum = PNG_MAXSUM;
2960
2961         else
2962            sum = (sumhi << PNG_HISHIFT) + sumlo;
2963      }
2964#endif
2965
2966      if (sum < mins)
2967      {
2968         best_row = png_ptr->paeth_row;
2969      }
2970   }
2971#endif /* WRITE_FILTER */
2972
2973   /* Do the actual writing of the filtered row data from the chosen filter. */
2974   png_write_filtered_row(png_ptr, best_row, row_info->rowbytes+1);
2975
2976#ifdef PNG_WRITE_FILTER_SUPPORTED
2977#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
2978   /* Save the type of filter we picked this time for future calculations */
2979   if (png_ptr->num_prev_filters > 0)
2980   {
2981      int j;
2982
2983      for (j = 1; j < num_p_filters; j++)
2984      {
2985         png_ptr->prev_filters[j] = png_ptr->prev_filters[j - 1];
2986      }
2987
2988      png_ptr->prev_filters[j] = best_row[0];
2989   }
2990#endif
2991#endif /* WRITE_FILTER */
2992}
2993
2994
2995/* Do the actual writing of a previously filtered row. */
2996static void
2997png_write_filtered_row(png_structrp png_ptr, png_bytep filtered_row,
2998   png_size_t full_row_length/*includes filter byte*/)
2999{
3000   png_debug(1, "in png_write_filtered_row");
3001
3002   png_debug1(2, "filter = %d", filtered_row[0]);
3003
3004   png_compress_IDAT(png_ptr, filtered_row, full_row_length, Z_NO_FLUSH);
3005
3006#ifdef PNG_WRITE_FILTER_SUPPORTED
3007   /* Swap the current and previous rows */
3008   if (png_ptr->prev_row != NULL)
3009   {
3010      png_bytep tptr;
3011
3012      tptr = png_ptr->prev_row;
3013      png_ptr->prev_row = png_ptr->row_buf;
3014      png_ptr->row_buf = tptr;
3015   }
3016#endif /* WRITE_FILTER */
3017
3018   /* Finish row - updates counters and flushes zlib if last row */
3019   png_write_finish_row(png_ptr);
3020
3021#ifdef PNG_WRITE_FLUSH_SUPPORTED
3022   png_ptr->flush_rows++;
3023
3024   if (png_ptr->flush_dist > 0 &&
3025       png_ptr->flush_rows >= png_ptr->flush_dist)
3026   {
3027      png_write_flush(png_ptr);
3028   }
3029#endif /* WRITE_FLUSH */
3030}
3031#endif /* WRITE */