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