1 module kodachrome.png; 2 import std.stdio; 3 import std.algorithm.mutation; 4 import std.string; 5 import x11.X; 6 import x11.Xlib; 7 import kodachrome.x; 8 9 /+ 10 + This part needs to be spun off into its own library. 11 +/ 12 extern(C): 13 alias png_byte = char; 14 alias png_bytep = png_byte*; 15 alias png_const_bytep = const(png_byte)*; 16 17 alias png_charp = char*; 18 alias png_const_charp = const(char)*; 19 alias png_voidp = void*; 20 21 struct png_struct; 22 alias png_structp = png_struct*; 23 alias png_structpp = png_struct**; 24 alias png_structrp = png_structp; 25 alias png_const_structp = const(png_struct)*; 26 alias png_const_structrp = png_const_structp; 27 28 struct png_info; 29 alias png_infop = png_info*; 30 alias png_infopp = png_info**; 31 alias png_inforp = png_infop; 32 alias png_const_infop = const(png_info)*; 33 alias png_const_inforp = png_const_infop; 34 35 png_infop png_create_info_struct(png_const_structrp); 36 37 alias png_error_ptr = void function(png_structp, png_const_charp); 38 39 void png_destroy_write_struct(png_structpp, png_infopp); 40 41 enum PNG_LIBPNG_VER_STRING = "1.6.37"; 42 43 png_structp png_create_write_struct(png_const_charp, png_voidp, 44 png_error_ptr, png_error_ptr); 45 46 alias png_FILE_p = FILE*; 47 48 void png_init_io(png_structrp, png_FILE_p); 49 50 void png_set_IHDR(png_const_structrp, png_inforp, png_uint_32, png_uint_32, 51 int, int, int, int, int); 52 53 alias png_uint_32 = uint; 54 55 struct png_text 56 { 57 int compression; 58 png_charp key; 59 png_charp text; 60 size_t text_length; 61 size_t itxt_length; 62 png_charp lang; 63 png_charp lang_key; 64 } 65 66 alias png_const_textp = const(png_text)*; 67 68 void png_set_text(png_const_structrp, png_inforp, png_const_textp, int); 69 70 void png_write_info(png_structrp, png_const_inforp); 71 72 void png_write_row(png_structrp, png_const_bytep); 73 74 void png_write_end(png_structrp, png_inforp); 75 76 void png_free_data(png_const_structrp, png_inforp, png_uint_32, int); 77 78 enum PNG_COLOR_MASK_COLOR = 2; 79 enum PNG_COLOR_MASK_ALPHA = 4; 80 enum PNG_COLOR_TYPE_RGB_ALPHA = PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_ALPHA; 81 82 enum PNG_INTERLACE_NONE = 0; 83 84 enum PNG_COMPRESSION_TYPE_BASE = 0; 85 86 enum PNG_FILTER_TYPE_BASE = 0; 87 88 enum PNG_TEXT_COMPRESSION_NONE = -1; 89 90 enum PNG_FREE_ALL = 0xffffU; 91 92 /+ 93 + This stays. 94 +/ 95 extern(D): 96 bool createPNG(string name, XImage* ximg) 97 { 98 png_text title_text; 99 100 png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 101 null, null, null); 102 if (png_ptr == null) { 103 stderr.writeln("kodachrome: Could not create PNG write struct"); 104 return false; 105 } 106 107 png_infop info_ptr = png_create_info_struct(png_ptr); 108 if (info_ptr == null) { 109 stderr.writeln("kodachrome: Could not create PNG info struct"); 110 png_destroy_write_struct(&png_ptr, null); 111 return false; 112 } 113 114 string nameWithExt = name ~ ".png"; 115 File f = File(nameWithExt, "w"); 116 117 png_init_io(png_ptr, f.getFP()); 118 119 png_set_IHDR(png_ptr, info_ptr, ximg.width, ximg.height, 8, 120 PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE, 121 PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); 122 123 title_text.compression = PNG_TEXT_COMPRESSION_NONE; 124 title_text.key = cast(char*)toStringz("Title"); 125 title_text.text = cast(char*)toStringz(name); 126 png_set_text(png_ptr, info_ptr, &title_text, 1); 127 128 png_write_info(png_ptr, info_ptr); 129 130 char* row = ximg.data; 131 for (int i = 0; i < ximg.height; i++) { 132 if (ximg.bitmap_bit_order == LSBFirst) { 133 for (int idx = 0; idx < ximg.chars_per_line; idx += 4) { 134 swap(row[idx], row[idx + 2]); 135 row[idx + 3] = 255; 136 } 137 } else { 138 for (int idx = 0; idx < ximg.chars_per_line; idx += 4) { 139 ubyte t1 = row[idx + 1]; 140 ubyte t2 = row[idx + 2]; 141 ubyte t3 = row[idx + 3]; 142 143 row[idx] = t1; 144 row[idx + 1] = t2; 145 row[idx + 2] = t3; 146 row[idx + 3] = 255; 147 } 148 } 149 150 png_write_row(png_ptr, row); 151 row += ximg.chars_per_line; 152 } 153 png_write_end(png_ptr, null); 154 155 f.close(); 156 157 png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1); 158 png_destroy_write_struct(&png_ptr, null); 159 160 return true; 161 }