00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #define PNG_INTERNAL
00013 #include "png.h"
00014 #ifdef PNG_WRITE_SUPPORTED
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 void PNGAPI
00026 png_write_info_before_PLTE(png_structp png_ptr, png_infop info_ptr)
00027 {
00028 png_debug(1, "in png_write_info_before_PLTE\n");
00029 if (png_ptr == NULL || info_ptr == NULL)
00030 return;
00031 if (!(png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE))
00032 {
00033 png_write_sig(png_ptr);
00034 #if defined(PNG_MNG_FEATURES_SUPPORTED)
00035 if((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE)&&(png_ptr->mng_features_permitted))
00036 {
00037 png_warning(png_ptr,"MNG features are not allowed in a PNG datastream");
00038 png_ptr->mng_features_permitted=0;
00039 }
00040 #endif
00041
00042 png_write_IHDR(png_ptr, info_ptr->width, info_ptr->height,
00043 info_ptr->bit_depth, info_ptr->color_type, info_ptr->compression_type,
00044 info_ptr->filter_type,
00045 #if defined(PNG_WRITE_INTERLACING_SUPPORTED)
00046 info_ptr->interlace_type);
00047 #else
00048 0);
00049 #endif
00050
00051
00052 #if defined(PNG_WRITE_gAMA_SUPPORTED)
00053 if (info_ptr->valid & PNG_INFO_gAMA)
00054 {
00055 # ifdef PNG_FLOATING_POINT_SUPPORTED
00056 png_write_gAMA(png_ptr, info_ptr->gamma);
00057 #else
00058 #ifdef PNG_FIXED_POINT_SUPPORTED
00059 png_write_gAMA_fixed(png_ptr, info_ptr->int_gamma);
00060 # endif
00061 #endif
00062 }
00063 #endif
00064 #if defined(PNG_WRITE_sRGB_SUPPORTED)
00065 if (info_ptr->valid & PNG_INFO_sRGB)
00066 png_write_sRGB(png_ptr, (int)info_ptr->srgb_intent);
00067 #endif
00068 #if defined(PNG_WRITE_iCCP_SUPPORTED)
00069 if (info_ptr->valid & PNG_INFO_iCCP)
00070 png_write_iCCP(png_ptr, info_ptr->iccp_name, PNG_COMPRESSION_TYPE_BASE,
00071 info_ptr->iccp_profile, (int)info_ptr->iccp_proflen);
00072 #endif
00073 #if defined(PNG_WRITE_sBIT_SUPPORTED)
00074 if (info_ptr->valid & PNG_INFO_sBIT)
00075 png_write_sBIT(png_ptr, &(info_ptr->sig_bit), info_ptr->color_type);
00076 #endif
00077 #if defined(PNG_WRITE_cHRM_SUPPORTED)
00078 if (info_ptr->valid & PNG_INFO_cHRM)
00079 {
00080 #ifdef PNG_FLOATING_POINT_SUPPORTED
00081 png_write_cHRM(png_ptr,
00082 info_ptr->x_white, info_ptr->y_white,
00083 info_ptr->x_red, info_ptr->y_red,
00084 info_ptr->x_green, info_ptr->y_green,
00085 info_ptr->x_blue, info_ptr->y_blue);
00086 #else
00087 # ifdef PNG_FIXED_POINT_SUPPORTED
00088 png_write_cHRM_fixed(png_ptr,
00089 info_ptr->int_x_white, info_ptr->int_y_white,
00090 info_ptr->int_x_red, info_ptr->int_y_red,
00091 info_ptr->int_x_green, info_ptr->int_y_green,
00092 info_ptr->int_x_blue, info_ptr->int_y_blue);
00093 # endif
00094 #endif
00095 }
00096 #endif
00097 #if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
00098 if (info_ptr->unknown_chunks_num)
00099 {
00100 png_unknown_chunk *up;
00101
00102 png_debug(5, "writing extra chunks\n");
00103
00104 for (up = info_ptr->unknown_chunks;
00105 up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num;
00106 up++)
00107 {
00108 int keep=png_handle_as_unknown(png_ptr, up->name);
00109 if (keep != PNG_HANDLE_CHUNK_NEVER &&
00110 up->location && !(up->location & PNG_HAVE_PLTE) &&
00111 !(up->location & PNG_HAVE_IDAT) &&
00112 ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS ||
00113 (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS)))
00114 {
00115 png_write_chunk(png_ptr, up->name, up->data, up->size);
00116 }
00117 }
00118 }
00119 #endif
00120 png_ptr->mode |= PNG_WROTE_INFO_BEFORE_PLTE;
00121 }
00122 }
00123
00124 void PNGAPI
00125 png_write_info(png_structp png_ptr, png_infop info_ptr)
00126 {
00127 #if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED)
00128 int i;
00129 #endif
00130
00131 png_debug(1, "in png_write_info\n");
00132
00133 if (png_ptr == NULL || info_ptr == NULL)
00134 return;
00135
00136 png_write_info_before_PLTE(png_ptr, info_ptr);
00137
00138 if (info_ptr->valid & PNG_INFO_PLTE)
00139 png_write_PLTE(png_ptr, info_ptr->palette,
00140 (png_uint_32)info_ptr->num_palette);
00141 else if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
00142 png_error(png_ptr, "Valid palette required for paletted images");
00143
00144 #if defined(PNG_WRITE_tRNS_SUPPORTED)
00145 if (info_ptr->valid & PNG_INFO_tRNS)
00146 {
00147 #if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
00148
00149 if ((png_ptr->transformations & PNG_INVERT_ALPHA) &&
00150 info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
00151 {
00152 int j;
00153 for (j=0; j<(int)info_ptr->num_trans; j++)
00154 info_ptr->trans[j] = (png_byte)(255 - info_ptr->trans[j]);
00155 }
00156 #endif
00157 png_write_tRNS(png_ptr, info_ptr->trans, &(info_ptr->trans_values),
00158 info_ptr->num_trans, info_ptr->color_type);
00159 }
00160 #endif
00161 #if defined(PNG_WRITE_bKGD_SUPPORTED)
00162 if (info_ptr->valid & PNG_INFO_bKGD)
00163 png_write_bKGD(png_ptr, &(info_ptr->background), info_ptr->color_type);
00164 #endif
00165 #if defined(PNG_WRITE_hIST_SUPPORTED)
00166 if (info_ptr->valid & PNG_INFO_hIST)
00167 png_write_hIST(png_ptr, info_ptr->hist, info_ptr->num_palette);
00168 #endif
00169 #if defined(PNG_WRITE_oFFs_SUPPORTED)
00170 if (info_ptr->valid & PNG_INFO_oFFs)
00171 png_write_oFFs(png_ptr, info_ptr->x_offset, info_ptr->y_offset,
00172 info_ptr->offset_unit_type);
00173 #endif
00174 #if defined(PNG_WRITE_pCAL_SUPPORTED)
00175 if (info_ptr->valid & PNG_INFO_pCAL)
00176 png_write_pCAL(png_ptr, info_ptr->pcal_purpose, info_ptr->pcal_X0,
00177 info_ptr->pcal_X1, info_ptr->pcal_type, info_ptr->pcal_nparams,
00178 info_ptr->pcal_units, info_ptr->pcal_params);
00179 #endif
00180 #if defined(PNG_WRITE_sCAL_SUPPORTED)
00181 if (info_ptr->valid & PNG_INFO_sCAL)
00182 #if defined(PNG_FLOATING_POINT_SUPPORTED) && !defined(PNG_NO_STDIO)
00183 png_write_sCAL(png_ptr, (int)info_ptr->scal_unit,
00184 info_ptr->scal_pixel_width, info_ptr->scal_pixel_height);
00185 #else
00186 #ifdef PNG_FIXED_POINT_SUPPORTED
00187 png_write_sCAL_s(png_ptr, (int)info_ptr->scal_unit,
00188 info_ptr->scal_s_width, info_ptr->scal_s_height);
00189 #else
00190 png_warning(png_ptr,
00191 "png_write_sCAL not supported; sCAL chunk not written.");
00192 #endif
00193 #endif
00194 #endif
00195 #if defined(PNG_WRITE_pHYs_SUPPORTED)
00196 if (info_ptr->valid & PNG_INFO_pHYs)
00197 png_write_pHYs(png_ptr, info_ptr->x_pixels_per_unit,
00198 info_ptr->y_pixels_per_unit, info_ptr->phys_unit_type);
00199 #endif
00200 #if defined(PNG_WRITE_tIME_SUPPORTED)
00201 if (info_ptr->valid & PNG_INFO_tIME)
00202 {
00203 png_write_tIME(png_ptr, &(info_ptr->mod_time));
00204 png_ptr->mode |= PNG_WROTE_tIME;
00205 }
00206 #endif
00207 #if defined(PNG_WRITE_sPLT_SUPPORTED)
00208 if (info_ptr->valid & PNG_INFO_sPLT)
00209 for (i = 0; i < (int)info_ptr->splt_palettes_num; i++)
00210 png_write_sPLT(png_ptr, info_ptr->splt_palettes + i);
00211 #endif
00212 #if defined(PNG_WRITE_TEXT_SUPPORTED)
00213
00214 for (i = 0; i < info_ptr->num_text; i++)
00215 {
00216 png_debug2(2, "Writing header text chunk %d, type %d\n", i,
00217 info_ptr->text[i].compression);
00218
00219 if (info_ptr->text[i].compression > 0)
00220 {
00221 #if defined(PNG_WRITE_iTXt_SUPPORTED)
00222
00223 png_write_iTXt(png_ptr,
00224 info_ptr->text[i].compression,
00225 info_ptr->text[i].key,
00226 info_ptr->text[i].lang,
00227 info_ptr->text[i].lang_key,
00228 info_ptr->text[i].text);
00229 #else
00230 png_warning(png_ptr, "Unable to write international text");
00231 #endif
00232
00233 info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
00234 }
00235
00236 else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_zTXt)
00237 {
00238 #if defined(PNG_WRITE_zTXt_SUPPORTED)
00239
00240 png_write_zTXt(png_ptr, info_ptr->text[i].key,
00241 info_ptr->text[i].text, 0,
00242 info_ptr->text[i].compression);
00243 #else
00244 png_warning(png_ptr, "Unable to write compressed text");
00245 #endif
00246
00247 info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR;
00248 }
00249 else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE)
00250 {
00251 #if defined(PNG_WRITE_tEXt_SUPPORTED)
00252
00253 png_write_tEXt(png_ptr, info_ptr->text[i].key,
00254 info_ptr->text[i].text,
00255 0);
00256 #else
00257 png_warning(png_ptr, "Unable to write uncompressed text");
00258 #endif
00259
00260 info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
00261 }
00262 }
00263 #endif
00264 #if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
00265 if (info_ptr->unknown_chunks_num)
00266 {
00267 png_unknown_chunk *up;
00268
00269 png_debug(5, "writing extra chunks\n");
00270
00271 for (up = info_ptr->unknown_chunks;
00272 up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num;
00273 up++)
00274 {
00275 int keep=png_handle_as_unknown(png_ptr, up->name);
00276 if (keep != PNG_HANDLE_CHUNK_NEVER &&
00277 up->location && (up->location & PNG_HAVE_PLTE) &&
00278 !(up->location & PNG_HAVE_IDAT) &&
00279 ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS ||
00280 (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS)))
00281 {
00282 png_write_chunk(png_ptr, up->name, up->data, up->size);
00283 }
00284 }
00285 }
00286 #endif
00287 }
00288
00289
00290
00291
00292
00293
00294 void PNGAPI
00295 png_write_end(png_structp png_ptr, png_infop info_ptr)
00296 {
00297 png_debug(1, "in png_write_end\n");
00298 if (png_ptr == NULL)
00299 return;
00300 if (!(png_ptr->mode & PNG_HAVE_IDAT))
00301 png_error(png_ptr, "No IDATs written into file");
00302
00303
00304 if (info_ptr != NULL)
00305 {
00306 #if defined(PNG_WRITE_TEXT_SUPPORTED)
00307 int i;
00308 #endif
00309 #if defined(PNG_WRITE_tIME_SUPPORTED)
00310
00311 if ((info_ptr->valid & PNG_INFO_tIME) &&
00312 !(png_ptr->mode & PNG_WROTE_tIME))
00313 png_write_tIME(png_ptr, &(info_ptr->mod_time));
00314 #endif
00315 #if defined(PNG_WRITE_TEXT_SUPPORTED)
00316
00317 for (i = 0; i < info_ptr->num_text; i++)
00318 {
00319 png_debug2(2, "Writing trailer text chunk %d, type %d\n", i,
00320 info_ptr->text[i].compression);
00321
00322 if (info_ptr->text[i].compression > 0)
00323 {
00324 #if defined(PNG_WRITE_iTXt_SUPPORTED)
00325
00326 png_write_iTXt(png_ptr,
00327 info_ptr->text[i].compression,
00328 info_ptr->text[i].key,
00329 info_ptr->text[i].lang,
00330 info_ptr->text[i].lang_key,
00331 info_ptr->text[i].text);
00332 #else
00333 png_warning(png_ptr, "Unable to write international text");
00334 #endif
00335
00336 info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
00337 }
00338 else if (info_ptr->text[i].compression >= PNG_TEXT_COMPRESSION_zTXt)
00339 {
00340 #if defined(PNG_WRITE_zTXt_SUPPORTED)
00341
00342 png_write_zTXt(png_ptr, info_ptr->text[i].key,
00343 info_ptr->text[i].text, 0,
00344 info_ptr->text[i].compression);
00345 #else
00346 png_warning(png_ptr, "Unable to write compressed text");
00347 #endif
00348
00349 info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR;
00350 }
00351 else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE)
00352 {
00353 #if defined(PNG_WRITE_tEXt_SUPPORTED)
00354
00355 png_write_tEXt(png_ptr, info_ptr->text[i].key,
00356 info_ptr->text[i].text, 0);
00357 #else
00358 png_warning(png_ptr, "Unable to write uncompressed text");
00359 #endif
00360
00361
00362 info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
00363 }
00364 }
00365 #endif
00366 #if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
00367 if (info_ptr->unknown_chunks_num)
00368 {
00369 png_unknown_chunk *up;
00370
00371 png_debug(5, "writing extra chunks\n");
00372
00373 for (up = info_ptr->unknown_chunks;
00374 up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num;
00375 up++)
00376 {
00377 int keep=png_handle_as_unknown(png_ptr, up->name);
00378 if (keep != PNG_HANDLE_CHUNK_NEVER &&
00379 up->location && (up->location & PNG_AFTER_IDAT) &&
00380 ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS ||
00381 (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS)))
00382 {
00383 png_write_chunk(png_ptr, up->name, up->data, up->size);
00384 }
00385 }
00386 }
00387 #endif
00388 }
00389
00390 png_ptr->mode |= PNG_AFTER_IDAT;
00391
00392
00393 png_write_IEND(png_ptr);
00394 }
00395
00396 #if defined(PNG_WRITE_tIME_SUPPORTED)
00397 #if !defined(_WIN32_WCE)
00398
00399 void PNGAPI
00400 png_convert_from_struct_tm(png_timep ptime, struct tm FAR * ttime)
00401 {
00402 png_debug(1, "in png_convert_from_struct_tm\n");
00403 ptime->year = (png_uint_16)(1900 + ttime->tm_year);
00404 ptime->month = (png_byte)(ttime->tm_mon + 1);
00405 ptime->day = (png_byte)ttime->tm_mday;
00406 ptime->hour = (png_byte)ttime->tm_hour;
00407 ptime->minute = (png_byte)ttime->tm_min;
00408 ptime->second = (png_byte)ttime->tm_sec;
00409 }
00410
00411 void PNGAPI
00412 png_convert_from_time_t(png_timep ptime, time_t ttime)
00413 {
00414 struct tm *tbuf;
00415
00416 png_debug(1, "in png_convert_from_time_t\n");
00417 tbuf = gmtime(&ttime);
00418 png_convert_from_struct_tm(ptime, tbuf);
00419 }
00420 #endif
00421 #endif
00422
00423
00424 png_structp PNGAPI
00425 png_create_write_struct(png_const_charp user_png_ver, png_voidp error_ptr,
00426 png_error_ptr error_fn, png_error_ptr warn_fn)
00427 {
00428 #ifdef PNG_USER_MEM_SUPPORTED
00429 return (png_create_write_struct_2(user_png_ver, error_ptr, error_fn,
00430 warn_fn, png_voidp_NULL, png_malloc_ptr_NULL, png_free_ptr_NULL));
00431 }
00432
00433
00434 png_structp PNGAPI
00435 png_create_write_struct_2(png_const_charp user_png_ver, png_voidp error_ptr,
00436 png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
00437 png_malloc_ptr malloc_fn, png_free_ptr free_fn)
00438 {
00439 #endif
00440 png_structp png_ptr;
00441 #ifdef PNG_SETJMP_SUPPORTED
00442 #ifdef USE_FAR_KEYWORD
00443 jmp_buf jmpbuf;
00444 #endif
00445 #endif
00446 int i;
00447 png_debug(1, "in png_create_write_struct\n");
00448 #ifdef PNG_USER_MEM_SUPPORTED
00449 png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG,
00450 (png_malloc_ptr)malloc_fn, (png_voidp)mem_ptr);
00451 #else
00452 png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG);
00453 #endif
00454 if (png_ptr == NULL)
00455 return (NULL);
00456
00457
00458 #ifdef PNG_SET_USER_LIMITS_SUPPORTED
00459 png_ptr->user_width_max=PNG_USER_WIDTH_MAX;
00460 png_ptr->user_height_max=PNG_USER_HEIGHT_MAX;
00461 #endif
00462
00463 #ifdef PNG_SETJMP_SUPPORTED
00464 #ifdef USE_FAR_KEYWORD
00465 if (setjmp(jmpbuf))
00466 #else
00467 if (setjmp(png_ptr->jmpbuf))
00468 #endif
00469 {
00470 png_free(png_ptr, png_ptr->zbuf);
00471 png_ptr->zbuf=NULL;
00472 png_destroy_struct(png_ptr);
00473 return (NULL);
00474 }
00475 #ifdef USE_FAR_KEYWORD
00476 png_memcpy(png_ptr->jmpbuf,jmpbuf,png_sizeof(jmp_buf));
00477 #endif
00478 #endif
00479
00480 #ifdef PNG_USER_MEM_SUPPORTED
00481 png_set_mem_fn(png_ptr, mem_ptr, malloc_fn, free_fn);
00482 #endif
00483 png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn);
00484
00485 i=0;
00486 do
00487 {
00488 if(user_png_ver[i] != png_libpng_ver[i])
00489 png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
00490 } while (png_libpng_ver[i++]);
00491
00492 if (png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH)
00493 {
00494
00495
00496
00497
00498
00499 if (user_png_ver == NULL || user_png_ver[0] != png_libpng_ver[0] ||
00500 (user_png_ver[0] == '1' && user_png_ver[2] != png_libpng_ver[2]) ||
00501 (user_png_ver[0] == '0' && user_png_ver[2] < '9'))
00502 {
00503 #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
00504 char msg[80];
00505 if (user_png_ver)
00506 {
00507 png_snprintf(msg, 80,
00508 "Application was compiled with png.h from libpng-%.20s",
00509 user_png_ver);
00510 png_warning(png_ptr, msg);
00511 }
00512 png_snprintf(msg, 80,
00513 "Application is running with png.c from libpng-%.20s",
00514 png_libpng_ver);
00515 png_warning(png_ptr, msg);
00516 #endif
00517 #ifdef PNG_ERROR_NUMBERS_SUPPORTED
00518 png_ptr->flags=0;
00519 #endif
00520 png_error(png_ptr,
00521 "Incompatible libpng version in application and library");
00522 }
00523 }
00524
00525
00526 png_ptr->zbuf_size = PNG_ZBUF_SIZE;
00527 png_ptr->zbuf = (png_bytep)png_malloc(png_ptr,
00528 (png_uint_32)png_ptr->zbuf_size);
00529
00530 png_set_write_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL,
00531 png_flush_ptr_NULL);
00532
00533 #if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
00534 png_set_filter_heuristics(png_ptr, PNG_FILTER_HEURISTIC_DEFAULT,
00535 1, png_doublep_NULL, png_doublep_NULL);
00536 #endif
00537
00538 #ifdef PNG_SETJMP_SUPPORTED
00539
00540
00541
00542 #ifdef USE_FAR_KEYWORD
00543 if (setjmp(jmpbuf))
00544 PNG_ABORT();
00545 png_memcpy(png_ptr->jmpbuf,jmpbuf,png_sizeof(jmp_buf));
00546 #else
00547 if (setjmp(png_ptr->jmpbuf))
00548 PNG_ABORT();
00549 #endif
00550 #endif
00551 return (png_ptr);
00552 }
00553
00554
00555 #if defined(PNG_1_0_X) || defined(PNG_1_2_X)
00556
00557 #undef png_write_init
00558 void PNGAPI
00559 png_write_init(png_structp png_ptr)
00560 {
00561
00562 png_write_init_2(png_ptr, "1.0.6 or earlier", 0, 0);
00563 }
00564
00565 void PNGAPI
00566 png_write_init_2(png_structp png_ptr, png_const_charp user_png_ver,
00567 png_size_t png_struct_size, png_size_t png_info_size)
00568 {
00569
00570 if(png_ptr == NULL) return;
00571 #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
00572 if(png_sizeof(png_struct) > png_struct_size ||
00573 png_sizeof(png_info) > png_info_size)
00574 {
00575 char msg[80];
00576 png_ptr->warning_fn=NULL;
00577 if (user_png_ver)
00578 {
00579 png_snprintf(msg, 80,
00580 "Application was compiled with png.h from libpng-%.20s",
00581 user_png_ver);
00582 png_warning(png_ptr, msg);
00583 }
00584 png_snprintf(msg, 80,
00585 "Application is running with png.c from libpng-%.20s",
00586 png_libpng_ver);
00587 png_warning(png_ptr, msg);
00588 }
00589 #endif
00590 if(png_sizeof(png_struct) > png_struct_size)
00591 {
00592 png_ptr->error_fn=NULL;
00593 #ifdef PNG_ERROR_NUMBERS_SUPPORTED
00594 png_ptr->flags=0;
00595 #endif
00596 png_error(png_ptr,
00597 "The png struct allocated by the application for writing is too small.");
00598 }
00599 if(png_sizeof(png_info) > png_info_size)
00600 {
00601 png_ptr->error_fn=NULL;
00602 #ifdef PNG_ERROR_NUMBERS_SUPPORTED
00603 png_ptr->flags=0;
00604 #endif
00605 png_error(png_ptr,
00606 "The info struct allocated by the application for writing is too small.");
00607 }
00608 png_write_init_3(&png_ptr, user_png_ver, png_struct_size);
00609 }
00610 #endif
00611
00612
00613 void PNGAPI
00614 png_write_init_3(png_structpp ptr_ptr, png_const_charp user_png_ver,
00615 png_size_t png_struct_size)
00616 {
00617 png_structp png_ptr=*ptr_ptr;
00618 #ifdef PNG_SETJMP_SUPPORTED
00619 jmp_buf tmp_jmp;
00620 #endif
00621
00622 int i = 0;
00623
00624 if (png_ptr == NULL)
00625 return;
00626
00627 do
00628 {
00629 if (user_png_ver[i] != png_libpng_ver[i])
00630 {
00631 #ifdef PNG_LEGACY_SUPPORTED
00632 png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
00633 #else
00634 png_ptr->warning_fn=NULL;
00635 png_warning(png_ptr,
00636 "Application uses deprecated png_write_init() and should be recompiled.");
00637 break;
00638 #endif
00639 }
00640 } while (png_libpng_ver[i++]);
00641
00642 png_debug(1, "in png_write_init_3\n");
00643
00644 #ifdef PNG_SETJMP_SUPPORTED
00645
00646 png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof (jmp_buf));
00647 #endif
00648
00649 if (png_sizeof(png_struct) > png_struct_size)
00650 {
00651 png_destroy_struct(png_ptr);
00652 png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG);
00653 *ptr_ptr = png_ptr;
00654 }
00655
00656
00657 png_memset(png_ptr, 0, png_sizeof (png_struct));
00658
00659
00660 #ifdef PNG_SET_USER_LIMITS_SUPPORTED
00661 png_ptr->user_width_max=PNG_USER_WIDTH_MAX;
00662 png_ptr->user_height_max=PNG_USER_HEIGHT_MAX;
00663 #endif
00664
00665 #ifdef PNG_SETJMP_SUPPORTED
00666
00667 png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof (jmp_buf));
00668 #endif
00669
00670 png_set_write_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL,
00671 png_flush_ptr_NULL);
00672
00673
00674 png_ptr->zbuf_size = PNG_ZBUF_SIZE;
00675 png_ptr->zbuf = (png_bytep)png_malloc(png_ptr,
00676 (png_uint_32)png_ptr->zbuf_size);
00677
00678 #if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
00679 png_set_filter_heuristics(png_ptr, PNG_FILTER_HEURISTIC_DEFAULT,
00680 1, png_doublep_NULL, png_doublep_NULL);
00681 #endif
00682 }
00683
00684
00685
00686
00687
00688
00689 void PNGAPI
00690 png_write_rows(png_structp png_ptr, png_bytepp row,
00691 png_uint_32 num_rows)
00692 {
00693 png_uint_32 i;
00694 png_bytepp rp;
00695
00696 png_debug(1, "in png_write_rows\n");
00697
00698 if (png_ptr == NULL)
00699 return;
00700
00701
00702 for (i = 0, rp = row; i < num_rows; i++, rp++)
00703 {
00704 png_write_row(png_ptr, *rp);
00705 }
00706 }
00707
00708
00709
00710
00711 void PNGAPI
00712 png_write_image(png_structp png_ptr, png_bytepp image)
00713 {
00714 png_uint_32 i;
00715 int pass, num_pass;
00716 png_bytepp rp;
00717
00718 if (png_ptr == NULL)
00719 return;
00720
00721 png_debug(1, "in png_write_image\n");
00722 #if defined(PNG_WRITE_INTERLACING_SUPPORTED)
00723
00724
00725 num_pass = png_set_interlace_handling(png_ptr);
00726 #else
00727 num_pass = 1;
00728 #endif
00729
00730 for (pass = 0; pass < num_pass; pass++)
00731 {
00732
00733 for (i = 0, rp = image; i < png_ptr->height; i++, rp++)
00734 {
00735 png_write_row(png_ptr, *rp);
00736 }
00737 }
00738 }
00739
00740
00741 void PNGAPI
00742 png_write_row(png_structp png_ptr, png_bytep row)
00743 {
00744 if (png_ptr == NULL)
00745 return;
00746 png_debug2(1, "in png_write_row (row %ld, pass %d)\n",
00747 png_ptr->row_number, png_ptr->pass);
00748
00749
00750 if (png_ptr->row_number == 0 && png_ptr->pass == 0)
00751 {
00752
00753 if (!(png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE))
00754 png_error(png_ptr,
00755 "png_write_info was never called before png_write_row.");
00756
00757
00758 #if !defined(PNG_WRITE_INVERT_SUPPORTED) && defined(PNG_READ_INVERT_SUPPORTED)
00759 if (png_ptr->transformations & PNG_INVERT_MONO)
00760 png_warning(png_ptr, "PNG_WRITE_INVERT_SUPPORTED is not defined.");
00761 #endif
00762 #if !defined(PNG_WRITE_FILLER_SUPPORTED) && defined(PNG_READ_FILLER_SUPPORTED)
00763 if (png_ptr->transformations & PNG_FILLER)
00764 png_warning(png_ptr, "PNG_WRITE_FILLER_SUPPORTED is not defined.");
00765 #endif
00766 #if !defined(PNG_WRITE_PACKSWAP_SUPPORTED) && defined(PNG_READ_PACKSWAP_SUPPORTED)
00767 if (png_ptr->transformations & PNG_PACKSWAP)
00768 png_warning(png_ptr, "PNG_WRITE_PACKSWAP_SUPPORTED is not defined.");
00769 #endif
00770 #if !defined(PNG_WRITE_PACK_SUPPORTED) && defined(PNG_READ_PACK_SUPPORTED)
00771 if (png_ptr->transformations & PNG_PACK)
00772 png_warning(png_ptr, "PNG_WRITE_PACK_SUPPORTED is not defined.");
00773 #endif
00774 #if !defined(PNG_WRITE_SHIFT_SUPPORTED) && defined(PNG_READ_SHIFT_SUPPORTED)
00775 if (png_ptr->transformations & PNG_SHIFT)
00776 png_warning(png_ptr, "PNG_WRITE_SHIFT_SUPPORTED is not defined.");
00777 #endif
00778 #if !defined(PNG_WRITE_BGR_SUPPORTED) && defined(PNG_READ_BGR_SUPPORTED)
00779 if (png_ptr->transformations & PNG_BGR)
00780 png_warning(png_ptr, "PNG_WRITE_BGR_SUPPORTED is not defined.");
00781 #endif
00782 #if !defined(PNG_WRITE_SWAP_SUPPORTED) && defined(PNG_READ_SWAP_SUPPORTED)
00783 if (png_ptr->transformations & PNG_SWAP_BYTES)
00784 png_warning(png_ptr, "PNG_WRITE_SWAP_SUPPORTED is not defined.");
00785 #endif
00786
00787 png_write_start_row(png_ptr);
00788 }
00789
00790 #if defined(PNG_WRITE_INTERLACING_SUPPORTED)
00791
00792 if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
00793 {
00794 switch (png_ptr->pass)
00795 {
00796 case 0:
00797 if (png_ptr->row_number & 0x07)
00798 {
00799 png_write_finish_row(png_ptr);
00800 return;
00801 }
00802 break;
00803 case 1:
00804 if ((png_ptr->row_number & 0x07) || png_ptr->width < 5)
00805 {
00806 png_write_finish_row(png_ptr);
00807 return;
00808 }
00809 break;
00810 case 2:
00811 if ((png_ptr->row_number & 0x07) != 4)
00812 {
00813 png_write_finish_row(png_ptr);
00814 return;
00815 }
00816 break;
00817 case 3:
00818 if ((png_ptr->row_number & 0x03) || png_ptr->width < 3)
00819 {
00820 png_write_finish_row(png_ptr);
00821 return;
00822 }
00823 break;
00824 case 4:
00825 if ((png_ptr->row_number & 0x03) != 2)
00826 {
00827 png_write_finish_row(png_ptr);
00828 return;
00829 }
00830 break;
00831 case 5:
00832 if ((png_ptr->row_number & 0x01) || png_ptr->width < 2)
00833 {
00834 png_write_finish_row(png_ptr);
00835 return;
00836 }
00837 break;
00838 case 6:
00839 if (!(png_ptr->row_number & 0x01))
00840 {
00841 png_write_finish_row(png_ptr);
00842 return;
00843 }
00844 break;
00845 }
00846 }
00847 #endif
00848
00849
00850 png_ptr->row_info.color_type = png_ptr->color_type;
00851 png_ptr->row_info.width = png_ptr->usr_width;
00852 png_ptr->row_info.channels = png_ptr->usr_channels;
00853 png_ptr->row_info.bit_depth = png_ptr->usr_bit_depth;
00854 png_ptr->row_info.pixel_depth = (png_byte)(png_ptr->row_info.bit_depth *
00855 png_ptr->row_info.channels);
00856
00857 png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
00858 png_ptr->row_info.width);
00859
00860 png_debug1(3, "row_info->color_type = %d\n", png_ptr->row_info.color_type);
00861 png_debug1(3, "row_info->width = %lu\n", png_ptr->row_info.width);
00862 png_debug1(3, "row_info->channels = %d\n", png_ptr->row_info.channels);
00863 png_debug1(3, "row_info->bit_depth = %d\n", png_ptr->row_info.bit_depth);
00864 png_debug1(3, "row_info->pixel_depth = %d\n", png_ptr->row_info.pixel_depth);
00865 png_debug1(3, "row_info->rowbytes = %lu\n", png_ptr->row_info.rowbytes);
00866
00867
00868 png_memcpy_check(png_ptr, png_ptr->row_buf + 1, row,
00869 png_ptr->row_info.rowbytes);
00870
00871 #if defined(PNG_WRITE_INTERLACING_SUPPORTED)
00872
00873 if (png_ptr->interlaced && png_ptr->pass < 6 &&
00874 (png_ptr->transformations & PNG_INTERLACE))
00875 {
00876 png_do_write_interlace(&(png_ptr->row_info),
00877 png_ptr->row_buf + 1, png_ptr->pass);
00878
00879 if (!(png_ptr->row_info.width))
00880 {
00881 png_write_finish_row(png_ptr);
00882 return;
00883 }
00884 }
00885 #endif
00886
00887
00888 if (png_ptr->transformations)
00889 png_do_write_transformations(png_ptr);
00890
00891 #if defined(PNG_MNG_FEATURES_SUPPORTED)
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901 if((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
00902 (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING))
00903 {
00904
00905 png_do_write_intrapixel(&(png_ptr->row_info), png_ptr->row_buf + 1);
00906 }
00907 #endif
00908
00909
00910 png_write_find_filter(png_ptr, &(png_ptr->row_info));
00911
00912 if (png_ptr->write_row_fn != NULL)
00913 (*(png_ptr->write_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass);
00914 }
00915
00916 #if defined(PNG_WRITE_FLUSH_SUPPORTED)
00917
00918 void PNGAPI
00919 png_set_flush(png_structp png_ptr, int nrows)
00920 {
00921 png_debug(1, "in png_set_flush\n");
00922 if (png_ptr == NULL)
00923 return;
00924 png_ptr->flush_dist = (nrows < 0 ? 0 : nrows);
00925 }
00926
00927
00928 void PNGAPI
00929 png_write_flush(png_structp png_ptr)
00930 {
00931 int wrote_IDAT;
00932
00933 png_debug(1, "in png_write_flush\n");
00934 if (png_ptr == NULL)
00935 return;
00936
00937 if (png_ptr->row_number >= png_ptr->num_rows)
00938 return;
00939
00940 do
00941 {
00942 int ret;
00943
00944
00945 ret = deflate(&png_ptr->zstream, Z_SYNC_FLUSH);
00946 wrote_IDAT = 0;
00947
00948
00949 if (ret != Z_OK)
00950 {
00951 if (png_ptr->zstream.msg != NULL)
00952 png_error(png_ptr, png_ptr->zstream.msg);
00953 else
00954 png_error(png_ptr, "zlib error");
00955 }
00956
00957 if (!(png_ptr->zstream.avail_out))
00958 {
00959
00960 png_write_IDAT(png_ptr, png_ptr->zbuf,
00961 png_ptr->zbuf_size);
00962 png_ptr->zstream.next_out = png_ptr->zbuf;
00963 png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
00964 wrote_IDAT = 1;
00965 }
00966 } while(wrote_IDAT == 1);
00967
00968
00969 if (png_ptr->zbuf_size != png_ptr->zstream.avail_out)
00970 {
00971
00972 png_write_IDAT(png_ptr, png_ptr->zbuf,
00973 png_ptr->zbuf_size - png_ptr->zstream.avail_out);
00974 png_ptr->zstream.next_out = png_ptr->zbuf;
00975 png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
00976 }
00977 png_ptr->flush_rows = 0;
00978 png_flush(png_ptr);
00979 }
00980 #endif
00981
00982
00983 void PNGAPI
00984 png_destroy_write_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr)
00985 {
00986 png_structp png_ptr = NULL;
00987 png_infop info_ptr = NULL;
00988 #ifdef PNG_USER_MEM_SUPPORTED
00989 png_free_ptr free_fn = NULL;
00990 png_voidp mem_ptr = NULL;
00991 #endif
00992
00993 png_debug(1, "in png_destroy_write_struct\n");
00994 if (png_ptr_ptr != NULL)
00995 {
00996 png_ptr = *png_ptr_ptr;
00997 #ifdef PNG_USER_MEM_SUPPORTED
00998 free_fn = png_ptr->free_fn;
00999 mem_ptr = png_ptr->mem_ptr;
01000 #endif
01001 }
01002
01003 if (info_ptr_ptr != NULL)
01004 info_ptr = *info_ptr_ptr;
01005
01006 if (info_ptr != NULL)
01007 {
01008 png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
01009
01010 #if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
01011 if (png_ptr->num_chunk_list)
01012 {
01013 png_free(png_ptr, png_ptr->chunk_list);
01014 png_ptr->chunk_list=NULL;
01015 png_ptr->num_chunk_list=0;
01016 }
01017 #endif
01018
01019 #ifdef PNG_USER_MEM_SUPPORTED
01020 png_destroy_struct_2((png_voidp)info_ptr, (png_free_ptr)free_fn,
01021 (png_voidp)mem_ptr);
01022 #else
01023 png_destroy_struct((png_voidp)info_ptr);
01024 #endif
01025 *info_ptr_ptr = NULL;
01026 }
01027
01028 if (png_ptr != NULL)
01029 {
01030 png_write_destroy(png_ptr);
01031 #ifdef PNG_USER_MEM_SUPPORTED
01032 png_destroy_struct_2((png_voidp)png_ptr, (png_free_ptr)free_fn,
01033 (png_voidp)mem_ptr);
01034 #else
01035 png_destroy_struct((png_voidp)png_ptr);
01036 #endif
01037 *png_ptr_ptr = NULL;
01038 }
01039 }
01040
01041
01042
01043 void
01044 png_write_destroy(png_structp png_ptr)
01045 {
01046 #ifdef PNG_SETJMP_SUPPORTED
01047 jmp_buf tmp_jmp;
01048 #endif
01049 png_error_ptr error_fn;
01050 png_error_ptr warning_fn;
01051 png_voidp error_ptr;
01052 #ifdef PNG_USER_MEM_SUPPORTED
01053 png_free_ptr free_fn;
01054 #endif
01055
01056 png_debug(1, "in png_write_destroy\n");
01057
01058 deflateEnd(&png_ptr->zstream);
01059
01060
01061 png_free(png_ptr, png_ptr->zbuf);
01062 png_free(png_ptr, png_ptr->row_buf);
01063 png_free(png_ptr, png_ptr->prev_row);
01064 png_free(png_ptr, png_ptr->sub_row);
01065 png_free(png_ptr, png_ptr->up_row);
01066 png_free(png_ptr, png_ptr->avg_row);
01067 png_free(png_ptr, png_ptr->paeth_row);
01068
01069 #if defined(PNG_TIME_RFC1123_SUPPORTED)
01070 png_free(png_ptr, png_ptr->time_buffer);
01071 #endif
01072
01073 #if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
01074 png_free(png_ptr, png_ptr->prev_filters);
01075 png_free(png_ptr, png_ptr->filter_weights);
01076 png_free(png_ptr, png_ptr->inv_filter_weights);
01077 png_free(png_ptr, png_ptr->filter_costs);
01078 png_free(png_ptr, png_ptr->inv_filter_costs);
01079 #endif
01080
01081 #ifdef PNG_SETJMP_SUPPORTED
01082
01083 png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof (jmp_buf));
01084 #endif
01085
01086 error_fn = png_ptr->error_fn;
01087 warning_fn = png_ptr->warning_fn;
01088 error_ptr = png_ptr->error_ptr;
01089 #ifdef PNG_USER_MEM_SUPPORTED
01090 free_fn = png_ptr->free_fn;
01091 #endif
01092
01093 png_memset(png_ptr, 0, png_sizeof (png_struct));
01094
01095 png_ptr->error_fn = error_fn;
01096 png_ptr->warning_fn = warning_fn;
01097 png_ptr->error_ptr = error_ptr;
01098 #ifdef PNG_USER_MEM_SUPPORTED
01099 png_ptr->free_fn = free_fn;
01100 #endif
01101
01102 #ifdef PNG_SETJMP_SUPPORTED
01103 png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof (jmp_buf));
01104 #endif
01105 }
01106
01107
01108 void PNGAPI
01109 png_set_filter(png_structp png_ptr, int method, int filters)
01110 {
01111 png_debug(1, "in png_set_filter\n");
01112 if (png_ptr == NULL)
01113 return;
01114 #if defined(PNG_MNG_FEATURES_SUPPORTED)
01115 if((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
01116 (method == PNG_INTRAPIXEL_DIFFERENCING))
01117 method = PNG_FILTER_TYPE_BASE;
01118 #endif
01119 if (method == PNG_FILTER_TYPE_BASE)
01120 {
01121 switch (filters & (PNG_ALL_FILTERS | 0x07))
01122 {
01123 #ifndef PNG_NO_WRITE_FILTER
01124 case 5:
01125 case 6:
01126 case 7: png_warning(png_ptr, "Unknown row filter for method 0");
01127 #endif
01128 case PNG_FILTER_VALUE_NONE:
01129 png_ptr->do_filter=PNG_FILTER_NONE; break;
01130 #ifndef PNG_NO_WRITE_FILTER
01131 case PNG_FILTER_VALUE_SUB:
01132 png_ptr->do_filter=PNG_FILTER_SUB; break;
01133 case PNG_FILTER_VALUE_UP:
01134 png_ptr->do_filter=PNG_FILTER_UP; break;
01135 case PNG_FILTER_VALUE_AVG:
01136 png_ptr->do_filter=PNG_FILTER_AVG; break;
01137 case PNG_FILTER_VALUE_PAETH:
01138 png_ptr->do_filter=PNG_FILTER_PAETH; break;
01139 default: png_ptr->do_filter = (png_byte)filters; break;
01140 #else
01141 default: png_warning(png_ptr, "Unknown row filter for method 0");
01142 #endif
01143 }
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154 if (png_ptr->row_buf != NULL)
01155 {
01156 #ifndef PNG_NO_WRITE_FILTER
01157 if ((png_ptr->do_filter & PNG_FILTER_SUB) && png_ptr->sub_row == NULL)
01158 {
01159 png_ptr->sub_row = (png_bytep)png_malloc(png_ptr,
01160 (png_ptr->rowbytes + 1));
01161 png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB;
01162 }
01163
01164 if ((png_ptr->do_filter & PNG_FILTER_UP) && png_ptr->up_row == NULL)
01165 {
01166 if (png_ptr->prev_row == NULL)
01167 {
01168 png_warning(png_ptr, "Can't add Up filter after starting");
01169 png_ptr->do_filter &= ~PNG_FILTER_UP;
01170 }
01171 else
01172 {
01173 png_ptr->up_row = (png_bytep)png_malloc(png_ptr,
01174 (png_ptr->rowbytes + 1));
01175 png_ptr->up_row[0] = PNG_FILTER_VALUE_UP;
01176 }
01177 }
01178
01179 if ((png_ptr->do_filter & PNG_FILTER_AVG) && png_ptr->avg_row == NULL)
01180 {
01181 if (png_ptr->prev_row == NULL)
01182 {
01183 png_warning(png_ptr, "Can't add Average filter after starting");
01184 png_ptr->do_filter &= ~PNG_FILTER_AVG;
01185 }
01186 else
01187 {
01188 png_ptr->avg_row = (png_bytep)png_malloc(png_ptr,
01189 (png_ptr->rowbytes + 1));
01190 png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG;
01191 }
01192 }
01193
01194 if ((png_ptr->do_filter & PNG_FILTER_PAETH) &&
01195 png_ptr->paeth_row == NULL)
01196 {
01197 if (png_ptr->prev_row == NULL)
01198 {
01199 png_warning(png_ptr, "Can't add Paeth filter after starting");
01200 png_ptr->do_filter &= (png_byte)(~PNG_FILTER_PAETH);
01201 }
01202 else
01203 {
01204 png_ptr->paeth_row = (png_bytep)png_malloc(png_ptr,
01205 (png_ptr->rowbytes + 1));
01206 png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH;
01207 }
01208 }
01209
01210 if (png_ptr->do_filter == PNG_NO_FILTERS)
01211 #endif
01212 png_ptr->do_filter = PNG_FILTER_NONE;
01213 }
01214 }
01215 else
01216 png_error(png_ptr, "Unknown custom filter method");
01217 }
01218
01219
01220
01221
01222
01223
01224
01225
01226 #if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
01227 void PNGAPI
01228 png_set_filter_heuristics(png_structp png_ptr, int heuristic_method,
01229 int num_weights, png_doublep filter_weights,
01230 png_doublep filter_costs)
01231 {
01232 int i;
01233
01234 png_debug(1, "in png_set_filter_heuristics\n");
01235 if (png_ptr == NULL)
01236 return;
01237 if (heuristic_method >= PNG_FILTER_HEURISTIC_LAST)
01238 {
01239 png_warning(png_ptr, "Unknown filter heuristic method");
01240 return;
01241 }
01242
01243 if (heuristic_method == PNG_FILTER_HEURISTIC_DEFAULT)
01244 {
01245 heuristic_method = PNG_FILTER_HEURISTIC_UNWEIGHTED;
01246 }
01247
01248 if (num_weights < 0 || filter_weights == NULL ||
01249 heuristic_method == PNG_FILTER_HEURISTIC_UNWEIGHTED)
01250 {
01251 num_weights = 0;
01252 }
01253
01254 png_ptr->num_prev_filters = (png_byte)num_weights;
01255 png_ptr->heuristic_method = (png_byte)heuristic_method;
01256
01257 if (num_weights > 0)
01258 {
01259 if (png_ptr->prev_filters == NULL)
01260 {
01261 png_ptr->prev_filters = (png_bytep)png_malloc(png_ptr,
01262 (png_uint_32)(png_sizeof(png_byte) * num_weights));
01263
01264
01265 for (i = 0; i < num_weights; i++)
01266 {
01267 png_ptr->prev_filters[i] = 255;
01268 }
01269 }
01270
01271 if (png_ptr->filter_weights == NULL)
01272 {
01273 png_ptr->filter_weights = (png_uint_16p)png_malloc(png_ptr,
01274 (png_uint_32)(png_sizeof(png_uint_16) * num_weights));
01275
01276 png_ptr->inv_filter_weights = (png_uint_16p)png_malloc(png_ptr,
01277 (png_uint_32)(png_sizeof(png_uint_16) * num_weights));
01278 for (i = 0; i < num_weights; i++)
01279 {
01280 png_ptr->inv_filter_weights[i] =
01281 png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR;
01282 }
01283 }
01284
01285 for (i = 0; i < num_weights; i++)
01286 {
01287 if (filter_weights[i] < 0.0)
01288 {
01289 png_ptr->inv_filter_weights[i] =
01290 png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR;
01291 }
01292 else
01293 {
01294 png_ptr->inv_filter_weights[i] =
01295 (png_uint_16)((double)PNG_WEIGHT_FACTOR*filter_weights[i]+0.5);
01296 png_ptr->filter_weights[i] =
01297 (png_uint_16)((double)PNG_WEIGHT_FACTOR/filter_weights[i]+0.5);
01298 }
01299 }
01300 }
01301
01302
01303
01304
01305 if (png_ptr->filter_costs == NULL)
01306 {
01307 png_ptr->filter_costs = (png_uint_16p)png_malloc(png_ptr,
01308 (png_uint_32)(png_sizeof(png_uint_16) * PNG_FILTER_VALUE_LAST));
01309
01310 png_ptr->inv_filter_costs = (png_uint_16p)png_malloc(png_ptr,
01311 (png_uint_32)(png_sizeof(png_uint_16) * PNG_FILTER_VALUE_LAST));
01312
01313 for (i = 0; i < PNG_FILTER_VALUE_LAST; i++)
01314 {
01315 png_ptr->inv_filter_costs[i] =
01316 png_ptr->filter_costs[i] = PNG_COST_FACTOR;
01317 }
01318 }
01319
01320
01321
01322
01323
01324
01325
01326
01327 for (i = 0; i < PNG_FILTER_VALUE_LAST; i++)
01328 {
01329 if (filter_costs == NULL || filter_costs[i] < 0.0)
01330 {
01331 png_ptr->inv_filter_costs[i] =
01332 png_ptr->filter_costs[i] = PNG_COST_FACTOR;
01333 }
01334 else if (filter_costs[i] >= 1.0)
01335 {
01336 png_ptr->inv_filter_costs[i] =
01337 (png_uint_16)((double)PNG_COST_FACTOR / filter_costs[i] + 0.5);
01338 png_ptr->filter_costs[i] =
01339 (png_uint_16)((double)PNG_COST_FACTOR * filter_costs[i] + 0.5);
01340 }
01341 }
01342 }
01343 #endif
01344
01345 void PNGAPI
01346 png_set_compression_level(png_structp png_ptr, int level)
01347 {
01348 png_debug(1, "in png_set_compression_level\n");
01349 if (png_ptr == NULL)
01350 return;
01351 png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_LEVEL;
01352 png_ptr->zlib_level = level;
01353 }
01354
01355 void PNGAPI
01356 png_set_compression_mem_level(png_structp png_ptr, int mem_level)
01357 {
01358 png_debug(1, "in png_set_compression_mem_level\n");
01359 if (png_ptr == NULL)
01360 return;
01361 png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL;
01362 png_ptr->zlib_mem_level = mem_level;
01363 }
01364
01365 void PNGAPI
01366 png_set_compression_strategy(png_structp png_ptr, int strategy)
01367 {
01368 png_debug(1, "in png_set_compression_strategy\n");
01369 if (png_ptr == NULL)
01370 return;
01371 png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_STRATEGY;
01372 png_ptr->zlib_strategy = strategy;
01373 }
01374
01375 void PNGAPI
01376 png_set_compression_window_bits(png_structp png_ptr, int window_bits)
01377 {
01378 if (png_ptr == NULL)
01379 return;
01380 if (window_bits > 15)
01381 png_warning(png_ptr, "Only compression windows <= 32k supported by PNG");
01382 else if (window_bits < 8)
01383 png_warning(png_ptr, "Only compression windows >= 256 supported by PNG");
01384 #ifndef WBITS_8_OK
01385
01386 if (window_bits == 8)
01387 {
01388 png_warning(png_ptr, "Compression window is being reset to 512");
01389 window_bits=9;
01390 }
01391 #endif
01392 png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS;
01393 png_ptr->zlib_window_bits = window_bits;
01394 }
01395
01396 void PNGAPI
01397 png_set_compression_method(png_structp png_ptr, int method)
01398 {
01399 png_debug(1, "in png_set_compression_method\n");
01400 if (png_ptr == NULL)
01401 return;
01402 if (method != 8)
01403 png_warning(png_ptr, "Only compression method 8 is supported by PNG");
01404 png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_METHOD;
01405 png_ptr->zlib_method = method;
01406 }
01407
01408 void PNGAPI
01409 png_set_write_status_fn(png_structp png_ptr, png_write_status_ptr write_row_fn)
01410 {
01411 if (png_ptr == NULL)
01412 return;
01413 png_ptr->write_row_fn = write_row_fn;
01414 }
01415
01416 #if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
01417 void PNGAPI
01418 png_set_write_user_transform_fn(png_structp png_ptr, png_user_transform_ptr
01419 write_user_transform_fn)
01420 {
01421 png_debug(1, "in png_set_write_user_transform_fn\n");
01422 if (png_ptr == NULL)
01423 return;
01424 png_ptr->transformations |= PNG_USER_TRANSFORM;
01425 png_ptr->write_user_transform_fn = write_user_transform_fn;
01426 }
01427 #endif
01428
01429
01430 #if defined(PNG_INFO_IMAGE_SUPPORTED)
01431 void PNGAPI
01432 png_write_png(png_structp png_ptr, png_infop info_ptr,
01433 int transforms, voidp params)
01434 {
01435 if (png_ptr == NULL || info_ptr == NULL)
01436 return;
01437 #if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
01438
01439 if (transforms & PNG_TRANSFORM_INVERT_ALPHA)
01440 png_set_invert_alpha(png_ptr);
01441 #endif
01442
01443
01444 png_write_info(png_ptr, info_ptr);
01445
01446
01447
01448 #if defined(PNG_WRITE_INVERT_SUPPORTED)
01449
01450 if (transforms & PNG_TRANSFORM_INVERT_MONO)
01451 png_set_invert_mono(png_ptr);
01452 #endif
01453
01454 #if defined(PNG_WRITE_SHIFT_SUPPORTED)
01455
01456
01457
01458 if ((transforms & PNG_TRANSFORM_SHIFT)
01459 && (info_ptr->valid & PNG_INFO_sBIT))
01460 png_set_shift(png_ptr, &info_ptr->sig_bit);
01461 #endif
01462
01463 #if defined(PNG_WRITE_PACK_SUPPORTED)
01464
01465 if (transforms & PNG_TRANSFORM_PACKING)
01466 png_set_packing(png_ptr);
01467 #endif
01468
01469 #if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
01470
01471 if (transforms & PNG_TRANSFORM_SWAP_ALPHA)
01472 png_set_swap_alpha(png_ptr);
01473 #endif
01474
01475 #if defined(PNG_WRITE_FILLER_SUPPORTED)
01476
01477
01478
01479 if (transforms & PNG_TRANSFORM_STRIP_FILLER)
01480 png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE);
01481 #endif
01482
01483 #if defined(PNG_WRITE_BGR_SUPPORTED)
01484
01485 if (transforms & PNG_TRANSFORM_BGR)
01486 png_set_bgr(png_ptr);
01487 #endif
01488
01489 #if defined(PNG_WRITE_SWAP_SUPPORTED)
01490
01491 if (transforms & PNG_TRANSFORM_SWAP_ENDIAN)
01492 png_set_swap(png_ptr);
01493 #endif
01494
01495 #if defined(PNG_WRITE_PACKSWAP_SUPPORTED)
01496
01497 if (transforms & PNG_TRANSFORM_PACKSWAP)
01498 png_set_packswap(png_ptr);
01499 #endif
01500
01501
01502
01503
01504 if (info_ptr->valid & PNG_INFO_IDAT)
01505 png_write_image(png_ptr, info_ptr->row_pointers);
01506
01507
01508 png_write_end(png_ptr, info_ptr);
01509
01510 transforms = transforms;
01511 params = params;
01512 }
01513 #endif
01514 #endif