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