Ticket #2877: libpng-1.2.38-apng-1.patch

File libpng-1.2.38-apng-1.patch, 54.8 KB (added by Guy Dalziel, 16 years ago)
  • TabularUnified libpng-1.2.

    Submitted By: Ken Moffat <ken at linuxfromscratch dot org>
    Date: 2008-11-08
    Initial Package Version: 1.2.10
    Upstream Status: Rejected
    Origin: Andrew Smith, updated for 1.2.31 by Jens Ornot, taken from cblfs.
            Updated for 1.2.34.  Taken from http://hp.vector.co.jp/authors/VA013651/freeSoftware/apng.html
            Rediffed for 1.2.35 by Randy McMurchy.
    	Reapplied against 1.2.38 by Guy Dalziel	
    Description: APNG is an extension of the [PNG][pngspec] format, adding support for animated images.
                 It is intended to be a replacement for simple animated images
                 that have traditionally used the [GIF][gifspec] format,
                 while adding support for 24-bit images and 8-bit transparency.
                 APNG is a simpler alternative to MNG,
                 providing a spec suitable for the most common usage of animated images on the Internet.
    
                 APNG is backwards-compatible with PNG;
                 any PNG decoder should be able to ignore the APNG-specific chunks and display a single image.
    
    diff -Naur libpng-1.2.38-orig/png.c libpng-1.2.38/png.c
    old new  
    5454PNG_tIME;
    5555PNG_tRNS;
    5656PNG_zTXt;
     57PNG_acTL;
     58PNG_fcTL;
     59PNG_fdAT;
    5760
    5861#ifdef PNG_READ_SUPPORTED
    5962/* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
  • TabularUnified libpng-1.2.

    diff -Naur libpng-1.2.38-orig/png.h libpng-1.2.38/png.h
    old new  
    10161016   png_fixed_point int_y_blue;
    10171017#endif
    10181018
     1019#if defined(PNG_APNG_SUPPORTED)
     1020   png_uint_32 num_frames; /* including default image */
     1021   png_uint_32 num_plays;
     1022   png_uint_32 next_frame_width;
     1023   png_uint_32 next_frame_height;
     1024   png_uint_32 next_frame_x_offset;
     1025   png_uint_32 next_frame_y_offset;
     1026   png_uint_16 next_frame_delay_num;
     1027   png_uint_16 next_frame_delay_den;
     1028   png_byte next_frame_dispose_op;
     1029   png_byte next_frame_blend_op;
     1030#endif
     1031
    10191032} png_info;
    10201033
    10211034typedef png_info FAR * png_infop;
     
    11171130#define PNG_INFO_sPLT 0x2000   /* ESR, 1.0.6 */
    11181131#define PNG_INFO_sCAL 0x4000   /* ESR, 1.0.6 */
    11191132#define PNG_INFO_IDAT 0x8000L  /* ESR, 1.0.6 */
     1133#define PNG_INFO_acTL 0x10000L
     1134#define PNG_INFO_fcTL 0x20000L
    11201135
    11211136/* This is used for the transformation routines, as some of them
    11221137 * change these values for the row.  It also should enable using
     
    11571172typedef void (PNGAPI *png_progressive_end_ptr) PNGARG((png_structp, png_infop));
    11581173typedef void (PNGAPI *png_progressive_row_ptr) PNGARG((png_structp, png_bytep,
    11591174   png_uint_32, int));
     1175#if defined(PNG_APNG_SUPPORTED)
     1176typedef void (PNGAPI *png_progressive_frame_ptr) PNGARG((png_structp,
     1177   png_uint_32));
     1178#endif
    11601179#endif
    11611180
    11621181#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
     
    14911510   png_uint_32 user_height_max;
    14921511#endif
    14931512
     1513#if defined(PNG_APNG_SUPPORTED)
     1514   png_uint_32 apng_flags;
     1515   png_uint_32 next_seq_num;         /* next fcTL/fdAT chunk sequence number */
     1516   png_uint_32 first_frame_width;
     1517   png_uint_32 first_frame_height;
     1518
     1519#if defined(PNG_READ_APNG_SUPPORTED)
     1520   png_uint_32 num_frames_read;      /* incremented after all image data of */
     1521                                     /* a frame is read */
     1522#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
     1523   png_progressive_frame_ptr frame_info_fn; /* frame info read callback */
     1524   png_progressive_frame_ptr frame_end_fn;  /* frame data read callback */
     1525#endif
     1526#endif
     1527
     1528#if defined(PNG_WRITE_APNG_SUPPORTED)
     1529   png_uint_32 num_frames_to_write;
     1530   png_uint_32 num_frames_written;
     1531#endif
     1532#endif
     1533
     1534/* For png_struct.apng_flags: */
     1535#define PNG_FIRST_FRAME_HIDDEN       0x0001
     1536
     1537/* dispose_op flags from inside fcTL */
     1538#define PNG_DISPOSE_OP_NONE        0x00
     1539#define PNG_DISPOSE_OP_BACKGROUND  0x01
     1540#define PNG_DISPOSE_OP_PREVIOUS    0x02
     1541
     1542/* blend_op flags from inside fcTL */
     1543#define PNG_BLEND_OP_SOURCE        0x00
     1544#define PNG_BLEND_OP_OVER          0x01
     1545
    14941546/* New member added in libpng-1.0.25 and 1.2.17 */
    14951547#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
    14961548   /* Storage for unknown chunk that the library doesn't recognize. */
     
    18241876extern PNG_EXPORT(void,png_write_image) PNGARG((png_structp png_ptr,
    18251877   png_bytepp image));
    18261878
     1879#if defined(PNG_WRITE_APNG_SUPPORTED)
     1880extern PNG_EXPORT (void,png_write_frame_head) PNGARG((png_structp png_ptr,
     1881   png_infop png_info, png_bytepp row_pointers,
     1882   png_uint_32 width, png_uint_32 height,
     1883   png_uint_32 x_offset, png_uint_32 y_offset,
     1884   png_uint_16 delay_num, png_uint_16 delay_den, png_byte dispose_op,
     1885   png_byte blend_op));
     1886
     1887extern PNG_EXPORT (void,png_write_frame_tail) PNGARG((png_structp png_ptr,
     1888   png_infop png_info));
     1889#endif
     1890
    18271891/* Writes the end of the PNG file. */
    18281892extern PNG_EXPORT(void,png_write_end) PNGARG((png_structp png_ptr,
    18291893   png_infop info_ptr));
     
    20772141   png_voidp progressive_ptr,
    20782142   png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn,
    20792143   png_progressive_end_ptr end_fn));
     2144#if defined(PNG_READ_APNG_SUPPORTED)
     2145extern PNG_EXPORT(void,png_set_progressive_frame_fn) PNGARG((png_structp png_ptr,
     2146   png_progressive_frame_ptr frame_info_fn,
     2147   png_progressive_frame_ptr frame_end_fn));
     2148#endif
    20802149
    20812150/* Returns the user pointer associated with the push read functions */
    20822151extern PNG_EXPORT(png_voidp,png_get_progressive_ptr)
     
    25172586#endif
    25182587#endif /* PNG_sCAL_SUPPORTED || PNG_WRITE_sCAL_SUPPORTED */
    25192588
     2589#if defined(PNG_APNG_SUPPORTED)
     2590extern PNG_EXPORT(png_uint_32,png_get_acTL) PNGARG((png_structp png_ptr,
     2591   png_infop info_ptr, png_uint_32 *num_frames, png_uint_32 *num_plays));
     2592extern PNG_EXPORT(png_uint_32,png_set_acTL) PNGARG((png_structp png_ptr,
     2593   png_infop info_ptr, png_uint_32 num_frames, png_uint_32 num_plays));
     2594extern PNG_EXPORT(png_uint_32,png_get_num_frames) PNGARG((png_structp png_ptr,
     2595   png_infop info_ptr));
     2596extern PNG_EXPORT(png_uint_32,png_get_num_plays)
     2597   PNGARG((png_structp png_ptr, png_infop info_ptr));
     2598
     2599extern PNG_EXPORT(png_uint_32,png_get_next_frame_fcTL)
     2600   PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 *width,
     2601   png_uint_32 *height, png_uint_32 *x_offset, png_uint_32 *y_offset,
     2602   png_uint_16 *delay_num, png_uint_16 *delay_den, png_byte *dispose_op,
     2603   png_byte *blend_op));
     2604extern PNG_EXPORT(png_uint_32,png_set_next_frame_fcTL)
     2605   PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 width,
     2606   png_uint_32 height, png_uint_32 x_offset, png_uint_32 y_offset,
     2607   png_uint_16 delay_num, png_uint_16 delay_den, png_byte dispose_op,
     2608   png_byte blend_op));
     2609extern PNG_EXPORT(void,png_ensure_fcTL_is_valid)
     2610   PNGARG((png_structp png_ptr,
     2611   png_uint_32 width, png_uint_32 height,
     2612   png_uint_32 x_offset, png_uint_32 y_offset,
     2613   png_uint_16 delay_num, png_uint_16 delay_den,
     2614   png_byte dispose_op, png_byte blend_op));
     2615extern PNG_EXPORT(png_uint_32,png_get_next_frame_width)
     2616   PNGARG((png_structp png_ptr, png_infop info_ptr));
     2617extern PNG_EXPORT(png_uint_32,png_get_next_frame_height)
     2618   PNGARG((png_structp png_ptr, png_infop info_ptr));
     2619extern PNG_EXPORT(png_uint_32,png_get_next_frame_x_offset)
     2620   PNGARG((png_structp png_ptr, png_infop info_ptr));
     2621extern PNG_EXPORT(png_uint_32,png_get_next_frame_y_offset)
     2622   PNGARG((png_structp png_ptr, png_infop info_ptr));
     2623extern PNG_EXPORT(png_uint_16,png_get_next_frame_delay_num)
     2624   PNGARG((png_structp png_ptr, png_infop info_ptr));
     2625extern PNG_EXPORT(png_uint_16,png_get_next_frame_delay_den)
     2626   PNGARG((png_structp png_ptr, png_infop info_ptr));
     2627extern PNG_EXPORT(png_byte,png_get_next_frame_dispose_op)
     2628   PNGARG((png_structp png_ptr, png_infop info_ptr));
     2629extern PNG_EXPORT(png_byte,png_get_next_frame_blend_op)
     2630   PNGARG((png_structp png_ptr, png_infop info_ptr));
     2631extern PNG_EXPORT(png_byte,png_get_first_frame_is_hidden)
     2632   PNGARG((png_structp png_ptr, png_infop info_ptr));
     2633extern PNG_EXPORT(png_uint_32,png_set_first_frame_is_hidden)
     2634   PNGARG((png_structp png_ptr, png_infop info_ptr, png_byte is_hidden));
     2635#endif /* PNG_APNG_SUPPORTED */
     2636
     2637#if defined(PNG_READ_APNG_SUPPORTED)
     2638extern PNG_EXPORT(void,png_read_frame_head) PNGARG((png_structp png_ptr,
     2639   png_infop info_ptr));
     2640#endif
     2641
    25202642#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
    25212643/* Provide a list of chunks and how they are to be handled, if the built-in
    25222644   handling or default unknown chunk handling is not desired.  Any chunks not
     
    28833005#define PNG_BACKGROUND_IS_GRAY     0x800
    28843006#define PNG_HAVE_PNG_SIGNATURE    0x1000
    28853007#define PNG_HAVE_CHUNK_AFTER_IDAT 0x2000 /* Have another chunk after IDAT */
     3008#define PNG_HAVE_acTL             0x4000
     3009#define PNG_HAVE_fcTL             0x8000L
    28863010
    28873011/* Flags for the transformations the PNG library does on the image data */
    28883012#define PNG_BGR                0x0001
     
    30243148#define PNG_tIME png_byte png_tIME[5] = {116,  73,  77,  69, '\0'}
    30253149#define PNG_tRNS png_byte png_tRNS[5] = {116,  82,  78,  83, '\0'}
    30263150#define PNG_zTXt png_byte png_zTXt[5] = {122,  84,  88, 116, '\0'}
     3151#define PNG_acTL png_byte png_acTL[5] = { 97,  99,  84,  76, '\0'}
     3152#define PNG_fcTL png_byte png_fcTL[5] = {102,  99,  84,  76, '\0'}
     3153#define PNG_fdAT png_byte png_fdAT[5] = {102, 100,  65,  84, '\0'}
    30273154
    30283155#ifdef PNG_USE_GLOBAL_ARRAYS
    30293156PNG_EXPORT_VAR (png_byte FARDATA) png_IHDR[5];
     
    30473174PNG_EXPORT_VAR (png_byte FARDATA) png_tIME[5];
    30483175PNG_EXPORT_VAR (png_byte FARDATA) png_tRNS[5];
    30493176PNG_EXPORT_VAR (png_byte FARDATA) png_zTXt[5];
     3177PNG_EXPORT_VAR (png_byte FARDATA) png_acTL[5];
     3178PNG_EXPORT_VAR (png_byte FARDATA) png_fcTL[5];
     3179PNG_EXPORT_VAR (png_byte FARDATA) png_fdAT[5];
    30503180#endif /* PNG_USE_GLOBAL_ARRAYS */
    30513181
    30523182#if defined(PNG_1_0_X) || defined (PNG_1_2_X)
     
    33223452#endif
    33233453#endif
    33243454
     3455#if defined(PNG_WRITE_APNG_SUPPORTED)
     3456PNG_EXTERN void png_write_acTL PNGARG((png_structp png_ptr,
     3457   png_uint_32 num_frames, png_uint_32 num_plays));
     3458
     3459PNG_EXTERN void png_write_fcTL PNGARG((png_structp png_ptr,
     3460   png_uint_32 width, png_uint_32 height,
     3461   png_uint_32 x_offset, png_uint_32 y_offset,
     3462   png_uint_16 delay_num, png_uint_16 delay_den,
     3463   png_byte dispose_op, png_byte blend_op));
     3464#endif
     3465
    33253466/* Called when finished processing a row of data */
    33263467PNG_EXTERN void png_write_finish_row PNGARG((png_structp png_ptr));
    33273468
     
    33733514PNG_EXTERN void png_read_transform_info PNGARG((png_structp png_ptr,
    33743515   png_infop info_ptr));
    33753516
     3517#if defined(PNG_READ_APNG_SUPPORTED)
     3518/* private, reset some things to become ready for reading next frame */
     3519PNG_EXTERN void png_read_reset PNGARG((png_structp png_ptr));
     3520PNG_EXTERN void png_read_reinit PNGARG((png_structp png_ptr,
     3521   png_infop info_ptr));
     3522PNG_EXTERN void png_progressive_read_reset PNGARG((png_structp png_ptr));
     3523#endif
     3524#if defined(PNG_WRITE_APNG_SUPPORTED)
     3525/* private, reset some things to become ready for writing next frame */
     3526PNG_EXTERN void png_write_reset PNGARG((png_structp png_ptr));
     3527PNG_EXTERN void png_write_reinit PNGARG((png_structp png_ptr,
     3528   png_infop info_ptr, png_uint_32 width, png_uint_32 height));
     3529#endif
     3530
    33763531/* These are the functions that do the transformations */
    33773532#if defined(PNG_READ_FILLER_SUPPORTED)
    33783533PNG_EXTERN void png_do_read_filler PNGARG((png_row_infop row_info,
     
    35883743   png_uint_32 length));
    35893744#endif
    35903745
     3746#if defined(PNG_READ_APNG_SUPPORTED)
     3747PNG_EXTERN void png_handle_acTL PNGARG((png_structp png_ptr, png_infop info_ptr,
     3748   png_uint_32 length));
     3749PNG_EXTERN void png_handle_fcTL PNGARG((png_structp png_ptr, png_infop info_ptr,
     3750   png_uint_32 length));
     3751PNG_EXTERN void png_have_info PNGARG((png_structp png_ptr, png_infop info_ptr));
     3752PNG_EXTERN void png_handle_fdAT PNGARG((png_structp png_ptr, png_infop info_ptr,
     3753   png_uint_32 length));
     3754PNG_EXTERN void png_ensure_sequence_number PNGARG((png_structp png_ptr,
     3755   png_uint_32 length));
     3756#endif
     3757
    35913758PNG_EXTERN void png_handle_unknown PNGARG((png_structp png_ptr,
    35923759   png_infop info_ptr, png_uint_32 length));
    35933760
  • TabularUnified libpng-1.2.

    diff -Naur libpng-1.2.38-orig/pngconf.h libpng-1.2.38/pngconf.h
    old new  
    944944#  define PNG_READ_zTXt_SUPPORTED
    945945#  define PNG_zTXt_SUPPORTED
    946946#endif
     947#ifndef PNG_NO_READ_APNG
     948#  define PNG_READ_APNG_SUPPORTED
     949#  define PNG_APNG_SUPPORTED
     950#endif
    947951#ifndef PNG_NO_READ_OPT_PLTE
    948952#  define PNG_READ_OPT_PLTE_SUPPORTED /* only affects support of the */
    949953#endif                      /* optional PLTE chunk in RGB and RGBA images */
     
    10911095#    define PNG_zTXt_SUPPORTED
    10921096#  endif
    10931097#endif
     1098#ifndef PNG_NO_WRITE_APNG
     1099#  define PNG_WRITE_APNG_SUPPORTED
     1100#  ifndef PNG_APNG_SUPPORTED
     1101#    define PNG_APNG_SUPPORTED
     1102#  endif
     1103#endif
    10941104#if defined(PNG_WRITE_iTXt_SUPPORTED) || defined(PNG_WRITE_tEXt_SUPPORTED) || \
    10951105    defined(PNG_WRITE_zTXt_SUPPORTED)
    10961106#  define PNG_WRITE_TEXT_SUPPORTED
  • TabularUnified libpng-1.2.

    diff -Naur libpng-1.2.38-orig/pngget.c libpng-1.2.38/pngget.c
    old new  
    839839}
    840840#endif
    841841
     842#if defined(PNG_APNG_SUPPORTED)
     843png_uint_32 PNGAPI
     844png_get_acTL(png_structp png_ptr, png_infop info_ptr,
     845             png_uint_32 *num_frames, png_uint_32 *num_plays)
     846{
     847    png_debug1(1, "in %s retrieval function\n", "acTL");
     848
     849    if (png_ptr != NULL && info_ptr != NULL &&
     850        (info_ptr->valid & PNG_INFO_acTL) &&
     851        num_frames != NULL && num_plays != NULL)
     852    {
     853        *num_frames = info_ptr->num_frames;
     854        *num_plays = info_ptr->num_plays;
     855        return (1);
     856    }
     857
     858    return (0);
     859}
     860
     861png_uint_32 PNGAPI
     862png_get_num_frames(png_structp png_ptr, png_infop info_ptr)
     863{
     864    png_debug(1, "in png_get_num_frames()\n");
     865
     866    if (png_ptr != NULL && info_ptr != NULL)
     867        return (info_ptr->num_frames);
     868    return (0);
     869}
     870
     871png_uint_32 PNGAPI
     872png_get_num_plays(png_structp png_ptr, png_infop info_ptr)
     873{
     874    png_debug(1, "in png_get_num_plays()\n");
     875
     876    if (png_ptr != NULL && info_ptr != NULL)
     877        return (info_ptr->num_plays);
     878    return (0);
     879}
     880png_uint_32 PNGAPI
     881png_get_next_frame_fcTL(png_structp png_ptr, png_infop info_ptr,
     882             png_uint_32 *width, png_uint_32 *height,
     883             png_uint_32 *x_offset, png_uint_32 *y_offset,
     884             png_uint_16 *delay_num, png_uint_16 *delay_den,
     885             png_byte *dispose_op, png_byte *blend_op)
     886{
     887    png_debug1(1, "in %s retrieval function\n", "fcTL");
     888
     889    if (png_ptr != NULL && info_ptr != NULL &&
     890        (info_ptr->valid & PNG_INFO_fcTL) &&
     891        width != NULL && height != NULL &&
     892        x_offset != NULL && x_offset != NULL &&
     893        delay_num != NULL && delay_den != NULL &&
     894       dispose_op != NULL && blend_op != NULL)
     895    {
     896        *width = info_ptr->next_frame_width;
     897        *height = info_ptr->next_frame_height;
     898        *x_offset = info_ptr->next_frame_x_offset;
     899        *y_offset = info_ptr->next_frame_y_offset;
     900        *delay_num = info_ptr->next_frame_delay_num;
     901        *delay_den = info_ptr->next_frame_delay_den;
     902        *dispose_op = info_ptr->next_frame_dispose_op;
     903        *blend_op = info_ptr->next_frame_blend_op;
     904        return (1);
     905    }
     906
     907    return (0);
     908}
     909
     910png_uint_32 PNGAPI
     911png_get_next_frame_width(png_structp png_ptr, png_infop info_ptr)
     912{
     913    png_debug(1, "in png_get_next_frame_width()\n");
     914
     915    if (png_ptr != NULL && info_ptr != NULL)
     916        return (info_ptr->next_frame_width);
     917    return (0);
     918}
     919
     920png_uint_32 PNGAPI
     921png_get_next_frame_height(png_structp png_ptr, png_infop info_ptr)
     922{
     923    png_debug(1, "in png_get_next_frame_height()\n");
     924
     925    if (png_ptr != NULL && info_ptr != NULL)
     926        return (info_ptr->next_frame_height);
     927    return (0);
     928}
     929
     930png_uint_32 PNGAPI
     931png_get_next_frame_x_offset(png_structp png_ptr, png_infop info_ptr)
     932{
     933    png_debug(1, "in png_get_next_frame_x_offset()\n");
     934
     935    if (png_ptr != NULL && info_ptr != NULL)
     936        return (info_ptr->next_frame_x_offset);
     937    return (0);
     938}
     939png_uint_32 PNGAPI
     940png_get_next_frame_y_offset(png_structp png_ptr, png_infop info_ptr)
     941{
     942    png_debug(1, "in png_get_next_frame_y_offset()\n");
     943
     944    if (png_ptr != NULL && info_ptr != NULL)
     945        return (info_ptr->next_frame_y_offset);
     946    return (0);
     947}
     948
     949png_uint_16 PNGAPI
     950png_get_next_frame_delay_num(png_structp png_ptr, png_infop info_ptr)
     951{
     952    png_debug(1, "in png_get_next_frame_delay_num()\n");
     953
     954    if (png_ptr != NULL && info_ptr != NULL)
     955        return (info_ptr->next_frame_delay_num);
     956    return (0);
     957}
     958
     959png_uint_16 PNGAPI
     960png_get_next_frame_delay_den(png_structp png_ptr, png_infop info_ptr)
     961{
     962    png_debug(1, "in png_get_next_frame_delay_den()\n");
     963
     964    if (png_ptr != NULL && info_ptr != NULL)
     965        return (info_ptr->next_frame_delay_den);
     966    return (0);
     967}
     968
     969png_byte PNGAPI
     970png_get_next_frame_dispose_op(png_structp png_ptr, png_infop info_ptr)
     971{
     972    png_debug(1, "in png_get_next_frame_dispose_op()\n");
     973
     974    if (png_ptr != NULL && info_ptr != NULL)
     975        return (info_ptr->next_frame_dispose_op);
     976    return (0);
     977}
     978
     979png_byte PNGAPI
     980png_get_next_frame_blend_op(png_structp png_ptr, png_infop info_ptr)
     981{
     982    png_debug(1, "in png_get_next_frame_blend_op()\n");
     983
     984    if (png_ptr != NULL && info_ptr != NULL)
     985        return (info_ptr->next_frame_blend_op);
     986    return (0);
     987}
     988
     989png_byte PNGAPI
     990png_get_first_frame_is_hidden(png_structp png_ptr, png_infop info_ptr)
     991{
     992    png_debug(1, "in png_first_frame_is_hidden()\n");
     993
     994    if (png_ptr != NULL)
     995       return (png_byte)(png_ptr->apng_flags & PNG_FIRST_FRAME_HIDDEN);
     996
     997    return 0;
     998}
     999#endif /* PNG_APNG_SUPPORTED */
     1000
    8421001#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
    8431002png_uint_32 PNGAPI
    8441003png_get_unknown_chunks(png_structp png_ptr, png_infop info_ptr,
  • TabularUnified pngpread.c

    diff -Naur libpng-1.2.38-orig/pngpread.c libpng-1.2.38/pngpread.c
    old new  
    8686      }
    8787
    8888#endif
     89#if defined(PNG_READ_APNG_SUPPORTED)
     90      PNG_CONST PNG_acTL;
     91      PNG_CONST PNG_fcTL;
     92      PNG_CONST PNG_fdAT;
     93#endif
    8994#if defined(PNG_READ_iTXt_SUPPORTED)
    9095      case PNG_READ_iTXt_MODE:
    9196      {
     
    230235      png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
    231236   }
    232237
     238#if defined(PNG_READ_APNG_SUPPORTED)
     239   if (png_ptr->num_frames_read > 0 &&
     240       png_ptr->num_frames_read < info_ptr->num_frames)
     241   {
     242      if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
     243      {
     244         /* discard trailing IDATs for the first frame */
     245         if (png_ptr->mode & PNG_HAVE_fcTL || png_ptr->num_frames_read > 1)
     246            png_error(png_ptr, "out of place IDAT");
     247
     248         if (png_ptr->push_length + 4 > png_ptr->buffer_size)
     249         {
     250            png_push_save_buffer(png_ptr);
     251            return;
     252         }
     253         png_push_crc_skip(png_ptr, png_ptr->push_length);
     254         png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
     255         return;
     256      }
     257      else if (!png_memcmp(png_ptr->chunk_name, png_fdAT, 4))
     258      {
     259         if (png_ptr->buffer_size < 4)
     260         {
     261            png_push_save_buffer(png_ptr);
     262            return;
     263         }
     264         png_ensure_sequence_number(png_ptr, 4);
     265
     266         if (!(png_ptr->mode & PNG_HAVE_fcTL))
     267         {
     268            /* discard trailing fdATs for frames other than the first */
     269            if (png_ptr->num_frames_read < 2)
     270               png_error(png_ptr, "out of place fdAT");
     271
     272            if (png_ptr->push_length + 4 > png_ptr->buffer_size)
     273            {
     274               png_push_save_buffer(png_ptr);
     275               return;
     276            }
     277            png_push_crc_skip(png_ptr, png_ptr->push_length);
     278            png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
     279            return;
     280         }
     281         else
     282         {
     283            /* frame data follows */
     284            png_ptr->idat_size = png_ptr->push_length - 4;
     285            png_ptr->mode |= PNG_HAVE_IDAT;
     286            png_ptr->process_mode = PNG_READ_IDAT_MODE;
     287
     288            return;
     289        }
     290      }
     291      else if(!png_memcmp(png_ptr->chunk_name, png_fcTL, 4))
     292      {
     293         if (png_ptr->push_length + 4 > png_ptr->buffer_size)
     294         {
     295            png_push_save_buffer(png_ptr);
     296            return;
     297         }
     298
     299         png_read_reset(png_ptr);
     300         png_ptr->mode &= ~PNG_HAVE_fcTL;
     301
     302         png_handle_fcTL(png_ptr, info_ptr, png_ptr->push_length);
     303
     304         if (!(png_ptr->mode & PNG_HAVE_fcTL))
     305            png_error(png_ptr, "missing required fcTL chunk");
     306
     307         png_read_reinit(png_ptr, info_ptr);
     308         png_progressive_read_reset(png_ptr);
     309
     310         if (png_ptr->frame_info_fn != NULL)
     311            (*(png_ptr->frame_info_fn))(png_ptr, png_ptr->num_frames_read);
     312
     313         png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
     314
     315         return;
     316      }
     317      else
     318      {
     319         if (png_ptr->push_length + 4 > png_ptr->buffer_size)
     320         {
     321            png_push_save_buffer(png_ptr);
     322            return;
     323         }
     324         png_warning(png_ptr, "Skipped (ignored) a chunk "
     325                              "between APNG chunks");
     326         png_push_crc_skip(png_ptr, png_ptr->push_length);
     327         png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
     328         return;
     329      }
     330
     331      return;
     332   }
     333#endif /* PNG_READ_APNG_SUPPORTED */
     334
    233335   if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
    234336     if (png_ptr->mode & PNG_AFTER_IDAT)
    235337        png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
     
    241343
    242344      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
    243345      {
     346         if (png_ptr->push_length != 13)
     347            png_error(png_ptr, "Invalid IHDR length");
    244348         png_push_save_buffer(png_ptr);
    245349         return;
    246350      }
     
    325429            png_error(png_ptr, "Too many IDAT's found");
    326430      }
    327431
     432#if defined(PNG_READ_APNG_SUPPORTED)
     433      png_have_info(png_ptr, info_ptr);
     434#endif
     435
    328436      png_ptr->idat_size = png_ptr->push_length;
    329437      png_ptr->mode |= PNG_HAVE_IDAT;
    330438      png_ptr->process_mode = PNG_READ_IDAT_MODE;
     
    386494   }
    387495
    388496#endif
     497
    389498#if defined(PNG_READ_iCCP_SUPPORTED)
    390499   else if (!png_memcmp(png_ptr->chunk_name, png_iCCP, 4))
    391500   {
     
    555664   }
    556665
    557666#endif
     667#if defined(PNG_READ_APNG_SUPPORTED)
     668   else if (!png_memcmp(png_ptr->chunk_name, png_acTL, 4))
     669   {
     670      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
     671      {
     672         png_push_save_buffer(png_ptr);
     673         return;
     674      }
     675      png_handle_acTL(png_ptr, info_ptr, png_ptr->push_length);
     676   }
     677   else if (!png_memcmp(png_ptr->chunk_name, png_fcTL, 4))
     678   {
     679      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
     680      {
     681         png_push_save_buffer(png_ptr);
     682         return;
     683      }
     684      png_handle_fcTL(png_ptr, info_ptr, png_ptr->push_length);
     685   }
     686   else if (!png_memcmp(png_ptr->chunk_name, png_fdAT, 4))
     687   {
     688      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
     689      {
     690         png_push_save_buffer(png_ptr);
     691         return;
     692      }
     693      png_handle_fdAT(png_ptr, info_ptr, png_ptr->push_length);
     694   }
     695#endif /* PNG_READ_APNG_SUPPORTED */
    558696   else
    559697   {
    560698      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
     
    729867png_push_read_IDAT(png_structp png_ptr)
    730868{
    731869#ifdef PNG_USE_LOCAL_ARRAYS
    732    PNG_CONST PNG_IDAT;
     870   PNG_IDAT;
     871#if defined(PNG_READ_APNG_SUPPORTED)
     872   PNG_fdAT;
     873   PNG_IEND;
     874#endif
    733875#endif
    734876   if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
    735877   {
    736878      png_byte chunk_length[4];
    737879
    738       if (png_ptr->buffer_size < 8)
     880      if (png_ptr->buffer_size < 12)
    739881      {
    740882         png_push_save_buffer(png_ptr);
    741883         return;
     
    747889      png_crc_read(png_ptr, png_ptr->chunk_name, 4);
    748890      png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
    749891
    750       if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
     892#if defined(PNG_READ_APNG_SUPPORTED)
     893      if (png_memcmp(png_ptr->chunk_name, (png_bytep)png_fdAT, 4)
     894          && png_ptr->num_frames_read > 0)
     895      {
     896          if (png_ptr->flags & PNG_FLAG_ZLIB_FINISHED)
     897          {
     898              png_ptr->process_mode = PNG_READ_CHUNK_MODE;
     899              if (png_ptr->frame_end_fn != NULL)
     900                 (*(png_ptr->frame_end_fn))(png_ptr, png_ptr->num_frames_read);
     901              png_ptr->num_frames_read++;
     902              return;
     903          }
     904          else
     905          {
     906              if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4))
     907                  png_error(png_ptr, "Not enough image data");
     908              if (png_ptr->push_length + 4 > png_ptr->buffer_size)
     909              {
     910                 png_push_save_buffer(png_ptr);
     911                 return;
     912              }
     913              png_warning(png_ptr, "Skipping (ignoring) a chunk between "
     914                                   "APNG chunks");
     915              png_crc_finish(png_ptr, png_ptr->push_length);
     916              png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
     917              return;
     918          }
     919      }
     920      else
     921#endif
     922      if ( png_memcmp(png_ptr->chunk_name, png_IDAT, 4)
     923                && (png_ptr->num_frames_read == 0) )
    751924      {
    752925         png_ptr->process_mode = PNG_READ_CHUNK_MODE;
    753926         if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
    754927            png_error(png_ptr, "Not enough compressed data");
     928#if defined(PNG_READ_APNG_SUPPORTED)
     929         if (png_ptr->frame_end_fn != NULL)
     930            (*(png_ptr->frame_end_fn))(png_ptr, png_ptr->num_frames_read);
     931         png_ptr->num_frames_read++;
     932#endif
    755933         return;
    756934      }
    757935
    758936      png_ptr->idat_size = png_ptr->push_length;
     937
     938#if defined(PNG_READ_APNG_SUPPORTED)
     939      if (png_ptr->num_frames_read > 0)
     940      {
     941         png_ensure_sequence_number(png_ptr, 4);
     942         png_ptr->idat_size -= 4;
     943      }
     944#endif
    759945   }
    760946   if (png_ptr->idat_size && png_ptr->save_buffer_size)
    761947   {
     
    17161902   png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer);
    17171903}
    17181904
     1905#if defined(PNG_READ_APNG_SUPPORTED)
     1906void PNGAPI
     1907png_set_progressive_frame_fn(png_structp png_ptr,
     1908   png_progressive_frame_ptr frame_info_fn,
     1909   png_progressive_frame_ptr frame_end_fn)
     1910{
     1911   png_ptr->frame_info_fn = frame_info_fn;
     1912   png_ptr->frame_end_fn = frame_end_fn;
     1913}
     1914#endif
     1915
    17191916png_voidp PNGAPI
    17201917png_get_progressive_ptr(png_structp png_ptr)
    17211918{
  • TabularUnified libpng-1.2.

    diff -Naur libpng-1.2.38-orig/pngread.c libpng-1.2.38/pngread.c
    old new  
    413413#if defined(PNG_READ_zTXt_SUPPORTED)
    414414      PNG_CONST PNG_zTXt;
    415415#endif
     416#if defined(PNG_READ_APNG_SUPPORTED)
     417      PNG_CONST PNG_acTL;
     418      PNG_CONST PNG_fcTL;
     419      PNG_CONST PNG_fdAT;
     420#endif
    416421#endif /* PNG_USE_LOCAL_ARRAYS */
    417422      png_uint_32 length = png_read_chunk_header(png_ptr);
    418423      PNG_CONST png_bytep chunk_name = png_ptr->chunk_name;
     
    456461         else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
    457462                  !(png_ptr->mode & PNG_HAVE_PLTE))
    458463            png_error(png_ptr, "Missing PLTE before IDAT");
    459 
     464#if defined(PNG_READ_APNG_SUPPORTED)
     465         png_have_info(png_ptr, info_ptr);
     466#endif
    460467         png_ptr->idat_size = length;
    461468         png_ptr->mode |= PNG_HAVE_IDAT;
    462469         break;
     
    529536      else if (!png_memcmp(chunk_name, png_iTXt, 4))
    530537         png_handle_iTXt(png_ptr, info_ptr, length);
    531538#endif
     539#if defined(PNG_READ_APNG_SUPPORTED)
     540      else if (!png_memcmp(chunk_name, png_acTL, 4))
     541         png_handle_acTL(png_ptr, info_ptr, length);
     542      else if (!png_memcmp(chunk_name, png_fcTL, 4))
     543         png_handle_fcTL(png_ptr, info_ptr, length);
     544      else if (!png_memcmp(chunk_name, png_fdAT, 4))
     545         png_handle_fdAT(png_ptr, info_ptr, length);
     546#endif
    532547      else
    533548         png_handle_unknown(png_ptr, info_ptr, length);
    534549   }
    535550}
    536551#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
    537552
     553#if defined(PNG_READ_APNG_SUPPORTED)
     554void PNGAPI
     555png_read_frame_head(png_structp png_ptr, png_infop info_ptr)
     556{
     557    png_byte have_chunk_after_DAT; /* after IDAT or after fdAT */
     558
     559    png_debug(0, "Reading frame head\n");
     560
     561    if (!(png_ptr->mode & PNG_HAVE_acTL))
     562        png_error(png_ptr, "attempt to png_read_frame_head() but "
     563                           "no acTL present");
     564
     565    /* do nothing for the main IDAT */
     566    if (png_ptr->num_frames_read == 0)
     567        return;
     568
     569    png_crc_finish(png_ptr, 0); /* CRC from last IDAT or fdAT chunk */
     570
     571    png_read_reset(png_ptr);
     572    png_ptr->mode &= ~PNG_HAVE_fcTL;
     573
     574    have_chunk_after_DAT = 0;
     575    for (;;)
     576    {
     577#ifdef PNG_USE_LOCAL_ARRAYS
     578        PNG_IDAT;
     579        PNG_fdAT;
     580        PNG_fcTL;
     581#endif
     582        png_byte chunk_length[4];
     583        png_uint_32 length;
     584
     585        png_read_data(png_ptr, chunk_length, 4);
     586        length = png_get_uint_31(png_ptr, chunk_length);
     587
     588        png_reset_crc(png_ptr);
     589        png_crc_read(png_ptr, png_ptr->chunk_name, 4);
     590
     591        if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
     592        {
     593            /* discard trailing IDATs for the first frame */
     594            if (have_chunk_after_DAT || png_ptr->num_frames_read > 1)
     595                png_error(png_ptr, "png_read_frame_head(): out of place IDAT");
     596            png_crc_finish(png_ptr, length);
     597        }
     598        else if (!png_memcmp(png_ptr->chunk_name, png_fcTL, 4))
     599        {
     600            png_handle_fcTL(png_ptr, info_ptr, length);
     601            have_chunk_after_DAT = 1;
     602        }
     603        else if (!png_memcmp(png_ptr->chunk_name, png_fdAT, 4))
     604        {
     605            png_ensure_sequence_number(png_ptr, length);
     606
     607            /* discard trailing fdATs for frames other than the first */
     608            if (!have_chunk_after_DAT && png_ptr->num_frames_read > 1)
     609                png_crc_finish(png_ptr, length - 4);
     610            else if(png_ptr->mode & PNG_HAVE_fcTL)
     611            {
     612                png_ptr->idat_size = length - 4;
     613                png_ptr->mode |= PNG_HAVE_IDAT;
     614
     615                break;
     616            }
     617            else
     618                png_error(png_ptr, "png_read_frame_head(): out of place fdAT");
     619        }
     620        else
     621        {
     622            png_warning(png_ptr, "Skipped (ignored) a chunk "
     623                                 "between APNG chunks");
     624            png_crc_finish(png_ptr, length);
     625        }
     626    }
     627}
     628#endif /* PNG_READ_APNG_SUPPORTED */
     629
    538630/* Optional call to update the users info_ptr structure */
    539631void PNGAPI
    540632png_read_update_info(png_structp png_ptr, png_infop info_ptr)
     
    573665{
    574666#ifdef PNG_USE_LOCAL_ARRAYS
    575667   PNG_CONST PNG_IDAT;
     668#if defined(PNG_READ_APNG_SUPPORTED)
     669   PNG_CONST PNG_fdAT;
     670   PNG_CONST PNG_IEND;
     671#endif
    576672   PNG_CONST int png_pass_dsp_mask[7] = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55,
    577673      0xff};
    578674   PNG_CONST int png_pass_mask[7] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff};
     
    703799   {
    704800      if (!(png_ptr->zstream.avail_in))
    705801      {
    706          while (!png_ptr->idat_size)
     802         png_uint_32 bytes_to_skip = 0;
     803
     804         while (!png_ptr->idat_size || bytes_to_skip != 0)
    707805         {
    708             png_crc_finish(png_ptr, 0);
     806            png_crc_finish(png_ptr, bytes_to_skip);
     807            bytes_to_skip = 0;
    709808
    710809            png_ptr->idat_size = png_read_chunk_header(png_ptr);
    711             if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
    712                png_error(png_ptr, "Not enough image data");
     810
     811#if defined(PNG_READ_APNG_SUPPORTED)
     812            if (png_ptr->num_frames_read == 0)
     813            {
     814#endif
     815               if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
     816                  png_error(png_ptr, "Not enough image data");
     817#if defined(PNG_READ_APNG_SUPPORTED)
     818            }
     819            else
     820            {
     821               if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4))
     822                  png_error(png_ptr, "Not enough image data");
     823               if (png_memcmp(png_ptr->chunk_name, png_fdAT, 4))
     824               {
     825                  png_warning(png_ptr, "Skipped (ignored) a chunk "
     826                                       "between APNG chunks");
     827                  bytes_to_skip = png_ptr->idat_size;
     828                  continue;
     829               }
     830
     831               png_ensure_sequence_number(png_ptr, png_ptr->idat_size);
     832
     833               png_ptr->idat_size -= 4;
     834            }
     835#endif
    713836         }
    714837         png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
    715838         png_ptr->zstream.next_in = png_ptr->zbuf;
     
    727850            png_error(png_ptr, "Extra compressed data");
    728851         png_ptr->mode |= PNG_AFTER_IDAT;
    729852         png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
     853#if defined(PNG_READ_APNG_SUPPORTED)
     854         png_ptr->num_frames_read++;
     855#endif
    730856         break;
    731857      }
    732858      if (ret != Z_OK)
     
    9811107#if defined(PNG_READ_zTXt_SUPPORTED)
    9821108      PNG_CONST PNG_zTXt;
    9831109#endif
     1110#if defined(PNG_READ_APNG_SUPPORTED)
     1111      PNG_CONST PNG_acTL;
     1112      PNG_CONST PNG_fcTL;
     1113      PNG_CONST PNG_fdAT;
     1114#endif
    9841115#endif /* PNG_USE_LOCAL_ARRAYS */
    9851116      png_uint_32 length = png_read_chunk_header(png_ptr);
    9861117      PNG_CONST png_bytep chunk_name = png_ptr->chunk_name;
     
    10811212      else if (!png_memcmp(chunk_name, png_iTXt, 4))
    10821213         png_handle_iTXt(png_ptr, info_ptr, length);
    10831214#endif
     1215#if defined(PNG_READ_APNG_SUPPORTED)
     1216      else if (!png_memcmp(png_ptr->chunk_name, png_acTL, 4))
     1217         png_handle_acTL(png_ptr, info_ptr, length);
     1218      else if (!png_memcmp(png_ptr->chunk_name, png_fcTL, 4))
     1219         png_handle_fcTL(png_ptr, info_ptr, length);
     1220      else if (!png_memcmp(png_ptr->chunk_name, png_fdAT, 4))
     1221         png_handle_fdAT(png_ptr, info_ptr, length);
     1222#endif
    10841223      else
    10851224         png_handle_unknown(png_ptr, info_ptr, length);
    10861225   } while (!(png_ptr->mode & PNG_HAVE_IEND));
  • TabularUnified pngrtran.c

    diff -Naur libpng-1.2.38-orig/pngrtran.c libpng-1.2.38/pngrtran.c
    old new  
    13211321       * pixels.  This check added to libpng-1.2.19
    13221322       */
    13231323#if (PNG_WARN_UNINITIALIZED_ROW==1)
    1324       png_error(png_ptr, "Uninitialized row");
     1324      png_warning(png_ptr, "Uninitialized row");
    13251325#else
    13261326      png_warning(png_ptr, "Uninitialized row");
    13271327#endif
  • TabularUnified pngrutil.c

    diff -Naur libpng-1.2.38-orig/pngrutil.c libpng-1.2.38/pngrutil.c
    old new  
    424424   filter_type = buf[11];
    425425   interlace_type = buf[12];
    426426
     427#if defined(PNG_READ_APNG_SUPPORTED)
     428   png_ptr->first_frame_width = width;
     429   png_ptr->first_frame_height = height;
     430#endif
     431
    427432   /* Set internal variables */
    428433   png_ptr->width = width;
    429434   png_ptr->height = height;
     
    22302235}
    22312236#endif
    22322237
     2238#if defined(PNG_READ_APNG_SUPPORTED)
     2239void /* PRIVATE */
     2240png_handle_acTL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
     2241{
     2242    png_byte data[8];
     2243    png_uint_32 num_frames;
     2244    png_uint_32 num_plays;
     2245    png_uint_32 didSet;
     2246
     2247    png_debug(1, "in png_handle_acTL\n");
     2248
     2249    if (!(png_ptr->mode & PNG_HAVE_IHDR))
     2250    {
     2251        png_error(png_ptr, "Missing IHDR before acTL");
     2252    }
     2253    else if (png_ptr->mode & PNG_HAVE_IDAT)
     2254    {
     2255        png_warning(png_ptr, "Invalid acTL after IDAT skipped");
     2256        png_crc_finish(png_ptr, length);
     2257        return;
     2258    }
     2259    else if (png_ptr->mode & PNG_HAVE_acTL)
     2260    {
     2261        png_warning(png_ptr, "Duplicate acTL skipped");
     2262        png_crc_finish(png_ptr, length);
     2263        return;
     2264    }
     2265    else if (length != 8)
     2266    {
     2267        png_warning(png_ptr, "acTL with invalid length skipped");
     2268        png_crc_finish(png_ptr, length);
     2269        return;
     2270    }
     2271
     2272    png_crc_read(png_ptr, data, 8);
     2273    png_crc_finish(png_ptr, 0);
     2274
     2275    num_frames = png_get_uint_31(png_ptr, data);
     2276    num_plays = png_get_uint_31(png_ptr, data + 4);
     2277
     2278    /* the set function will do error checking on num_frames */
     2279    didSet = png_set_acTL(png_ptr, info_ptr, num_frames, num_plays);
     2280    if(didSet)
     2281        png_ptr->mode |= PNG_HAVE_acTL;
     2282}
     2283
     2284void /* PRIVATE */
     2285png_handle_fcTL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
     2286{
     2287    png_byte data[22];
     2288    png_uint_32 width;
     2289    png_uint_32 height;
     2290    png_uint_32 x_offset;
     2291    png_uint_32 y_offset;
     2292    png_uint_16 delay_num;
     2293    png_uint_16 delay_den;
     2294    png_byte dispose_op;
     2295    png_byte blend_op;
     2296
     2297    png_debug(1, "in png_handle_fcTL\n");
     2298
     2299    if (!(png_ptr->mode & PNG_HAVE_IHDR))
     2300    {
     2301        png_error(png_ptr, "Missing IHDR before fcTL");
     2302    }
     2303    else if (png_ptr->mode & PNG_HAVE_IDAT)
     2304    {
     2305        /* for any frames other then the first this message may be misleading,
     2306        * but correct. PNG_HAVE_IDAT is unset before the frame head is read
     2307        * i can't think of a better message */
     2308        png_warning(png_ptr, "Invalid fcTL after IDAT skipped");
     2309        png_crc_finish(png_ptr, length);
     2310        return;
     2311    }
     2312    else if (png_ptr->mode & PNG_HAVE_fcTL)
     2313    {
     2314        png_warning(png_ptr, "Duplicate fcTL within one frame skipped");
     2315        png_crc_finish(png_ptr, length);
     2316        return;
     2317    }
     2318    else if (length != 26)
     2319    {
     2320        png_warning(png_ptr, "fcTL with invalid length skipped");
     2321        png_crc_finish(png_ptr, length);
     2322        return;
     2323    }
     2324
     2325    png_ensure_sequence_number(png_ptr, length);
     2326
     2327    png_crc_read(png_ptr, data, 22);
     2328    png_crc_finish(png_ptr, 0);
     2329
     2330    width = png_get_uint_31(png_ptr, data);
     2331    height = png_get_uint_31(png_ptr, data + 4);
     2332    x_offset = png_get_uint_31(png_ptr, data + 8);
     2333    y_offset = png_get_uint_31(png_ptr, data + 12);
     2334    delay_num = png_get_uint_16(data + 16);
     2335    delay_den = png_get_uint_16(data + 18);
     2336    dispose_op = data[20];
     2337    blend_op = data[21];
     2338
     2339    if (png_ptr->num_frames_read == 0 && (x_offset != 0 || y_offset != 0))
     2340        png_error(png_ptr, "fcTL for the first frame must have zero offset");
     2341    if (png_ptr->num_frames_read == 0 &&
     2342        (width != info_ptr->width || height != info_ptr->height))
     2343        png_error(png_ptr, "size in first frame's fcTL must match "
     2344                           "the size in IHDR");
     2345
     2346    /* the set function will do more error checking */
     2347    png_set_next_frame_fcTL(png_ptr, info_ptr, width, height,
     2348                            x_offset, y_offset, delay_num, delay_den,
     2349                            dispose_op, blend_op);
     2350
     2351    png_read_reinit(png_ptr, info_ptr);
     2352
     2353    png_ptr->mode |= PNG_HAVE_fcTL;
     2354}
     2355
     2356void /* PRIVATE */
     2357png_have_info(png_structp png_ptr, png_infop info_ptr)
     2358{
     2359    if((info_ptr->valid & PNG_INFO_acTL) && !(info_ptr->valid & PNG_INFO_fcTL))
     2360    {
     2361        png_ptr->apng_flags |= PNG_FIRST_FRAME_HIDDEN;
     2362        info_ptr->num_frames++;
     2363    }
     2364}
     2365
     2366void /* PRIVATE */
     2367png_handle_fdAT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
     2368{
     2369    png_ensure_sequence_number(png_ptr, length);
     2370
     2371    /* This function is only called from png_read_end(), png_read_info(),
     2372    * and png_push_read_chunk() which means that:
     2373    * - the user doesn't want to read this frame
     2374    * - or this is an out-of-place fdAT
     2375    * in either case it is safe to ignore the chunk with a warning */
     2376    png_warning(png_ptr, "ignoring fdAT chunk");
     2377    png_crc_finish(png_ptr, length - 4);
     2378}
     2379
     2380void /* PRIVATE */
     2381png_ensure_sequence_number(png_structp png_ptr, png_uint_32 length)
     2382{
     2383    png_byte data[4];
     2384    png_uint_32 sequence_number;
     2385
     2386    if (length < 4)
     2387        png_error(png_ptr, "invalid fcTL or fdAT chunk found");
     2388
     2389    png_crc_read(png_ptr, data, 4);
     2390    sequence_number = png_get_uint_31(png_ptr, data);
     2391
     2392    if (sequence_number != png_ptr->next_seq_num)
     2393        png_error(png_ptr, "fcTL or fdAT chunk with out-of-order sequence "
     2394                           "number found");
     2395
     2396    png_ptr->next_seq_num++;
     2397}
     2398#endif /* PNG_READ_APNG_SUPPORTED */
     2399
    22332400/* This function is called when we haven't found a handler for a
    22342401   chunk.  If there isn't a problem with the chunk itself (ie bad
    22352402   chunk name, CRC, or a critical chunk), the chunk is silently ignored
     
    32493416
    32503417   png_ptr->flags |= PNG_FLAG_ROW_INIT;
    32513418}
     3419
     3420#if defined(PNG_READ_APNG_SUPPORTED)
     3421/* This function is to be called after the main IDAT set has been read and
     3422 * before a new IDAT is read. It resets some parts of png_ptr
     3423 * to make them usable by the read functions again */
     3424void /* PRIVATE */
     3425png_read_reset(png_structp png_ptr)
     3426{
     3427    png_ptr->mode &= ~PNG_HAVE_IDAT;
     3428    png_ptr->mode &= ~PNG_AFTER_IDAT;
     3429    png_ptr->row_number = 0;
     3430    png_ptr->pass = 0;
     3431    png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
     3432}
     3433
     3434void /* PRIVATE */
     3435png_read_reinit(png_structp png_ptr, png_infop info_ptr)
     3436{
     3437    png_ptr->width = info_ptr->next_frame_width;
     3438    png_ptr->height = info_ptr->next_frame_height;
     3439    png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth,png_ptr->width);
     3440}
     3441
     3442/* same as png_read_reset() but for the progressive reader */
     3443void /* PRIVATE */
     3444png_progressive_read_reset(png_structp png_ptr)
     3445{
     3446#ifdef PNG_USE_LOCAL_ARRAYS
     3447    /* start of interlace block */
     3448    const int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
     3449
     3450    /* offset to next interlace block */
     3451    const int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
     3452
     3453    /* start of interlace block in the y direction */
     3454    const int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
     3455
     3456    /* offset to next interlace block in the y direction */
     3457    const int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
     3458#endif
     3459    png_uint_32 row_bytes;
     3460
     3461    if (png_ptr->interlaced)
     3462    {
     3463        if (!(png_ptr->transformations & PNG_INTERLACE))
     3464            png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
     3465                                png_pass_ystart[0]) / png_pass_yinc[0];
     3466        else
     3467           png_ptr->num_rows = png_ptr->height;
     3468
     3469        png_ptr->iwidth = (png_ptr->width +
     3470                           png_pass_inc[png_ptr->pass] - 1 -
     3471                           png_pass_start[png_ptr->pass]) /
     3472                           png_pass_inc[png_ptr->pass];
     3473
     3474        row_bytes = PNG_ROWBYTES(png_ptr->pixel_depth,png_ptr->iwidth) + 1;
     3475
     3476        png_ptr->irowbytes = (png_size_t)row_bytes;
     3477        if((png_uint_32)png_ptr->irowbytes != row_bytes)
     3478            png_error(png_ptr, "png_progressive_read_reset(): Rowbytes "
     3479                               "overflow");
     3480    }
     3481    else
     3482    {
     3483        png_ptr->num_rows = png_ptr->height;
     3484        png_ptr->iwidth = png_ptr->width;
     3485        png_ptr->irowbytes = png_ptr->rowbytes + 1;
     3486    }
     3487    png_ptr->flags &= ~PNG_FLAG_ZLIB_FINISHED;
     3488    if (inflateReset(&(png_ptr->zstream)) != Z_OK)
     3489        png_error(png_ptr, "inflateReset failed");
     3490    png_ptr->zstream.avail_in = 0;
     3491    png_ptr->zstream.next_in = 0;
     3492    png_ptr->zstream.next_out = png_ptr->row_buf;
     3493    png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes;
     3494}
     3495#endif /* PNG_READ_APNG_SUPPORTED */
    32523496#endif /* PNG_READ_SUPPORTED */
  • TabularUnified libpng-1.2.

    diff -Naur libpng-1.2.38-orig/pngset.c libpng-1.2.38/pngset.c
    old new  
    320320      info_ptr->rowbytes = (png_size_t)0;
    321321   else
    322322      info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, width);
     323
     324#if defined(PNG_APNG_SUPPORTED)
     325   /* for non-animated png. this may be overritten from an acTL chunk later */
     326   info_ptr->num_frames = 1;
     327#endif
    323328}
    324329
    325330#if defined(PNG_oFFs_SUPPORTED)
     
    10071012}
    10081013#endif /* PNG_sPLT_SUPPORTED */
    10091014
     1015#if defined(PNG_APNG_SUPPORTED)
     1016png_uint_32 PNGAPI
     1017png_set_acTL(png_structp png_ptr, png_infop info_ptr,
     1018    png_uint_32 num_frames, png_uint_32 num_plays)
     1019{
     1020    png_debug1(1, "in %s storage function\n", "acTL");
     1021
     1022    if (png_ptr == NULL || info_ptr == NULL)
     1023    {
     1024        png_warning(png_ptr,
     1025                    "Call to png_set_acTL() with NULL png_ptr "
     1026                    "or info_ptr ignored");
     1027        return (0);
     1028    }
     1029    if (num_frames == 0)
     1030    {
     1031        png_warning(png_ptr,
     1032                    "Ignoring attempt to set acTL with num_frames zero");
     1033        return (0);
     1034    }
     1035    if (num_frames > PNG_UINT_31_MAX)
     1036    {
     1037        png_warning(png_ptr,
     1038                    "Ignoring attempt to set acTL with num_frames > 2^31-1");
     1039        return (0);
     1040    }
     1041    if (num_plays > PNG_UINT_31_MAX)
     1042    {
     1043        png_warning(png_ptr,
     1044                    "Ignoring attempt to set acTL with num_plays "
     1045                    "> 2^31-1");
     1046        return (0);
     1047    }
     1048
     1049    info_ptr->num_frames = num_frames;
     1050    info_ptr->num_plays = num_plays;
     1051
     1052    info_ptr->valid |= PNG_INFO_acTL;
     1053
     1054    return (1);
     1055}
     1056
     1057/* delay_num and delay_den can hold any 16-bit values including zero */
     1058png_uint_32 PNGAPI
     1059png_set_next_frame_fcTL(png_structp png_ptr, png_infop info_ptr,
     1060    png_uint_32 width, png_uint_32 height,
     1061    png_uint_32 x_offset, png_uint_32 y_offset,
     1062    png_uint_16 delay_num, png_uint_16 delay_den,
     1063    png_byte dispose_op, png_byte blend_op)
     1064{
     1065    png_debug1(1, "in %s storage function\n", "fcTL");
     1066
     1067    if (png_ptr == NULL || info_ptr == NULL)
     1068    {
     1069        png_warning(png_ptr,
     1070                    "Call to png_set_fcTL() with NULL png_ptr or info_ptr "
     1071                    "ignored");
     1072        return (0);
     1073    }
     1074
     1075    png_ensure_fcTL_is_valid(png_ptr, width, height, x_offset, y_offset,
     1076                             delay_num, delay_den, dispose_op, blend_op);
     1077
     1078    info_ptr->next_frame_width = width;
     1079    info_ptr->next_frame_height = height;
     1080    info_ptr->next_frame_x_offset = x_offset;
     1081    info_ptr->next_frame_y_offset = y_offset;
     1082    info_ptr->next_frame_delay_num = delay_num;
     1083    info_ptr->next_frame_delay_den = delay_den;
     1084    info_ptr->next_frame_dispose_op = dispose_op;
     1085    info_ptr->next_frame_blend_op = blend_op;
     1086
     1087    info_ptr->valid |= PNG_INFO_fcTL;
     1088
     1089    return (1);
     1090}
     1091
     1092void /* PRIVATE */
     1093png_ensure_fcTL_is_valid(png_structp png_ptr,
     1094    png_uint_32 width, png_uint_32 height,
     1095    png_uint_32 x_offset, png_uint_32 y_offset,
     1096    png_uint_16 delay_num, png_uint_16 delay_den,
     1097    png_byte dispose_op, png_byte blend_op)
     1098{
     1099    if (width + x_offset > png_ptr->first_frame_width ||
     1100        height + y_offset > png_ptr->first_frame_height)
     1101        png_error(png_ptr, "dimensions of a frame are greater than"
     1102                           "the ones in IHDR");
     1103    if (width > PNG_UINT_31_MAX)
     1104        png_error(png_ptr, "invalid width in fcTL (> 2^31-1)");
     1105    if (height > PNG_UINT_31_MAX)
     1106        png_error(png_ptr, "invalid height in fcTL (> 2^31-1)");
     1107    if (x_offset > PNG_UINT_31_MAX)
     1108        png_error(png_ptr, "invalid x_offset in fcTL (> 2^31-1)");
     1109    if (y_offset > PNG_UINT_31_MAX)
     1110        png_error(png_ptr, "invalid y_offset in fcTL (> 2^31-1)");
     1111
     1112    if (dispose_op != PNG_DISPOSE_OP_NONE &&
     1113       dispose_op != PNG_DISPOSE_OP_BACKGROUND &&
     1114       dispose_op != PNG_DISPOSE_OP_PREVIOUS)
     1115        png_error(png_ptr, "invalid dispose_op in fcTL");
     1116
     1117    if (blend_op != PNG_BLEND_OP_SOURCE &&
     1118       blend_op != PNG_BLEND_OP_OVER)
     1119        png_error(png_ptr, "invalid blend_op in fcTL");
     1120
     1121    if (blend_op == PNG_BLEND_OP_OVER) {
     1122        if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
     1123            png_error(png_ptr, "PNG_BLEND_OP_OVER is not valid for "
     1124                               "color type 'greyscale without alpha'");
     1125        else if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) &&
     1126                !(png_ptr->color_type & PNG_COLOR_MASK_ALPHA))
     1127            png_error(png_ptr, "PNG_BLEND_OP_OVER is not valid for "
     1128                               "color type 'truecolor without alpha'");
     1129    }
     1130}
     1131
     1132png_uint_32 PNGAPI
     1133png_set_first_frame_is_hidden(png_structp png_ptr, png_infop info_ptr,
     1134                              png_byte is_hidden)
     1135{
     1136    png_debug(1, "in png_first_frame_is_hidden()\n");
     1137
     1138    if (png_ptr == NULL)
     1139        return 0;
     1140
     1141    if(is_hidden)
     1142        png_ptr->apng_flags |= PNG_FIRST_FRAME_HIDDEN;
     1143    else
     1144        png_ptr->apng_flags &= ~PNG_FIRST_FRAME_HIDDEN;
     1145
     1146    return 1;
     1147}
     1148#endif /* PNG_APNG_SUPPORTED */
     1149
    10101150#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
    10111151void PNGAPI
    10121152png_set_unknown_chunks(png_structp png_ptr,
  • TabularUnified pngtrans.c

    diff -Naur libpng-1.2.38-orig/pngtrans.c libpng-1.2.38/pngtrans.c
    old new  
    670670      return (NULL);
    671671#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
    672672   return ((png_voidp)png_ptr->user_transform_ptr);
    673 #else
    674    return (NULL);
    675673#endif
     674   return (NULL);
    676675}
    677676#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
  • TabularUnified pngwrite.c

    diff -Naur libpng-1.2.38-orig/pngwrite.c libpng-1.2.38/pngwrite.c
    old new  
    9898#endif
    9999   }
    100100#endif
     101#if defined(PNG_WRITE_APNG_SUPPORTED)
     102   if (info_ptr->valid & PNG_INFO_acTL)
     103      png_write_acTL(png_ptr, info_ptr->num_frames, info_ptr->num_plays);
     104#endif
    101105#if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
    102106   if (info_ptr->unknown_chunks_num)
    103107   {
     
    314318      return;
    315319   if (!(png_ptr->mode & PNG_HAVE_IDAT))
    316320      png_error(png_ptr, "No IDATs written into file");
     321#if defined(PNG_WRITE_APNG_SUPPORTED)
     322   if (png_ptr->num_frames_written != png_ptr->num_frames_to_write)
     323      png_error(png_ptr, "Not enough frames written");
     324#endif
    317325
    318326   /* See if user wants us to write information chunks */
    319327   if (info_ptr != NULL)
     
    15581566   params = params;
    15591567}
    15601568#endif
     1569
     1570#if defined(PNG_WRITE_APNG_SUPPORTED)
     1571void PNGAPI
     1572png_write_frame_head(png_structp png_ptr, png_infop info_ptr,
     1573    png_bytepp row_pointers, png_uint_32 width, png_uint_32 height,
     1574    png_uint_32 x_offset, png_uint_32 y_offset,
     1575    png_uint_16 delay_num, png_uint_16 delay_den, png_byte dispose_op,
     1576    png_byte blend_op)
     1577{
     1578    png_debug(1, "in png_write_frame_head\n");
     1579
     1580    /* there is a chance this has been set after png_write_info was called,
     1581    * so it would be set but not written. is there a way to be sure? */
     1582    if (!(info_ptr->valid & PNG_INFO_acTL))
     1583        png_error(png_ptr, "png_write_frame_head(): acTL not set");
     1584
     1585    png_write_reset(png_ptr);
     1586
     1587    png_write_reinit(png_ptr, info_ptr, width, height);
     1588
     1589    if ( !(png_ptr->num_frames_written == 0 &&
     1590           (png_ptr->apng_flags & PNG_FIRST_FRAME_HIDDEN) ) )
     1591        png_write_fcTL(png_ptr, width, height, x_offset, y_offset,
     1592                       delay_num, delay_den, dispose_op, blend_op);
     1593}
     1594
     1595void PNGAPI
     1596png_write_frame_tail(png_structp png_ptr, png_infop png_info)
     1597{
     1598    png_debug(1, "in png_write_frame_tail\n");
     1599
     1600    png_ptr->num_frames_written++;
     1601}
     1602#endif /* PNG_WRITE_APNG_SUPPORTED */
     1603
    15611604#endif /* PNG_WRITE_SUPPORTED */
  • TabularUnified pngwutil.c

    diff -Naur libpng-1.2.38-orig/pngwutil.c libpng-1.2.38/pngwutil.c
    old new  
    511511   /* Write the chunk */
    512512   png_write_chunk(png_ptr, (png_bytep)png_IHDR, buf, (png_size_t)13);
    513513
     514#if defined(PNG_WRITE_APNG_SUPPORTED)
     515   png_ptr->first_frame_width = width;
     516   png_ptr->first_frame_height = height;
     517#endif
     518
    514519   /* Initialize zlib with PNG info */
    515520   png_ptr->zstream.zalloc = png_zalloc;
    516521   png_ptr->zstream.zfree = png_zfree;
     
    633638{
    634639#ifdef PNG_USE_LOCAL_ARRAYS
    635640   PNG_IDAT;
     641#if defined(PNG_WRITE_APNG_SUPPORTED)
     642   PNG_fdAT;
     643#endif
    636644#endif
    637645   png_debug(1, "in png_write_IDAT");
    638646
     
    677685            "Invalid zlib compression method or flags in IDAT");
    678686   }
    679687
    680    png_write_chunk(png_ptr, (png_bytep)png_IDAT, data, length);
     688#if defined(PNG_WRITE_APNG_SUPPORTED)
     689   if(png_ptr->num_frames_written == 0)
     690#endif
     691      png_write_chunk(png_ptr, (png_bytep)png_IDAT, data, length);
     692#if defined(PNG_WRITE_APNG_SUPPORTED)
     693   else
     694   {
     695      png_byte buf[4];
     696
     697      png_write_chunk_start(png_ptr, (png_bytep)png_fdAT, 4 + length);
     698
     699      png_save_uint_32(buf, png_ptr->next_seq_num);
     700      png_write_chunk_data(png_ptr, buf, 4);
     701
     702      png_write_chunk_data(png_ptr, data, length);
     703
     704      png_write_chunk_end(png_ptr);
     705
     706      png_ptr->next_seq_num++;
     707   }
     708#endif
     709
    681710   png_ptr->mode |= PNG_HAVE_IDAT;
    682711}
    683712
     
    17191748}
    17201749#endif
    17211750
     1751#if defined(PNG_WRITE_APNG_SUPPORTED)
     1752void /* PRIVATE */
     1753png_write_acTL(png_structp png_ptr,
     1754   png_uint_32 num_frames, png_uint_32 num_plays)
     1755{
     1756#ifdef PNG_USE_LOCAL_ARRAYS
     1757    PNG_acTL;
     1758#endif
     1759    png_byte data[16];
     1760
     1761    png_debug(1, "in png_write_acTL\n");
     1762
     1763    png_ptr->num_frames_to_write = num_frames;
     1764
     1765    if (png_ptr->apng_flags & PNG_FIRST_FRAME_HIDDEN)
     1766        num_frames--;
     1767
     1768    png_save_uint_32(data, num_frames);
     1769    png_save_uint_32(data + 4, num_plays);
     1770
     1771    png_write_chunk(png_ptr, (png_bytep)png_acTL, data, (png_size_t)8);
     1772}
     1773
     1774void /* PRIVATE */
     1775png_write_fcTL(png_structp png_ptr, png_uint_32 width, png_uint_32 height,
     1776    png_uint_32 x_offset, png_uint_32 y_offset,
     1777    png_uint_16 delay_num, png_uint_16 delay_den, png_byte dispose_op,
     1778    png_byte blend_op)
     1779{
     1780#ifdef PNG_USE_LOCAL_ARRAYS
     1781    PNG_fcTL;
     1782#endif
     1783    png_byte data[26];
     1784
     1785    png_debug(1, "in png_write_fcTL\n");
     1786
     1787    if (png_ptr->num_frames_written == 0 && (x_offset != 0 || y_offset != 0))
     1788        png_error(png_ptr, "x and/or y offset for the first frame aren't 0\n");
     1789    if (png_ptr->num_frames_written == 0 &&
     1790        (width != png_ptr->first_frame_width ||
     1791         height != png_ptr->first_frame_height))
     1792        png_error(png_ptr, "width and/or height in the first frame's fcTL "
     1793                           "don't match the ones in IHDR\n");
     1794
     1795    /* more error checking */
     1796    png_ensure_fcTL_is_valid(png_ptr, width, height, x_offset, y_offset,
     1797                             delay_num, delay_den, dispose_op, blend_op);
     1798    png_save_uint_32(data, png_ptr->next_seq_num);
     1799    png_save_uint_32(data + 4, width);
     1800    png_save_uint_32(data + 8, height);
     1801    png_save_uint_32(data + 12, x_offset);
     1802    png_save_uint_32(data + 16, y_offset);
     1803    png_save_uint_16(data + 20, delay_num);
     1804    png_save_uint_16(data + 22, delay_den);
     1805    data[24] = dispose_op;
     1806    data[25] = blend_op;
     1807
     1808    png_write_chunk(png_ptr, (png_bytep)png_fcTL, data, (png_size_t)26);
     1809
     1810    png_ptr->next_seq_num++;
     1811}
     1812#endif /* PNG_WRITE_APNG_SUPPORTED */
     1813
    17221814/* Initializes the row writing capability of libpng */
    17231815void /* PRIVATE */
    17241816png_write_start_row(png_structp png_ptr)
     
    27882880   }
    27892881#endif
    27902882}
     2883
     2884#if defined(PNG_WRITE_APNG_SUPPORTED)
     2885void /* PRIVATE */
     2886png_write_reset(png_structp png_ptr)
     2887{
     2888    png_ptr->row_number = 0;
     2889    png_ptr->pass = 0;
     2890    png_ptr->mode &= ~PNG_HAVE_IDAT;
     2891}
     2892
     2893void /* PRIVATE */
     2894png_write_reinit(png_structp png_ptr, png_infop info_ptr,
     2895                 png_uint_32 width, png_uint_32 height)
     2896{
     2897    if (png_ptr->num_frames_written == 0 &&
     2898        (width != png_ptr->first_frame_width ||
     2899         height != png_ptr->first_frame_height))
     2900        png_error(png_ptr, "width and/or height in the first frame's fcTL "
     2901                           "don't match the ones in IHDR\n");
     2902    if (width > png_ptr->first_frame_width ||
     2903        height > png_ptr->first_frame_height)
     2904        png_error(png_ptr, "width and/or height for a frame greater than"
     2905                           "the ones in IHDR");
     2906
     2907    png_set_IHDR(png_ptr, info_ptr, width, height,
     2908                 info_ptr->bit_depth, info_ptr->color_type,
     2909                 info_ptr->interlace_type, info_ptr->compression_type,
     2910                 info_ptr->filter_type);
     2911
     2912    png_ptr->width = width;
     2913    png_ptr->height = height;
     2914    png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, width);
     2915    png_ptr->usr_width = png_ptr->width;
     2916}
     2917#endif
    27912918#endif /* PNG_WRITE_SUPPORTED */