mightymandel v16

GPU-based Mandelbrot set explorer

png.c
Go to the documentation of this file.
1 // mightymandel -- GPU-based Mandelbrot Set explorer
2 // Copyright (C) 2012,2013,2014,2015 Claude Heiland-Allen
3 // License GPL3+ http://www.gnu.org/licenses/gpl.html
4 
5 #include <assert.h>
6 #include <stdbool.h>
7 #include <string.h>
8 
9 #include "crc.h"
10 #include "png.h"
11 
12 int png_iTXt_length(const char *keyword, const char *text) {
13  int keyword_length = strlen(keyword);
14  int text_length = strlen(text);
15  int data_length = keyword_length + 5 + text_length;
16  int chunk_length = 8 + data_length + 4;
17  return chunk_length;
18 }
19 
20 bool png_iTXt(const char *keyword, const char *text, unsigned char *chunk, int length) {
21 #define INT(l) { l >> 24 & 0xff, l >> 16 & 0xff, l >> 8 & 0xff, l & 0xff }
22  int keyword_length = strlen(keyword);
23  int text_length = strlen(text);
24  int data_length = keyword_length + 5 + text_length;
25  int chunk_length = 8 + data_length + 4;
26  if (length < chunk_length) {
27  return false;
28  }
29  int k = 0;
30  unsigned char len[4] = INT(data_length);
31  chunk[k++] = len[0]; // chunk length
32  chunk[k++] = len[1];
33  chunk[k++] = len[2];
34  chunk[k++] = len[3];
35  const unsigned char iTXt[4] = { 105, 84, 88, 116 };
36  chunk[k++] = iTXt[0]; // chunk type
37  chunk[k++] = iTXt[1];
38  chunk[k++] = iTXt[2];
39  chunk[k++] = iTXt[3]; // chunk data
40  memcpy(chunk + k, keyword, keyword_length); // keyword
41  k += keyword_length;
42  chunk[k++] = 0; // null separator
43  chunk[k++] = 0; // compression flag
44  chunk[k++] = 0; // compression method
45  // language tag
46  chunk[k++] = 0; // null separator
47  // translated keyword
48  chunk[k++] = 0; // null separator
49  memcpy(chunk + k, text, text_length); // text
50  k += text_length;
51  unsigned long crc_data = crc(chunk + 4, data_length + 4);
52  unsigned char cyclic[4] = INT(crc_data);
53  chunk[k++] = cyclic[0]; // chunk CRC
54  chunk[k++] = cyclic[1];
55  chunk[k++] = cyclic[2];
56  chunk[k++] = cyclic[3];
57  assert(k == chunk_length);
58  return true;
59 }