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