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