21 bool parse_png(
const char *source,
int length, mpfr_t cx, mpfr_t cy, mpfr_t cz) {
23 const unsigned char *s = (
const unsigned char *) source;
25 const unsigned char signature[8] = { 137, 80, 78, 71, 13, 10, 26, 10 };
26 if (! (length >= 8 && 0 == memcmp(s, signature, 8))) {
31 #define INT ((s[0] << 24) | (s[1] << 16) | (s[2] << 8) | (s[3])); s+= 4
33 const unsigned int tEXt = (116 << 24) | (69 << 16) | (88 << 8) | (116);
36 const unsigned char *software = (
const unsigned char *)
"Software";
37 const int software_length = 9;
39 const unsigned char *title = (
const unsigned char *)
"Title";
40 const int title_length = 6;
42 const unsigned char *mightymandel = (
const unsigned char *)
"mightymandel";
43 const int mightymandel_length = 12;
45 bool have_mightymandel =
false;
47 while (s + 4 <= (
const unsigned char *) source + length) {
49 unsigned int chunk_length =
INT;
50 if (! (s + chunk_length + 4 <= (
const unsigned char *) source + length)) {
54 unsigned long chunk_data_crc =
crc(s, 4 + chunk_length);
55 unsigned int type =
INT;
56 debug_message(
"parse_png type = %08x (want %08x)\n", type, tEXt);
59 if (! have_mightymandel && 0 == memcmp(s, software, software_length)) {
62 chunk_length -= software_length;
63 if ((
int) chunk_length == mightymandel_length && 0 == memcmp(s, mightymandel, mightymandel_length)) {
65 have_mightymandel =
true;
69 if (! have_title && 0 == memcmp(s, title, title_length)) {
72 chunk_length -= title_length;
73 have_title = malloc(chunk_length + 1);
74 memcpy(have_title, s, chunk_length);
75 have_title[chunk_length] = 0;
80 unsigned long chunk_crc =
INT;
81 if ((chunk_data_crc & 0xFFffFFff) != (chunk_crc & 0xFFffFFff)) {
85 if (have_mightymandel && have_title) {
89 int len = strlen(have_title) + 1;
90 char *sx = malloc(len); sx[0] = 0;
91 char *sy = malloc(len); sy[0] = 0;
92 char *sz = malloc(len); sz[0] = 0;
94 if (3 == sscanf(have_title,
"%s + %s i @ %s", sx, sy, sz)) {
98 mpfr_set_prec(cz, 53);
99 mpfr_set_str(cz, sz, 10, MPFR_RNDN);
102 mpfr_set_prec(cx, p);
103 mpfr_set_prec(cy, p);
104 mpfr_set_str(cx, sx, 10, MPFR_RNDN);
105 mpfr_set_str(cy, sy, 10, MPFR_RNDN);