156cff25e873beb81548683781dccbffb60efdec
[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 return (0);
245         
246         return (1);
247 }
248
249
250 int imb_savetarga(struct ImBuf *ibuf, const char *name, int flags)
251 {
252         char buf[20] = {0};
253         FILE *fildes;
254         short ok = 0;
255         
256         (void)flags; /* unused */
257
258         buf[16] = (ibuf->planes + 0x7) & ~0x7;
259         if (ibuf->planes > 8) {
260                 buf[2] = 10;
261         }
262         else {
263                 buf[2] = 11;
264         }
265
266         if (ibuf->ftype == RAWTGA) buf[2] &= ~8;
267         
268         buf[8] = 0;
269         buf[9] = 0;
270         buf[10] = 0;
271         buf[11] = 0;
272
273         buf[12] = ibuf->x & 0xff;
274         buf[13] = ibuf->x >> 8;
275         buf[14] = ibuf->y & 0xff;
276         buf[15] = ibuf->y >> 8;
277
278         /* Don't forget to indicate that your 32 bit
279          * targa uses 8 bits for the alpha channel! */
280         if (ibuf->planes == 32) {
281                 buf[17] |= 0x08;
282         }
283         fildes = BLI_fopen(name, "wb");
284         if (!fildes) return 0;
285
286         if (fwrite(buf, 1, 18, fildes) != 18) {
287                 fclose(fildes);
288                 return (0);
289         }
290
291         if (ibuf->ftype == RAWTGA) {
292                 ok = dumptarga(ibuf, fildes);
293         }
294         else {
295                 switch ((ibuf->planes + 7) >> 3) {
296                         case 1:
297                                 ok = makebody_tga(ibuf, fildes, tga_out1);
298                                 break;
299                         case 2:
300                                 ok = makebody_tga(ibuf, fildes, tga_out2);
301                                 break;
302                         case 3:
303                                 ok = makebody_tga(ibuf, fildes, tga_out3);
304                                 break;
305                         case 4:
306                                 ok = makebody_tga(ibuf, fildes, tga_out4);
307                                 break;
308                 }
309         }
310         
311         fclose(fildes);
312         return (ok);
313 }
314
315
316 static int checktarga(TARGA *tga, unsigned char *mem)
317 {
318         tga->numid = mem[0];
319         tga->maptyp = mem[1];
320         tga->imgtyp = mem[2];
321
322         tga->maporig = GSS(mem + 3);
323         tga->mapsize = GSS(mem + 5);
324         tga->mapbits = mem[7];
325         tga->xorig = GSS(mem + 8);
326         tga->yorig = GSS(mem + 10);
327         tga->xsize = GSS(mem + 12);
328         tga->ysize = GSS(mem + 14);
329         tga->pixsize = mem[16];
330         tga->imgdes = mem[17];
331
332         if (tga->maptyp > 1) return(0);
333         switch (tga->imgtyp) {
334                 case 1:     /* raw cmap */
335                 case 2:     /* raw rgb */
336                 case 3:     /* raw b&w */
337                 case 9:     /* cmap */
338                 case 10:        /* rgb */
339                 case 11:        /* b&w */
340                         break;
341                 default:
342                         return(0);
343         }
344         if (tga->mapsize && tga->mapbits > 32) return(0);
345         if (tga->xsize <= 0 || tga->xsize >= 8192) return(0);
346         if (tga->ysize <= 0 || tga->ysize >= 8192) return(0);
347         if (tga->pixsize > 32) return(0);
348         if (tga->pixsize == 0) return(0);
349         return(1);
350 }
351
352 int imb_is_a_targa(unsigned char *buf)
353 {
354         TARGA tga;
355         
356         return checktarga(&tga, buf);
357 }
358
359 static void complete_partial_load(struct ImBuf *ibuf, unsigned int *rect)
360 {
361         int size = (ibuf->x * ibuf->y) - (rect - ibuf->rect);
362         if (size) {
363                 printf("decodetarga: incomplete file, %.1f%% missing\n", 100 * ((float)size / (ibuf->x * ibuf->y)));
364
365                 /* not essential but makes displaying partially rendered TGA's less ugly  */
366                 memset(rect, 0, size);
367         }
368         else {
369                 /* shouldnt happen */
370                 printf("decodetarga: incomplete file, all pixels written\n");
371         }
372 }
373
374 static void decodetarga(struct ImBuf *ibuf, unsigned char *mem, size_t mem_size, int psize)
375 {
376         unsigned char *mem_end = mem + mem_size;
377         int count, col, size;
378         unsigned int *rect;
379         uchar *cp = (uchar *) &col;
380         
381         if (ibuf == NULL) return;
382         if (ibuf->rect == NULL) return;
383
384         size = ibuf->x * ibuf->y;
385         rect = ibuf->rect;
386         
387         /* set alpha */
388         cp[0] = 0xff;
389         cp[1] = cp[2] = 0;
390
391         while (size > 0) {
392                 count = *mem++;
393
394                 if (mem > mem_end)
395                         goto partial_load;
396
397                 if (count >= 128) {
398                         /*if (count == 128) printf("TARGA: 128 in file !\n");*/
399                         count -= 127;
400
401                         if (psize & 2) {
402                                 if (psize & 1) {
403                                         /* order = bgra */
404                                         cp[0] = mem[3];
405                                         cp[1] = mem[0];
406                                         cp[2] = mem[1];
407                                         cp[3] = mem[2];
408                                         /*col = (mem[3] << 24) + (mem[0] << 16) + (mem[1] << 8) + mem[2];*/
409                                         mem += 4;
410                                 }
411                                 else {
412                                         cp[1] = mem[0];
413                                         cp[2] = mem[1];
414                                         cp[3] = mem[2];
415                                         /*col = 0xff000000 + (mem[0] << 16) + (mem[1] << 8) + mem[2];*/
416                                         mem += 3;
417                                 }
418                         }
419                         else {
420                                 if (psize & 1) {
421                                         cp[0] = mem[0];
422                                         cp[1] = mem[1];
423                                         mem += 2;
424                                 }
425                                 else {
426                                         col = *mem++;
427                                 }
428                         }
429
430                         size -= count;
431                         if (size >= 0) {
432                                 while (count > 0) {
433                                         *rect++ = col;
434                                         count--;
435                                 }
436                         }
437                 }
438                 else {
439                         count++;
440                         size -= count;
441                         if (size >= 0) {
442                                 while (count > 0) {
443                                         if (psize & 2) {
444                                                 if (psize & 1) {
445                                                         /* order = bgra */
446                                                         cp[0] = mem[3];
447                                                         cp[1] = mem[0];
448                                                         cp[2] = mem[1];
449                                                         cp[3] = mem[2];
450                                                         /*col = (mem[3] << 24) + (mem[0] << 16) + (mem[1] << 8) + mem[2];*/
451                                                         mem += 4;
452                                                 }
453                                                 else {
454                                                         cp[1] = mem[0];
455                                                         cp[2] = mem[1];
456                                                         cp[3] = mem[2];
457                                                         /*col = 0xff000000 + (mem[0] << 16) + (mem[1] << 8) + mem[2];*/
458                                                         mem += 3;
459                                                 }
460                                         }
461                                         else {
462                                                 if (psize & 1) {
463                                                         cp[0] = mem[0];
464                                                         cp[1] = mem[1];
465                                                         mem += 2;
466                                                 }
467                                                 else {
468                                                         col = *mem++;
469                                                 }
470                                         }
471                                         *rect++ = col;
472                                         count--;
473
474                                         if (mem > mem_end)
475                                                 goto partial_load;
476                                 }
477
478                                 if (mem > mem_end)
479                                         goto partial_load;
480                         }
481                 }
482         }
483         if (size) {
484                 printf("decodetarga: count would overwrite %d pixels\n", -size);
485         }
486         return;
487
488 partial_load:
489         complete_partial_load(ibuf, rect);
490 }
491
492 static void ldtarga(struct ImBuf *ibuf, unsigned char *mem, size_t mem_size, int psize)
493 {
494         unsigned char *mem_end = mem + mem_size;
495         int col, size;
496         unsigned int *rect;
497         uchar *cp = (uchar *) &col;
498
499         if (ibuf == NULL) return;
500         if (ibuf->rect == NULL) return;
501
502         size = ibuf->x * ibuf->y;
503         rect = ibuf->rect;
504
505         /* set alpha */
506         cp[0] = 0xff;
507         cp[1] = cp[2] = 0;
508
509         while (size > 0) {
510                 if (mem > mem_end)
511                         goto partial_load;
512
513                 if (psize & 2) {
514                         if (psize & 1) {
515                                 /* order = bgra */
516                                 cp[0] = mem[3];
517                                 cp[1] = mem[0];
518                                 cp[2] = mem[1];
519                                 cp[3] = mem[2];
520                                 /*col = (mem[3] << 24) + (mem[0] << 16) + (mem[1] << 8) + mem[2];*/
521                                 mem += 4;
522                         }
523                         else {
524                                 /* set alpha for 24 bits colors */
525                                 cp[1] = mem[0];
526                                 cp[2] = mem[1];
527                                 cp[3] = mem[2];
528                                 /*col = 0xff000000 + (mem[0] << 16) + (mem[1] << 8) + mem[2];*/
529                                 mem += 3;
530                         }
531                 }
532                 else {
533                         if (psize & 1) {
534                                 cp[0] = mem[0];
535                                 cp[1] = mem[1];
536                                 mem += 2;
537                         }
538                         else {
539                                 col = *mem++;
540                         }
541                 }
542                 *rect++ = col;
543                 size--;
544         }
545         return;
546
547 partial_load:
548         complete_partial_load(ibuf, rect);
549 }
550
551
552 ImBuf *imb_loadtarga(unsigned char *mem, size_t mem_size, int flags, char colorspace[IM_MAX_SPACE])
553 {
554         TARGA tga;
555         struct ImBuf *ibuf;
556         int col, count, size;
557         unsigned int *rect, *cmap = NULL /*, mincol = 0*/, maxcol = 0;
558         uchar *cp = (uchar *) &col;
559
560         if (checktarga(&tga, mem) == 0) return(NULL);
561
562         colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE);
563
564         if (flags & IB_test) ibuf = IMB_allocImBuf(tga.xsize, tga.ysize, tga.pixsize, 0);
565         else ibuf = IMB_allocImBuf(tga.xsize, tga.ysize, (tga.pixsize + 0x7) & ~0x7, IB_rect);
566
567         if (ibuf == NULL) return(NULL);
568         ibuf->ftype = TGA;
569         mem = mem + 18 + tga.numid;
570         
571         cp[0] = 0xff;
572         cp[1] = cp[2] = 0;
573         
574         if (tga.mapsize) {
575                 /* load color map */
576                 /*mincol = tga.maporig;*/ /*UNUSED*/
577                 maxcol = tga.mapsize;
578                 cmap = MEM_callocN(sizeof(unsigned int) * maxcol, "targa cmap");
579
580                 for (count = 0; count < maxcol; count++) {
581                         switch (tga.mapbits >> 3) {
582                                 case 4:
583                                         cp[0] = mem[3];
584                                         cp[1] = mem[0];
585                                         cp[2] = mem[1];
586                                         cp[3] = mem[2];
587                                         mem += 4;
588                                         break;
589                                 case 3:
590                                         cp[1] = mem[0];
591                                         cp[2] = mem[1];
592                                         cp[3] = mem[2];
593                                         mem += 3;
594                                         break;
595                                 case 2:
596                                         cp[1] = mem[1];
597                                         cp[0] = mem[0];
598                                         mem += 2;
599                                         break;
600                                 case 1:
601                                         col = *mem++;
602                                         break;
603                         }
604                         cmap[count] = col;
605                 }
606                 
607                 size = 0;
608                 for (col = maxcol - 1; col > 0; col >>= 1) size++;
609                 ibuf->planes = size;
610
611                 if (tga.mapbits != 32) {    /* set alpha bits  */
612                         cmap[0] &= BIG_LONG(0x00ffffffl);
613                 }
614         }
615         
616         if (flags & IB_test) return (ibuf);
617
618         if (tga.imgtyp != 1 && tga.imgtyp != 9) { /* happens sometimes (beuh) */
619                 if (cmap) {
620                         MEM_freeN(cmap); 
621                         cmap = NULL;
622                 }
623         }
624
625         switch (tga.imgtyp) {
626                 case 1:
627                 case 2:
628                 case 3:
629                         if (tga.pixsize <= 8) ldtarga(ibuf, mem, mem_size, 0);
630                         else if (tga.pixsize <= 16) ldtarga(ibuf, mem, mem_size, 1);
631                         else if (tga.pixsize <= 24) ldtarga(ibuf, mem, mem_size, 2);
632                         else if (tga.pixsize <= 32) ldtarga(ibuf, mem, mem_size, 3);
633                         break;
634                 case 9:
635                 case 10:
636                 case 11:
637                         if (tga.pixsize <= 8) decodetarga(ibuf, mem, mem_size, 0);
638                         else if (tga.pixsize <= 16) decodetarga(ibuf, mem, mem_size, 1);
639                         else if (tga.pixsize <= 24) decodetarga(ibuf, mem, mem_size, 2);
640                         else if (tga.pixsize <= 32) decodetarga(ibuf, mem, mem_size, 3);
641                         break;
642         }
643         
644         if (cmap) {
645                 /* apply color map */
646                 rect = ibuf->rect;
647                 for (size = ibuf->x * ibuf->y; size > 0; --size, ++rect) {
648                         col = *rect;
649                         if (col >= 0 && col < maxcol) *rect = cmap[col];
650                 }
651
652                 MEM_freeN(cmap);
653         }
654         
655         if (tga.pixsize == 16) {
656                 rect = ibuf->rect;
657                 for (size = ibuf->x * ibuf->y; size > 0; --size, ++rect) {
658                         col = *rect;
659                         cp = (uchar *)rect;
660                         mem = (uchar *)&col;
661
662                         cp[3] = ((mem[1] << 1) & 0xf8);
663                         cp[2] = ((mem[0] & 0xe0) >> 2) + ((mem[1] & 0x03) << 6);
664                         cp[1] = ((mem[0] << 3) & 0xf8);
665                         cp[1] += cp[1] >> 5;
666                         cp[2] += cp[2] >> 5;
667                         cp[3] += cp[3] >> 5;
668                         cp[0] = 0xff;
669                 }
670                 ibuf->planes = 24;
671         }
672         
673         if (tga.imgtyp == 3 || tga.imgtyp == 11) {
674                 uchar *crect;
675                 unsigned int *lrect, col;
676                 
677                 crect = (uchar *) ibuf->rect;
678                 lrect = (unsigned int *) ibuf->rect;
679                 
680                 for (size = ibuf->x * ibuf->y; size > 0; size--) {
681                         col = *lrect++;
682                         
683                         crect[0] = 255;
684                         crect[1] = crect[2] = crect[3] = col;
685                         crect += 4;
686                 }
687         }
688         
689         if (tga.imgdes & 0x20) {
690                 IMB_flipy(ibuf);
691         }
692
693         if (ibuf->rect)
694                 IMB_convert_rgba_to_abgr(ibuf);
695         
696         return(ibuf);
697 }