< prev index next >

src/java.desktop/share/native/libsplashscreen/libpng/pngwrite.c

Print this page




  13  * version 2 for more details (a copy is included in the LICENSE file that
  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  */
  24 
  25 /* pngwrite.c - general routines to write a PNG file
  26  *
  27  * This file is available under and governed by the GNU General Public
  28  * License version 2 only, as published by the Free Software Foundation.
  29  * However, the following notice accompanied the original version of this
  30  * file and, per its terms, should not be removed:
  31  *
  32  * Last changed in libpng 1.6.19 [November 12, 2015]
  33  * Copyright (c) 1998-2015 Glenn Randers-Pehrson
  34  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  35  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  36  *
  37  * This code is released under the libpng license.
  38  * For conditions of distribution and use, see the disclaimer
  39  * and license in png.h
  40  */
  41 
  42 #include "pngpriv.h"
  43 #if defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) && defined(PNG_STDIO_SUPPORTED)
  44 #  include <errno.h>
  45 #endif
  46 
  47 #ifdef PNG_WRITE_SUPPORTED
  48 
  49 #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
  50 /* Write out all the unknown chunks for the current given location */
  51 static void
  52 write_unknown_chunks(png_structrp png_ptr, png_const_inforp info_ptr,
  53    unsigned int where)
  54 {
  55    if (info_ptr->unknown_chunks_num != 0)
  56    {
  57       png_const_unknown_chunkp up;
  58 
  59       png_debug(5, "writing extra chunks");
  60 
  61       for (up = info_ptr->unknown_chunks;
  62            up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num;
  63            ++up)
  64          if ((up->location & where) != 0)
  65       {


1463 #ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
1464       png_set_invert_alpha(png_ptr);
1465 #else
1466       png_app_error(png_ptr, "PNG_TRANSFORM_INVERT_ALPHA not supported");
1467 #endif
1468 
1469    /* ----------------------- end of transformations ------------------- */
1470 
1471    /* Write the bits */
1472    png_write_image(png_ptr, info_ptr->row_pointers);
1473 
1474    /* It is REQUIRED to call this to finish writing the rest of the file */
1475    png_write_end(png_ptr, info_ptr);
1476 
1477    PNG_UNUSED(params)
1478 }
1479 #endif
1480 
1481 
1482 #ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED
1483 # ifdef PNG_STDIO_SUPPORTED /* currently required for png_image_write_* */
1484 /* Initialize the write structure - general purpose utility. */
1485 static int
1486 png_image_write_init(png_imagep image)
1487 {
1488    png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, image,
1489        png_safe_error, png_safe_warning);
1490 
1491    if (png_ptr != NULL)
1492    {
1493       png_infop info_ptr = png_create_info_struct(png_ptr);
1494 
1495       if (info_ptr != NULL)
1496       {
1497          png_controlp control = png_voidcast(png_controlp,
1498              png_malloc_warn(png_ptr, (sizeof *control)));
1499 
1500          if (control != NULL)
1501          {
1502             memset(control, 0, (sizeof *control));
1503 


1515 
1516       png_destroy_write_struct(&png_ptr, NULL);
1517    }
1518 
1519    return png_image_error(image, "png_image_write_: out of memory");
1520 }
1521 
1522 /* Arguments to png_image_write_main: */
1523 typedef struct
1524 {
1525    /* Arguments: */
1526    png_imagep      image;
1527    png_const_voidp buffer;
1528    png_int_32      row_stride;
1529    png_const_voidp colormap;
1530    int             convert_to_8bit;
1531    /* Local variables: */
1532    png_const_voidp first_row;
1533    ptrdiff_t       row_bytes;
1534    png_voidp       local_row;




1535 } png_image_write_control;
1536 
1537 /* Write png_uint_16 input to a 16-bit PNG; the png_ptr has already been set to
1538  * do any necessary byte swapping.  The component order is defined by the
1539  * png_image format value.
1540  */
1541 static int
1542 png_write_image_16bit(png_voidp argument)
1543 {
1544    png_image_write_control *display = png_voidcast(png_image_write_control*,
1545        argument);
1546    png_imagep image = display->image;
1547    png_structrp png_ptr = image->opaque->png_ptr;
1548 
1549    png_const_uint_16p input_row = png_voidcast(png_const_uint_16p,
1550        display->first_row);
1551    png_uint_16p output_row = png_voidcast(png_uint_16p, display->local_row);
1552    png_uint_16p row_end;
1553    const int channels = (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ? 3 : 1;
1554    int aindex = 0;


1942 png_image_write_main(png_voidp argument)
1943 {
1944    png_image_write_control *display = png_voidcast(png_image_write_control*,
1945       argument);
1946    png_imagep image = display->image;
1947    png_structrp png_ptr = image->opaque->png_ptr;
1948    png_inforp info_ptr = image->opaque->info_ptr;
1949    png_uint_32 format = image->format;
1950 
1951    /* The following four ints are actually booleans */
1952    int colormap = (format & PNG_FORMAT_FLAG_COLORMAP);
1953    int linear = !colormap && (format & PNG_FORMAT_FLAG_LINEAR); /* input */
1954    int alpha = !colormap && (format & PNG_FORMAT_FLAG_ALPHA);
1955    int write_16bit = linear && !colormap && (display->convert_to_8bit == 0);
1956 
1957 #   ifdef PNG_BENIGN_ERRORS_SUPPORTED
1958       /* Make sure we error out on any bad situation */
1959       png_set_benign_errors(png_ptr, 0/*error*/);
1960 #   endif
1961 
1962    /* Default the 'row_stride' parameter if required. */










1963    if (display->row_stride == 0)
1964       display->row_stride = PNG_IMAGE_ROW_STRIDE(*image);
























1965 
1966    /* Set the required transforms then write the rows in the correct order. */
1967    if ((format & PNG_FORMAT_FLAG_COLORMAP) != 0)
1968    {
1969       if (display->colormap != NULL && image->colormap_entries > 0)
1970       {
1971          png_uint_32 entries = image->colormap_entries;
1972 
1973          png_set_IHDR(png_ptr, info_ptr, image->width, image->height,
1974             entries > 16 ? 8 : (entries > 4 ? 4 : (entries > 2 ? 2 : 1)),
1975             PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE,
1976             PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
1977 
1978          png_image_set_PLTE(display);
1979       }
1980 
1981       else
1982          png_error(image->opaque->png_ptr,
1983             "no color-map for color-mapped image");
1984    }


2121    /* Otherwise this is the case where the input is in a format currently
2122     * supported by the rest of the libpng write code; call it directly.
2123     */
2124    else
2125    {
2126       png_const_bytep row = png_voidcast(png_const_bytep, display->first_row);
2127       ptrdiff_t row_bytes = display->row_bytes;
2128       png_uint_32 y = image->height;
2129 
2130       while (y-- > 0)
2131       {
2132          png_write_row(png_ptr, row);
2133          row += row_bytes;
2134       }
2135    }
2136 
2137    png_write_end(png_ptr, info_ptr);
2138    return 1;
2139 }
2140 




















































































































2141 int PNGAPI
2142 png_image_write_to_stdio(png_imagep image, FILE *file, int convert_to_8bit,
2143    const void *buffer, png_int_32 row_stride, const void *colormap)
2144 {
2145    /* Write the image to the given (FILE*). */
2146    if (image != NULL && image->version == PNG_IMAGE_VERSION)
2147    {
2148       if (file != NULL)
2149       {
2150          if (png_image_write_init(image) != 0)
2151          {
2152             png_image_write_control display;
2153             int result;
2154 
2155             /* This is slightly evil, but png_init_io doesn't do anything other
2156              * than this and we haven't changed the standard IO functions so
2157              * this saves a 'safe' function.
2158              */
2159             image->opaque->png_ptr->io_ptr = file;
2160 
2161             memset(&display, 0, (sizeof display));
2162             display.image = image;
2163             display.buffer = buffer;
2164             display.row_stride = row_stride;
2165             display.colormap = colormap;
2166             display.convert_to_8bit = convert_to_8bit;
2167 
2168             result = png_safe_execute(image, png_image_write_main, &display);


2178          return png_image_error(image,
2179             "png_image_write_to_stdio: invalid argument");
2180    }
2181 
2182    else if (image != NULL)
2183       return png_image_error(image,
2184          "png_image_write_to_stdio: incorrect PNG_IMAGE_VERSION");
2185 
2186    else
2187       return 0;
2188 }
2189 
2190 int PNGAPI
2191 png_image_write_to_file(png_imagep image, const char *file_name,
2192    int convert_to_8bit, const void *buffer, png_int_32 row_stride,
2193    const void *colormap)
2194 {
2195    /* Write the image to the named file. */
2196    if (image != NULL && image->version == PNG_IMAGE_VERSION)
2197    {
2198       if (file_name != NULL)
2199       {
2200          FILE *fp = fopen(file_name, "wb");
2201 
2202          if (fp != NULL)
2203          {
2204             if (png_image_write_to_stdio(image, fp, convert_to_8bit, buffer,
2205                row_stride, colormap) != 0)
2206             {
2207                int error; /* from fflush/fclose */
2208 
2209                /* Make sure the file is flushed correctly. */
2210                if (fflush(fp) == 0 && ferror(fp) == 0)
2211                {
2212                   if (fclose(fp) == 0)
2213                      return 1;
2214 
2215                   error = errno; /* from fclose */
2216                }
2217 
2218                else


2236                return 0;
2237             }
2238          }
2239 
2240          else
2241             return png_image_error(image, strerror(errno));
2242       }
2243 
2244       else
2245          return png_image_error(image,
2246             "png_image_write_to_file: invalid argument");
2247    }
2248 
2249    else if (image != NULL)
2250       return png_image_error(image,
2251          "png_image_write_to_file: incorrect PNG_IMAGE_VERSION");
2252 
2253    else
2254       return 0;
2255 }
2256 # endif /* STDIO */
2257 #endif /* SIMPLIFIED_WRITE */
2258 #endif /* WRITE */


  13  * version 2 for more details (a copy is included in the LICENSE file that
  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  */
  24 
  25 /* pngwrite.c - general routines to write a PNG file
  26  *
  27  * This file is available under and governed by the GNU General Public
  28  * License version 2 only, as published by the Free Software Foundation.
  29  * However, the following notice accompanied the original version of this
  30  * file and, per its terms, should not be removed:
  31  *
  32  * Last changed in libpng 1.6.19 [November 12, 2015]
  33  * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson
  34  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  35  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  36  *
  37  * This code is released under the libpng license.
  38  * For conditions of distribution and use, see the disclaimer
  39  * and license in png.h
  40  */
  41 
  42 #include "pngpriv.h"
  43 #ifdef PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED
  44 #  include <errno.h>
  45 #endif /* SIMPLIFIED_WRITE_STDIO */
  46 
  47 #ifdef PNG_WRITE_SUPPORTED
  48 
  49 #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
  50 /* Write out all the unknown chunks for the current given location */
  51 static void
  52 write_unknown_chunks(png_structrp png_ptr, png_const_inforp info_ptr,
  53    unsigned int where)
  54 {
  55    if (info_ptr->unknown_chunks_num != 0)
  56    {
  57       png_const_unknown_chunkp up;
  58 
  59       png_debug(5, "writing extra chunks");
  60 
  61       for (up = info_ptr->unknown_chunks;
  62            up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num;
  63            ++up)
  64          if ((up->location & where) != 0)
  65       {


1463 #ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
1464       png_set_invert_alpha(png_ptr);
1465 #else
1466       png_app_error(png_ptr, "PNG_TRANSFORM_INVERT_ALPHA not supported");
1467 #endif
1468 
1469    /* ----------------------- end of transformations ------------------- */
1470 
1471    /* Write the bits */
1472    png_write_image(png_ptr, info_ptr->row_pointers);
1473 
1474    /* It is REQUIRED to call this to finish writing the rest of the file */
1475    png_write_end(png_ptr, info_ptr);
1476 
1477    PNG_UNUSED(params)
1478 }
1479 #endif
1480 
1481 
1482 #ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED

1483 /* Initialize the write structure - general purpose utility. */
1484 static int
1485 png_image_write_init(png_imagep image)
1486 {
1487    png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, image,
1488        png_safe_error, png_safe_warning);
1489 
1490    if (png_ptr != NULL)
1491    {
1492       png_infop info_ptr = png_create_info_struct(png_ptr);
1493 
1494       if (info_ptr != NULL)
1495       {
1496          png_controlp control = png_voidcast(png_controlp,
1497              png_malloc_warn(png_ptr, (sizeof *control)));
1498 
1499          if (control != NULL)
1500          {
1501             memset(control, 0, (sizeof *control));
1502 


1514 
1515       png_destroy_write_struct(&png_ptr, NULL);
1516    }
1517 
1518    return png_image_error(image, "png_image_write_: out of memory");
1519 }
1520 
1521 /* Arguments to png_image_write_main: */
1522 typedef struct
1523 {
1524    /* Arguments: */
1525    png_imagep      image;
1526    png_const_voidp buffer;
1527    png_int_32      row_stride;
1528    png_const_voidp colormap;
1529    int             convert_to_8bit;
1530    /* Local variables: */
1531    png_const_voidp first_row;
1532    ptrdiff_t       row_bytes;
1533    png_voidp       local_row;
1534    /* Byte count for memory writing */
1535    png_bytep        memory;
1536    png_alloc_size_t memory_bytes; /* not used for STDIO */
1537    png_alloc_size_t output_bytes; /* running total */
1538 } png_image_write_control;
1539 
1540 /* Write png_uint_16 input to a 16-bit PNG; the png_ptr has already been set to
1541  * do any necessary byte swapping.  The component order is defined by the
1542  * png_image format value.
1543  */
1544 static int
1545 png_write_image_16bit(png_voidp argument)
1546 {
1547    png_image_write_control *display = png_voidcast(png_image_write_control*,
1548        argument);
1549    png_imagep image = display->image;
1550    png_structrp png_ptr = image->opaque->png_ptr;
1551 
1552    png_const_uint_16p input_row = png_voidcast(png_const_uint_16p,
1553        display->first_row);
1554    png_uint_16p output_row = png_voidcast(png_uint_16p, display->local_row);
1555    png_uint_16p row_end;
1556    const int channels = (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ? 3 : 1;
1557    int aindex = 0;


1945 png_image_write_main(png_voidp argument)
1946 {
1947    png_image_write_control *display = png_voidcast(png_image_write_control*,
1948       argument);
1949    png_imagep image = display->image;
1950    png_structrp png_ptr = image->opaque->png_ptr;
1951    png_inforp info_ptr = image->opaque->info_ptr;
1952    png_uint_32 format = image->format;
1953 
1954    /* The following four ints are actually booleans */
1955    int colormap = (format & PNG_FORMAT_FLAG_COLORMAP);
1956    int linear = !colormap && (format & PNG_FORMAT_FLAG_LINEAR); /* input */
1957    int alpha = !colormap && (format & PNG_FORMAT_FLAG_ALPHA);
1958    int write_16bit = linear && !colormap && (display->convert_to_8bit == 0);
1959 
1960 #   ifdef PNG_BENIGN_ERRORS_SUPPORTED
1961       /* Make sure we error out on any bad situation */
1962       png_set_benign_errors(png_ptr, 0/*error*/);
1963 #   endif
1964 
1965    /* Default the 'row_stride' parameter if required, also check the row stride
1966     * and total image size to ensure that they are within the system limits.
1967     */
1968    {
1969       const unsigned int channels = PNG_IMAGE_PIXEL_CHANNELS(image->format);
1970 
1971       if (image->width <= 0x7FFFFFFFU/channels) /* no overflow */
1972       {
1973          png_uint_32 check;
1974          const png_uint_32 png_row_stride = image->width * channels;
1975 
1976          if (display->row_stride == 0)
1977             display->row_stride = (png_int_32)/*SAFE*/png_row_stride;
1978 
1979          if (display->row_stride < 0)
1980             check = -display->row_stride;
1981 
1982          else
1983             check = display->row_stride;
1984 
1985          if (check >= png_row_stride)
1986          {
1987             /* Now check for overflow of the image buffer calculation; this
1988              * limits the whole image size to 32 bits for API compatibility with
1989              * the current, 32-bit, PNG_IMAGE_BUFFER_SIZE macro.
1990              */
1991             if (image->height > 0xFFFFFFFF/png_row_stride)
1992                png_error(image->opaque->png_ptr, "memory image too large");
1993          }
1994 
1995          else
1996             png_error(image->opaque->png_ptr, "supplied row stride too small");
1997       }
1998 
1999       else
2000          png_error(image->opaque->png_ptr, "image row stride too large");
2001    }
2002 
2003    /* Set the required transforms then write the rows in the correct order. */
2004    if ((format & PNG_FORMAT_FLAG_COLORMAP) != 0)
2005    {
2006       if (display->colormap != NULL && image->colormap_entries > 0)
2007       {
2008          png_uint_32 entries = image->colormap_entries;
2009 
2010          png_set_IHDR(png_ptr, info_ptr, image->width, image->height,
2011             entries > 16 ? 8 : (entries > 4 ? 4 : (entries > 2 ? 2 : 1)),
2012             PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE,
2013             PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
2014 
2015          png_image_set_PLTE(display);
2016       }
2017 
2018       else
2019          png_error(image->opaque->png_ptr,
2020             "no color-map for color-mapped image");
2021    }


2158    /* Otherwise this is the case where the input is in a format currently
2159     * supported by the rest of the libpng write code; call it directly.
2160     */
2161    else
2162    {
2163       png_const_bytep row = png_voidcast(png_const_bytep, display->first_row);
2164       ptrdiff_t row_bytes = display->row_bytes;
2165       png_uint_32 y = image->height;
2166 
2167       while (y-- > 0)
2168       {
2169          png_write_row(png_ptr, row);
2170          row += row_bytes;
2171       }
2172    }
2173 
2174    png_write_end(png_ptr, info_ptr);
2175    return 1;
2176 }
2177 
2178 
2179 static void (PNGCBAPI
2180 image_memory_write)(png_structp png_ptr, png_bytep/*const*/ data,
2181    png_size_t size)
2182 {
2183    png_image_write_control *display = png_voidcast(png_image_write_control*,
2184       png_ptr->io_ptr/*backdoor: png_get_io_ptr(png_ptr)*/);
2185    const png_alloc_size_t ob = display->output_bytes;
2186 
2187    /* Check for overflow; this should never happen: */
2188    if (size <= ((png_alloc_size_t)-1) - ob)
2189    {
2190       /* I don't think libpng ever does this, but just in case: */
2191       if (size > 0)
2192       {
2193          if (display->memory_bytes >= ob+size) /* writing */
2194             memcpy(display->memory+ob, data, size);
2195 
2196          /* Always update the size: */
2197          display->output_bytes = ob+size;
2198       }
2199    }
2200 
2201    else
2202       png_error(png_ptr, "png_image_write_to_memory: PNG too big");
2203 }
2204 
2205 static void (PNGCBAPI
2206 image_memory_flush)(png_structp png_ptr)
2207 {
2208    PNG_UNUSED(png_ptr)
2209 }
2210 
2211 static int
2212 png_image_write_memory(png_voidp argument)
2213 {
2214    png_image_write_control *display = png_voidcast(png_image_write_control*,
2215       argument);
2216 
2217    /* The rest of the memory-specific init and write_main in an error protected
2218     * environment.  This case needs to use callbacks for the write operations
2219     * since libpng has no built in support for writing to memory.
2220     */
2221    png_set_write_fn(display->image->opaque->png_ptr, display/*io_ptr*/,
2222          image_memory_write, image_memory_flush);
2223 
2224    return png_image_write_main(display);
2225 }
2226 
2227 int PNGAPI
2228 png_image_write_to_memory(png_imagep image, void *memory,
2229    png_alloc_size_t * PNG_RESTRICT memory_bytes, int convert_to_8bit,
2230    const void *buffer, png_int_32 row_stride, const void *colormap)
2231 {
2232    /* Write the image to the given buffer, or count the bytes if it is NULL */
2233    if (image != NULL && image->version == PNG_IMAGE_VERSION)
2234    {
2235       if (memory_bytes != NULL && buffer != NULL)
2236       {
2237          /* This is to give the caller an easier error detection in the NULL
2238           * case and guard against uninitialized variable problems:
2239           */
2240          if (memory == NULL)
2241             *memory_bytes = 0;
2242 
2243          if (png_image_write_init(image) != 0)
2244          {
2245             png_image_write_control display;
2246             int result;
2247 
2248             memset(&display, 0, (sizeof display));
2249             display.image = image;
2250             display.buffer = buffer;
2251             display.row_stride = row_stride;
2252             display.colormap = colormap;
2253             display.convert_to_8bit = convert_to_8bit;
2254             display.memory = png_voidcast(png_bytep, memory);
2255             display.memory_bytes = *memory_bytes;
2256             display.output_bytes = 0;
2257 
2258             result = png_safe_execute(image, png_image_write_memory, &display);
2259             png_image_free(image);
2260 
2261             /* write_memory returns true even if we ran out of buffer. */
2262             if (result)
2263             {
2264                /* On out-of-buffer this function returns '0' but still updates
2265                 * memory_bytes:
2266                 */
2267                if (memory != NULL && display.output_bytes > *memory_bytes)
2268                   result = 0;
2269 
2270                *memory_bytes = display.output_bytes;
2271             }
2272 
2273             return result;
2274          }
2275 
2276          else
2277             return 0;
2278       }
2279 
2280       else
2281          return png_image_error(image,
2282             "png_image_write_to_memory: invalid argument");
2283    }
2284 
2285    else if (image != NULL)
2286       return png_image_error(image,
2287          "png_image_write_to_memory: incorrect PNG_IMAGE_VERSION");
2288 
2289    else
2290       return 0;
2291 }
2292 
2293 #ifdef PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED
2294 int PNGAPI
2295 png_image_write_to_stdio(png_imagep image, FILE *file, int convert_to_8bit,
2296    const void *buffer, png_int_32 row_stride, const void *colormap)
2297 {
2298    /* Write the image to the given (FILE*). */
2299    if (image != NULL && image->version == PNG_IMAGE_VERSION)
2300    {
2301       if (file != NULL && buffer != NULL)
2302       {
2303          if (png_image_write_init(image) != 0)
2304          {
2305             png_image_write_control display;
2306             int result;
2307 
2308             /* This is slightly evil, but png_init_io doesn't do anything other
2309              * than this and we haven't changed the standard IO functions so
2310              * this saves a 'safe' function.
2311              */
2312             image->opaque->png_ptr->io_ptr = file;
2313 
2314             memset(&display, 0, (sizeof display));
2315             display.image = image;
2316             display.buffer = buffer;
2317             display.row_stride = row_stride;
2318             display.colormap = colormap;
2319             display.convert_to_8bit = convert_to_8bit;
2320 
2321             result = png_safe_execute(image, png_image_write_main, &display);


2331          return png_image_error(image,
2332             "png_image_write_to_stdio: invalid argument");
2333    }
2334 
2335    else if (image != NULL)
2336       return png_image_error(image,
2337          "png_image_write_to_stdio: incorrect PNG_IMAGE_VERSION");
2338 
2339    else
2340       return 0;
2341 }
2342 
2343 int PNGAPI
2344 png_image_write_to_file(png_imagep image, const char *file_name,
2345    int convert_to_8bit, const void *buffer, png_int_32 row_stride,
2346    const void *colormap)
2347 {
2348    /* Write the image to the named file. */
2349    if (image != NULL && image->version == PNG_IMAGE_VERSION)
2350    {
2351       if (file_name != NULL && buffer != NULL)
2352       {
2353          FILE *fp = fopen(file_name, "wb");
2354 
2355          if (fp != NULL)
2356          {
2357             if (png_image_write_to_stdio(image, fp, convert_to_8bit, buffer,
2358                row_stride, colormap) != 0)
2359             {
2360                int error; /* from fflush/fclose */
2361 
2362                /* Make sure the file is flushed correctly. */
2363                if (fflush(fp) == 0 && ferror(fp) == 0)
2364                {
2365                   if (fclose(fp) == 0)
2366                      return 1;
2367 
2368                   error = errno; /* from fclose */
2369                }
2370 
2371                else


2389                return 0;
2390             }
2391          }
2392 
2393          else
2394             return png_image_error(image, strerror(errno));
2395       }
2396 
2397       else
2398          return png_image_error(image,
2399             "png_image_write_to_file: invalid argument");
2400    }
2401 
2402    else if (image != NULL)
2403       return png_image_error(image,
2404          "png_image_write_to_file: incorrect PNG_IMAGE_VERSION");
2405 
2406    else
2407       return 0;
2408 }
2409 #endif /* SIMPLIFIED_WRITE_STDIO */
2410 #endif /* SIMPLIFIED_WRITE */
2411 #endif /* WRITE */
< prev index next >