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