Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1897 | serge | 1 | |
2 | * |
||
3 | * Last changed in libpng 1.5.1 [February 3, 2011] |
||
4 | * Copyright (c) 1998-2011 Glenn Randers-Pehrson |
||
5 | * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) |
||
6 | * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) |
||
7 | * |
||
8 | * This code is released under the libpng license. |
||
9 | * For conditions of distribution and use, see the disclaimer |
||
10 | * and license in png.h |
||
11 | */ |
||
12 | |||
13 | |||
14 | |||
15 | |||
16 | typedef png_libpng_version_1_5_1 Your_png_h_is_not_version_1_5_1; |
||
17 | |||
18 | |||
19 | * of the PNG file signature. If the PNG data is embedded into another |
||
20 | * stream we can set num_bytes = 8 so that libpng will not attempt to read |
||
21 | * or write any of the magic bytes before it starts on the IHDR. |
||
22 | */ |
||
23 | |||
24 | |||
25 | void PNGAPI |
||
26 | png_set_sig_bytes(png_structp png_ptr, int num_bytes) |
||
27 | { |
||
28 | png_debug(1, "in png_set_sig_bytes"); |
||
29 | |||
30 | |||
31 | return; |
||
32 | |||
33 | |||
34 | png_error(png_ptr, "Too many bytes for PNG signature"); |
||
35 | |||
36 | |||
37 | } |
||
38 | |||
39 | |||
40 | * checking less than the full 8-byte signature so that those apps that |
||
41 | * already read the first few bytes of a file to determine the file type |
||
42 | * can simply check the remaining bytes for extra assurance. Returns |
||
43 | * an integer less than, equal to, or greater than zero if sig is found, |
||
44 | * respectively, to be less than, to match, or be greater than the correct |
||
45 | * PNG signature (this is the same behaviour as strcmp, memcmp, etc). |
||
46 | */ |
||
47 | int PNGAPI |
||
48 | png_sig_cmp(png_const_bytep sig, png_size_t start, png_size_t num_to_check) |
||
49 | { |
||
50 | png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10}; |
||
51 | |||
52 | |||
53 | num_to_check = 8; |
||
54 | |||
55 | |||
56 | return (-1); |
||
57 | |||
58 | |||
59 | return (-1); |
||
60 | |||
61 | |||
62 | num_to_check = 8 - start; |
||
63 | |||
64 | |||
65 | } |
||
66 | |||
67 | |||
68 | |||
69 | |||
70 | /* Function to allocate memory for zlib */ |
||
71 | PNG_FUNCTION(voidpf /* PRIVATE */, |
||
72 | png_zalloc,(voidpf png_ptr, uInt items, uInt size),PNG_ALLOCATED) |
||
73 | { |
||
74 | png_voidp ptr; |
||
75 | png_structp p=(png_structp)png_ptr; |
||
76 | png_uint_32 save_flags=p->flags; |
||
77 | png_alloc_size_t num_bytes; |
||
78 | |||
79 | |||
80 | return (NULL); |
||
81 | |||
82 | |||
83 | { |
||
84 | png_warning (p, "Potential overflow in png_zalloc()"); |
||
85 | return (NULL); |
||
86 | } |
||
87 | num_bytes = (png_alloc_size_t)items * size; |
||
88 | |||
89 | |||
90 | ptr = (png_voidp)png_malloc((png_structp)png_ptr, num_bytes); |
||
91 | p->flags=save_flags; |
||
92 | |||
93 | |||
94 | } |
||
95 | |||
96 | |||
97 | void /* PRIVATE */ |
||
98 | png_zfree(voidpf png_ptr, voidpf ptr) |
||
99 | { |
||
100 | png_free((png_structp)png_ptr, (png_voidp)ptr); |
||
101 | } |
||
102 | |||
103 | |||
104 | * in case CRC is > 32 bits to leave the top bits 0. |
||
105 | */ |
||
106 | void /* PRIVATE */ |
||
107 | png_reset_crc(png_structp png_ptr) |
||
108 | { |
||
109 | png_ptr->crc = crc32(0, Z_NULL, 0); |
||
110 | } |
||
111 | |||
112 | |||
113 | * much data to this routine as the largest single buffer size. We |
||
114 | * also check that this data will actually be used before going to the |
||
115 | * trouble of calculating it. |
||
116 | */ |
||
117 | void /* PRIVATE */ |
||
118 | png_calculate_crc(png_structp png_ptr, png_const_bytep ptr, png_size_t length) |
||
119 | { |
||
120 | int need_crc = 1; |
||
121 | |||
122 | |||
123 | { |
||
124 | if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) == |
||
125 | (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN)) |
||
126 | need_crc = 0; |
||
127 | } |
||
128 | |||
129 | |||
130 | { |
||
131 | if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) |
||
132 | need_crc = 0; |
||
133 | } |
||
134 | |||
135 | |||
136 | png_ptr->crc = crc32(png_ptr->crc, ptr, (uInt)length); |
||
137 | } |
||
138 | |||
139 | |||
140 | * really need the png_ptr, but it could potentially be useful in the |
||
141 | * future. This should be used in favour of malloc(png_sizeof(png_info)) |
||
142 | * and png_info_init() so that applications that want to use a shared |
||
143 | * libpng don't have to be recompiled if png_info changes size. |
||
144 | */ |
||
145 | PNG_FUNCTION(png_infop,PNGAPI |
||
146 | png_create_info_struct,(png_structp png_ptr),PNG_ALLOCATED) |
||
147 | { |
||
148 | png_infop info_ptr; |
||
149 | |||
150 | |||
151 | |||
152 | |||
153 | return (NULL); |
||
154 | |||
155 | |||
156 | info_ptr = (png_infop)png_create_struct_2(PNG_STRUCT_INFO, |
||
157 | png_ptr->malloc_fn, png_ptr->mem_ptr); |
||
158 | #else |
||
159 | info_ptr = (png_infop)png_create_struct(PNG_STRUCT_INFO); |
||
160 | #endif |
||
161 | if (info_ptr != NULL) |
||
162 | png_info_init_3(&info_ptr, png_sizeof(png_info)); |
||
163 | |||
164 | |||
165 | } |
||
166 | |||
167 | |||
168 | * Normally, one would use either png_destroy_read_struct() or |
||
169 | * png_destroy_write_struct() to free an info struct, but this may be |
||
170 | * useful for some applications. |
||
171 | */ |
||
172 | void PNGAPI |
||
173 | png_destroy_info_struct(png_structp png_ptr, png_infopp info_ptr_ptr) |
||
174 | { |
||
175 | png_infop info_ptr = NULL; |
||
176 | |||
177 | |||
178 | |||
179 | |||
180 | return; |
||
181 | |||
182 | |||
183 | info_ptr = *info_ptr_ptr; |
||
184 | |||
185 | |||
186 | { |
||
187 | png_info_destroy(png_ptr, info_ptr); |
||
188 | |||
189 | |||
190 | png_destroy_struct_2((png_voidp)info_ptr, png_ptr->free_fn, |
||
191 | png_ptr->mem_ptr); |
||
192 | #else |
||
193 | png_destroy_struct((png_voidp)info_ptr); |
||
194 | #endif |
||
195 | *info_ptr_ptr = NULL; |
||
196 | } |
||
197 | } |
||
198 | |||
199 | |||
200 | * and applications using it are urged to use png_create_info_struct() |
||
201 | * instead. |
||
202 | */ |
||
203 | |||
204 | |||
205 | png_info_init_3(png_infopp ptr_ptr, png_size_t png_info_struct_size) |
||
206 | { |
||
207 | png_infop info_ptr = *ptr_ptr; |
||
208 | |||
209 | |||
210 | |||
211 | |||
212 | return; |
||
213 | |||
214 | |||
215 | { |
||
216 | png_destroy_struct(info_ptr); |
||
217 | info_ptr = (png_infop)png_create_struct(PNG_STRUCT_INFO); |
||
218 | *ptr_ptr = info_ptr; |
||
219 | } |
||
220 | |||
221 | |||
222 | png_memset(info_ptr, 0, png_sizeof(png_info)); |
||
223 | } |
||
224 | |||
225 | |||
226 | png_data_freer(png_structp png_ptr, png_infop info_ptr, |
||
227 | int freer, png_uint_32 mask) |
||
228 | { |
||
229 | png_debug(1, "in png_data_freer"); |
||
230 | |||
231 | |||
232 | return; |
||
233 | |||
234 | |||
235 | info_ptr->free_me |= mask; |
||
236 | |||
237 | |||
238 | info_ptr->free_me &= ~mask; |
||
239 | |||
240 | |||
241 | png_warning(png_ptr, |
||
242 | "Unknown freer parameter in png_data_freer"); |
||
243 | } |
||
244 | |||
245 | |||
246 | png_free_data(png_structp png_ptr, png_infop info_ptr, png_uint_32 mask, |
||
247 | int num) |
||
248 | { |
||
249 | png_debug(1, "in png_free_data"); |
||
250 | |||
251 | |||
252 | return; |
||
253 | |||
254 | |||
255 | /* Free text item num or (if num == -1) all text items */ |
||
256 | if ((mask & PNG_FREE_TEXT) & info_ptr->free_me) |
||
257 | { |
||
258 | if (num != -1) |
||
259 | { |
||
260 | if (info_ptr->text && info_ptr->text[num].key) |
||
261 | { |
||
262 | png_free(png_ptr, info_ptr->text[num].key); |
||
263 | info_ptr->text[num].key = NULL; |
||
264 | } |
||
265 | } |
||
266 | |||
267 | |||
268 | { |
||
269 | int i; |
||
270 | for (i = 0; i < info_ptr->num_text; i++) |
||
271 | png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, i); |
||
272 | png_free(png_ptr, info_ptr->text); |
||
273 | info_ptr->text = NULL; |
||
274 | info_ptr->num_text=0; |
||
275 | } |
||
276 | } |
||
277 | #endif |
||
278 | |||
279 | |||
280 | /* Free any tRNS entry */ |
||
281 | if ((mask & PNG_FREE_TRNS) & info_ptr->free_me) |
||
282 | { |
||
283 | png_free(png_ptr, info_ptr->trans_alpha); |
||
284 | info_ptr->trans_alpha = NULL; |
||
285 | info_ptr->valid &= ~PNG_INFO_tRNS; |
||
286 | } |
||
287 | #endif |
||
288 | |||
289 | |||
290 | /* Free any sCAL entry */ |
||
291 | if ((mask & PNG_FREE_SCAL) & info_ptr->free_me) |
||
292 | { |
||
293 | #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED) |
||
294 | png_free(png_ptr, info_ptr->scal_s_width); |
||
295 | png_free(png_ptr, info_ptr->scal_s_height); |
||
296 | info_ptr->scal_s_width = NULL; |
||
297 | info_ptr->scal_s_height = NULL; |
||
298 | #endif |
||
299 | info_ptr->valid &= ~PNG_INFO_sCAL; |
||
300 | } |
||
301 | #endif |
||
302 | |||
303 | |||
304 | /* Free any pCAL entry */ |
||
305 | if ((mask & PNG_FREE_PCAL) & info_ptr->free_me) |
||
306 | { |
||
307 | png_free(png_ptr, info_ptr->pcal_purpose); |
||
308 | png_free(png_ptr, info_ptr->pcal_units); |
||
309 | info_ptr->pcal_purpose = NULL; |
||
310 | info_ptr->pcal_units = NULL; |
||
311 | if (info_ptr->pcal_params != NULL) |
||
312 | { |
||
313 | int i; |
||
314 | for (i = 0; i < (int)info_ptr->pcal_nparams; i++) |
||
315 | { |
||
316 | png_free(png_ptr, info_ptr->pcal_params[i]); |
||
317 | info_ptr->pcal_params[i] = NULL; |
||
318 | } |
||
319 | png_free(png_ptr, info_ptr->pcal_params); |
||
320 | info_ptr->pcal_params = NULL; |
||
321 | } |
||
322 | info_ptr->valid &= ~PNG_INFO_pCAL; |
||
323 | } |
||
324 | #endif |
||
325 | |||
326 | |||
327 | /* Free any iCCP entry */ |
||
328 | if ((mask & PNG_FREE_ICCP) & info_ptr->free_me) |
||
329 | { |
||
330 | png_free(png_ptr, info_ptr->iccp_name); |
||
331 | png_free(png_ptr, info_ptr->iccp_profile); |
||
332 | info_ptr->iccp_name = NULL; |
||
333 | info_ptr->iccp_profile = NULL; |
||
334 | info_ptr->valid &= ~PNG_INFO_iCCP; |
||
335 | } |
||
336 | #endif |
||
337 | |||
338 | |||
339 | /* Free a given sPLT entry, or (if num == -1) all sPLT entries */ |
||
340 | if ((mask & PNG_FREE_SPLT) & info_ptr->free_me) |
||
341 | { |
||
342 | if (num != -1) |
||
343 | { |
||
344 | if (info_ptr->splt_palettes) |
||
345 | { |
||
346 | png_free(png_ptr, info_ptr->splt_palettes[num].name); |
||
347 | png_free(png_ptr, info_ptr->splt_palettes[num].entries); |
||
348 | info_ptr->splt_palettes[num].name = NULL; |
||
349 | info_ptr->splt_palettes[num].entries = NULL; |
||
350 | } |
||
351 | } |
||
352 | |||
353 | |||
354 | { |
||
355 | if (info_ptr->splt_palettes_num) |
||
356 | { |
||
357 | int i; |
||
358 | for (i = 0; i < (int)info_ptr->splt_palettes_num; i++) |
||
359 | png_free_data(png_ptr, info_ptr, PNG_FREE_SPLT, i); |
||
360 | |||
361 | |||
362 | info_ptr->splt_palettes = NULL; |
||
363 | info_ptr->splt_palettes_num = 0; |
||
364 | } |
||
365 | info_ptr->valid &= ~PNG_INFO_sPLT; |
||
366 | } |
||
367 | } |
||
368 | #endif |
||
369 | |||
370 | |||
371 | if (png_ptr->unknown_chunk.data) |
||
372 | { |
||
373 | png_free(png_ptr, png_ptr->unknown_chunk.data); |
||
374 | png_ptr->unknown_chunk.data = NULL; |
||
375 | } |
||
376 | |||
377 | |||
378 | { |
||
379 | if (num != -1) |
||
380 | { |
||
381 | if (info_ptr->unknown_chunks) |
||
382 | { |
||
383 | png_free(png_ptr, info_ptr->unknown_chunks[num].data); |
||
384 | info_ptr->unknown_chunks[num].data = NULL; |
||
385 | } |
||
386 | } |
||
387 | |||
388 | |||
389 | { |
||
390 | int i; |
||
391 | |||
392 | |||
393 | { |
||
394 | for (i = 0; i < info_ptr->unknown_chunks_num; i++) |
||
395 | png_free_data(png_ptr, info_ptr, PNG_FREE_UNKN, i); |
||
396 | |||
397 | |||
398 | info_ptr->unknown_chunks = NULL; |
||
399 | info_ptr->unknown_chunks_num = 0; |
||
400 | } |
||
401 | } |
||
402 | } |
||
403 | #endif |
||
404 | |||
405 | |||
406 | /* Free any hIST entry */ |
||
407 | if ((mask & PNG_FREE_HIST) & info_ptr->free_me) |
||
408 | { |
||
409 | png_free(png_ptr, info_ptr->hist); |
||
410 | info_ptr->hist = NULL; |
||
411 | info_ptr->valid &= ~PNG_INFO_hIST; |
||
412 | } |
||
413 | #endif |
||
414 | |||
415 | |||
416 | if ((mask & PNG_FREE_PLTE) & info_ptr->free_me) |
||
417 | { |
||
418 | png_zfree(png_ptr, info_ptr->palette); |
||
419 | info_ptr->palette = NULL; |
||
420 | info_ptr->valid &= ~PNG_INFO_PLTE; |
||
421 | info_ptr->num_palette = 0; |
||
422 | } |
||
423 | |||
424 | |||
425 | /* Free any image bits attached to the info structure */ |
||
426 | if ((mask & PNG_FREE_ROWS) & info_ptr->free_me) |
||
427 | { |
||
428 | if (info_ptr->row_pointers) |
||
429 | { |
||
430 | int row; |
||
431 | for (row = 0; row < (int)info_ptr->height; row++) |
||
432 | { |
||
433 | png_free(png_ptr, info_ptr->row_pointers[row]); |
||
434 | info_ptr->row_pointers[row] = NULL; |
||
435 | } |
||
436 | png_free(png_ptr, info_ptr->row_pointers); |
||
437 | info_ptr->row_pointers = NULL; |
||
438 | } |
||
439 | info_ptr->valid &= ~PNG_INFO_IDAT; |
||
440 | } |
||
441 | #endif |
||
442 | |||
443 | |||
444 | mask &= ~PNG_FREE_MUL; |
||
445 | |||
446 | |||
447 | } |
||
448 | |||
449 | |||
450 | * pointing to before re-using it or freeing the struct itself. Recall |
||
451 | * that png_free() checks for NULL pointers for us. |
||
452 | */ |
||
453 | void /* PRIVATE */ |
||
454 | png_info_destroy(png_structp png_ptr, png_infop info_ptr) |
||
455 | { |
||
456 | png_debug(1, "in png_info_destroy"); |
||
457 | |||
458 | |||
459 | |||
460 | |||
461 | if (png_ptr->num_chunk_list) |
||
462 | { |
||
463 | png_free(png_ptr, png_ptr->chunk_list); |
||
464 | png_ptr->chunk_list = NULL; |
||
465 | png_ptr->num_chunk_list = 0; |
||
466 | } |
||
467 | #endif |
||
468 | |||
469 | |||
470 | } |
||
471 | #endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */ |
||
472 | |||
473 | |||
474 | * functions. The application should free any memory associated with this |
||
475 | * pointer before png_write_destroy() or png_read_destroy() are called. |
||
476 | */ |
||
477 | png_voidp PNGAPI |
||
478 | png_get_io_ptr(png_structp png_ptr) |
||
479 | { |
||
480 | if (png_ptr == NULL) |
||
481 | return (NULL); |
||
482 | |||
483 | |||
484 | } |
||
485 | |||
486 | |||
487 | # ifdef PNG_STDIO_SUPPORTED |
||
488 | /* Initialize the default input/output functions for the PNG file. If you |
||
489 | * use your own read or write routines, you can call either png_set_read_fn() |
||
490 | * or png_set_write_fn() instead of png_init_io(). If you have defined |
||
491 | * PNG_NO_STDIO, you must use a function of your own because "FILE *" isn't |
||
492 | * necessarily available. |
||
493 | */ |
||
494 | void PNGAPI |
||
495 | png_init_io(png_structp png_ptr, png_FILE_p fp) |
||
496 | { |
||
497 | png_debug(1, "in png_init_io"); |
||
498 | |||
499 | |||
500 | return; |
||
501 | |||
502 | |||
503 | } |
||
504 | # endif |
||
505 | |||
506 | |||
507 | /* Convert the supplied time into an RFC 1123 string suitable for use in |
||
508 | * a "Creation Time" or other text-based time string. |
||
509 | */ |
||
510 | png_const_charp PNGAPI |
||
511 | png_convert_to_rfc1123(png_structp png_ptr, png_const_timep ptime) |
||
512 | { |
||
513 | static PNG_CONST char short_months[12][4] = |
||
514 | {"Jan", "Feb", "Mar", "Apr", "May", "Jun", |
||
515 | "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; |
||
516 | |||
517 | |||
518 | return (NULL); |
||
519 | |||
520 | |||
521 | { |
||
522 | png_ptr->time_buffer = (png_charp)png_malloc(png_ptr, (png_uint_32)(29* |
||
523 | png_sizeof(char))); |
||
524 | } |
||
525 | |||
526 | |||
527 | { |
||
528 | char near_time_buf[29]; |
||
529 | png_snprintf6(near_time_buf, 29, "%d %s %d %02d:%02d:%02d +0000", |
||
530 | ptime->day % 32, short_months[(ptime->month - 1) % 12], |
||
531 | ptime->year, ptime->hour % 24, ptime->minute % 60, |
||
532 | ptime->second % 61); |
||
533 | png_memcpy(png_ptr->time_buffer, near_time_buf, |
||
534 | 29*png_sizeof(char)); |
||
535 | } |
||
536 | # else |
||
537 | png_snprintf6(png_ptr->time_buffer, 29, "%d %s %d %02d:%02d:%02d +0000", |
||
538 | ptime->day % 32, short_months[(ptime->month - 1) % 12], |
||
539 | ptime->year, ptime->hour % 24, ptime->minute % 60, |
||
540 | ptime->second % 61); |
||
541 | # endif |
||
542 | return png_ptr->time_buffer; |
||
543 | } |
||
544 | # endif /* PNG_TIME_RFC1123_SUPPORTED */ |
||
545 | |||
546 | |||
547 | |||
548 | |||
549 | png_get_copyright(png_const_structp png_ptr) |
||
550 | { |
||
551 | PNG_UNUSED(png_ptr) /* Silence compiler warning about unused png_ptr */ |
||
552 | #ifdef PNG_STRING_COPYRIGHT |
||
553 | return PNG_STRING_COPYRIGHT |
||
554 | #else |
||
555 | # ifdef __STDC__ |
||
556 | return PNG_STRING_NEWLINE \ |
||
557 | "libpng version 1.5.1 - February 3, 2011" PNG_STRING_NEWLINE \ |
||
558 | "Copyright (c) 1998-2011 Glenn Randers-Pehrson" PNG_STRING_NEWLINE \ |
||
559 | "Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \ |
||
560 | "Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \ |
||
561 | PNG_STRING_NEWLINE; |
||
562 | # else |
||
563 | return "libpng version 1.5.1 - February 3, 2011\ |
||
564 | Copyright (c) 1998-2011 Glenn Randers-Pehrson\ |
||
565 | Copyright (c) 1996-1997 Andreas Dilger\ |
||
566 | Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc."; |
||
567 | # endif |
||
568 | #endif |
||
569 | } |
||
570 | |||
571 | |||
572 | * format 1.0.0 through 99.99.99zz. To get the version of *.h files |
||
573 | * used with your application, print out PNG_LIBPNG_VER_STRING, which |
||
574 | * is defined in png.h. |
||
575 | * Note: now there is no difference between png_get_libpng_ver() and |
||
576 | * png_get_header_ver(). Due to the version_nn_nn_nn typedef guard, |
||
577 | * it is guaranteed that png.c uses the correct version of png.h. |
||
578 | */ |
||
579 | png_const_charp PNGAPI |
||
580 | png_get_libpng_ver(png_const_structp png_ptr) |
||
581 | { |
||
582 | /* Version of *.c files used when building libpng */ |
||
583 | return png_get_header_ver(png_ptr); |
||
584 | } |
||
585 | |||
586 | |||
587 | png_get_header_ver(png_const_structp png_ptr) |
||
588 | { |
||
589 | /* Version of *.h files used when building libpng */ |
||
590 | PNG_UNUSED(png_ptr) /* Silence compiler warning about unused png_ptr */ |
||
591 | return PNG_LIBPNG_VER_STRING; |
||
592 | } |
||
593 | |||
594 | |||
595 | png_get_header_version(png_const_structp png_ptr) |
||
596 | { |
||
597 | /* Returns longer string containing both version and date */ |
||
598 | PNG_UNUSED(png_ptr) /* Silence compiler warning about unused png_ptr */ |
||
599 | #ifdef __STDC__ |
||
600 | return PNG_HEADER_VERSION_STRING |
||
601 | # ifndef PNG_READ_SUPPORTED |
||
602 | " (NO READ SUPPORT)" |
||
603 | # endif |
||
604 | PNG_STRING_NEWLINE; |
||
605 | #else |
||
606 | return PNG_HEADER_VERSION_STRING; |
||
607 | #endif |
||
608 | } |
||
609 | |||
610 | |||
611 | # ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED |
||
612 | int PNGAPI |
||
613 | png_handle_as_unknown(png_structp png_ptr, png_const_bytep chunk_name) |
||
614 | { |
||
615 | /* Check chunk_name and return "keep" value if it's on the list, else 0 */ |
||
616 | int i; |
||
617 | png_bytep p; |
||
618 | if (png_ptr == NULL || chunk_name == NULL || png_ptr->num_chunk_list<=0) |
||
619 | return 0; |
||
620 | |||
621 | |||
622 | for (i = png_ptr->num_chunk_list; i; i--, p -= 5) |
||
623 | if (!png_memcmp(chunk_name, p, 4)) |
||
624 | return ((int)*(p + 4)); |
||
625 | return 0; |
||
626 | } |
||
627 | # endif |
||
628 | #endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */ |
||
629 | |||
630 | |||
631 | /* This function, added to libpng-1.0.6g, is untested. */ |
||
632 | int PNGAPI |
||
633 | png_reset_zstream(png_structp png_ptr) |
||
634 | { |
||
635 | if (png_ptr == NULL) |
||
636 | return Z_STREAM_ERROR; |
||
637 | |||
638 | |||
639 | } |
||
640 | #endif /* PNG_READ_SUPPORTED */ |
||
641 | |||
642 | |||
643 | png_uint_32 PNGAPI |
||
644 | png_access_version_number(void) |
||
645 | { |
||
646 | /* Version of *.c files used when building libpng */ |
||
647 | return((png_uint_32)PNG_LIBPNG_VER); |
||
648 | } |
||
649 | |||
650 | |||
651 | |||
652 | |||
653 | # ifdef PNG_SIZE_T |
||
654 | /* Added at libpng version 1.2.6 */ |
||
655 | PNG_EXTERN png_size_t PNGAPI png_convert_size PNGARG((size_t size)); |
||
656 | png_size_t PNGAPI |
||
657 | png_convert_size(size_t size) |
||
658 | { |
||
659 | if (size > (png_size_t)-1) |
||
660 | PNG_ABORT(); /* We haven't got access to png_ptr, so no png_error() */ |
||
661 | |||
662 | |||
663 | } |
||
664 | # endif /* PNG_SIZE_T */ |
||
665 | |||
666 | |||
667 | # ifdef PNG_CHECK_cHRM_SUPPORTED |
||
668 | |||
669 | |||
670 | png_check_cHRM_fixed(png_structp png_ptr, |
||
671 | png_fixed_point white_x, png_fixed_point white_y, png_fixed_point red_x, |
||
672 | png_fixed_point red_y, png_fixed_point green_x, png_fixed_point green_y, |
||
673 | png_fixed_point blue_x, png_fixed_point blue_y) |
||
674 | { |
||
675 | int ret = 1; |
||
676 | unsigned long xy_hi,xy_lo,yx_hi,yx_lo; |
||
677 | |||
678 | |||
679 | |||
680 | |||
681 | return 0; |
||
682 | |||
683 | |||
684 | red_x < 0 || red_y < 0 || |
||
685 | green_x < 0 || green_y < 0 || |
||
686 | blue_x < 0 || blue_y < 0) |
||
687 | { |
||
688 | png_warning(png_ptr, |
||
689 | "Ignoring attempt to set negative chromaticity value"); |
||
690 | ret = 0; |
||
691 | } |
||
692 | if (white_x > (png_fixed_point)PNG_UINT_31_MAX || |
||
693 | white_y > (png_fixed_point)PNG_UINT_31_MAX || |
||
694 | red_x > (png_fixed_point)PNG_UINT_31_MAX || |
||
695 | red_y > (png_fixed_point)PNG_UINT_31_MAX || |
||
696 | green_x > (png_fixed_point)PNG_UINT_31_MAX || |
||
697 | green_y > (png_fixed_point)PNG_UINT_31_MAX || |
||
698 | blue_x > (png_fixed_point)PNG_UINT_31_MAX || |
||
699 | blue_y > (png_fixed_point)PNG_UINT_31_MAX ) |
||
700 | { |
||
701 | png_warning(png_ptr, |
||
702 | "Ignoring attempt to set chromaticity value exceeding 21474.83"); |
||
703 | ret = 0; |
||
704 | } |
||
705 | if (white_x > 100000L - white_y) |
||
706 | { |
||
707 | png_warning(png_ptr, "Invalid cHRM white point"); |
||
708 | ret = 0; |
||
709 | } |
||
710 | |||
711 | |||
712 | { |
||
713 | png_warning(png_ptr, "Invalid cHRM red point"); |
||
714 | ret = 0; |
||
715 | } |
||
716 | |||
717 | |||
718 | { |
||
719 | png_warning(png_ptr, "Invalid cHRM green point"); |
||
720 | ret = 0; |
||
721 | } |
||
722 | |||
723 | |||
724 | { |
||
725 | png_warning(png_ptr, "Invalid cHRM blue point"); |
||
726 | ret = 0; |
||
727 | } |
||
728 | |||
729 | |||
730 | png_64bit_product(green_y - red_y, blue_x - red_x, &yx_hi, &yx_lo); |
||
731 | |||
732 | |||
733 | { |
||
734 | png_warning(png_ptr, |
||
735 | "Ignoring attempt to set cHRM RGB triangle with zero area"); |
||
736 | ret = 0; |
||
737 | } |
||
738 | |||
739 | |||
740 | } |
||
741 | # endif /* PNG_CHECK_cHRM_SUPPORTED */ |
||
742 | |||
743 | |||
744 | png_check_IHDR(png_structp png_ptr, |
||
745 | png_uint_32 width, png_uint_32 height, int bit_depth, |
||
746 | int color_type, int interlace_type, int compression_type, |
||
747 | int filter_type) |
||
748 | { |
||
749 | int error = 0; |
||
750 | |||
751 | |||
752 | if (width == 0) |
||
753 | { |
||
754 | png_warning(png_ptr, "Image width is zero in IHDR"); |
||
755 | error = 1; |
||
756 | } |
||
757 | |||
758 | |||
759 | { |
||
760 | png_warning(png_ptr, "Image height is zero in IHDR"); |
||
761 | error = 1; |
||
762 | } |
||
763 | |||
764 | |||
765 | if (width > png_ptr->user_width_max || width > PNG_USER_WIDTH_MAX) |
||
766 | |||
767 | |||
768 | if (width > PNG_USER_WIDTH_MAX) |
||
769 | # endif |
||
770 | { |
||
771 | png_warning(png_ptr, "Image width exceeds user limit in IHDR"); |
||
772 | error = 1; |
||
773 | } |
||
774 | |||
775 | |||
776 | if (height > png_ptr->user_height_max || height > PNG_USER_HEIGHT_MAX) |
||
777 | # else |
||
778 | if (height > PNG_USER_HEIGHT_MAX) |
||
779 | # endif |
||
780 | { |
||
781 | png_warning(png_ptr, "Image height exceeds user limit in IHDR"); |
||
782 | error = 1; |
||
783 | } |
||
784 | |||
785 | |||
786 | { |
||
787 | png_warning(png_ptr, "Invalid image width in IHDR"); |
||
788 | error = 1; |
||
789 | } |
||
790 | |||
791 | |||
792 | { |
||
793 | png_warning(png_ptr, "Invalid image height in IHDR"); |
||
794 | error = 1; |
||
795 | } |
||
796 | |||
797 | |||
798 | >> 3) /* 8-byte RGBA pixels */ |
||
799 | - 48 /* bigrowbuf hack */ |
||
800 | - 1 /* filter byte */ |
||
801 | - 7*8 /* rounding of width to multiple of 8 pixels */ |
||
802 | - 8) /* extra max_pixel_depth pad */ |
||
803 | png_warning(png_ptr, "Width is too large for libpng to process pixels"); |
||
804 | |||
805 | |||
806 | if (bit_depth != 1 && bit_depth != 2 && bit_depth != 4 && |
||
807 | bit_depth != 8 && bit_depth != 16) |
||
808 | { |
||
809 | png_warning(png_ptr, "Invalid bit depth in IHDR"); |
||
810 | error = 1; |
||
811 | } |
||
812 | |||
813 | |||
814 | color_type == 5 || color_type > 6) |
||
815 | { |
||
816 | png_warning(png_ptr, "Invalid color type in IHDR"); |
||
817 | error = 1; |
||
818 | } |
||
819 | |||
820 | |||
821 | ((color_type == PNG_COLOR_TYPE_RGB || |
||
822 | color_type == PNG_COLOR_TYPE_GRAY_ALPHA || |
||
823 | color_type == PNG_COLOR_TYPE_RGB_ALPHA) && bit_depth < 8)) |
||
824 | { |
||
825 | png_warning(png_ptr, "Invalid color type/bit depth combination in IHDR"); |
||
826 | error = 1; |
||
827 | } |
||
828 | |||
829 | |||
830 | { |
||
831 | png_warning(png_ptr, "Unknown interlace method in IHDR"); |
||
832 | error = 1; |
||
833 | } |
||
834 | |||
835 | |||
836 | { |
||
837 | png_warning(png_ptr, "Unknown compression method in IHDR"); |
||
838 | error = 1; |
||
839 | } |
||
840 | |||
841 | |||
842 | /* Accept filter_method 64 (intrapixel differencing) only if |
||
843 | * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and |
||
844 | * 2. Libpng did not read a PNG signature (this filter_method is only |
||
845 | * used in PNG datastreams that are embedded in MNG datastreams) and |
||
846 | * 3. The application called png_permit_mng_features with a mask that |
||
847 | * included PNG_FLAG_MNG_FILTER_64 and |
||
848 | * 4. The filter_method is 64 and |
||
849 | * 5. The color_type is RGB or RGBA |
||
850 | */ |
||
851 | if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) && |
||
852 | png_ptr->mng_features_permitted) |
||
853 | png_warning(png_ptr, "MNG features are not allowed in a PNG datastream"); |
||
854 | |||
855 | |||
856 | { |
||
857 | if (!((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && |
||
858 | (filter_type == PNG_INTRAPIXEL_DIFFERENCING) && |
||
859 | ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) == 0) && |
||
860 | (color_type == PNG_COLOR_TYPE_RGB || |
||
861 | color_type == PNG_COLOR_TYPE_RGB_ALPHA))) |
||
862 | { |
||
863 | png_warning(png_ptr, "Unknown filter method in IHDR"); |
||
864 | error = 1; |
||
865 | } |
||
866 | |||
867 | |||
868 | { |
||
869 | png_warning(png_ptr, "Invalid filter method in IHDR"); |
||
870 | error = 1; |
||
871 | } |
||
872 | } |
||
873 | |||
874 | |||
875 | if (filter_type != PNG_FILTER_TYPE_BASE) |
||
876 | { |
||
877 | png_warning(png_ptr, "Unknown filter method in IHDR"); |
||
878 | error = 1; |
||
879 | } |
||
880 | # endif |
||
881 | |||
882 | |||
883 | png_error(png_ptr, "Invalid IHDR data"); |
||
884 | } |
||
885 | |||
886 | |||
887 | /* ASCII to fp functions */ |
||
888 | /* Check an ASCII formated floating point value, see the more detailed |
||
889 | * comments in pngpriv.h |
||
890 | */ |
||
891 | /* The following is used internally to preserve the 'valid' flag */ |
||
892 | #define png_fp_add(state, flags) ((state) |= (flags)) |
||
893 | #define png_fp_set(state, value)\ |
||
894 | ((state) = (value) | ((state) & PNG_FP_WAS_VALID)) |
||
895 | |||
896 | |||
897 | #define PNG_FP_SIGN 0 /* [+-] */ |
||
898 | #define PNG_FP_DOT 4 /* . */ |
||
899 | #define PNG_FP_DIGIT 8 /* [0123456789] */ |
||
900 | #define PNG_FP_E 12 /* [Ee] */ |
||
901 | |||
902 | |||
903 | png_check_fp_number(png_const_charp string, png_size_t size, int *statep, |
||
904 | png_size_tp whereami) |
||
905 | { |
||
906 | int state = *statep; |
||
907 | png_size_t i = *whereami; |
||
908 | |||
909 | |||
910 | { |
||
911 | int type; |
||
912 | /* First find the type of the next character */ |
||
913 | { |
||
914 | char ch = string[i]; |
||
915 | |||
916 | |||
917 | type = PNG_FP_DIGIT; |
||
918 | |||
919 | |||
920 | { |
||
921 | case 43: case 45: type = PNG_FP_SIGN; break; |
||
922 | case 46: type = PNG_FP_DOT; break; |
||
923 | case 69: case 101: type = PNG_FP_E; break; |
||
924 | default: goto PNG_FP_End; |
||
925 | } |
||
926 | } |
||
927 | |||
928 | |||
929 | * state, the type is arranged to not overlap the |
||
930 | * bits of the PNG_FP_STATE. |
||
931 | */ |
||
932 | switch ((state & PNG_FP_STATE) + type) |
||
933 | { |
||
934 | case PNG_FP_INTEGER + PNG_FP_SIGN: |
||
935 | if (state & PNG_FP_SAW_ANY) |
||
936 | goto PNG_FP_End; /* not a part of the number */ |
||
937 | |||
938 | |||
939 | break; |
||
940 | |||
941 | |||
942 | /* Ok as trailer, ok as lead of fraction. */ |
||
943 | if (state & PNG_FP_SAW_DOT) /* two dots */ |
||
944 | goto PNG_FP_End; |
||
945 | |||
946 | |||
947 | png_fp_add(state, PNG_FP_SAW_DOT); |
||
948 | |||
949 | |||
950 | png_fp_set(state, PNG_FP_FRACTION | PNG_FP_SAW_DOT); |
||
951 | |||
952 | |||
953 | |||
954 | |||
955 | if (state & PNG_FP_SAW_DOT) /* delayed fraction */ |
||
956 | png_fp_set(state, PNG_FP_FRACTION | PNG_FP_SAW_DOT); |
||
957 | |||
958 | |||
959 | |||
960 | |||
961 | case PNG_FP_INTEGER + PNG_FP_E: |
||
962 | if ((state & PNG_FP_SAW_DIGIT) == 0) |
||
963 | goto PNG_FP_End; |
||
964 | |||
965 | |||
966 | |||
967 | |||
968 | |||
969 | |||
970 | goto PNG_FP_End; ** no sign in exponent */ |
||
971 | |||
972 | |||
973 | goto PNG_FP_End; ** Because SAW_DOT is always set */ |
||
974 | |||
975 | |||
976 | png_fp_add(state, PNG_FP_SAW_DIGIT + PNG_FP_WAS_VALID); |
||
977 | break; |
||
978 | |||
979 | |||
980 | /* This is correct because the trailing '.' on an |
||
981 | * integer is handled above - so we can only get here |
||
982 | * with the sequence ".E" (with no preceding digits). |
||
983 | */ |
||
984 | if ((state & PNG_FP_SAW_DIGIT) == 0) |
||
985 | goto PNG_FP_End; |
||
986 | |||
987 | |||
988 | |||
989 | |||
990 | |||
991 | |||
992 | if (state & PNG_FP_SAW_ANY) |
||
993 | goto PNG_FP_End; /* not a part of the number */ |
||
994 | |||
995 | |||
996 | |||
997 | |||
998 | |||
999 | |||
1000 | goto PNG_FP_End; */ |
||
1001 | |||
1002 | |||
1003 | png_fp_add(state, PNG_FP_SAW_DIGIT + PNG_FP_WAS_VALID); |
||
1004 | |||
1005 | |||
1006 | |||
1007 | |||
1008 | goto PNG_FP_End; */ |
||
1009 | |||
1010 | |||
1011 | } |
||
1012 | |||
1013 | |||
1014 | ++i; |
||
1015 | } |
||
1016 | |||
1017 | |||
1018 | /* Here at the end, update the state and return the correct |
||
1019 | * return code. |
||
1020 | */ |
||
1021 | *statep = state; |
||
1022 | *whereami = i; |
||
1023 | |||
1024 | |||
1025 | } |
||
1026 | |||
1027 | |||
1028 | |||
1029 | int |
||
1030 | png_check_fp_string(png_const_charp string, png_size_t size) |
||
1031 | { |
||
1032 | int state=0; |
||
1033 | png_size_t char_index=0; |
||
1034 | |||
1035 | |||
1036 | (char_index == size || string[char_index] == 0); |
||
1037 | } |
||
1038 | #endif /* pCAL or sCAL */ |
||
1039 | |||
1040 | |||
1041 | # ifdef PNG_FLOATING_POINT_SUPPORTED |
||
1042 | /* Utility used below - a simple accurate power of ten from an integral |
||
1043 | * exponent. |
||
1044 | */ |
||
1045 | static double |
||
1046 | png_pow10(int power) |
||
1047 | { |
||
1048 | int recip = 0; |
||
1049 | double d = 1; |
||
1050 | |||
1051 | |||
1052 | * 10 is exact whereas .1 is inexact in base 2 |
||
1053 | */ |
||
1054 | if (power < 0) |
||
1055 | { |
||
1056 | if (power < DBL_MIN_10_EXP) return 0; |
||
1057 | recip = 1, power = -power; |
||
1058 | } |
||
1059 | |||
1060 | |||
1061 | { |
||
1062 | /* Decompose power bitwise. */ |
||
1063 | double mult = 10; |
||
1064 | do |
||
1065 | { |
||
1066 | if (power & 1) d *= mult; |
||
1067 | mult *= mult; |
||
1068 | power >>= 1; |
||
1069 | } |
||
1070 | while (power > 0); |
||
1071 | |||
1072 | |||
1073 | } |
||
1074 | /* else power is 0 and d is 1 */ |
||
1075 | |||
1076 | |||
1077 | } |
||
1078 | |||
1079 | |||
1080 | * precision. |
||
1081 | */ |
||
1082 | void /* PRIVATE */ |
||
1083 | png_ascii_from_fp(png_structp png_ptr, png_charp ascii, png_size_t size, |
||
1084 | double fp, unsigned int precision) |
||
1085 | { |
||
1086 | /* We use standard functions from math.h, but not printf because |
||
1087 | * that would require stdio. The caller must supply a buffer of |
||
1088 | * sufficient size or we will png_error. The tests on size and |
||
1089 | * the space in ascii[] consumed are indicated below. |
||
1090 | */ |
||
1091 | if (precision < 1) |
||
1092 | precision = DBL_DIG; |
||
1093 | |||
1094 | |||
1095 | if (precision > DBL_DIG+1) |
||
1096 | precision = DBL_DIG+1; |
||
1097 | |||
1098 | |||
1099 | if (size >= precision+5) /* See the requirements below. */ |
||
1100 | { |
||
1101 | if (fp < 0) |
||
1102 | { |
||
1103 | fp = -fp; |
||
1104 | *ascii++ = 45; /* '-' PLUS 1 TOTAL 1*/ |
||
1105 | --size; |
||
1106 | } |
||
1107 | |||
1108 | |||
1109 | { |
||
1110 | int exp_b10; /* A base 10 exponent */ |
||
1111 | double base; /* 10^exp_b10 */ |
||
1112 | |||
1113 | |||
1114 | * the calculation below rounds down when converting |
||
1115 | * from base 2 to base 10 (multiply by log10(2) - |
||
1116 | * 0.3010, but 77/256 is 0.3008, so exp_b10 needs to |
||
1117 | * be increased. Note that the arithmetic shift |
||
1118 | * performs a floor() unlike C arithmetic - using a |
||
1119 | * C multiply would break the following for negative |
||
1120 | * exponents. |
||
1121 | */ |
||
1122 | (void)frexp(fp, &exp_b10); /* exponent to base 2 */ |
||
1123 | |||
1124 | |||
1125 | |||
1126 | |||
1127 | base = png_pow10(exp_b10); /* May underflow */ |
||
1128 | |||
1129 | |||
1130 | { |
||
1131 | /* And this may overflow. */ |
||
1132 | double test = png_pow10(exp_b10+1); |
||
1133 | |||
1134 | |||
1135 | ++exp_b10, base = test; |
||
1136 | |||
1137 | |||
1138 | break; |
||
1139 | } |
||
1140 | |||
1141 | |||
1142 | * range [.1,1) and exp_b10 is both the exponent and the digit |
||
1143 | * *before* which the decimal point should be inserted |
||
1144 | * (starting with 0 for the first digit). Note that this |
||
1145 | * works even if 10^exp_b10 is out of range because of the |
||
1146 | * test on DBL_MAX above. |
||
1147 | */ |
||
1148 | fp /= base; |
||
1149 | while (fp >= 1) fp /= 10, ++exp_b10; |
||
1150 | |||
1151 | |||
1152 | * less than .1, this is ok because the code below can |
||
1153 | * handle the leading zeros this generates, so no attempt |
||
1154 | * is made to correct that here. |
||
1155 | */ |
||
1156 | |||
1157 | |||
1158 | int czero, clead, cdigits; |
||
1159 | char exponent[10]; |
||
1160 | |||
1161 | |||
1162 | * the number compared to using E-n. |
||
1163 | */ |
||
1164 | if (exp_b10 < 0 && exp_b10 > -3) /* PLUS 3 TOTAL 4 */ |
||
1165 | { |
||
1166 | czero = -exp_b10; /* PLUS 2 digits: TOTAL 3 */ |
||
1167 | exp_b10 = 0; /* Dot added below before first output. */ |
||
1168 | } |
||
1169 | else |
||
1170 | czero = 0; /* No zeros to add */ |
||
1171 | |||
1172 | |||
1173 | * inserting a '.' before a digit if the exponent is 0. |
||
1174 | */ |
||
1175 | clead = czero; /* Count of leading zeros */ |
||
1176 | cdigits = 0; /* Count of digits in list. */ |
||
1177 | |||
1178 | |||
1179 | { |
||
1180 | double d; |
||
1181 | |||
1182 | |||
1183 | /* Use modf here, not floor and subtract, so that |
||
1184 | * the separation is done in one step. At the end |
||
1185 | * of the loop don't break the number into parts so |
||
1186 | * that the final digit is rounded. |
||
1187 | */ |
||
1188 | if (cdigits+czero-clead+1 < (int)precision) |
||
1189 | fp = modf(fp, &d); |
||
1190 | |||
1191 | |||
1192 | { |
||
1193 | d = floor(fp + .5); |
||
1194 | |||
1195 | |||
1196 | { |
||
1197 | /* Rounding up to 10, handle that here. */ |
||
1198 | if (czero > 0) |
||
1199 | { |
||
1200 | --czero, d = 1; |
||
1201 | if (cdigits == 0) --clead; |
||
1202 | } |
||
1203 | else |
||
1204 | { |
||
1205 | while (cdigits > 0 && d > 9) |
||
1206 | { |
||
1207 | int ch = *--ascii; |
||
1208 | |||
1209 | |||
1210 | ++exp_b10; |
||
1211 | |||
1212 | |||
1213 | { |
||
1214 | ch = *--ascii, ++size; |
||
1215 | /* Advance exp_b10 to '1', so that the |
||
1216 | * decimal point happens after the |
||
1217 | * previous digit. |
||
1218 | */ |
||
1219 | exp_b10 = 1; |
||
1220 | } |
||
1221 | |||
1222 | |||
1223 | d = ch - 47; /* I.e. 1+(ch-48) */ |
||
1224 | } |
||
1225 | |||
1226 | |||
1227 | * exponent but take into account the leading |
||
1228 | * decimal point. |
||
1229 | */ |
||
1230 | if (d > 9) /* cdigits == 0 */ |
||
1231 | { |
||
1232 | if (exp_b10 == (-1)) |
||
1233 | { |
||
1234 | /* Leading decimal point (plus zeros?), if |
||
1235 | * we lose the decimal point here it must |
||
1236 | * be reentered below. |
||
1237 | */ |
||
1238 | int ch = *--ascii; |
||
1239 | |||
1240 | |||
1241 | ++size, exp_b10 = 1; |
||
1242 | |||
1243 | |||
1244 | * still ok at (-1) |
||
1245 | */ |
||
1246 | } |
||
1247 | else |
||
1248 | ++exp_b10; |
||
1249 | |||
1250 | |||
1251 | d = 1; |
||
1252 | } |
||
1253 | } |
||
1254 | } |
||
1255 | fp = 0; /* Guarantees termination below. */ |
||
1256 | } |
||
1257 | |||
1258 | |||
1259 | { |
||
1260 | ++czero; |
||
1261 | if (cdigits == 0) ++clead; |
||
1262 | } |
||
1263 | else |
||
1264 | { |
||
1265 | /* Included embedded zeros in the digit count. */ |
||
1266 | cdigits += czero - clead; |
||
1267 | clead = 0; |
||
1268 | |||
1269 | |||
1270 | { |
||
1271 | /* exp_b10 == (-1) means we just output the decimal |
||
1272 | * place - after the DP don't adjust 'exp_b10' any |
||
1273 | * more! |
||
1274 | */ |
||
1275 | if (exp_b10 != (-1)) |
||
1276 | { |
||
1277 | if (exp_b10 == 0) *ascii++ = 46, --size; |
||
1278 | /* PLUS 1: TOTAL 4 */ |
||
1279 | --exp_b10; |
||
1280 | } |
||
1281 | *ascii++ = 48, --czero; |
||
1282 | } |
||
1283 | |||
1284 | |||
1285 | { |
||
1286 | if (exp_b10 == 0) *ascii++ = 46, --size; /* counted |
||
1287 | above */ |
||
1288 | --exp_b10; |
||
1289 | } |
||
1290 | *ascii++ = (char)(48 + (int)d), ++cdigits; |
||
1291 | } |
||
1292 | } |
||
1293 | while (cdigits+czero-clead < (int)precision && fp > DBL_MIN); |
||
1294 | |||
1295 | |||
1296 | |||
1297 | |||
1298 | * done and just need to terminate the string. At |
||
1299 | * this point exp_b10==(-1) is effectively if flag - it got |
||
1300 | * to '-1' because of the decrement after outputing |
||
1301 | * the decimal point above (the exponent required is |
||
1302 | * *not* -1!) |
||
1303 | */ |
||
1304 | if (exp_b10 >= (-1) && exp_b10 <= 2) |
||
1305 | { |
||
1306 | /* The following only happens if we didn't output the |
||
1307 | * leading zeros above for negative exponent, so this |
||
1308 | * doest add to the digit requirement. Note that the |
||
1309 | * two zeros here can only be output if the two leading |
||
1310 | * zeros were *not* output, so this doesn't increase |
||
1311 | * the output count. |
||
1312 | */ |
||
1313 | while (--exp_b10 >= 0) *ascii++ = 48; |
||
1314 | |||
1315 | |||
1316 | |||
1317 | |||
1318 | * 5+precision - see check at the start. |
||
1319 | */ |
||
1320 | return; |
||
1321 | } |
||
1322 | |||
1323 | |||
1324 | * the digits we output but did not count. The total |
||
1325 | * digit output here so far is at most 1+precision - no |
||
1326 | * decimal point and no leading or trailing zeros have |
||
1327 | * been output. |
||
1328 | */ |
||
1329 | size -= cdigits; |
||
1330 | |||
1331 | |||
1332 | if (exp_b10 < 0) |
||
1333 | { |
||
1334 | *ascii++ = 45, --size; /* '-': PLUS 1 TOTAL 3+precision */ |
||
1335 | exp_b10 = -exp_b10; |
||
1336 | } |
||
1337 | |||
1338 | |||
1339 | |||
1340 | |||
1341 | { |
||
1342 | exponent[cdigits++] = (char)(48 + exp_b10 % 10); |
||
1343 | exp_b10 /= 10; |
||
1344 | } |
||
1345 | |||
1346 | |||
1347 | * this need not be considered above. |
||
1348 | */ |
||
1349 | if ((int)size > cdigits) |
||
1350 | { |
||
1351 | while (cdigits > 0) *ascii++ = exponent[--cdigits]; |
||
1352 | |||
1353 | |||
1354 | |||
1355 | |||
1356 | } |
||
1357 | } |
||
1358 | } |
||
1359 | else if (!(fp >= DBL_MIN)) |
||
1360 | { |
||
1361 | *ascii++ = 48; /* '0' */ |
||
1362 | *ascii = 0; |
||
1363 | return; |
||
1364 | } |
||
1365 | else |
||
1366 | { |
||
1367 | *ascii++ = 105; /* 'i' */ |
||
1368 | *ascii++ = 110; /* 'n' */ |
||
1369 | *ascii++ = 102; /* 'f' */ |
||
1370 | *ascii = 0; |
||
1371 | return; |
||
1372 | } |
||
1373 | } |
||
1374 | |||
1375 | |||
1376 | png_error(png_ptr, "ASCII conversion buffer too small"); |
||
1377 | } |
||
1378 | |||
1379 | |||
1380 | |||
1381 | |||
1382 | /* Function to format a fixed point value in ASCII. |
||
1383 | */ |
||
1384 | void /* PRIVATE */ |
||
1385 | png_ascii_from_fixed(png_structp png_ptr, png_charp ascii, png_size_t size, |
||
1386 | png_fixed_point fp) |
||
1387 | { |
||
1388 | /* Require space for 10 decimal digits, a decimal point, a minus sign and a |
||
1389 | * trailing \0, 13 characters: |
||
1390 | */ |
||
1391 | if (size > 12) |
||
1392 | { |
||
1393 | png_uint_32 num; |
||
1394 | |||
1395 | |||
1396 | if (fp < 0) |
||
1397 | *ascii++ = 45, --size, num = -fp; |
||
1398 | else |
||
1399 | num = fp; |
||
1400 | |||
1401 | |||
1402 | { |
||
1403 | unsigned int ndigits = 0, first = 16/*flag value*/; |
||
1404 | char digits[10]; |
||
1405 | |||
1406 | |||
1407 | { |
||
1408 | /* Split the low digit off num: */ |
||
1409 | unsigned int tmp = num/10; |
||
1410 | num -= tmp*10; |
||
1411 | digits[ndigits++] = (char)(48 + num); |
||
1412 | /* Record the first non-zero digit, note that this is a number |
||
1413 | * starting at 1, it's not actually the array index. |
||
1414 | */ |
||
1415 | if (first == 16 && num > 0) |
||
1416 | first = ndigits; |
||
1417 | num = tmp; |
||
1418 | } |
||
1419 | |||
1420 | |||
1421 | { |
||
1422 | while (ndigits > 5) *ascii++ = digits[--ndigits]; |
||
1423 | /* The remaining digits are fractional digits, ndigits is '5' or |
||
1424 | * smaller at this point. It is certainly not zero. Check for a |
||
1425 | * non-zero fractional digit: |
||
1426 | */ |
||
1427 | if (first <= 5) |
||
1428 | { |
||
1429 | unsigned int i; |
||
1430 | *ascii++ = 46; /* decimal point */ |
||
1431 | /* ndigits may be <5 for small numbers, output leading zeros |
||
1432 | * then ndigits digits to first: |
||
1433 | */ |
||
1434 | i = 5; |
||
1435 | while (ndigits < i) *ascii++ = 48, --i; |
||
1436 | while (ndigits >= first) *ascii++ = digits[--ndigits]; |
||
1437 | /* Don't output the trailing zeros! */ |
||
1438 | } |
||
1439 | } |
||
1440 | else |
||
1441 | *ascii++ = 48; |
||
1442 | |||
1443 | |||
1444 | *ascii = 0; |
||
1445 | return; |
||
1446 | } |
||
1447 | } |
||
1448 | |||
1449 | |||
1450 | png_error(png_ptr, "ASCII conversion buffer too small"); |
||
1451 | } |
||
1452 | # endif /* FIXED_POINT */ |
||
1453 | #endif /* READ_SCAL */ |
||
1454 | |||
1455 | |||
1456 | !defined(PNG_FIXED_POINT_MACRO_SUPPORTED) |
||
1457 | png_fixed_point |
||
1458 | png_fixed(png_structp png_ptr, double fp, png_const_charp text) |
||
1459 | { |
||
1460 | double r = floor(100000 * fp + .5); |
||
1461 | |||
1462 | |||
1463 | png_fixed_error(png_ptr, text); |
||
1464 | |||
1465 | |||
1466 | } |
||
1467 | #endif |
||
1468 | |||
1469 | |||
1470 | defined(PNG_INCH_CONVERSIONS_SUPPORTED) || defined(PNG__READ_pHYs_SUPPORTED) |
||
1471 | /* muldiv functions */ |
||
1472 | /* This API takes signed arguments and rounds the result to the nearest |
||
1473 | * integer (or, for a fixed point number - the standard argument - to |
||
1474 | * the nearest .00001). Overflow and divide by zero are signalled in |
||
1475 | * the result, a boolean - true on success, false on overflow. |
||
1476 | */ |
||
1477 | int |
||
1478 | png_muldiv(png_fixed_point_p res, png_fixed_point a, png_int_32 times, |
||
1479 | png_int_32 divisor) |
||
1480 | { |
||
1481 | /* Return a * times / divisor, rounded. */ |
||
1482 | if (divisor != 0) |
||
1483 | { |
||
1484 | if (a == 0 || times == 0) |
||
1485 | { |
||
1486 | *res = 0; |
||
1487 | return 1; |
||
1488 | } |
||
1489 | else |
||
1490 | { |
||
1491 | #ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED |
||
1492 | double r = a; |
||
1493 | r *= times; |
||
1494 | r /= divisor; |
||
1495 | r = floor(r+.5); |
||
1496 | |||
1497 | |||
1498 | if (r <= 2147483647. && r >= -2147483648.) |
||
1499 | { |
||
1500 | *res = (png_fixed_point)r; |
||
1501 | return 1; |
||
1502 | } |
||
1503 | #else |
||
1504 | int negative = 0; |
||
1505 | png_uint_32 A, T, D; |
||
1506 | png_uint_32 s16, s32, s00; |
||
1507 | |||
1508 | |||
1509 | negative = 1, A = -a; |
||
1510 | else |
||
1511 | A = a; |
||
1512 | |||
1513 | |||
1514 | negative = !negative, T = -times; |
||
1515 | else |
||
1516 | T = times; |
||
1517 | |||
1518 | |||
1519 | negative = !negative, D = -divisor; |
||
1520 | else |
||
1521 | D = divisor; |
||
1522 | |||
1523 | |||
1524 | * have 31 bits each, however the result may be 32 bits. |
||
1525 | */ |
||
1526 | s16 = (A >> 16) * (T & 0xffff) + |
||
1527 | (A & 0xffff) * (T >> 16); |
||
1528 | /* Can't overflow because the a*times bit is only 30 |
||
1529 | * bits at most. |
||
1530 | */ |
||
1531 | s32 = (A >> 16) * (T >> 16) + (s16 >> 16); |
||
1532 | s00 = (A & 0xffff) * (T & 0xffff); |
||
1533 | |||
1534 | |||
1535 | s00 += s16; |
||
1536 | |||
1537 | |||
1538 | ++s32; /* carry */ |
||
1539 | |||
1540 | |||
1541 | { |
||
1542 | /* s32.s00 is now the 64 bit product, do a standard |
||
1543 | * division, we know that s32 < D, so the maximum |
||
1544 | * required shift is 31. |
||
1545 | */ |
||
1546 | int bitshift = 32; |
||
1547 | png_fixed_point result = 0; /* NOTE: signed */ |
||
1548 | |||
1549 | |||
1550 | { |
||
1551 | png_uint_32 d32, d00; |
||
1552 | |||
1553 | |||
1554 | d32 = D >> (32-bitshift), d00 = D << bitshift; |
||
1555 | |||
1556 | |||
1557 | d32 = 0, d00 = D; |
||
1558 | |||
1559 | |||
1560 | { |
||
1561 | if (s00 < d00) --s32; /* carry */ |
||
1562 | s32 -= d32, s00 -= d00, result += 1< |
||
1563 | } |
||
1564 | |||
1565 | |||
1566 | if (s32 == d32 && s00 >= d00) |
||
1567 | s32 = 0, s00 -= d00, result += 1< |
||
1568 | } |
||
1569 | |||
1570 | |||
1571 | if (s00 >= (D >> 1)) |
||
1572 | ++result; |
||
1573 | |||
1574 | |||
1575 | result = -result; |
||
1576 | |||
1577 | |||
1578 | if ((negative && result <= 0) || (!negative && result >= 0)) |
||
1579 | { |
||
1580 | *res = result; |
||
1581 | return 1; |
||
1582 | } |
||
1583 | } |
||
1584 | #endif |
||
1585 | } |
||
1586 | } |
||
1587 | |||
1588 | |||
1589 | } |
||
1590 | #endif /* READ_GAMMA || INCH_CONVERSIONS */ |
||
1591 | |||
1592 | |||
1593 | /* The following is for when the caller doesn't much care about the |
||
1594 | * result. |
||
1595 | */ |
||
1596 | png_fixed_point |
||
1597 | png_muldiv_warn(png_structp png_ptr, png_fixed_point a, png_int_32 times, |
||
1598 | png_int_32 divisor) |
||
1599 | { |
||
1600 | png_fixed_point result; |
||
1601 | |||
1602 | |||
1603 | return result; |
||
1604 | |||
1605 | |||
1606 | return 0; |
||
1607 | } |
||
1608 | #endif |
||
1609 | |||
1610 | |||
1611 | /* Calculate a reciprocal, return 0 on div-by-zero or overflow. */ |
||
1612 | png_fixed_point |
||
1613 | png_reciprocal(png_fixed_point a) |
||
1614 | { |
||
1615 | #ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED |
||
1616 | double r = floor(1E10/a+.5); |
||
1617 | |||
1618 | |||
1619 | return (png_fixed_point)r; |
||
1620 | #else |
||
1621 | png_fixed_point res; |
||
1622 | |||
1623 | |||
1624 | return res; |
||
1625 | #endif |
||
1626 | |||
1627 | |||
1628 | } |
||
1629 | |||
1630 | |||
1631 | static png_fixed_point |
||
1632 | png_product2(png_fixed_point a, png_fixed_point b) |
||
1633 | { |
||
1634 | /* The required result is 1/a * 1/b; the following preserves accuracy. */ |
||
1635 | #ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED |
||
1636 | double r = a * 1E-5; |
||
1637 | r *= b; |
||
1638 | r = floor(r+.5); |
||
1639 | |||
1640 | |||
1641 | return (png_fixed_point)r; |
||
1642 | #else |
||
1643 | png_fixed_point res; |
||
1644 | |||
1645 | |||
1646 | return res; |
||
1647 | #endif |
||
1648 | |||
1649 | |||
1650 | } |
||
1651 | |||
1652 | |||
1653 | png_fixed_point |
||
1654 | png_reciprocal2(png_fixed_point a, png_fixed_point b) |
||
1655 | { |
||
1656 | /* The required result is 1/a * 1/b; the following preserves accuracy. */ |
||
1657 | #ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED |
||
1658 | double r = 1E15/a; |
||
1659 | r /= b; |
||
1660 | r = floor(r+.5); |
||
1661 | |||
1662 | |||
1663 | return (png_fixed_point)r; |
||
1664 | #else |
||
1665 | /* This may overflow because the range of png_fixed_point isn't symmetric, |
||
1666 | * but this API is only used for the product of file and screen gamma so it |
||
1667 | * doesn't matter that the smallest number it can produce is 1/21474, not |
||
1668 | * 1/100000 |
||
1669 | */ |
||
1670 | png_fixed_point res = png_product2(a, b); |
||
1671 | |||
1672 | |||
1673 | return png_reciprocal(res); |
||
1674 | #endif |
||
1675 | |||
1676 | |||
1677 | } |
||
1678 | #endif /* READ_GAMMA */ |
||
1679 | |||
1680 | |||
1681 | /* Added at libpng version 1.2.34 (Dec 8, 2008) and 1.4.0 (Jan 2, |
||
1682 | * 2010: moved from pngset.c) */ |
||
1683 | /* |
||
1684 | * Multiply two 32-bit numbers, V1 and V2, using 32-bit |
||
1685 | * arithmetic, to produce a 64 bit result in the HI/LO words. |
||
1686 | * |
||
1687 | * A B |
||
1688 | * x C D |
||
1689 | * ------ |
||
1690 | * AD || BD |
||
1691 | * AC || CB || 0 |
||
1692 | * |
||
1693 | * where A and B are the high and low 16-bit words of V1, |
||
1694 | * C and D are the 16-bit words of V2, AD is the product of |
||
1695 | * A and D, and X || Y is (X << 16) + Y. |
||
1696 | */ |
||
1697 | |||
1698 | |||
1699 | png_64bit_product (long v1, long v2, unsigned long *hi_product, |
||
1700 | unsigned long *lo_product) |
||
1701 | { |
||
1702 | int a, b, c, d; |
||
1703 | long lo, hi, x, y; |
||
1704 | |||
1705 | |||
1706 | b = v1 & 0xffff; |
||
1707 | c = (v2 >> 16) & 0xffff; |
||
1708 | d = v2 & 0xffff; |
||
1709 | |||
1710 | |||
1711 | x = a * d + c * b; /* AD + CB */ |
||
1712 | y = ((lo >> 16) & 0xffff) + x; |
||
1713 | |||
1714 | |||
1715 | hi = (y >> 16) & 0xffff; |
||
1716 | |||
1717 | |||
1718 | |||
1719 | |||
1720 | *lo_product = (unsigned long)lo; |
||
1721 | } |
||
1722 | #endif /* CHECK_cHRM */ |
||
1723 | |||
1724 | |||
1725 | #ifndef PNG_FLOATING_ARITHMETIC_SUPPORTED |
||
1726 | /* Fixed point gamma. |
||
1727 | * |
||
1728 | * To calculate gamma this code implements fast log() and exp() calls using only |
||
1729 | * fixed point arithmetic. This code has sufficient precision for either 8 or |
||
1730 | * 16 bit sample values. |
||
1731 | * |
||
1732 | * The tables used here were calculated using simple 'bc' programs, but C double |
||
1733 | * precision floating point arithmetic would work fine. The programs are given |
||
1734 | * at the head of each table. |
||
1735 | * |
||
1736 | * 8 bit log table |
||
1737 | * This is a table of -log(value/255)/log(2) for 'value' in the range 128 to |
||
1738 | * 255, so it's the base 2 logarithm of a normalized 8 bit floating point |
||
1739 | * mantissa. The numbers are 32 bit fractions. |
||
1740 | */ |
||
1741 | static png_uint_32 |
||
1742 | png_8bit_l2[128] = |
||
1743 | { |
||
1744 | # if PNG_DO_BC |
||
1745 | for (i=128;i<256;++i) { .5 - l(i/255)/l(2)*65536*65536; } |
||
1746 | # endif |
||
1747 | 4270715492U, 4222494797U, 4174646467U, 4127164793U, 4080044201U, 4033279239U, |
||
1748 | 3986864580U, 3940795015U, 3895065449U, 3849670902U, 3804606499U, 3759867474U, |
||
1749 | 3715449162U, 3671346997U, 3627556511U, 3584073329U, 3540893168U, 3498011834U, |
||
1750 | 3455425220U, 3413129301U, 3371120137U, 3329393864U, 3287946700U, 3246774933U, |
||
1751 | 3205874930U, 3165243125U, 3124876025U, 3084770202U, 3044922296U, 3005329011U, |
||
1752 | 2965987113U, 2926893432U, 2888044853U, 2849438323U, 2811070844U, 2772939474U, |
||
1753 | 2735041326U, 2697373562U, 2659933400U, 2622718104U, 2585724991U, 2548951424U, |
||
1754 | 2512394810U, 2476052606U, 2439922311U, 2404001468U, 2368287663U, 2332778523U, |
||
1755 | 2297471715U, 2262364947U, 2227455964U, 2192742551U, 2158222529U, 2123893754U, |
||
1756 | 2089754119U, 2055801552U, 2022034013U, 1988449497U, 1955046031U, 1921821672U, |
||
1757 | 1888774511U, 1855902668U, 1823204291U, 1790677560U, 1758320682U, 1726131893U, |
||
1758 | 1694109454U, 1662251657U, 1630556815U, 1599023271U, 1567649391U, 1536433567U, |
||
1759 | 1505374214U, 1474469770U, 1443718700U, 1413119487U, 1382670639U, 1352370686U, |
||
1760 | 1322218179U, 1292211689U, 1262349810U, 1232631153U, 1203054352U, 1173618059U, |
||
1761 | 1144320946U, 1115161701U, 1086139034U, 1057251672U, 1028498358U, 999877854U, |
||
1762 | 971388940U, 943030410U, 914801076U, 886699767U, 858725327U, 830876614U, |
||
1763 | 803152505U, 775551890U, 748073672U, 720716771U, 693480120U, 666362667U, |
||
1764 | 639363374U, 612481215U, 585715177U, 559064263U, 532527486U, 506103872U, |
||
1765 | 479792461U, 453592303U, 427502463U, 401522014U, 375650043U, 349885648U, |
||
1766 | 324227938U, 298676034U, 273229066U, 247886176U, 222646516U, 197509248U, |
||
1767 | 172473545U, 147538590U, 122703574U, 97967701U, 73330182U, 48790236U, |
||
1768 | 24347096U, 0U |
||
1769 | #if 0 |
||
1770 | /* The following are the values for 16 bit tables - these work fine for the 8 |
||
1771 | * bit conversions but produce very slightly larger errors in the 16 bit log |
||
1772 | * (about 1.2 as opposed to 0.7 absolute error in the final value). To use |
||
1773 | * these all the shifts below must be adjusted appropriately. |
||
1774 | */ |
||
1775 | 65166, 64430, 63700, 62976, 62257, 61543, 60835, 60132, 59434, 58741, 58054, |
||
1776 | 57371, 56693, 56020, 55352, 54689, 54030, 53375, 52726, 52080, 51439, 50803, |
||
1777 | 50170, 49542, 48918, 48298, 47682, 47070, 46462, 45858, 45257, 44661, 44068, |
||
1778 | 43479, 42894, 42312, 41733, 41159, 40587, 40020, 39455, 38894, 38336, 37782, |
||
1779 | 37230, 36682, 36137, 35595, 35057, 34521, 33988, 33459, 32932, 32408, 31887, |
||
1780 | 31369, 30854, 30341, 29832, 29325, 28820, 28319, 27820, 27324, 26830, 26339, |
||
1781 | 25850, 25364, 24880, 24399, 23920, 23444, 22970, 22499, 22029, 21562, 21098, |
||
1782 | 20636, 20175, 19718, 19262, 18808, 18357, 17908, 17461, 17016, 16573, 16132, |
||
1783 | 15694, 15257, 14822, 14390, 13959, 13530, 13103, 12678, 12255, 11834, 11415, |
||
1784 | 10997, 10582, 10168, 9756, 9346, 8937, 8531, 8126, 7723, 7321, 6921, 6523, |
||
1785 | 6127, 5732, 5339, 4947, 4557, 4169, 3782, 3397, 3014, 2632, 2251, 1872, 1495, |
||
1786 | 1119, 744, 372 |
||
1787 | #endif |
||
1788 | }; |
||
1789 | |||
1790 | |||
1791 | png_log8bit(unsigned int x) |
||
1792 | { |
||
1793 | unsigned int lg2 = 0; |
||
1794 | /* Each time 'x' is multiplied by 2, 1 must be subtracted off the final log, |
||
1795 | * because the log is actually negate that means adding 1. The final |
||
1796 | * returned value thus has the range 0 (for 255 input) to 7.994 (for 1 |
||
1797 | * input), return 7.99998 for the overflow (log 0) case - so the result is |
||
1798 | * always at most 19 bits. |
||
1799 | */ |
||
1800 | if ((x &= 0xff) == 0) |
||
1801 | return 0xffffffff; |
||
1802 | |||
1803 | |||
1804 | lg2 = 4, x <<= 4; |
||
1805 | |||
1806 | |||
1807 | lg2 += 2, x <<= 2; |
||
1808 | |||
1809 | |||
1810 | lg2 += 1, x <<= 1; |
||
1811 | |||
1812 | |||
1813 | return (png_int_32)((lg2 << 16) + ((png_8bit_l2[x-128]+32768)>>16)); |
||
1814 | } |
||
1815 | |||
1816 | |||
1817 | * for 16 bit images we use the most significant 8 bits of the 16 bit value to |
||
1818 | * get an approximation then multiply the approximation by a correction factor |
||
1819 | * determined by the remaining up to 8 bits. This requires an additional step |
||
1820 | * in the 16 bit case. |
||
1821 | * |
||
1822 | * We want log2(value/65535), we have log2(v'/255), where: |
||
1823 | * |
||
1824 | * value = v' * 256 + v'' |
||
1825 | * = v' * f |
||
1826 | * |
||
1827 | * So f is value/v', which is equal to (256+v''/v') since v' is in the range 128 |
||
1828 | * to 255 and v'' is in the range 0 to 255 f will be in the range 256 to less |
||
1829 | * than 258. The final factor also needs to correct for the fact that our 8 bit |
||
1830 | * value is scaled by 255, whereas the 16 bit values must be scaled by 65535. |
||
1831 | * |
||
1832 | * This gives a final formula using a calculated value 'x' which is value/v' and |
||
1833 | * scaling by 65536 to match the above table: |
||
1834 | * |
||
1835 | * log2(x/257) * 65536 |
||
1836 | * |
||
1837 | * Since these numbers are so close to '1' we can use simple linear |
||
1838 | * interpolation between the two end values 256/257 (result -368.61) and 258/257 |
||
1839 | * (result 367.179). The values used below are scaled by a further 64 to give |
||
1840 | * 16 bit precision in the interpolation: |
||
1841 | * |
||
1842 | * Start (256): -23591 |
||
1843 | * Zero (257): 0 |
||
1844 | * End (258): 23499 |
||
1845 | */ |
||
1846 | static png_int_32 |
||
1847 | png_log16bit(png_uint_32 x) |
||
1848 | { |
||
1849 | unsigned int lg2 = 0; |
||
1850 | |||
1851 | |||
1852 | if ((x &= 0xffff) == 0) |
||
1853 | return 0xffffffff; |
||
1854 | |||
1855 | |||
1856 | lg2 = 8, x <<= 8; |
||
1857 | |||
1858 | |||
1859 | lg2 += 4, x <<= 4; |
||
1860 | |||
1861 | |||
1862 | lg2 += 2, x <<= 2; |
||
1863 | |||
1864 | |||
1865 | lg2 += 1, x <<= 1; |
||
1866 | |||
1867 | |||
1868 | * value. |
||
1869 | */ |
||
1870 | lg2 <<= 28; |
||
1871 | lg2 += (png_8bit_l2[(x>>8)-128]+8) >> 4; |
||
1872 | |||
1873 | |||
1874 | * 8 bits. Do this with maximum precision. |
||
1875 | */ |
||
1876 | x = ((x << 16) + (x >> 9)) / (x >> 8); |
||
1877 | |||
1878 | |||
1879 | * the value at 1<<16 (ignoring this) will be 0 or 1; this gives us exactly |
||
1880 | * 16 bits to interpolate to get the low bits of the result. Round the |
||
1881 | * answer. Note that the end point values are scaled by 64 to retain overall |
||
1882 | * precision and that 'lg2' is current scaled by an extra 12 bits, so adjust |
||
1883 | * the overall scaling by 6-12. Round at every step. |
||
1884 | */ |
||
1885 | x -= 1U << 24; |
||
1886 | |||
1887 | |||
1888 | lg2 += ((23591U * (65536U-x)) + (1U << (16+6-12-1))) >> (16+6-12); |
||
1889 | |||
1890 | |||
1891 | lg2 -= ((23499U * (x-65536U)) + (1U << (16+6-12-1))) >> (16+6-12); |
||
1892 | |||
1893 | |||
1894 | return (png_int_32)((lg2 + 2048) >> 12); |
||
1895 | } |
||
1896 | |||
1897 | |||
1898 | * logarithmic value and returning a 16 or 8 bit number as appropriate. In |
||
1899 | * each case only the low 16 bits are relevant - the fraction - since the |
||
1900 | * integer bits (the top 4) simply determine a shift. |
||
1901 | * |
||
1902 | * The worst case is the 16 bit distinction between 65535 and 65534, this |
||
1903 | * requires perhaps spurious accuracty in the decoding of the logarithm to |
||
1904 | * distinguish log2(65535/65534.5) - 10^-5 or 17 bits. There is little chance |
||
1905 | * of getting this accuracy in practice. |
||
1906 | * |
||
1907 | * To deal with this the following exp() function works out the exponent of the |
||
1908 | * frational part of the logarithm by using an accurate 32 bit value from the |
||
1909 | * top four fractional bits then multiplying in the remaining bits. |
||
1910 | */ |
||
1911 | static png_uint_32 |
||
1912 | png_32bit_exp[16] = |
||
1913 | { |
||
1914 | # if PNG_DO_BC |
||
1915 | for (i=0;i<16;++i) { .5 + e(-i/16*l(2))*2^32; } |
||
1916 | # endif |
||
1917 | /* NOTE: the first entry is deliberately set to the maximum 32 bit value. */ |
||
1918 | 4294967295U, 4112874773U, 3938502376U, 3771522796U, 3611622603U, 3458501653U, |
||
1919 | 3311872529U, 3171459999U, 3037000500U, 2908241642U, 2784941738U, 2666869345U, |
||
1920 | 2553802834U, 2445529972U, 2341847524U, 2242560872U |
||
1921 | }; |
||
1922 | |||
1923 | |||
1924 | #if PNG_DO_BC |
||
1925 | for (i=11;i>=0;--i){ print i, " ", (1 - e(-(2^i)/65536*l(2))) * 2^(32-i), "\n"} |
||
1926 | 11 44937.64284865548751208448 |
||
1927 | 10 45180.98734845585101160448 |
||
1928 | 9 45303.31936980687359311872 |
||
1929 | 8 45364.65110595323018870784 |
||
1930 | 7 45395.35850361789624614912 |
||
1931 | 6 45410.72259715102037508096 |
||
1932 | 5 45418.40724413220722311168 |
||
1933 | 4 45422.25021786898173001728 |
||
1934 | 3 45424.17186732298419044352 |
||
1935 | 2 45425.13273269940811464704 |
||
1936 | 1 45425.61317555035558641664 |
||
1937 | 0 45425.85339951654943850496 |
||
1938 | |||
1939 | |||
1940 | |||
1941 | png_exp(png_fixed_point x) |
||
1942 | { |
||
1943 | if (x > 0 && x <= 0xfffff) /* Else overflow or zero (underflow) */ |
||
1944 | { |
||
1945 | /* Obtain a 4 bit approximation */ |
||
1946 | png_uint_32 e = png_32bit_exp[(x >> 12) & 0xf]; |
||
1947 | |||
1948 | |||
1949 | * multiplying by a number less than 1 if the bit is set. The multiplier |
||
1950 | * is determined by the above table and the shift. Notice that the values |
||
1951 | * converge on 45426 and this is used to allow linear interpolation of the |
||
1952 | * low bits. |
||
1953 | */ |
||
1954 | if (x & 0x800) |
||
1955 | e -= (((e >> 16) * 44938U) + 16U) >> 5; |
||
1956 | |||
1957 | |||
1958 | e -= (((e >> 16) * 45181U) + 32U) >> 6; |
||
1959 | |||
1960 | |||
1961 | e -= (((e >> 16) * 45303U) + 64U) >> 7; |
||
1962 | |||
1963 | |||
1964 | e -= (((e >> 16) * 45365U) + 128U) >> 8; |
||
1965 | |||
1966 | |||
1967 | e -= (((e >> 16) * 45395U) + 256U) >> 9; |
||
1968 | |||
1969 | |||
1970 | e -= (((e >> 16) * 45410U) + 512U) >> 10; |
||
1971 | |||
1972 | |||
1973 | e -= (((e >> 16) * 355U * (x & 0x3fU)) + 256U) >> 9; |
||
1974 | |||
1975 | |||
1976 | e >>= x >> 16; |
||
1977 | return e; |
||
1978 | } |
||
1979 | |||
1980 | |||
1981 | if (x <= 0) |
||
1982 | return png_32bit_exp[0]; |
||
1983 | |||
1984 | |||
1985 | return 0; |
||
1986 | } |
||
1987 | |||
1988 | |||
1989 | png_exp8bit(png_fixed_point lg2) |
||
1990 | { |
||
1991 | /* Get a 32 bit value: */ |
||
1992 | png_uint_32 x = png_exp(lg2); |
||
1993 | |||
1994 | |||
1995 | * second, rounding, step can't overflow because of the first, subtraction, |
||
1996 | * step. |
||
1997 | */ |
||
1998 | x -= x >> 8; |
||
1999 | return (png_byte)((x + 0x7fffffU) >> 24); |
||
2000 | } |
||
2001 | |||
2002 | |||
2003 | png_exp16bit(png_fixed_point lg2) |
||
2004 | { |
||
2005 | /* Get a 32 bit value: */ |
||
2006 | png_uint_32 x = png_exp(lg2); |
||
2007 | |||
2008 | |||
2009 | x -= x >> 16; |
||
2010 | return (png_uint_16)((x + 32767U) >> 16); |
||
2011 | } |
||
2012 | #endif /* FLOATING_ARITHMETIC */ |
||
2013 | |||
2014 | |||
2015 | png_gamma_8bit_correct(unsigned int value, png_fixed_point gamma_val) |
||
2016 | { |
||
2017 | if (value > 0 && value < 255) |
||
2018 | { |
||
2019 | # ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED |
||
2020 | double r = floor(255*pow(value/255.,gamma_val*.00001)+.5); |
||
2021 | return (png_byte)r; |
||
2022 | # else |
||
2023 | png_int_32 lg2 = png_log8bit(value); |
||
2024 | png_fixed_point res; |
||
2025 | |||
2026 | |||
2027 | return png_exp8bit(res); |
||
2028 | |||
2029 | |||
2030 | value = 0; |
||
2031 | # endif |
||
2032 | } |
||
2033 | |||
2034 | |||
2035 | } |
||
2036 | |||
2037 | |||
2038 | png_gamma_16bit_correct(unsigned int value, png_fixed_point gamma_val) |
||
2039 | { |
||
2040 | if (value > 0 && value < 65535) |
||
2041 | { |
||
2042 | # ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED |
||
2043 | double r = floor(65535*pow(value/65535.,gamma_val*.00001)+.5); |
||
2044 | return (png_uint_16)r; |
||
2045 | # else |
||
2046 | png_int_32 lg2 = png_log16bit(value); |
||
2047 | png_fixed_point res; |
||
2048 | |||
2049 | |||
2050 | return png_exp16bit(res); |
||
2051 | |||
2052 | |||
2053 | value = 0; |
||
2054 | # endif |
||
2055 | } |
||
2056 | |||
2057 | |||
2058 | } |
||
2059 | |||
2060 | |||
2061 | * png_struct, interpreting values as 8 or 16 bit. While the result |
||
2062 | * is nominally a 16 bit value if bit depth is 8 then the result is |
||
2063 | * 8 bit (as are the arguments.) |
||
2064 | */ |
||
2065 | png_uint_16 /* PRIVATE */ |
||
2066 | png_gamma_correct(png_structp png_ptr, unsigned int value, |
||
2067 | png_fixed_point gamma_val) |
||
2068 | { |
||
2069 | if (png_ptr->bit_depth == 8) |
||
2070 | return png_gamma_8bit_correct(value, gamma_val); |
||
2071 | |||
2072 | |||
2073 | return png_gamma_16bit_correct(value, gamma_val); |
||
2074 | } |
||
2075 | |||
2076 | |||
2077 | * it is worth doing gamma correction. |
||
2078 | */ |
||
2079 | int /* PRIVATE */ |
||
2080 | png_gamma_significant(png_fixed_point gamma_val) |
||
2081 | { |
||
2082 | return gamma_val < PNG_FP_1 - PNG_GAMMA_THRESHOLD_FIXED || |
||
2083 | gamma_val > PNG_FP_1 + PNG_GAMMA_THRESHOLD_FIXED; |
||
2084 | } |
||
2085 | |||
2086 | |||
2087 | * 'num' 256 entry subtables, where 'num' is determined by 'shift' - the amount |
||
2088 | * to shift the input values right (or 16-number_of_signifiant_bits). |
||
2089 | * |
||
2090 | * The caller is responsible for ensuring that the table gets cleaned up on |
||
2091 | * png_error (i.e. if one of the mallocs below fails) - i.e. the *table argument |
||
2092 | * should be somewhere that will be cleaned. |
||
2093 | */ |
||
2094 | static void |
||
2095 | png_build_16bit_table(png_structp png_ptr, png_uint_16pp *ptable, |
||
2096 | PNG_CONST unsigned int shift, PNG_CONST png_fixed_point gamma_val) |
||
2097 | { |
||
2098 | /* Various values derived from 'shift': */ |
||
2099 | PNG_CONST unsigned int num = 1U << (8U - shift); |
||
2100 | PNG_CONST unsigned int max = (1U << (16U - shift))-1U; |
||
2101 | PNG_CONST unsigned int max_by_2 = 1U << (15U-shift); |
||
2102 | unsigned int i; |
||
2103 | |||
2104 | |||
2105 | (png_uint_16pp)png_calloc(png_ptr, num * png_sizeof(png_uint_16p)); |
||
2106 | |||
2107 | |||
2108 | { |
||
2109 | png_uint_16p sub_table = table[i] = |
||
2110 | (png_uint_16p)png_malloc(png_ptr, 256 * png_sizeof(png_uint_16)); |
||
2111 | |||
2112 | |||
2113 | * the 16 bit tables even if the others don't hit it. |
||
2114 | */ |
||
2115 | if (png_gamma_significant(gamma_val)) |
||
2116 | { |
||
2117 | /* The old code would overflow at the end and this would cause the |
||
2118 | * 'pow' function to return a result >1, resulting in an |
||
2119 | * arithmetic error. This code follows the spec exactly; ig is |
||
2120 | * the recovered input sample, it always has 8-16 bits. |
||
2121 | * |
||
2122 | * We want input * 65535/max, rounded, the arithmetic fits in 32 |
||
2123 | * bits (unsigned) so long as max <= 32767. |
||
2124 | */ |
||
2125 | unsigned int j; |
||
2126 | for (j = 0; j < 256; j++) |
||
2127 | { |
||
2128 | png_uint_32 ig = (j << (8-shift)) + i; |
||
2129 | # ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED |
||
2130 | /* Inline the 'max' scaling operation: */ |
||
2131 | double d = floor(65535*pow(ig/(double)max, gamma_val*.00001)+.5); |
||
2132 | sub_table[j] = (png_uint_16)d; |
||
2133 | # else |
||
2134 | if (shift) |
||
2135 | ig = (ig * 65535U + max_by_2)/max; |
||
2136 | |||
2137 | |||
2138 | # endif |
||
2139 | } |
||
2140 | } |
||
2141 | else |
||
2142 | { |
||
2143 | /* We must still build a table, but do it the fast way. */ |
||
2144 | unsigned int j; |
||
2145 | |||
2146 | |||
2147 | { |
||
2148 | png_uint_32 ig = (j << (8-shift)) + i; |
||
2149 | |||
2150 | |||
2151 | ig = (ig * 65535U + max_by_2)/max; |
||
2152 | |||
2153 | |||
2154 | } |
||
2155 | } |
||
2156 | } |
||
2157 | } |
||
2158 | |||
2159 | |||
2160 | * required. |
||
2161 | */ |
||
2162 | static void |
||
2163 | png_build_16to8_table(png_structp png_ptr, png_uint_16pp *ptable, |
||
2164 | PNG_CONST unsigned int shift, PNG_CONST png_fixed_point gamma_val) |
||
2165 | { |
||
2166 | PNG_CONST unsigned int num = 1U << (8U - shift); |
||
2167 | PNG_CONST unsigned int max = (1U << (16U - shift))-1U; |
||
2168 | unsigned int i; |
||
2169 | png_uint_32 last; |
||
2170 | |||
2171 | |||
2172 | (png_uint_16pp)png_calloc(png_ptr, num * png_sizeof(png_uint_16p)); |
||
2173 | |||
2174 | |||
2175 | * bits of the input 16 bit value used to select a table. Each table is |
||
2176 | * itself index by the high 8 bits of the value. |
||
2177 | */ |
||
2178 | for (i = 0; i < num; i++) |
||
2179 | table[i] = (png_uint_16p)png_malloc(png_ptr, |
||
2180 | 256 * png_sizeof(png_uint_16)); |
||
2181 | |||
2182 | |||
2183 | * pow(out,g) is an *input* value. 'last' is the last input value set. |
||
2184 | * |
||
2185 | * In the loop 'i' is used to find output values. Since the output is 8 |
||
2186 | * bit there are only 256 possible values. The tables are set up to |
||
2187 | * select the closest possible output value for each input by finding |
||
2188 | * the input value at the boundary between each pair of output values |
||
2189 | * and filling the table up to that boundary with the lower output |
||
2190 | * value. |
||
2191 | * |
||
2192 | * The boundary values are 0.5,1.5..253.5,254.5. Since these are 9 bit |
||
2193 | * values the code below uses a 16 bit value in i; the values start at |
||
2194 | * 128.5 (for 0.5) and step by 257, for a total of 254 values (the last |
||
2195 | * entries are filled with 255). Start i at 128 and fill all 'last' |
||
2196 | * table entries <= 'max' |
||
2197 | */ |
||
2198 | last = 0; |
||
2199 | for (i = 0; i < 255; ++i) /* 8 bit output value */ |
||
2200 | { |
||
2201 | /* Find the corresponding maximum input value */ |
||
2202 | png_uint_16 out = (png_uint_16)(i * 257U); /* 16 bit output value */ |
||
2203 | |||
2204 | |||
2205 | png_uint_32 bound = png_gamma_16bit_correct(out+128U, gamma_val); |
||
2206 | |||
2207 | |||
2208 | bound = (bound * max + 32768U)/65535U + 1U; |
||
2209 | |||
2210 | |||
2211 | { |
||
2212 | table[last & (0xffU >> shift)][last >> (8U - shift)] = out; |
||
2213 | last++; |
||
2214 | } |
||
2215 | } |
||
2216 | |||
2217 | |||
2218 | while (last < (num << 8)) |
||
2219 | { |
||
2220 | table[last & (0xff >> shift)][last >> (8U - shift)] = 65535U; |
||
2221 | last++; |
||
2222 | } |
||
2223 | } |
||
2224 | |||
2225 | |||
2226 | * typically much faster). Note that libpng currently does no sBIT processing |
||
2227 | * (apparently contrary to the spec) so a 256 entry table is always generated. |
||
2228 | */ |
||
2229 | static void |
||
2230 | png_build_8bit_table(png_structp png_ptr, png_bytepp ptable, |
||
2231 | PNG_CONST png_fixed_point gamma_val) |
||
2232 | { |
||
2233 | unsigned int i; |
||
2234 | png_bytep table = *ptable = (png_bytep)png_malloc(png_ptr, 256); |
||
2235 | |||
2236 | |||
2237 | table[i] = png_gamma_8bit_correct(i, gamma_val); |
||
2238 | |||
2239 | |||
2240 | table[i] = (png_byte)i; |
||
2241 | } |
||
2242 | |||
2243 | |||
2244 | * tables, we don't make a full table if we are reducing to 8-bit in |
||
2245 | * the future. Note also how the gamma_16 tables are segmented so that |
||
2246 | * we don't need to allocate > 64K chunks for a full 16-bit table. |
||
2247 | */ |
||
2248 | void /* PRIVATE */ |
||
2249 | png_build_gamma_table(png_structp png_ptr, int bit_depth) |
||
2250 | { |
||
2251 | png_debug(1, "in png_build_gamma_table"); |
||
2252 | |||
2253 | |||
2254 | { |
||
2255 | png_build_8bit_table(png_ptr, &png_ptr->gamma_table, |
||
2256 | png_ptr->screen_gamma > 0 ? png_reciprocal2(png_ptr->gamma, |
||
2257 | png_ptr->screen_gamma) : PNG_FP_1); |
||
2258 | |||
2259 | |||
2260 | defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) |
||
2261 | if (png_ptr->transformations & ((PNG_BACKGROUND) | PNG_RGB_TO_GRAY)) |
||
2262 | { |
||
2263 | png_build_8bit_table(png_ptr, &png_ptr->gamma_to_1, |
||
2264 | png_reciprocal(png_ptr->gamma)); |
||
2265 | |||
2266 | |||
2267 | png_ptr->screen_gamma > 0 ? png_reciprocal(png_ptr->screen_gamma) : |
||
2268 | png_ptr->gamma/* Probably doing rgb_to_gray */); |
||
2269 | } |
||
2270 | #endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */ |
||
2271 | } |
||
2272 | else |
||
2273 | { |
||
2274 | png_byte shift, sig_bit; |
||
2275 | |||
2276 | |||
2277 | { |
||
2278 | sig_bit = png_ptr->sig_bit.red; |
||
2279 | |||
2280 | |||
2281 | sig_bit = png_ptr->sig_bit.green; |
||
2282 | |||
2283 | |||
2284 | sig_bit = png_ptr->sig_bit.blue; |
||
2285 | } |
||
2286 | else |
||
2287 | sig_bit = png_ptr->sig_bit.gray; |
||
2288 | |||
2289 | |||
2290 | * |
||
2291 | * ov = table[(iv & 0xff) >> gamma_shift][iv >> 8] |
||
2292 | * |
||
2293 | * Where 'iv' is the input color value and 'ov' is the output value - |
||
2294 | * pow(iv, gamma). |
||
2295 | * |
||
2296 | * Thus the gamma table consists of up to 256 256 entry tables. The table |
||
2297 | * is selected by the (8-gamma_shift) most significant of the low 8 bits of |
||
2298 | * the color value then indexed by the upper 8 bits: |
||
2299 | * |
||
2300 | * table[low bits][high 8 bits] |
||
2301 | * |
||
2302 | * So the table 'n' corresponds to all those 'iv' of: |
||
2303 | * |
||
2304 | * |
||
2305 | * |
||
2306 | */ |
||
2307 | if (sig_bit > 0 && sig_bit < 16U) |
||
2308 | shift = (png_byte)(16U - sig_bit); /* shift == insignificant bits */ |
||
2309 | |||
2310 | |||
2311 | shift = 0; /* keep all 16 bits */ |
||
2312 | |||
2313 | |||
2314 | { |
||
2315 | /* PNG_MAX_GAMMA_8 is the number of bits to keep - effectively |
||
2316 | * the significant bits in the *input* when the output will |
||
2317 | * eventually be 8 bits. By default it is 11. |
||
2318 | */ |
||
2319 | if (shift < (16U - PNG_MAX_GAMMA_8)) |
||
2320 | shift = (16U - PNG_MAX_GAMMA_8); |
||
2321 | } |
||
2322 | |||
2323 | |||
2324 | shift = 8U; /* Guarantees at least one table! */ |
||
2325 | |||
2326 | |||
2327 | |||
2328 | |||
2329 | if (png_ptr->transformations & (PNG_16_TO_8 | PNG_BACKGROUND)) |
||
2330 | #endif |
||
2331 | png_build_16to8_table(png_ptr, &png_ptr->gamma_16_table, shift, |
||
2332 | png_ptr->screen_gamma > 0 ? png_product2(png_ptr->gamma, |
||
2333 | png_ptr->screen_gamma) : PNG_FP_1); |
||
2334 | |||
2335 | |||
2336 | else |
||
2337 | png_build_16bit_table(png_ptr, &png_ptr->gamma_16_table, shift, |
||
2338 | png_ptr->screen_gamma > 0 ? png_reciprocal2(png_ptr->gamma, |
||
2339 | png_ptr->screen_gamma) : PNG_FP_1); |
||
2340 | #endif |
||
2341 | |||
2342 | |||
2343 | defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) |
||
2344 | if (png_ptr->transformations & (PNG_BACKGROUND | PNG_RGB_TO_GRAY)) |
||
2345 | { |
||
2346 | png_build_16bit_table(png_ptr, &png_ptr->gamma_16_to_1, shift, |
||
2347 | png_reciprocal(png_ptr->gamma)); |
||
2348 | |||
2349 | |||
2350 | * the lookup on this table still uses gamma_shift, so it can't be. |
||
2351 | * TODO: fix this. |
||
2352 | */ |
||
2353 | png_build_16bit_table(png_ptr, &png_ptr->gamma_16_from_1, shift, |
||
2354 | png_ptr->screen_gamma > 0 ? png_reciprocal(png_ptr->screen_gamma) : |
||
2355 | png_ptr->gamma/* Probably doing rgb_to_gray */); |
||
2356 | } |
||
2357 | #endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */ |
||
2358 | } |
||
2359 | } |
||
2360 | #endif /* READ_GAMMA */ |
||
2361 | #endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */>>><>(n+1>><>=>256;>256;>><>>>>=>>><>><>><>>><>>=>>><>><>><>>>>=>=>16;++i)>><>><>=>=>><>16><16>24, |
||
2362 | ><24, |