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