Eeek! last minute error.
[blender.git] / source / blender / imbuf / intern / targa.c
1 /**
2  *
3  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version. The Blender
9  * Foundation also sells licenses for use in proprietary software under
10  * the Blender License.  See http://www.blender.org/BL/ for information
11  * about this.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software Foundation,
20  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21  *
22  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
23  * All rights reserved.
24  *
25  * The Original Code is: all of this file.
26  *
27  * Contributor(s): none yet.
28  *
29  * ***** END GPL/BL DUAL LICENSE BLOCK *****
30  * $Id$
31  */
32
33 #ifdef WIN32
34 #include "BLI_winstuff.h"
35 #include <io.h>
36 #endif
37 #include "BLI_blenlib.h"
38
39 #include "imbuf.h"
40 #include "imbuf_patch.h"
41
42 #include "IMB_imbuf_types.h"
43 #include "IMB_imbuf.h"
44
45 #include "IMB_allocimbuf.h"
46 #include "IMB_cmap.h"
47 #include "IMB_targa.h"
48
49
50 /* this one is only def-ed once, strangely... related to GS? */
51 #define GSS(x) (((uchar *)(x))[1] << 8 | ((uchar *)(x))[0])
52
53 /***/
54
55 typedef struct TARGA 
56 {
57         unsigned char numid;    
58         unsigned char maptyp;
59         unsigned char imgtyp;   
60         short maporig;
61         short mapsize;
62         unsigned char mapbits;
63         short xorig;
64         short yorig;
65         short xsize;
66         short ysize;
67         unsigned char pixsize;
68         unsigned char imgdes;
69 } TARGA;
70
71 /***/
72
73 static int tga_out1(unsigned int data, FILE *file)
74 {
75         uchar *p;
76
77         p = (uchar *) & data;
78         if (putc(p[0],file) == EOF) return(EOF);
79         return (~EOF);
80 }
81
82 static int tga_out2(unsigned int data, FILE * file)
83 {
84         uchar *p;
85
86         p = (uchar *) & data;
87         if (putc(p[0],file) == EOF) return(EOF);
88         if (putc(p[1],file) == EOF) return(EOF);
89         return (~EOF);
90 }
91
92
93 static int tga_out3(unsigned int data, FILE * file)
94 {
95         uchar *p;
96
97         p = (uchar *) & data;
98         if (putc(p[2],file) == EOF) return(EOF);
99         if (putc(p[1],file) == EOF) return(EOF);
100         if (putc(p[0],file) == EOF) return(EOF);
101         return (~EOF);
102 }
103
104
105 static int tga_out4(unsigned int data, FILE * file)
106 {
107         uchar *p;
108
109         p = (uchar *) & data;
110         /* order = bgra */
111         if (putc(p[2],file) == EOF) return(EOF);
112         if (putc(p[1],file) == EOF) return(EOF);
113         if (putc(p[0],file) == EOF) return(EOF);
114         if (putc(p[3],file) == EOF) return(EOF);
115         return (~EOF);
116 }
117
118 static short makebody_tga(ImBuf * ibuf, FILE * file, int (*out)(unsigned int, FILE*))
119 {
120         register int last,this;
121         register int copy, bytes;
122         register unsigned int *rect, *rectstart, *temp;
123         int y;
124         
125         for (y = 0; y < ibuf->y; y++) {
126                 bytes = ibuf->x - 1;
127                 rectstart = rect = ibuf->rect + (y * ibuf->x);
128                 last = *rect++;
129                 this = *rect++;
130                 copy = last^this;
131                 while (bytes > 0){
132                         if (copy){
133                                 do{
134                                         last = this;
135                                         this = *rect++;
136                                         if (last == this){
137                                                 if (this == rect[-3]){  /* three the same? */
138                                                         bytes --;               /* set bytes */
139                                                         break;
140                                                 }
141                                         }
142                                 }while (--bytes != 0);
143
144                                 copy = rect-rectstart;
145                                 copy --;
146                                 if (bytes) copy -= 2;
147
148                                 temp = rect;
149                                 rect = rectstart;
150
151                                 while (copy){
152                                         last = copy;
153                                         if (copy>=128) last = 128;
154                                         copy -= last;
155                                         if (fputc(last-1,file) == EOF) return(0);
156                                         do{
157                                                 if (out(*rect++,file) == EOF) return(0);
158                                         }while(--last != 0);
159                                 }
160                                 rectstart = rect;
161                                 rect = temp;
162                                 last = this;
163
164                                 copy = FALSE;
165                         } else {
166                                 while (*rect++ == this){                /* seek for first different byte */
167                                         if (--bytes == 0) break;        /* oor end of line */
168                                 }
169                                 rect --;
170                                 copy = rect-rectstart;
171                                 rectstart = rect;
172                                 bytes --;
173                                 this = *rect++;
174
175                                 while (copy){
176                                         if (copy>128){
177                                                 if (fputc(255,file) == EOF) return(0);
178                                                 copy -= 128;
179                                         } else {
180                                                 if (copy == 1){
181                                                         if (fputc(0,file) == EOF) return(0);
182                                                 } else if (fputc(127 + copy,file) == EOF) return(0);
183                                                 copy = 0;
184                                         }
185                                         if (out(last,file) == EOF) return(0);
186                                 }
187                                 copy=TRUE;
188                         }
189                 }
190         }
191         return (1);
192 }
193
194 static int dumptarga(struct ImBuf * ibuf, FILE * file)
195 {
196         int size;
197         uchar *rect;
198
199         if (ibuf == 0) return (0);
200         if (ibuf->rect == 0) return (0);
201
202         size = ibuf->x * ibuf->y;
203         rect = (uchar *) ibuf->rect;
204
205         if (ibuf->depth <= 8) {
206                 while(size > 0){
207                         if (putc(*rect, file) == EOF) return (0);
208                         size--;
209                         rect += 4;
210                 }
211         } else if (ibuf->depth <= 16) {
212                 while(size > 0){
213                         putc(rect[0], file);
214                         if (putc(rect[1], file) == EOF) return (0);
215                         size--;
216                         rect += 4;
217                 }
218         } else if (ibuf->depth <= 24) {
219                 while(size > 0){
220                         putc(rect[2], file);
221                         putc(rect[1], file);
222                         if (putc(rect[0], file) == EOF) return (0);
223                         size--;
224                         rect += 4;
225                 }
226         } else if (ibuf->depth <= 32) {
227                 while(size > 0){
228                         putc(rect[2], file);
229                         putc(rect[1], file);
230                         putc(rect[0], file);
231                         if (putc(rect[3], file) == EOF) return (0);
232                         size--;
233                         rect += 4;
234                 }
235         } else return (0);
236         
237         return (1);
238 }
239
240
241 short imb_savetarga(struct ImBuf * ibuf, char *name, int flags)
242 {
243         char buf[20];
244         FILE *fildes;
245         int i;
246         short ok = 0;
247
248         if (ibuf == 0) return (0);
249         if (ibuf->rect == 0) return (0);
250
251         memset(buf,0,sizeof(buf));
252
253         /* buf[0] = 0;  length string */
254
255         buf[16] = (ibuf->depth + 0x7 ) & ~0x7;
256         if (ibuf->cmap) {
257                 buf[1] = 1;
258                 buf[2] = 9;
259                 buf[3] = ibuf->mincol & 0xff;
260                 buf[4] = ibuf->mincol >> 8;
261                 buf[5] = ibuf->maxcol & 0xff;
262                 buf[6] = ibuf->maxcol >> 8;
263                 buf[7] = 24;
264                 if ((flags & IB_ttob) == 0) {
265                         IMB_flipy(ibuf);
266                         buf[17] = 0x20;
267                 }
268         } else if (ibuf->depth > 8 ){
269                 buf[2] = 10;
270         } else{
271                 buf[2] = 11;
272         }
273
274         if (ibuf->ftype == RAWTGA) buf[2] &= ~8;
275         
276         buf[8] = ibuf->xorig & 0xff;
277         buf[9] = ibuf->xorig >> 8;
278         buf[10] = ibuf->yorig & 0xff;
279         buf[11] = ibuf->yorig >> 8;
280
281         buf[12] = ibuf->x & 0xff;
282         buf[13] = ibuf->x >> 8;
283         buf[14] = ibuf->y & 0xff;
284         buf[15] = ibuf->y >> 8;
285
286         if (flags & IB_ttob) buf[17] ^= 0x20;
287
288         /* Don't forget to indicate that your 32 bit
289          * targa uses 8 bits for the alpha channel! */
290         if (ibuf->depth==32) {
291            buf[17] |= 0x08;
292         }
293         fildes = fopen(name,"wb");
294         
295
296         if (fwrite(buf, 1, 18,fildes) != 18) return (0);
297
298         if (ibuf->cmap){
299                 for (i = 0 ; i<ibuf->maxcol ; i++){
300                         if (fwrite(((uchar *)(ibuf->cmap + i)) + 1,1,3,fildes) != 3) return (0);
301                 }
302         }
303         
304         if (ibuf->cmap && (flags & IB_cmap) == 0) IMB_converttocmap(ibuf);
305         
306         if (ibuf->ftype == RAWTGA) {
307                 ok = dumptarga(ibuf, fildes);
308         } else {                
309                 switch((ibuf->depth + 7) >> 3){
310                 case 1:
311                         ok = makebody_tga(ibuf, fildes, tga_out1);
312                         break;
313                 case 2:
314                         ok = makebody_tga(ibuf, fildes, tga_out2);
315                         break;
316                 case 3:
317                         ok = makebody_tga(ibuf, fildes, tga_out3);
318                         break;
319                 case 4:
320                         ok = makebody_tga(ibuf, fildes, tga_out4);
321                         break;
322                 }
323         }
324         
325         fclose(fildes);
326         return (ok);
327 }
328
329
330 static int checktarga(TARGA *tga, unsigned char *mem)
331 {
332         tga->numid = mem[0];
333         tga->maptyp = mem[1];
334         tga->imgtyp = mem[2];
335
336         tga->maporig = GSS(mem+3);
337         tga->mapsize = GSS(mem+5);
338         tga->mapbits = mem[7];
339         tga->xorig = GSS(mem+8);
340         tga->yorig = GSS(mem+10);
341         tga->xsize = GSS(mem+12);
342         tga->ysize = GSS(mem+14);
343         tga->pixsize = mem[16];
344         tga->imgdes = mem[17];
345
346         if (tga->maptyp > 1) return(0);
347         switch (tga->imgtyp){
348         case 1:                 /* raw cmap */
349         case 2:                 /* raw rgb */
350         case 3:                 /* raw b&w */
351         case 9:                 /* cmap */
352         case 10:                        /* rgb */
353         case 11:                        /* b&w */
354                 break;
355         default:
356                 return(0);
357         }
358         if (tga->mapsize && tga->mapbits > 32) return(0);
359         if (tga->xsize <= 0 || tga->xsize >= 8192) return(0);
360         if (tga->ysize <= 0 || tga->ysize >= 8192) return(0);
361         if (tga->pixsize > 32) return(0);
362         if (tga->pixsize == 0) return(0);
363         return(1);
364 }
365
366 int imb_is_a_targa(void *buf) {
367         TARGA tga;
368         
369         return checktarga(&tga, buf);
370 }
371
372 static void decodetarga(struct ImBuf *ibuf, unsigned char *mem, int psize)
373 {
374         int count, col, size;
375         unsigned int *rect;
376         uchar * cp = (uchar *) &col;
377         
378         if (ibuf == 0) return;
379         if (ibuf->rect == 0) return;
380
381         size = ibuf->x * ibuf->y;
382         rect = ibuf->rect;
383         
384         /* set alpha */
385         cp[0] = 0xff;
386         cp[1] = cp[2] = 0;
387         
388         while(size > 0){
389                 count = *mem++;
390                 if (count >= 128) {
391                         /*if (count == 128) printf("TARGA: 128 in file !\n");*/
392                         count -= 127;
393
394                         if (psize & 2){
395                                 if (psize & 1){
396                                         /* order = bgra */
397                                         cp[0] = mem[3];
398                                         cp[1] = mem[0];
399                                         cp[2] = mem[1];
400                                         cp[3] = mem[2];
401                                         /*col = (mem[3] << 24) + (mem[0] << 16) + (mem[1] << 8) + mem[2];*/
402                                         mem += 4;
403                                 } else{
404                                         cp[1] = mem[0];
405                                         cp[2] = mem[1];
406                                         cp[3] = mem[2];
407                                         /*col = 0xff000000 + (mem[0] << 16) + (mem[1] << 8) + mem[2];*/
408                                         mem += 3;
409                                 }
410                         } else{
411                                 if (psize & 1){
412                                         col = (mem[0] << 8) + mem[1];
413                                         mem += 2;
414                                 } else{
415                                         col = *mem++;
416                                 }
417                         }
418
419                         size -= count;
420                         if (size >= 0) {
421                                 while (count > 0) {
422                                         *rect++ = col;
423                                         count--;
424                                 }
425                         }
426                 } else{
427                         count ++;
428                         size -= count;
429                         if (size >= 0) {
430                                 while (count > 0){
431                                         if (psize & 2){
432                                                 if (psize & 1){
433                                                         /* order = bgra */
434                                                         cp[0] = mem[3];
435                                                         cp[1] = mem[0];
436                                                         cp[2] = mem[1];
437                                                         cp[3] = mem[2];
438                                                         /*col = (mem[3] << 24) + (mem[0] << 16) + (mem[1] << 8) + mem[2];*/
439                                                         mem += 4;
440                                                 } else{
441                                                         cp[1] = mem[0];
442                                                         cp[2] = mem[1];
443                                                         cp[3] = mem[2];
444                                                         /*col = 0xff000000 + (mem[0] << 16) + (mem[1] << 8) + mem[2];*/
445                                                         mem += 3;
446                                                 }
447                                         } else{
448                                                 if (psize & 1){
449                                                         col = (mem[0] << 8) + mem[1];
450                                                         mem += 2;
451                                                 } else{
452                                                         col = *mem++;
453                                                 }
454                                         }
455                                         *rect++ = col;
456                                         count --;
457                                 }
458                         }
459                 }
460         }
461         if (size) printf("decodetarga: count would overwrite %d pixels\n", -size);
462 }
463
464 static void ldtarga(struct ImBuf * ibuf,unsigned char * mem, int psize)
465 {
466         int col,size;
467         unsigned int *rect;
468         uchar * cp = (uchar *) &col;
469
470         if (ibuf == 0) return;
471         if (ibuf->rect == 0) return;
472
473         size = ibuf->x * ibuf->y;
474         rect = ibuf->rect;
475
476         /* set alpha */
477         cp[0] = 0xff;
478         cp[1] = cp[2] = 0;
479
480         while(size > 0){
481                 if (psize & 2){
482                         if (psize & 1){
483                                 /* order = bgra */
484                                 cp[0] = mem[3];
485                                 cp[1] = mem[0];
486                                 cp[2] = mem[1];
487                                 cp[3] = mem[2];
488                                 /*col = (mem[3] << 24) + (mem[0] << 16) + (mem[1] << 8) + mem[2];*/
489                                 mem += 4;
490                         } else{
491                                 /* set alpha for 24 bits colors */
492                                 cp[1] = mem[0];
493                                 cp[2] = mem[1];
494                                 cp[3] = mem[2];
495                                 /*col = 0xff000000 + (mem[0] << 16) + (mem[1] << 8) + mem[2];*/
496                                 mem += 3;
497                         }
498                 } else{
499                         if (psize & 1){
500                                 col = (mem[1] << 8) + mem[0];
501                                 mem += 2;
502                         } else{
503                                 col = *mem++;
504                         }
505                 }
506                 *rect++ = col;
507                 size--;
508         }
509 }
510
511
512 struct ImBuf *imb_loadtarga(unsigned char *mem, int flags)
513 {
514         TARGA tga;
515         struct ImBuf * ibuf;
516         int col, count, size;
517         unsigned int * rect;
518         uchar * cp = (uchar *) &col;
519         
520         if (checktarga(&tga,mem) == 0) return(0);
521
522         if (flags & IB_test) ibuf = IMB_allocImBuf(tga.xsize,tga.ysize,tga.pixsize,0,0);
523         else ibuf = IMB_allocImBuf(tga.xsize,tga.ysize,(tga.pixsize + 0x7) & ~0x7,1,0);
524
525         if (ibuf == 0) return(0);
526         ibuf->ftype = TGA;
527         ibuf->xorig = tga.xorig;
528         ibuf->yorig = tga.yorig;
529         mem = mem + 18 + tga.numid;
530         
531         cp[0] = 0xff;
532         cp[1] = cp[2] = 0;
533         
534         if (tga.mapsize){
535                 ibuf->mincol = tga.maporig;
536                 ibuf->maxcol = tga.mapsize;
537                 imb_addcmapImBuf(ibuf);
538                 ibuf->cbits = 8;
539                 for (count = 0 ; count < ibuf->maxcol ; count ++) {
540                         switch (tga.mapbits >> 3) {
541                                 case 4:
542                                         cp[0] = mem[3];
543                                         cp[1] = mem[0];
544                                         cp[2] = mem[1];
545                                         cp[3] = mem[2];
546                                         mem += 4;
547                                         break;
548                                 case 3:
549                                         cp[1] = mem[0];
550                                         cp[2] = mem[1];
551                                         cp[3] = mem[2];
552                                         mem += 3;
553                                         break;
554                                 case 2:
555                                         col = (mem[1] << 8) + mem[0];
556                                         mem += 2;
557                                         break;
558                                 case 1:
559                                         col = *mem++;
560                                         break;
561                         }
562                         ibuf->cmap[count] = col;
563                 }
564                 
565                 size = 0;
566                 for (col = ibuf->maxcol - 1; col > 0; col >>= 1) size++;
567                 ibuf->depth = size;
568
569                 if (tga.mapbits != 32) {        /* set alpha bits  */
570                         ibuf->cmap[0] &= BIG_LONG(0x00ffffff);
571                 }
572         }
573         
574         if (flags & IB_test) return (ibuf);
575
576         if (tga.imgtyp != 1 && tga.imgtyp != 9) IMB_freecmapImBuf(ibuf); /* happens sometimes (beuh) */
577
578         switch(tga.imgtyp){
579         case 1:
580         case 2:
581         case 3:
582                 if (tga.pixsize <= 8) ldtarga(ibuf,mem,0);
583                 else if (tga.pixsize <= 16) ldtarga(ibuf,mem,1);
584                 else if (tga.pixsize <= 24) ldtarga(ibuf,mem,2);
585                 else if (tga.pixsize <= 32) ldtarga(ibuf,mem,3);
586                 break;
587         case 9:
588         case 10:
589         case 11:
590                 if (tga.pixsize <= 8) decodetarga(ibuf,mem,0);
591                 else if (tga.pixsize <= 16) decodetarga(ibuf,mem,1);
592                 else if (tga.pixsize <= 24) decodetarga(ibuf,mem,2);
593                 else if (tga.pixsize <= 32) decodetarga(ibuf,mem,3);
594                 break;
595         }
596         
597         if (ibuf->cmap){
598                 if ((flags & IB_cmap) == 0) IMB_applycmap(ibuf);
599         }
600         
601         if (tga.pixsize == 16 && ibuf->cmap == 0){
602                 rect = ibuf->rect;
603                 for (size = ibuf->x * ibuf->y; size > 0; size --){
604                         col = *rect;
605                         col = ((col & 0x1f) << 19) +  ((col & 0x3e0) << 6) + ((col & 0x7c00) >> 7) ;
606                         col += (col & 0xe0e0e0) >> 5;
607                         *rect++ = col + 0xff000000;
608                 }
609                 ibuf->depth = 24;
610         }
611         
612         if (tga.imgtyp == 3 || tga.imgtyp == 11){
613                 uchar *crect;
614                 unsigned int *lrect, col;
615                 
616                 crect = (uchar *) ibuf->rect;
617                 lrect = (unsigned int *) ibuf->rect;
618                 
619                 for (size = ibuf->x * ibuf->y; size > 0; size --){
620                         col = *lrect++;
621                         
622                         crect[0] = 255;
623                         crect[1] = crect[2] = crect[3] = col;
624                         crect += 4;
625                 }
626         }
627         
628         if (flags & IB_ttob) tga.imgdes ^= 0x20;
629         if (tga.imgdes & 0x20) IMB_flipy(ibuf);
630
631         if (ibuf) {
632                 if (ibuf->rect && (flags & IB_cmap)==0) 
633                         IMB_convert_rgba_to_abgr((ibuf->x+ibuf->skipx)*ibuf->y, ibuf->rect);
634         }
635         
636         return(ibuf);
637 }