|
fltk 1.3.0rc3
About: FLTK (Fast Light Tool Kit) is a cross-platform C++ GUI toolkit for UNIX/Linux (X11), Microsoft Windows, and MacOS X. Release candidate.
SfR Fresh Dox: fltk-1.3.0rc3-source.tar.gz ("inofficial" and yet experimental doxygen-generated source code documentation) ![]() |
00001 00002 /* pngset.c - storage of image information into info struct 00003 * 00004 * Last changed in libpng 1.2.40 [September 10, 2009] 00005 * Copyright (c) 1998-2009 Glenn Randers-Pehrson 00006 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) 00007 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) 00008 * 00009 * This code is released under the libpng license. 00010 * For conditions of distribution and use, see the disclaimer 00011 * and license in png.h 00012 * 00013 * The functions here are used during reads to store data from the file 00014 * into the info struct, and during writes to store application data 00015 * into the info struct for writing into the file. This abstracts the 00016 * info struct and allows us to change the structure in the future. 00017 */ 00018 00019 #define PNG_INTERNAL 00020 #include "png.h" 00021 #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) 00022 00023 #if defined(PNG_bKGD_SUPPORTED) 00024 void PNGAPI 00025 png_set_bKGD(png_structp png_ptr, png_infop info_ptr, png_color_16p background) 00026 { 00027 png_debug1(1, "in %s storage function", "bKGD"); 00028 00029 if (png_ptr == NULL || info_ptr == NULL) 00030 return; 00031 00032 png_memcpy(&(info_ptr->background), background, png_sizeof(png_color_16)); 00033 info_ptr->valid |= PNG_INFO_bKGD; 00034 } 00035 #endif 00036 00037 #if defined(PNG_cHRM_SUPPORTED) 00038 #ifdef PNG_FLOATING_POINT_SUPPORTED 00039 void PNGAPI 00040 png_set_cHRM(png_structp png_ptr, png_infop info_ptr, 00041 double white_x, double white_y, double red_x, double red_y, 00042 double green_x, double green_y, double blue_x, double blue_y) 00043 { 00044 png_debug1(1, "in %s storage function", "cHRM"); 00045 00046 if (png_ptr == NULL || info_ptr == NULL) 00047 return; 00048 00049 info_ptr->x_white = (float)white_x; 00050 info_ptr->y_white = (float)white_y; 00051 info_ptr->x_red = (float)red_x; 00052 info_ptr->y_red = (float)red_y; 00053 info_ptr->x_green = (float)green_x; 00054 info_ptr->y_green = (float)green_y; 00055 info_ptr->x_blue = (float)blue_x; 00056 info_ptr->y_blue = (float)blue_y; 00057 #ifdef PNG_FIXED_POINT_SUPPORTED 00058 info_ptr->int_x_white = (png_fixed_point)(white_x*100000.+0.5); 00059 info_ptr->int_y_white = (png_fixed_point)(white_y*100000.+0.5); 00060 info_ptr->int_x_red = (png_fixed_point)( red_x*100000.+0.5); 00061 info_ptr->int_y_red = (png_fixed_point)( red_y*100000.+0.5); 00062 info_ptr->int_x_green = (png_fixed_point)(green_x*100000.+0.5); 00063 info_ptr->int_y_green = (png_fixed_point)(green_y*100000.+0.5); 00064 info_ptr->int_x_blue = (png_fixed_point)( blue_x*100000.+0.5); 00065 info_ptr->int_y_blue = (png_fixed_point)( blue_y*100000.+0.5); 00066 #endif 00067 info_ptr->valid |= PNG_INFO_cHRM; 00068 } 00069 #endif /* PNG_FLOATING_POINT_SUPPORTED */ 00070 00071 #ifdef PNG_FIXED_POINT_SUPPORTED 00072 void PNGAPI 00073 png_set_cHRM_fixed(png_structp png_ptr, png_infop info_ptr, 00074 png_fixed_point white_x, png_fixed_point white_y, png_fixed_point red_x, 00075 png_fixed_point red_y, png_fixed_point green_x, png_fixed_point green_y, 00076 png_fixed_point blue_x, png_fixed_point blue_y) 00077 { 00078 png_debug1(1, "in %s storage function", "cHRM fixed"); 00079 00080 if (png_ptr == NULL || info_ptr == NULL) 00081 return; 00082 00083 #if !defined(PNG_NO_CHECK_cHRM) 00084 if (png_check_cHRM_fixed(png_ptr, 00085 white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y)) 00086 #endif 00087 { 00088 info_ptr->int_x_white = white_x; 00089 info_ptr->int_y_white = white_y; 00090 info_ptr->int_x_red = red_x; 00091 info_ptr->int_y_red = red_y; 00092 info_ptr->int_x_green = green_x; 00093 info_ptr->int_y_green = green_y; 00094 info_ptr->int_x_blue = blue_x; 00095 info_ptr->int_y_blue = blue_y; 00096 #ifdef PNG_FLOATING_POINT_SUPPORTED 00097 info_ptr->x_white = (float)(white_x/100000.); 00098 info_ptr->y_white = (float)(white_y/100000.); 00099 info_ptr->x_red = (float)( red_x/100000.); 00100 info_ptr->y_red = (float)( red_y/100000.); 00101 info_ptr->x_green = (float)(green_x/100000.); 00102 info_ptr->y_green = (float)(green_y/100000.); 00103 info_ptr->x_blue = (float)( blue_x/100000.); 00104 info_ptr->y_blue = (float)( blue_y/100000.); 00105 #endif 00106 info_ptr->valid |= PNG_INFO_cHRM; 00107 } 00108 } 00109 #endif /* PNG_FIXED_POINT_SUPPORTED */ 00110 #endif /* PNG_cHRM_SUPPORTED */ 00111 00112 #if defined(PNG_gAMA_SUPPORTED) 00113 #ifdef PNG_FLOATING_POINT_SUPPORTED 00114 void PNGAPI 00115 png_set_gAMA(png_structp png_ptr, png_infop info_ptr, double file_gamma) 00116 { 00117 double png_gamma; 00118 00119 png_debug1(1, "in %s storage function", "gAMA"); 00120 00121 if (png_ptr == NULL || info_ptr == NULL) 00122 return; 00123 00124 /* Check for overflow */ 00125 if (file_gamma > 21474.83) 00126 { 00127 png_warning(png_ptr, "Limiting gamma to 21474.83"); 00128 png_gamma=21474.83; 00129 } 00130 else 00131 png_gamma = file_gamma; 00132 info_ptr->gamma = (float)png_gamma; 00133 #ifdef PNG_FIXED_POINT_SUPPORTED 00134 info_ptr->int_gamma = (int)(png_gamma*100000.+.5); 00135 #endif 00136 info_ptr->valid |= PNG_INFO_gAMA; 00137 if (png_gamma == 0.0) 00138 png_warning(png_ptr, "Setting gamma=0"); 00139 } 00140 #endif 00141 void PNGAPI 00142 png_set_gAMA_fixed(png_structp png_ptr, png_infop info_ptr, png_fixed_point 00143 int_gamma) 00144 { 00145 png_fixed_point png_gamma; 00146 00147 png_debug1(1, "in %s storage function", "gAMA"); 00148 00149 if (png_ptr == NULL || info_ptr == NULL) 00150 return; 00151 00152 if (int_gamma > (png_fixed_point)PNG_UINT_31_MAX) 00153 { 00154 png_warning(png_ptr, "Limiting gamma to 21474.83"); 00155 png_gamma=PNG_UINT_31_MAX; 00156 } 00157 else 00158 { 00159 if (int_gamma < 0) 00160 { 00161 png_warning(png_ptr, "Setting negative gamma to zero"); 00162 png_gamma = 0; 00163 } 00164 else 00165 png_gamma = int_gamma; 00166 } 00167 #ifdef PNG_FLOATING_POINT_SUPPORTED 00168 info_ptr->gamma = (float)(png_gamma/100000.); 00169 #endif 00170 #ifdef PNG_FIXED_POINT_SUPPORTED 00171 info_ptr->int_gamma = png_gamma; 00172 #endif 00173 info_ptr->valid |= PNG_INFO_gAMA; 00174 if (png_gamma == 0) 00175 png_warning(png_ptr, "Setting gamma=0"); 00176 } 00177 #endif 00178 00179 #if defined(PNG_hIST_SUPPORTED) 00180 void PNGAPI 00181 png_set_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_16p hist) 00182 { 00183 int i; 00184 00185 png_debug1(1, "in %s storage function", "hIST"); 00186 00187 if (png_ptr == NULL || info_ptr == NULL) 00188 return; 00189 00190 if (info_ptr->num_palette == 0 || info_ptr->num_palette 00191 > PNG_MAX_PALETTE_LENGTH) 00192 { 00193 png_warning(png_ptr, 00194 "Invalid palette size, hIST allocation skipped."); 00195 return; 00196 } 00197 00198 #ifdef PNG_FREE_ME_SUPPORTED 00199 png_free_data(png_ptr, info_ptr, PNG_FREE_HIST, 0); 00200 #endif 00201 /* Changed from info->num_palette to PNG_MAX_PALETTE_LENGTH in 00202 * version 1.2.1 00203 */ 00204 png_ptr->hist = (png_uint_16p)png_malloc_warn(png_ptr, 00205 (png_uint_32)(PNG_MAX_PALETTE_LENGTH * png_sizeof(png_uint_16))); 00206 if (png_ptr->hist == NULL) 00207 { 00208 png_warning(png_ptr, "Insufficient memory for hIST chunk data."); 00209 return; 00210 } 00211 00212 for (i = 0; i < info_ptr->num_palette; i++) 00213 png_ptr->hist[i] = hist[i]; 00214 info_ptr->hist = png_ptr->hist; 00215 info_ptr->valid |= PNG_INFO_hIST; 00216 00217 #ifdef PNG_FREE_ME_SUPPORTED 00218 info_ptr->free_me |= PNG_FREE_HIST; 00219 #else 00220 png_ptr->flags |= PNG_FLAG_FREE_HIST; 00221 #endif 00222 } 00223 #endif 00224 00225 void PNGAPI 00226 png_set_IHDR(png_structp png_ptr, png_infop info_ptr, 00227 png_uint_32 width, png_uint_32 height, int bit_depth, 00228 int color_type, int interlace_type, int compression_type, 00229 int filter_type) 00230 { 00231 png_debug1(1, "in %s storage function", "IHDR"); 00232 00233 if (png_ptr == NULL || info_ptr == NULL) 00234 return; 00235 00236 /* Check for width and height valid values */ 00237 if (width == 0 || height == 0) 00238 png_error(png_ptr, "Image width or height is zero in IHDR"); 00239 #ifdef PNG_SET_USER_LIMITS_SUPPORTED 00240 if (width > png_ptr->user_width_max || height > png_ptr->user_height_max) 00241 png_error(png_ptr, "image size exceeds user limits in IHDR"); 00242 #else 00243 if (width > PNG_USER_WIDTH_MAX || height > PNG_USER_HEIGHT_MAX) 00244 png_error(png_ptr, "image size exceeds user limits in IHDR"); 00245 #endif 00246 if (width > PNG_UINT_31_MAX || height > PNG_UINT_31_MAX) 00247 png_error(png_ptr, "Invalid image size in IHDR"); 00248 if ( width > (PNG_UINT_32_MAX 00249 >> 3) /* 8-byte RGBA pixels */ 00250 - 64 /* bigrowbuf hack */ 00251 - 1 /* filter byte */ 00252 - 7*8 /* rounding of width to multiple of 8 pixels */ 00253 - 8) /* extra max_pixel_depth pad */ 00254 png_warning(png_ptr, "Width is too large for libpng to process pixels"); 00255 00256 /* Check other values */ 00257 if (bit_depth != 1 && bit_depth != 2 && bit_depth != 4 && 00258 bit_depth != 8 && bit_depth != 16) 00259 png_error(png_ptr, "Invalid bit depth in IHDR"); 00260 00261 if (color_type < 0 || color_type == 1 || 00262 color_type == 5 || color_type > 6) 00263 png_error(png_ptr, "Invalid color type in IHDR"); 00264 00265 if (((color_type == PNG_COLOR_TYPE_PALETTE) && bit_depth > 8) || 00266 ((color_type == PNG_COLOR_TYPE_RGB || 00267 color_type == PNG_COLOR_TYPE_GRAY_ALPHA || 00268 color_type == PNG_COLOR_TYPE_RGB_ALPHA) && bit_depth < 8)) 00269 png_error(png_ptr, "Invalid color type/bit depth combination in IHDR"); 00270 00271 if (interlace_type >= PNG_INTERLACE_LAST) 00272 png_error(png_ptr, "Unknown interlace method in IHDR"); 00273 00274 if (compression_type != PNG_COMPRESSION_TYPE_BASE) 00275 png_error(png_ptr, "Unknown compression method in IHDR"); 00276 00277 #if defined(PNG_MNG_FEATURES_SUPPORTED) 00278 /* Accept filter_method 64 (intrapixel differencing) only if 00279 * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and 00280 * 2. Libpng did not read a PNG signature (this filter_method is only 00281 * used in PNG datastreams that are embedded in MNG datastreams) and 00282 * 3. The application called png_permit_mng_features with a mask that 00283 * included PNG_FLAG_MNG_FILTER_64 and 00284 * 4. The filter_method is 64 and 00285 * 5. The color_type is RGB or RGBA 00286 */ 00287 if ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE)&&png_ptr->mng_features_permitted) 00288 png_warning(png_ptr, "MNG features are not allowed in a PNG datastream"); 00289 if (filter_type != PNG_FILTER_TYPE_BASE) 00290 { 00291 if (!((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && 00292 (filter_type == PNG_INTRAPIXEL_DIFFERENCING) && 00293 ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) == 0) && 00294 (color_type == PNG_COLOR_TYPE_RGB || 00295 color_type == PNG_COLOR_TYPE_RGB_ALPHA))) 00296 png_error(png_ptr, "Unknown filter method in IHDR"); 00297 if (png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) 00298 png_warning(png_ptr, "Invalid filter method in IHDR"); 00299 } 00300 #else 00301 if (filter_type != PNG_FILTER_TYPE_BASE) 00302 png_error(png_ptr, "Unknown filter method in IHDR"); 00303 #endif 00304 00305 info_ptr->width = width; 00306 info_ptr->height = height; 00307 info_ptr->bit_depth = (png_byte)bit_depth; 00308 info_ptr->color_type =(png_byte) color_type; 00309 info_ptr->compression_type = (png_byte)compression_type; 00310 info_ptr->filter_type = (png_byte)filter_type; 00311 info_ptr->interlace_type = (png_byte)interlace_type; 00312 if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 00313 info_ptr->channels = 1; 00314 else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR) 00315 info_ptr->channels = 3; 00316 else 00317 info_ptr->channels = 1; 00318 if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA) 00319 info_ptr->channels++; 00320 info_ptr->pixel_depth = (png_byte)(info_ptr->channels * info_ptr->bit_depth); 00321 00322 /* Check for potential overflow */ 00323 if (width > (PNG_UINT_32_MAX 00324 >> 3) /* 8-byte RGBA pixels */ 00325 - 64 /* bigrowbuf hack */ 00326 - 1 /* filter byte */ 00327 - 7*8 /* rounding of width to multiple of 8 pixels */ 00328 - 8) /* extra max_pixel_depth pad */ 00329 info_ptr->rowbytes = (png_size_t)0; 00330 else 00331 info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, width); 00332 } 00333 00334 #if defined(PNG_oFFs_SUPPORTED) 00335 void PNGAPI 00336 png_set_oFFs(png_structp png_ptr, png_infop info_ptr, 00337 png_int_32 offset_x, png_int_32 offset_y, int unit_type) 00338 { 00339 png_debug1(1, "in %s storage function", "oFFs"); 00340 00341 if (png_ptr == NULL || info_ptr == NULL) 00342 return; 00343 00344 info_ptr->x_offset = offset_x; 00345 info_ptr->y_offset = offset_y; 00346 info_ptr->offset_unit_type = (png_byte)unit_type; 00347 info_ptr->valid |= PNG_INFO_oFFs; 00348 } 00349 #endif 00350 00351 #if defined(PNG_pCAL_SUPPORTED) 00352 void PNGAPI 00353 png_set_pCAL(png_structp png_ptr, png_infop info_ptr, 00354 png_charp purpose, png_int_32 X0, png_int_32 X1, int type, int nparams, 00355 png_charp units, png_charpp params) 00356 { 00357 png_uint_32 length; 00358 int i; 00359 00360 png_debug1(1, "in %s storage function", "pCAL"); 00361 00362 if (png_ptr == NULL || info_ptr == NULL) 00363 return; 00364 00365 length = png_strlen(purpose) + 1; 00366 png_debug1(3, "allocating purpose for info (%lu bytes)", 00367 (unsigned long)length); 00368 info_ptr->pcal_purpose = (png_charp)png_malloc_warn(png_ptr, length); 00369 if (info_ptr->pcal_purpose == NULL) 00370 { 00371 png_warning(png_ptr, "Insufficient memory for pCAL purpose."); 00372 return; 00373 } 00374 png_memcpy(info_ptr->pcal_purpose, purpose, (png_size_t)length); 00375 00376 png_debug(3, "storing X0, X1, type, and nparams in info"); 00377 info_ptr->pcal_X0 = X0; 00378 info_ptr->pcal_X1 = X1; 00379 info_ptr->pcal_type = (png_byte)type; 00380 info_ptr->pcal_nparams = (png_byte)nparams; 00381 00382 length = png_strlen(units) + 1; 00383 png_debug1(3, "allocating units for info (%lu bytes)", 00384 (unsigned long)length); 00385 info_ptr->pcal_units = (png_charp)png_malloc_warn(png_ptr, length); 00386 if (info_ptr->pcal_units == NULL) 00387 { 00388 png_warning(png_ptr, "Insufficient memory for pCAL units."); 00389 return; 00390 } 00391 png_memcpy(info_ptr->pcal_units, units, (png_size_t)length); 00392 00393 info_ptr->pcal_params = (png_charpp)png_malloc_warn(png_ptr, 00394 (png_uint_32)((nparams + 1) * png_sizeof(png_charp))); 00395 if (info_ptr->pcal_params == NULL) 00396 { 00397 png_warning(png_ptr, "Insufficient memory for pCAL params."); 00398 return; 00399 } 00400 00401 png_memset(info_ptr->pcal_params, 0, (nparams + 1) * png_sizeof(png_charp)); 00402 00403 for (i = 0; i < nparams; i++) 00404 { 00405 length = png_strlen(params[i]) + 1; 00406 png_debug2(3, "allocating parameter %d for info (%lu bytes)", i, 00407 (unsigned long)length); 00408 info_ptr->pcal_params[i] = (png_charp)png_malloc_warn(png_ptr, length); 00409 if (info_ptr->pcal_params[i] == NULL) 00410 { 00411 png_warning(png_ptr, "Insufficient memory for pCAL parameter."); 00412 return; 00413 } 00414 png_memcpy(info_ptr->pcal_params[i], params[i], (png_size_t)length); 00415 } 00416 00417 info_ptr->valid |= PNG_INFO_pCAL; 00418 #ifdef PNG_FREE_ME_SUPPORTED 00419 info_ptr->free_me |= PNG_FREE_PCAL; 00420 #endif 00421 } 00422 #endif 00423 00424 #if defined(PNG_READ_sCAL_SUPPORTED) || defined(PNG_WRITE_sCAL_SUPPORTED) 00425 #ifdef PNG_FLOATING_POINT_SUPPORTED 00426 void PNGAPI 00427 png_set_sCAL(png_structp png_ptr, png_infop info_ptr, 00428 int unit, double width, double height) 00429 { 00430 png_debug1(1, "in %s storage function", "sCAL"); 00431 00432 if (png_ptr == NULL || info_ptr == NULL) 00433 return; 00434 00435 info_ptr->scal_unit = (png_byte)unit; 00436 info_ptr->scal_pixel_width = width; 00437 info_ptr->scal_pixel_height = height; 00438 00439 info_ptr->valid |= PNG_INFO_sCAL; 00440 } 00441 #else 00442 #ifdef PNG_FIXED_POINT_SUPPORTED 00443 void PNGAPI 00444 png_set_sCAL_s(png_structp png_ptr, png_infop info_ptr, 00445 int unit, png_charp swidth, png_charp sheight) 00446 { 00447 png_uint_32 length; 00448 00449 png_debug1(1, "in %s storage function", "sCAL"); 00450 00451 if (png_ptr == NULL || info_ptr == NULL) 00452 return; 00453 00454 info_ptr->scal_unit = (png_byte)unit; 00455 00456 length = png_strlen(swidth) + 1; 00457 png_debug1(3, "allocating unit for info (%u bytes)", 00458 (unsigned int)length); 00459 info_ptr->scal_s_width = (png_charp)png_malloc_warn(png_ptr, length); 00460 if (info_ptr->scal_s_width == NULL) 00461 { 00462 png_warning(png_ptr, 00463 "Memory allocation failed while processing sCAL."); 00464 return; 00465 } 00466 png_memcpy(info_ptr->scal_s_width, swidth, (png_size_t)length); 00467 00468 length = png_strlen(sheight) + 1; 00469 png_debug1(3, "allocating unit for info (%u bytes)", 00470 (unsigned int)length); 00471 info_ptr->scal_s_height = (png_charp)png_malloc_warn(png_ptr, length); 00472 if (info_ptr->scal_s_height == NULL) 00473 { 00474 png_free (png_ptr, info_ptr->scal_s_width); 00475 info_ptr->scal_s_width = NULL; 00476 png_warning(png_ptr, 00477 "Memory allocation failed while processing sCAL."); 00478 return; 00479 } 00480 png_memcpy(info_ptr->scal_s_height, sheight, (png_size_t)length); 00481 info_ptr->valid |= PNG_INFO_sCAL; 00482 #ifdef PNG_FREE_ME_SUPPORTED 00483 info_ptr->free_me |= PNG_FREE_SCAL; 00484 #endif 00485 } 00486 #endif 00487 #endif 00488 #endif 00489 00490 #if defined(PNG_pHYs_SUPPORTED) 00491 void PNGAPI 00492 png_set_pHYs(png_structp png_ptr, png_infop info_ptr, 00493 png_uint_32 res_x, png_uint_32 res_y, int unit_type) 00494 { 00495 png_debug1(1, "in %s storage function", "pHYs"); 00496 00497 if (png_ptr == NULL || info_ptr == NULL) 00498 return; 00499 00500 info_ptr->x_pixels_per_unit = res_x; 00501 info_ptr->y_pixels_per_unit = res_y; 00502 info_ptr->phys_unit_type = (png_byte)unit_type; 00503 info_ptr->valid |= PNG_INFO_pHYs; 00504 } 00505 #endif 00506 00507 void PNGAPI 00508 png_set_PLTE(png_structp png_ptr, png_infop info_ptr, 00509 png_colorp palette, int num_palette) 00510 { 00511 00512 png_debug1(1, "in %s storage function", "PLTE"); 00513 00514 if (png_ptr == NULL || info_ptr == NULL) 00515 return; 00516 00517 if (num_palette < 0 || num_palette > PNG_MAX_PALETTE_LENGTH) 00518 { 00519 if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 00520 png_error(png_ptr, "Invalid palette length"); 00521 else 00522 { 00523 png_warning(png_ptr, "Invalid palette length"); 00524 return; 00525 } 00526 } 00527 00528 /* 00529 * It may not actually be necessary to set png_ptr->palette here; 00530 * we do it for backward compatibility with the way the png_handle_tRNS 00531 * function used to do the allocation. 00532 */ 00533 #ifdef PNG_FREE_ME_SUPPORTED 00534 png_free_data(png_ptr, info_ptr, PNG_FREE_PLTE, 0); 00535 #endif 00536 00537 /* Changed in libpng-1.2.1 to allocate PNG_MAX_PALETTE_LENGTH instead 00538 * of num_palette entries, in case of an invalid PNG file that has 00539 * too-large sample values. 00540 */ 00541 png_ptr->palette = (png_colorp)png_malloc(png_ptr, 00542 PNG_MAX_PALETTE_LENGTH * png_sizeof(png_color)); 00543 png_memset(png_ptr->palette, 0, PNG_MAX_PALETTE_LENGTH * 00544 png_sizeof(png_color)); 00545 png_memcpy(png_ptr->palette, palette, num_palette * png_sizeof(png_color)); 00546 info_ptr->palette = png_ptr->palette; 00547 info_ptr->num_palette = png_ptr->num_palette = (png_uint_16)num_palette; 00548 00549 #ifdef PNG_FREE_ME_SUPPORTED 00550 info_ptr->free_me |= PNG_FREE_PLTE; 00551 #else 00552 png_ptr->flags |= PNG_FLAG_FREE_PLTE; 00553 #endif 00554 00555 info_ptr->valid |= PNG_INFO_PLTE; 00556 } 00557 00558 #if defined(PNG_sBIT_SUPPORTED) 00559 void PNGAPI 00560 png_set_sBIT(png_structp png_ptr, png_infop info_ptr, 00561 png_color_8p sig_bit) 00562 { 00563 png_debug1(1, "in %s storage function", "sBIT"); 00564 00565 if (png_ptr == NULL || info_ptr == NULL) 00566 return; 00567 00568 png_memcpy(&(info_ptr->sig_bit), sig_bit, png_sizeof(png_color_8)); 00569 info_ptr->valid |= PNG_INFO_sBIT; 00570 } 00571 #endif 00572 00573 #if defined(PNG_sRGB_SUPPORTED) 00574 void PNGAPI 00575 png_set_sRGB(png_structp png_ptr, png_infop info_ptr, int intent) 00576 { 00577 png_debug1(1, "in %s storage function", "sRGB"); 00578 00579 if (png_ptr == NULL || info_ptr == NULL) 00580 return; 00581 00582 info_ptr->srgb_intent = (png_byte)intent; 00583 info_ptr->valid |= PNG_INFO_sRGB; 00584 } 00585 00586 void PNGAPI 00587 png_set_sRGB_gAMA_and_cHRM(png_structp png_ptr, png_infop info_ptr, 00588 int intent) 00589 { 00590 #if defined(PNG_gAMA_SUPPORTED) 00591 #ifdef PNG_FLOATING_POINT_SUPPORTED 00592 float file_gamma; 00593 #endif 00594 #ifdef PNG_FIXED_POINT_SUPPORTED 00595 png_fixed_point int_file_gamma; 00596 #endif 00597 #endif 00598 #if defined(PNG_cHRM_SUPPORTED) 00599 #ifdef PNG_FLOATING_POINT_SUPPORTED 00600 float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y; 00601 #endif 00602 png_fixed_point int_white_x, int_white_y, int_red_x, int_red_y, int_green_x, 00603 int_green_y, int_blue_x, int_blue_y; 00604 #endif 00605 png_debug1(1, "in %s storage function", "sRGB_gAMA_and_cHRM"); 00606 00607 if (png_ptr == NULL || info_ptr == NULL) 00608 return; 00609 00610 png_set_sRGB(png_ptr, info_ptr, intent); 00611 00612 #if defined(PNG_gAMA_SUPPORTED) 00613 #ifdef PNG_FLOATING_POINT_SUPPORTED 00614 file_gamma = (float).45455; 00615 png_set_gAMA(png_ptr, info_ptr, file_gamma); 00616 #endif 00617 #ifdef PNG_FIXED_POINT_SUPPORTED 00618 int_file_gamma = 45455L; 00619 png_set_gAMA_fixed(png_ptr, info_ptr, int_file_gamma); 00620 #endif 00621 #endif 00622 00623 #if defined(PNG_cHRM_SUPPORTED) 00624 int_white_x = 31270L; 00625 int_white_y = 32900L; 00626 int_red_x = 64000L; 00627 int_red_y = 33000L; 00628 int_green_x = 30000L; 00629 int_green_y = 60000L; 00630 int_blue_x = 15000L; 00631 int_blue_y = 6000L; 00632 00633 #ifdef PNG_FLOATING_POINT_SUPPORTED 00634 white_x = (float).3127; 00635 white_y = (float).3290; 00636 red_x = (float).64; 00637 red_y = (float).33; 00638 green_x = (float).30; 00639 green_y = (float).60; 00640 blue_x = (float).15; 00641 blue_y = (float).06; 00642 #endif 00643 00644 #if !defined(PNG_NO_CHECK_cHRM) 00645 if (png_check_cHRM_fixed(png_ptr, 00646 int_white_x, int_white_y, int_red_x, int_red_y, int_green_x, 00647 int_green_y, int_blue_x, int_blue_y)) 00648 #endif 00649 { 00650 #ifdef PNG_FIXED_POINT_SUPPORTED 00651 png_set_cHRM_fixed(png_ptr, info_ptr, 00652 int_white_x, int_white_y, int_red_x, int_red_y, int_green_x, 00653 int_green_y, int_blue_x, int_blue_y); 00654 #endif 00655 #ifdef PNG_FLOATING_POINT_SUPPORTED 00656 png_set_cHRM(png_ptr, info_ptr, 00657 white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y); 00658 #endif 00659 } 00660 #endif /* cHRM */ 00661 } 00662 #endif /* sRGB */ 00663 00664 00665 #if defined(PNG_iCCP_SUPPORTED) 00666 void PNGAPI 00667 png_set_iCCP(png_structp png_ptr, png_infop info_ptr, 00668 png_charp name, int compression_type, 00669 png_charp profile, png_uint_32 proflen) 00670 { 00671 png_charp new_iccp_name; 00672 png_charp new_iccp_profile; 00673 png_uint_32 length; 00674 00675 png_debug1(1, "in %s storage function", "iCCP"); 00676 00677 if (png_ptr == NULL || info_ptr == NULL || name == NULL || profile == NULL) 00678 return; 00679 00680 length = png_strlen(name)+1; 00681 new_iccp_name = (png_charp)png_malloc_warn(png_ptr, length); 00682 if (new_iccp_name == NULL) 00683 { 00684 png_warning(png_ptr, "Insufficient memory to process iCCP chunk."); 00685 return; 00686 } 00687 png_memcpy(new_iccp_name, name, length); 00688 new_iccp_profile = (png_charp)png_malloc_warn(png_ptr, proflen); 00689 if (new_iccp_profile == NULL) 00690 { 00691 png_free (png_ptr, new_iccp_name); 00692 png_warning(png_ptr, 00693 "Insufficient memory to process iCCP profile."); 00694 return; 00695 } 00696 png_memcpy(new_iccp_profile, profile, (png_size_t)proflen); 00697 00698 png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, 0); 00699 00700 info_ptr->iccp_proflen = proflen; 00701 info_ptr->iccp_name = new_iccp_name; 00702 info_ptr->iccp_profile = new_iccp_profile; 00703 /* Compression is always zero but is here so the API and info structure 00704 * does not have to change if we introduce multiple compression types */ 00705 info_ptr->iccp_compression = (png_byte)compression_type; 00706 #ifdef PNG_FREE_ME_SUPPORTED 00707 info_ptr->free_me |= PNG_FREE_ICCP; 00708 #endif 00709 info_ptr->valid |= PNG_INFO_iCCP; 00710 } 00711 #endif 00712 00713 #if defined(PNG_TEXT_SUPPORTED) 00714 void PNGAPI 00715 png_set_text(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr, 00716 int num_text) 00717 { 00718 int ret; 00719 ret = png_set_text_2(png_ptr, info_ptr, text_ptr, num_text); 00720 if (ret) 00721 png_error(png_ptr, "Insufficient memory to store text"); 00722 } 00723 00724 int /* PRIVATE */ 00725 png_set_text_2(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr, 00726 int num_text) 00727 { 00728 int i; 00729 00730 png_debug1(1, "in %s storage function", ((png_ptr == NULL || 00731 png_ptr->chunk_name[0] == '\0') ? 00732 "text" : (png_const_charp)png_ptr->chunk_name)); 00733 00734 if (png_ptr == NULL || info_ptr == NULL || num_text == 0) 00735 return(0); 00736 00737 /* Make sure we have enough space in the "text" array in info_struct 00738 * to hold all of the incoming text_ptr objects. 00739 */ 00740 if (info_ptr->num_text + num_text > info_ptr->max_text) 00741 { 00742 if (info_ptr->text != NULL) 00743 { 00744 png_textp old_text; 00745 int old_max; 00746 00747 old_max = info_ptr->max_text; 00748 info_ptr->max_text = info_ptr->num_text + num_text + 8; 00749 old_text = info_ptr->text; 00750 info_ptr->text = (png_textp)png_malloc_warn(png_ptr, 00751 (png_uint_32)(info_ptr->max_text * png_sizeof(png_text))); 00752 if (info_ptr->text == NULL) 00753 { 00754 png_free(png_ptr, old_text); 00755 return(1); 00756 } 00757 png_memcpy(info_ptr->text, old_text, (png_size_t)(old_max * 00758 png_sizeof(png_text))); 00759 png_free(png_ptr, old_text); 00760 } 00761 else 00762 { 00763 info_ptr->max_text = num_text + 8; 00764 info_ptr->num_text = 0; 00765 info_ptr->text = (png_textp)png_malloc_warn(png_ptr, 00766 (png_uint_32)(info_ptr->max_text * png_sizeof(png_text))); 00767 if (info_ptr->text == NULL) 00768 return(1); 00769 #ifdef PNG_FREE_ME_SUPPORTED 00770 info_ptr->free_me |= PNG_FREE_TEXT; 00771 #endif 00772 } 00773 png_debug1(3, "allocated %d entries for info_ptr->text", 00774 info_ptr->max_text); 00775 } 00776 for (i = 0; i < num_text; i++) 00777 { 00778 png_size_t text_length, key_len; 00779 png_size_t lang_len, lang_key_len; 00780 png_textp textp = &(info_ptr->text[info_ptr->num_text]); 00781 00782 if (text_ptr[i].key == NULL) 00783 continue; 00784 00785 key_len = png_strlen(text_ptr[i].key); 00786 00787 if (text_ptr[i].compression <= 0) 00788 { 00789 lang_len = 0; 00790 lang_key_len = 0; 00791 } 00792 else 00793 #ifdef PNG_iTXt_SUPPORTED 00794 { 00795 /* Set iTXt data */ 00796 if (text_ptr[i].lang != NULL) 00797 lang_len = png_strlen(text_ptr[i].lang); 00798 else 00799 lang_len = 0; 00800 if (text_ptr[i].lang_key != NULL) 00801 lang_key_len = png_strlen(text_ptr[i].lang_key); 00802 else 00803 lang_key_len = 0; 00804 } 00805 #else 00806 { 00807 png_warning(png_ptr, "iTXt chunk not supported."); 00808 continue; 00809 } 00810 #endif 00811 00812 if (text_ptr[i].text == NULL || text_ptr[i].text[0] == '\0') 00813 { 00814 text_length = 0; 00815 #ifdef PNG_iTXt_SUPPORTED 00816 if (text_ptr[i].compression > 0) 00817 textp->compression = PNG_ITXT_COMPRESSION_NONE; 00818 else 00819 #endif 00820 textp->compression = PNG_TEXT_COMPRESSION_NONE; 00821 } 00822 else 00823 { 00824 text_length = png_strlen(text_ptr[i].text); 00825 textp->compression = text_ptr[i].compression; 00826 } 00827 00828 textp->key = (png_charp)png_malloc_warn(png_ptr, 00829 (png_uint_32) 00830 (key_len + text_length + lang_len + lang_key_len + 4)); 00831 if (textp->key == NULL) 00832 return(1); 00833 png_debug2(2, "Allocated %lu bytes at %x in png_set_text", 00834 (png_uint_32) 00835 (key_len + lang_len + lang_key_len + text_length + 4), 00836 (int)textp->key); 00837 00838 png_memcpy(textp->key, text_ptr[i].key,(png_size_t)(key_len)); 00839 *(textp->key + key_len) = '\0'; 00840 #ifdef PNG_iTXt_SUPPORTED 00841 if (text_ptr[i].compression > 0) 00842 { 00843 textp->lang = textp->key + key_len + 1; 00844 png_memcpy(textp->lang, text_ptr[i].lang, lang_len); 00845 *(textp->lang + lang_len) = '\0'; 00846 textp->lang_key = textp->lang + lang_len + 1; 00847 png_memcpy(textp->lang_key, text_ptr[i].lang_key, lang_key_len); 00848 *(textp->lang_key + lang_key_len) = '\0'; 00849 textp->text = textp->lang_key + lang_key_len + 1; 00850 } 00851 else 00852 #endif 00853 { 00854 #ifdef PNG_iTXt_SUPPORTED 00855 textp->lang=NULL; 00856 textp->lang_key=NULL; 00857 #endif 00858 textp->text = textp->key + key_len + 1; 00859 } 00860 if (text_length) 00861 png_memcpy(textp->text, text_ptr[i].text, 00862 (png_size_t)(text_length)); 00863 *(textp->text + text_length) = '\0'; 00864 00865 #ifdef PNG_iTXt_SUPPORTED 00866 if (textp->compression > 0) 00867 { 00868 textp->text_length = 0; 00869 textp->itxt_length = text_length; 00870 } 00871 else 00872 #endif 00873 { 00874 textp->text_length = text_length; 00875 #ifdef PNG_iTXt_SUPPORTED 00876 textp->itxt_length = 0; 00877 #endif 00878 } 00879 info_ptr->num_text++; 00880 png_debug1(3, "transferred text chunk %d", info_ptr->num_text); 00881 } 00882 return(0); 00883 } 00884 #endif 00885 00886 #if defined(PNG_tIME_SUPPORTED) 00887 void PNGAPI 00888 png_set_tIME(png_structp png_ptr, png_infop info_ptr, png_timep mod_time) 00889 { 00890 png_debug1(1, "in %s storage function", "tIME"); 00891 00892 if (png_ptr == NULL || info_ptr == NULL || 00893 (png_ptr->mode & PNG_WROTE_tIME)) 00894 return; 00895 00896 png_memcpy(&(info_ptr->mod_time), mod_time, png_sizeof(png_time)); 00897 info_ptr->valid |= PNG_INFO_tIME; 00898 } 00899 #endif 00900 00901 #if defined(PNG_tRNS_SUPPORTED) 00902 void PNGAPI 00903 png_set_tRNS(png_structp png_ptr, png_infop info_ptr, 00904 png_bytep trans, int num_trans, png_color_16p trans_values) 00905 { 00906 png_debug1(1, "in %s storage function", "tRNS"); 00907 00908 if (png_ptr == NULL || info_ptr == NULL) 00909 return; 00910 00911 if (trans != NULL) 00912 { 00913 /* 00914 * It may not actually be necessary to set png_ptr->trans here; 00915 * we do it for backward compatibility with the way the png_handle_tRNS 00916 * function used to do the allocation. 00917 */ 00918 00919 #ifdef PNG_FREE_ME_SUPPORTED 00920 png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0); 00921 #endif 00922 00923 /* Changed from num_trans to PNG_MAX_PALETTE_LENGTH in version 1.2.1 */ 00924 png_ptr->trans = info_ptr->trans = (png_bytep)png_malloc(png_ptr, 00925 (png_uint_32)PNG_MAX_PALETTE_LENGTH); 00926 if (num_trans > 0 && num_trans <= PNG_MAX_PALETTE_LENGTH) 00927 png_memcpy(info_ptr->trans, trans, (png_size_t)num_trans); 00928 } 00929 00930 if (trans_values != NULL) 00931 { 00932 int sample_max = (1 << info_ptr->bit_depth); 00933 if ((info_ptr->color_type == PNG_COLOR_TYPE_GRAY && 00934 (int)trans_values->gray > sample_max) || 00935 (info_ptr->color_type == PNG_COLOR_TYPE_RGB && 00936 ((int)trans_values->red > sample_max || 00937 (int)trans_values->green > sample_max || 00938 (int)trans_values->blue > sample_max))) 00939 png_warning(png_ptr, 00940 "tRNS chunk has out-of-range samples for bit_depth"); 00941 png_memcpy(&(info_ptr->trans_values), trans_values, 00942 png_sizeof(png_color_16)); 00943 if (num_trans == 0) 00944 num_trans = 1; 00945 } 00946 00947 info_ptr->num_trans = (png_uint_16)num_trans; 00948 if (num_trans != 0) 00949 { 00950 info_ptr->valid |= PNG_INFO_tRNS; 00951 #ifdef PNG_FREE_ME_SUPPORTED 00952 info_ptr->free_me |= PNG_FREE_TRNS; 00953 #else 00954 png_ptr->flags |= PNG_FLAG_FREE_TRNS; 00955 #endif 00956 } 00957 } 00958 #endif 00959 00960 #if defined(PNG_sPLT_SUPPORTED) 00961 void PNGAPI 00962 png_set_sPLT(png_structp png_ptr, 00963 png_infop info_ptr, png_sPLT_tp entries, int nentries) 00964 /* 00965 * entries - array of png_sPLT_t structures 00966 * to be added to the list of palettes 00967 * in the info structure. 00968 * nentries - number of palette structures to be 00969 * added. 00970 */ 00971 { 00972 png_sPLT_tp np; 00973 int i; 00974 00975 if (png_ptr == NULL || info_ptr == NULL) 00976 return; 00977 00978 np = (png_sPLT_tp)png_malloc_warn(png_ptr, 00979 (info_ptr->splt_palettes_num + nentries) * 00980 (png_uint_32)png_sizeof(png_sPLT_t)); 00981 if (np == NULL) 00982 { 00983 png_warning(png_ptr, "No memory for sPLT palettes."); 00984 return; 00985 } 00986 00987 png_memcpy(np, info_ptr->splt_palettes, 00988 info_ptr->splt_palettes_num * png_sizeof(png_sPLT_t)); 00989 png_free(png_ptr, info_ptr->splt_palettes); 00990 info_ptr->splt_palettes=NULL; 00991 00992 for (i = 0; i < nentries; i++) 00993 { 00994 png_sPLT_tp to = np + info_ptr->splt_palettes_num + i; 00995 png_sPLT_tp from = entries + i; 00996 png_uint_32 length; 00997 00998 length = png_strlen(from->name) + 1; 00999 to->name = (png_charp)png_malloc_warn(png_ptr, length); 01000 if (to->name == NULL) 01001 { 01002 png_warning(png_ptr, 01003 "Out of memory while processing sPLT chunk"); 01004 continue; 01005 } 01006 png_memcpy(to->name, from->name, length); 01007 to->entries = (png_sPLT_entryp)png_malloc_warn(png_ptr, 01008 (png_uint_32)(from->nentries * png_sizeof(png_sPLT_entry))); 01009 if (to->entries == NULL) 01010 { 01011 png_warning(png_ptr, 01012 "Out of memory while processing sPLT chunk"); 01013 png_free(png_ptr, to->name); 01014 to->name = NULL; 01015 continue; 01016 } 01017 png_memcpy(to->entries, from->entries, 01018 from->nentries * png_sizeof(png_sPLT_entry)); 01019 to->nentries = from->nentries; 01020 to->depth = from->depth; 01021 } 01022 01023 info_ptr->splt_palettes = np; 01024 info_ptr->splt_palettes_num += nentries; 01025 info_ptr->valid |= PNG_INFO_sPLT; 01026 #ifdef PNG_FREE_ME_SUPPORTED 01027 info_ptr->free_me |= PNG_FREE_SPLT; 01028 #endif 01029 } 01030 #endif /* PNG_sPLT_SUPPORTED */ 01031 01032 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED 01033 void PNGAPI 01034 png_set_unknown_chunks(png_structp png_ptr, 01035 png_infop info_ptr, png_unknown_chunkp unknowns, int num_unknowns) 01036 { 01037 png_unknown_chunkp np; 01038 int i; 01039 01040 if (png_ptr == NULL || info_ptr == NULL || num_unknowns == 0) 01041 return; 01042 01043 np = (png_unknown_chunkp)png_malloc_warn(png_ptr, 01044 (png_uint_32)((info_ptr->unknown_chunks_num + num_unknowns) * 01045 png_sizeof(png_unknown_chunk))); 01046 if (np == NULL) 01047 { 01048 png_warning(png_ptr, 01049 "Out of memory while processing unknown chunk."); 01050 return; 01051 } 01052 01053 png_memcpy(np, info_ptr->unknown_chunks, 01054 info_ptr->unknown_chunks_num * png_sizeof(png_unknown_chunk)); 01055 png_free(png_ptr, info_ptr->unknown_chunks); 01056 info_ptr->unknown_chunks=NULL; 01057 01058 for (i = 0; i < num_unknowns; i++) 01059 { 01060 png_unknown_chunkp to = np + info_ptr->unknown_chunks_num + i; 01061 png_unknown_chunkp from = unknowns + i; 01062 01063 png_memcpy((png_charp)to->name, 01064 (png_charp)from->name, 01065 png_sizeof(from->name)); 01066 to->name[png_sizeof(to->name)-1] = '\0'; 01067 to->size = from->size; 01068 /* Note our location in the read or write sequence */ 01069 to->location = (png_byte)(png_ptr->mode & 0xff); 01070 01071 if (from->size == 0) 01072 to->data=NULL; 01073 else 01074 { 01075 to->data = (png_bytep)png_malloc_warn(png_ptr, 01076 (png_uint_32)from->size); 01077 if (to->data == NULL) 01078 { 01079 png_warning(png_ptr, 01080 "Out of memory while processing unknown chunk."); 01081 to->size = 0; 01082 } 01083 else 01084 png_memcpy(to->data, from->data, from->size); 01085 } 01086 } 01087 01088 info_ptr->unknown_chunks = np; 01089 info_ptr->unknown_chunks_num += num_unknowns; 01090 #ifdef PNG_FREE_ME_SUPPORTED 01091 info_ptr->free_me |= PNG_FREE_UNKN; 01092 #endif 01093 } 01094 void PNGAPI 01095 png_set_unknown_chunk_location(png_structp png_ptr, png_infop info_ptr, 01096 int chunk, int location) 01097 { 01098 if (png_ptr != NULL && info_ptr != NULL && chunk >= 0 && chunk < 01099 (int)info_ptr->unknown_chunks_num) 01100 info_ptr->unknown_chunks[chunk].location = (png_byte)location; 01101 } 01102 #endif 01103 01104 #if defined(PNG_1_0_X) || defined(PNG_1_2_X) 01105 #if defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \ 01106 defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) 01107 void PNGAPI 01108 png_permit_empty_plte (png_structp png_ptr, int empty_plte_permitted) 01109 { 01110 /* This function is deprecated in favor of png_permit_mng_features() 01111 and will be removed from libpng-1.3.0 */ 01112 01113 png_debug(1, "in png_permit_empty_plte, DEPRECATED."); 01114 01115 if (png_ptr == NULL) 01116 return; 01117 png_ptr->mng_features_permitted = (png_byte) 01118 ((png_ptr->mng_features_permitted & (~PNG_FLAG_MNG_EMPTY_PLTE)) | 01119 ((empty_plte_permitted & PNG_FLAG_MNG_EMPTY_PLTE))); 01120 } 01121 #endif 01122 #endif 01123 01124 #if defined(PNG_MNG_FEATURES_SUPPORTED) 01125 png_uint_32 PNGAPI 01126 png_permit_mng_features (png_structp png_ptr, png_uint_32 mng_features) 01127 { 01128 png_debug(1, "in png_permit_mng_features"); 01129 01130 if (png_ptr == NULL) 01131 return (png_uint_32)0; 01132 png_ptr->mng_features_permitted = 01133 (png_byte)(mng_features & PNG_ALL_MNG_FEATURES); 01134 return (png_uint_32)png_ptr->mng_features_permitted; 01135 } 01136 #endif 01137 01138 #if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) 01139 void PNGAPI 01140 png_set_keep_unknown_chunks(png_structp png_ptr, int keep, png_bytep 01141 chunk_list, int num_chunks) 01142 { 01143 png_bytep new_list, p; 01144 int i, old_num_chunks; 01145 if (png_ptr == NULL) 01146 return; 01147 if (num_chunks == 0) 01148 { 01149 if (keep == PNG_HANDLE_CHUNK_ALWAYS || keep == PNG_HANDLE_CHUNK_IF_SAFE) 01150 png_ptr->flags |= PNG_FLAG_KEEP_UNKNOWN_CHUNKS; 01151 else 01152 png_ptr->flags &= ~PNG_FLAG_KEEP_UNKNOWN_CHUNKS; 01153 01154 if (keep == PNG_HANDLE_CHUNK_ALWAYS) 01155 png_ptr->flags |= PNG_FLAG_KEEP_UNSAFE_CHUNKS; 01156 else 01157 png_ptr->flags &= ~PNG_FLAG_KEEP_UNSAFE_CHUNKS; 01158 return; 01159 } 01160 if (chunk_list == NULL) 01161 return; 01162 old_num_chunks = png_ptr->num_chunk_list; 01163 new_list=(png_bytep)png_malloc(png_ptr, 01164 (png_uint_32) 01165 (5*(num_chunks + old_num_chunks))); 01166 if (png_ptr->chunk_list != NULL) 01167 { 01168 png_memcpy(new_list, png_ptr->chunk_list, 01169 (png_size_t)(5*old_num_chunks)); 01170 png_free(png_ptr, png_ptr->chunk_list); 01171 png_ptr->chunk_list=NULL; 01172 } 01173 png_memcpy(new_list + 5*old_num_chunks, chunk_list, 01174 (png_size_t)(5*num_chunks)); 01175 for (p = new_list + 5*old_num_chunks + 4, i = 0; i<num_chunks; i++, p += 5) 01176 *p=(png_byte)keep; 01177 png_ptr->num_chunk_list = old_num_chunks + num_chunks; 01178 png_ptr->chunk_list = new_list; 01179 #ifdef PNG_FREE_ME_SUPPORTED 01180 png_ptr->free_me |= PNG_FREE_LIST; 01181 #endif 01182 } 01183 #endif 01184 01185 #if defined(PNG_READ_USER_CHUNKS_SUPPORTED) 01186 void PNGAPI 01187 png_set_read_user_chunk_fn(png_structp png_ptr, png_voidp user_chunk_ptr, 01188 png_user_chunk_ptr read_user_chunk_fn) 01189 { 01190 png_debug(1, "in png_set_read_user_chunk_fn"); 01191 01192 if (png_ptr == NULL) 01193 return; 01194 01195 png_ptr->read_user_chunk_fn = read_user_chunk_fn; 01196 png_ptr->user_chunk_ptr = user_chunk_ptr; 01197 } 01198 #endif 01199 01200 #if defined(PNG_INFO_IMAGE_SUPPORTED) 01201 void PNGAPI 01202 png_set_rows(png_structp png_ptr, png_infop info_ptr, png_bytepp row_pointers) 01203 { 01204 png_debug1(1, "in %s storage function", "rows"); 01205 01206 if (png_ptr == NULL || info_ptr == NULL) 01207 return; 01208 01209 if (info_ptr->row_pointers && (info_ptr->row_pointers != row_pointers)) 01210 png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0); 01211 info_ptr->row_pointers = row_pointers; 01212 if (row_pointers) 01213 info_ptr->valid |= PNG_INFO_IDAT; 01214 } 01215 #endif 01216 01217 #ifdef PNG_WRITE_SUPPORTED 01218 void PNGAPI 01219 png_set_compression_buffer_size(png_structp png_ptr, 01220 png_uint_32 size) 01221 { 01222 if (png_ptr == NULL) 01223 return; 01224 png_free(png_ptr, png_ptr->zbuf); 01225 png_ptr->zbuf_size = (png_size_t)size; 01226 png_ptr->zbuf = (png_bytep)png_malloc(png_ptr, size); 01227 png_ptr->zstream.next_out = png_ptr->zbuf; 01228 png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; 01229 } 01230 #endif 01231 01232 void PNGAPI 01233 png_set_invalid(png_structp png_ptr, png_infop info_ptr, int mask) 01234 { 01235 if (png_ptr && info_ptr) 01236 info_ptr->valid &= ~mask; 01237 } 01238 01239 01240 #ifndef PNG_1_0_X 01241 #ifdef PNG_ASSEMBLER_CODE_SUPPORTED 01242 /* Function was added to libpng 1.2.0 and should always exist by default */ 01243 void PNGAPI 01244 png_set_asm_flags (png_structp png_ptr, png_uint_32 asm_flags) 01245 { 01246 /* Obsolete as of libpng-1.2.20 and will be removed from libpng-1.4.0 */ 01247 if (png_ptr != NULL) 01248 png_ptr->asm_flags = 0; 01249 asm_flags = asm_flags; /* Quiet the compiler */ 01250 } 01251 01252 /* This function was added to libpng 1.2.0 */ 01253 void PNGAPI 01254 png_set_mmx_thresholds (png_structp png_ptr, 01255 png_byte mmx_bitdepth_threshold, 01256 png_uint_32 mmx_rowbytes_threshold) 01257 { 01258 /* Obsolete as of libpng-1.2.20 and will be removed from libpng-1.4.0 */ 01259 if (png_ptr == NULL) 01260 return; 01261 /* Quiet the compiler */ 01262 mmx_bitdepth_threshold = mmx_bitdepth_threshold; 01263 mmx_rowbytes_threshold = mmx_rowbytes_threshold; 01264 } 01265 #endif /* ?PNG_ASSEMBLER_CODE_SUPPORTED */ 01266 01267 #ifdef PNG_SET_USER_LIMITS_SUPPORTED 01268 /* This function was added to libpng 1.2.6 */ 01269 void PNGAPI 01270 png_set_user_limits (png_structp png_ptr, png_uint_32 user_width_max, 01271 png_uint_32 user_height_max) 01272 { 01273 /* Images with dimensions larger than these limits will be 01274 * rejected by png_set_IHDR(). To accept any PNG datastream 01275 * regardless of dimensions, set both limits to 0x7ffffffL. 01276 */ 01277 if (png_ptr == NULL) 01278 return; 01279 png_ptr->user_width_max = user_width_max; 01280 png_ptr->user_height_max = user_height_max; 01281 } 01282 #endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */ 01283 01284 #endif /* ?PNG_1_0_X */ 01285 #endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */