1 | /* GFX2mo5 - png2mo5.c
|
---|
2 | * CloudStrife - 20080921
|
---|
3 | * PulkoMandy - 2012-2014
|
---|
4 | * Diffusé sous licence libre CeCILL v2
|
---|
5 | * Voir LICENCE
|
---|
6 | */
|
---|
7 |
|
---|
8 | #include <getopt.h>
|
---|
9 | #include <stdio.h>
|
---|
10 | #include <stdlib.h>
|
---|
11 | #include <time.h>
|
---|
12 | #include <png.h>
|
---|
13 | #include "libraw2mo5.h"
|
---|
14 |
|
---|
15 | #include <assert.h>
|
---|
16 |
|
---|
17 | #define ERROR 1
|
---|
18 |
|
---|
19 | int main(int argc, char **argv)
|
---|
20 | {
|
---|
21 | FILE *inFile, *outFile;
|
---|
22 | unsigned char *inBuffer, *outBuffer;
|
---|
23 |
|
---|
24 | png_uint_32 width;
|
---|
25 | png_uint_32 height;
|
---|
26 | int bitdepth;
|
---|
27 | int colorType;
|
---|
28 |
|
---|
29 | unsigned char header[8];
|
---|
30 | unsigned char is_png;
|
---|
31 |
|
---|
32 | unsigned int y;
|
---|
33 | png_structp png_ptr;
|
---|
34 | png_infop info_ptr;
|
---|
35 | png_infop end_info;
|
---|
36 |
|
---|
37 | png_bytep * ptrRow;
|
---|
38 | int pxsize;
|
---|
39 |
|
---|
40 | char opt;
|
---|
41 | int fixup = -1;
|
---|
42 | bool to = false;
|
---|
43 |
|
---|
44 | unsigned char thomheader[] = {
|
---|
45 | // Block 1 : address A7C0, 1 byte, select FORME
|
---|
46 | 0x00, 0x00, 0x01, 0xA7, 0xC0, 0x51,
|
---|
47 | // Block 2 : address 0000, 1F40 bytes, FORME data
|
---|
48 | 0x00, 0x1F, 0x40, 0x00, 0x00
|
---|
49 | };
|
---|
50 |
|
---|
51 |
|
---|
52 | // End marker block : type=255, size and address=0
|
---|
53 | const unsigned char end[]={255,0,0,0,0};
|
---|
54 |
|
---|
55 | if(argc < 3)
|
---|
56 | {
|
---|
57 | printf("Utilisation : %s [options] input_filename output_filename\n",argv[0]);
|
---|
58 | printf("Option -t: use TO transcoding.\n");
|
---|
59 | printf("Option -f n: use modified algorithm to avoid artifacts on some MO5 gate array versions. n is the index of the background color.\n");
|
---|
60 | exit(0);
|
---|
61 | }
|
---|
62 |
|
---|
63 | while((opt = getopt(argc, argv, "tf:")) != -1) {
|
---|
64 | switch(opt) {
|
---|
65 | case 't':
|
---|
66 | to = true;
|
---|
67 | thomheader[3] = 0xE7;
|
---|
68 | thomheader[4] = 0xC3;
|
---|
69 | thomheader[5] = 0x65;
|
---|
70 | thomheader[9] = 0x40;
|
---|
71 | break;
|
---|
72 | case 'f':
|
---|
73 | fixup = atoi(optarg);
|
---|
74 | break;
|
---|
75 | }
|
---|
76 | }
|
---|
77 |
|
---|
78 | inFile = fopen(argv[optind++],"rb");
|
---|
79 |
|
---|
80 | if (inFile == NULL)
|
---|
81 | {
|
---|
82 | printf("Fichier Inexistant\n");
|
---|
83 | exit(1);
|
---|
84 | }
|
---|
85 |
|
---|
86 | fread(header, 1, 8, inFile);
|
---|
87 | is_png = !png_sig_cmp(header, 0, 8);
|
---|
88 | if (!is_png)
|
---|
89 | {
|
---|
90 | printf("Ce n'est pas un png\n");
|
---|
91 | exit(2);
|
---|
92 | }
|
---|
93 |
|
---|
94 | png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, (png_voidp)NULL, NULL, NULL);
|
---|
95 | if (!png_ptr) return (ERROR);
|
---|
96 |
|
---|
97 | info_ptr = png_create_info_struct(png_ptr);
|
---|
98 | if (!info_ptr)
|
---|
99 | {
|
---|
100 | png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
|
---|
101 | return (ERROR);
|
---|
102 | }
|
---|
103 |
|
---|
104 | end_info = png_create_info_struct(png_ptr);
|
---|
105 | if (!end_info)
|
---|
106 | {
|
---|
107 | png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
|
---|
108 | return (ERROR);
|
---|
109 | }
|
---|
110 |
|
---|
111 | if (setjmp(png_jmpbuf(png_ptr)))
|
---|
112 | {
|
---|
113 | png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
|
---|
114 | fclose(inFile);
|
---|
115 | return (ERROR);
|
---|
116 | }
|
---|
117 |
|
---|
118 | png_init_io(png_ptr, inFile);
|
---|
119 | png_set_sig_bytes(png_ptr, 8);
|
---|
120 |
|
---|
121 | png_read_info(png_ptr, info_ptr);
|
---|
122 |
|
---|
123 | png_get_IHDR(png_ptr, info_ptr, &width, &height, &bitdepth, &colorType, NULL, NULL, NULL);
|
---|
124 |
|
---|
125 | if(!((colorType == PNG_COLOR_TYPE_GRAY) || (colorType == PNG_COLOR_TYPE_PALETTE)))
|
---|
126 | {
|
---|
127 | puts("Ce PNG n'est pas dans un format exploitable (niveaux de gris ou palette)");
|
---|
128 | return (ERROR);
|
---|
129 | }
|
---|
130 |
|
---|
131 | if (bitdepth > 8)
|
---|
132 | {
|
---|
133 | puts("Ce PNG n'est pas dans un format exploitable (bitdepth = 1, 2 ou 4)");
|
---|
134 | return (ERROR);
|
---|
135 | }
|
---|
136 |
|
---|
137 | png_set_packing(png_ptr); /* Convertir en mode 1 pixel par octets */
|
---|
138 | png_read_update_info(png_ptr, info_ptr);
|
---|
139 |
|
---|
140 | inBuffer = (unsigned char*)malloc(width*height);
|
---|
141 | if (inBuffer == NULL)
|
---|
142 | {
|
---|
143 | printf("Allocation inBuffer raté\n");
|
---|
144 | exit(3);
|
---|
145 | }
|
---|
146 |
|
---|
147 | ptrRow = (png_bytep*)malloc(sizeof(png_bytep)*height);
|
---|
148 | for(y = 0; y < height; y++)
|
---|
149 | {
|
---|
150 | ptrRow[y] = (inBuffer + width*y);
|
---|
151 | }
|
---|
152 |
|
---|
153 | png_read_image(png_ptr, ptrRow);
|
---|
154 |
|
---|
155 | outBuffer = raw2mo5(inBuffer, height, fixup, to);
|
---|
156 |
|
---|
157 | pxsize = width * height / 8;
|
---|
158 | thomheader[7] = pxsize >> 8;
|
---|
159 | thomheader[8] = pxsize;
|
---|
160 |
|
---|
161 | outFile = fopen(argv[optind++], "wb");
|
---|
162 | fwrite(thomheader, 1, sizeof(thomheader), outFile);
|
---|
163 | //write forme data
|
---|
164 | fwrite(outBuffer, 1, pxsize, outFile);
|
---|
165 | --thomheader[5];
|
---|
166 | fwrite(thomheader, 1, sizeof(thomheader), outFile);
|
---|
167 | // write color data
|
---|
168 | fwrite(outBuffer+0x2000, 1, pxsize, outFile);
|
---|
169 | fwrite(end, 1, sizeof(end), outFile);
|
---|
170 |
|
---|
171 |
|
---|
172 | fclose(outFile);
|
---|
173 |
|
---|
174 | png_read_end(png_ptr, end_info);
|
---|
175 | png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
|
---|
176 |
|
---|
177 | free(inBuffer);
|
---|
178 | inBuffer = NULL;
|
---|
179 |
|
---|
180 | free(outBuffer);
|
---|
181 | outBuffer = NULL;
|
---|
182 |
|
---|
183 | return 0;
|
---|
184 | }
|
---|