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