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