source: vital-to8-sdk/gfx-tools/extract_sprite_chunky.c @ 2

Last change on this file since 2 was 1, checked in by svn, 6 years ago

Import initial

File size: 8.6 KB
RevLine 
[1]1#include "stdio.h"
2#include "stdlib.h"
3#include "math.h"
4
5/*
6
7        raw font converter from TGA image type 2 and 10
8
9*/
10
11typedef struct {
12   char  idlength;
13   char  colourmaptype;
14   char  datatypecode;
15   short int colourmaporigin;
16   short int colourmaplength;
17   char  colourmapdepth;
18   short int x_origin;
19   short int y_origin;
20   short width;
21   short height;
22   char  bitsperpixel;
23   char  imagedescriptor;
24} HEADER;
25
26typedef struct {
27   unsigned char r,g,b,a;
28} PIXEL;
29
30void MergeBytes(PIXEL *,unsigned char *,int);
31
32int main(int argc,char **argv)
33{
34   int n=0,i,j;
35   int bytes2read,skipover = 0;
36   unsigned char p[5];
37   FILE *fptr;
38   HEADER header;
39   PIXEL *pixels;
40
41   if (argc < 2) {
42      fprintf(stderr,"Usage: %s tgafile\n",argv[0]);
43      exit(-1);
44   }
45
46   /* Open the file */
47   if ((fptr = fopen(argv[1],"r")) == NULL) {
48      fprintf(stderr,"File open failed\n");
49      exit(-1);
50   }
51
52   /* Display the header fields */
53   header.idlength = fgetc(fptr);
54   fprintf(stderr,"ID length:         %d\n",header.idlength);
55   header.colourmaptype = fgetc(fptr);
56   fprintf(stderr,"Colourmap type:    %d\n",header.colourmaptype);
57   header.datatypecode = fgetc(fptr);
58   fprintf(stderr,"Image type:        %d\n",header.datatypecode);
59   fread(&header.colourmaporigin,2,1,fptr);
60   fprintf(stderr,"Colour map offset: %d\n",header.colourmaporigin);
61   fread(&header.colourmaplength,2,1,fptr);
62   fprintf(stderr,"Colour map length: %d\n",header.colourmaplength);
63   header.colourmapdepth = fgetc(fptr);
64   fprintf(stderr,"Colour map depth:  %d\n",header.colourmapdepth);
65   fread(&header.x_origin,2,1,fptr);
66   fprintf(stderr,"X origin:          %d\n",header.x_origin);
67   fread(&header.y_origin,2,1,fptr);
68   fprintf(stderr,"Y origin:          %d\n",header.y_origin);
69   fread(&header.width,2,1,fptr);
70   fprintf(stderr,"Width:             %d\n",header.width);
71   fread(&header.height,2,1,fptr);
72   fprintf(stderr,"Height:            %d\n",header.height);
73   header.bitsperpixel = fgetc(fptr);
74   fprintf(stderr,"Bits per pixel:    %d\n",header.bitsperpixel);
75   header.imagedescriptor = fgetc(fptr);
76   fprintf(stderr,"Descriptor:        %d\n",header.imagedescriptor);
77
78   /* Allocate space for the image */
79   if ((pixels = malloc(header.width*header.height*sizeof(PIXEL))) == NULL) {
80      fprintf(stderr,"malloc of image failed\n");
81      exit(-1);
82   }
83   for (i=0;i<header.width*header.height;i++) {
84      pixels[i].r = 0;
85      pixels[i].g = 0;
86      pixels[i].b = 0;
87      pixels[i].a = 0;
88   }
89
90   /* What can we handle */
91   if (header.datatypecode != 2 && header.datatypecode != 10) {
92      fprintf(stderr,"Can only handle image type 2 and 10\n");
93      exit(-1);
94   }
95   if (header.bitsperpixel != 16 &&
96       header.bitsperpixel != 24 && header.bitsperpixel != 32) {
97      fprintf(stderr,"Can only handle pixel depths of 16, 24, and 32\n");
98      exit(-1);
99   }
100   if (header.colourmaptype != 0 && header.colourmaptype != 1) {
101      fprintf(stderr,"Can only handle colour map types of 0 and 1\n");
102      exit(-1);
103   }
104
105   /* Skip over unnecessary stuff */
106   skipover += header.idlength;
107   skipover += header.colourmaptype * header.colourmaplength;
108   fprintf(stderr,"Skip over %d bytes\n",skipover);
109   fseek(fptr,skipover,SEEK_CUR);
110
111   /* Read the image */
112   bytes2read = header.bitsperpixel / 8;
113   while (n < header.width * header.height) {
114      if (header.datatypecode == 2) {                     /* Uncompressed */
115         if (fread(p,1,bytes2read,fptr) != bytes2read) {
116            fprintf(stderr,"Unexpected end of file at pixel %d\n",i);
117            exit(-1);
118         }
119         MergeBytes(&(pixels[n]),p,bytes2read);
120         n++;
121      } else if (header.datatypecode == 10) {             /* Compressed */
122         if (fread(p,1,bytes2read+1,fptr) != bytes2read+1) {
123            fprintf(stderr,"Unexpected end of file at pixel %d\n",i);
124            exit(-1);
125         }
126         j = p[0] & 0x7f;
127         MergeBytes(&(pixels[n]),&(p[1]),bytes2read);
128         n++;
129         if (p[0] & 0x80) {         /* RLE chunk */
130            for (i=0;i<j;i++) {
131               MergeBytes(&(pixels[n]),&(p[1]),bytes2read);
132               n++;
133            }
134         } else {                   /* Normal chunk */
135            for (i=0;i<j;i++) {
136               if (fread(p,1,bytes2read,fptr) != bytes2read) {
137                  fprintf(stderr,"Unexpected end of file at pixel %d\n",i);
138                  exit(-1);
139               }
140               MergeBytes(&(pixels[n]),p,bytes2read);
141               n++;
142            }
143         }
144      }
145   }
146   fclose(fptr);
147
148   fprintf(stderr,"[INFO] now in vm part ;) \n");
149   /* now count colors used */
150   int palette_24b[256];
151   int palette_to[16];
152   int col_num=1;
153   int val;
154   palette_24b[0]=(pixels[0].b<<16)|(pixels[0].g<<8)|(pixels[0].r);
155   for (i=1;i<header.height*header.width;i++) {
156      val=(pixels[i].b<<16)|(pixels[i].g<<8)|(pixels[i].r);
157      // does this color exists in palette     
158      for (j=0;j<col_num;j++) {
159        if (palette_24b[j]==val) break;
160      }
161      if (j==col_num) {
162         if (col_num==255) {
163            col_num=256;
164            fprintf(stderr,"[ERROR] too many colors (+256) !!!\n");
165            exit(-1);
166         }
167         palette_24b[col_num]=val;
168         col_num++;
169      }
170   }
171   fprintf(stderr,"[INFO] Number of unique colors %d\n",col_num);
172
173   if (col_num>16) {
174            fprintf(stderr,"[ERROR] too many colors %d\n",col_num);
175            exit(-1);
176   }
177
178   for (i=0;i<16;i++) palette_to[i]=0;
179
180
181   for (i=0;i<col_num;i++) {
182        palette_to[i]=pal_conv((palette_24b[i]&0xFF0000)>>16)<<8;
183        palette_to[i]|=pal_conv((palette_24b[i]&0xFF00)>>8)<<4;
184        palette_to[i]|=pal_conv((palette_24b[i]&0xFF));
185        fprintf(stderr,"[INFO] palette[%d]=%03x\n",i,palette_to[i]);
186   }
187
188
189   /* ouput in 2 files raw data 8kb each (palette at end) */
190   FILE *COL;
191   FILE *PT;
192   FILE *SPRITE;
193
194   COL=fopen("COL.BIN","wb");
195   PT=fopen("PT.BIN","wb");
196   SPRITE=fopen("SPRITE.BIN","wb");
197
198   // on modifie les pixels 2 par 2
199   for (i=0;i<header.height*header.width;i++) {
200      int mem;
201      val=(pixels[i].b<<16)|(pixels[i].g<<8)|(pixels[i].r);
202      // on retrouve l'index dans la palette dans j
203      for (j=0;j<16;j++) {
204        if (val==palette_24b[j]) break;
205      }
206      switch (i%4) {
207      case 0 : mem=j<<4;
208        break;
209      case 1 : fputc(mem|j,PT);
210        break;
211      case 2 : mem=j<<4;
212        break;
213      case 3 : fputc(mem|j,COL);
214        break;
215      }
216   }
217   for (i=0;i<16;i++) {
218        fputc((palette_to[i]&0xFF00)>>8,PT);
219        fputc((palette_to[i]&0xFF),PT);
220        fputc((palette_to[i]&0xFF00)>>8,COL);
221        fputc((palette_to[i]&0xFF),COL);
222   }
223
224   fclose(PT);
225   fclose(COL);
226   
227   int x,y;
228   
229   for (y=0;y<64;y++) {
230       for (x=0;x<64;x++) {
231          i=header.width*y+x;
232          val=(pixels[i].b<<16)|(pixels[i].g<<8)|(pixels[i].r);
233          // on retrouve l'index dans la palette dans j
234          for (j=0;j<16;j++) {
235            if (val==palette_24b[j]) break;
236          }
237          if (j>15) j=0;
238          fputc(j,SPRITE);
239       }
240   }
241   fclose (SPRITE);
242}
243
244int
245pal_conv(int v) {
246   int i;
247   /* convert palette to thomson gamma factor */
248//   static int gamma[16]={0,100,127,147,163,179,191,203,215,223,231,239,243,247,251,255};
249   static int seuils[17]={0,50,114,137,155,171,185,197,209,219,227,235,241,245,249,253,257};
250   for (i=0;i<16;i++) {
251      if (v<seuils[i+1]) break;
252   }
253   return i;
254}
255
256
257void
258output_tga(HEADER header,PIXEL *pixels) {
259   FILE *fptr;
260   int i;
261   /* Write the result as a uncompressed TGA */
262   if ((fptr = fopen("tgatest.tga","w")) == NULL) {
263      fprintf(stderr,"Failed to open outputfile\n");
264      exit(-1);
265   }
266   putc(0,fptr);
267   putc(0,fptr);
268   putc(2,fptr);                         /* uncompressed RGB */
269   putc(0,fptr); putc(0,fptr);
270   putc(0,fptr); putc(0,fptr);
271   putc(0,fptr);
272   putc(0,fptr); putc(0,fptr);           /* X origin */
273   putc(0,fptr); putc(0,fptr);           /* y origin */
274   putc((header.width & 0x00FF),fptr);
275   putc((header.width & 0xFF00) / 256,fptr);
276   putc((header.height & 0x00FF),fptr);
277   putc((header.height & 0xFF00) / 256,fptr);
278   putc(32,fptr);                        /* 24 bit bitmap */
279   putc(0,fptr);
280   for (i=0;i<header.height*header.width;i++) {
281      putc(pixels[i].b,fptr);
282      putc(pixels[i].g,fptr);
283      putc(pixels[i].r,fptr);
284      putc(pixels[i].a,fptr);
285   }
286   fclose(fptr);
287}
288
289void MergeBytes(PIXEL *pixel,unsigned char *p,int bytes)
290{
291   if (bytes == 4) {
292      pixel->r = p[2];
293      pixel->g = p[1];
294      pixel->b = p[0];
295      pixel->a = p[3];
296   } else if (bytes == 3) {
297      pixel->r = p[2];
298      pixel->g = p[1];
299      pixel->b = p[0];
300      pixel->a = 0;
301   } else if (bytes == 2) {
302      pixel->r = (p[1] & 0x7c) << 1;
303      pixel->g = ((p[1] & 0x03) << 6) | ((p[0] & 0xe0) >> 2);
304      pixel->b = (p[0] & 0x1f) << 3;
305      pixel->a = (p[1] & 0x80);
306   }
307}
308
Note: See TracBrowser for help on using the repository browser.