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