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