Blender V2.61 - r43446
|
00001 /* 00002 * ***** BEGIN GPL LICENSE BLOCK ***** 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 * 00018 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. 00019 * All rights reserved. 00020 * 00021 * The Original Code is: all of this file. 00022 * 00023 * Contributor(s): none yet. 00024 * 00025 * ***** END GPL LICENSE BLOCK ***** 00026 */ 00027 00033 #ifdef WIN32 00034 #include <io.h> 00035 #endif 00036 #include "BLI_blenlib.h" 00037 #include "MEM_guardedalloc.h" 00038 00039 #include "imbuf.h" 00040 00041 #include "IMB_imbuf_types.h" 00042 #include "IMB_imbuf.h" 00043 00044 #include "IMB_allocimbuf.h" 00045 #include "IMB_filetype.h" 00046 00047 00048 /* this one is only def-ed once, strangely... related to GS? */ 00049 #define GSS(x) (((uchar *)(x))[1] << 8 | ((uchar *)(x))[0]) 00050 00051 /***/ 00052 00053 typedef struct TARGA 00054 { 00055 unsigned char numid; 00056 unsigned char maptyp; 00057 unsigned char imgtyp; 00058 short maporig; 00059 short mapsize; 00060 unsigned char mapbits; 00061 short xorig; 00062 short yorig; 00063 short xsize; 00064 short ysize; 00065 unsigned char pixsize; 00066 unsigned char imgdes; 00067 } TARGA; 00068 00069 /***/ 00070 00071 static int tga_out1(unsigned int data, FILE *file) 00072 { 00073 uchar *p; 00074 00075 p = (uchar *) & data; 00076 if (putc(p[0],file) == EOF) return(EOF); 00077 return (~EOF); 00078 } 00079 00080 static int tga_out2(unsigned int data, FILE * file) 00081 { 00082 uchar *p; 00083 00084 p = (uchar *) & data; 00085 if (putc(p[0],file) == EOF) return(EOF); 00086 if (putc(p[1],file) == EOF) return(EOF); 00087 return (~EOF); 00088 } 00089 00090 00091 static int tga_out3(unsigned int data, FILE * file) 00092 { 00093 uchar *p; 00094 00095 p = (uchar *) & data; 00096 if (putc(p[2],file) == EOF) return(EOF); 00097 if (putc(p[1],file) == EOF) return(EOF); 00098 if (putc(p[0],file) == EOF) return(EOF); 00099 return (~EOF); 00100 } 00101 00102 00103 static int tga_out4(unsigned int data, FILE * file) 00104 { 00105 uchar *p; 00106 00107 p = (uchar *) & data; 00108 /* order = bgra */ 00109 if (putc(p[2],file) == EOF) return(EOF); 00110 if (putc(p[1],file) == EOF) return(EOF); 00111 if (putc(p[0],file) == EOF) return(EOF); 00112 if (putc(p[3],file) == EOF) return(EOF); 00113 return (~EOF); 00114 } 00115 00116 static short makebody_tga(ImBuf * ibuf, FILE * file, int (*out)(unsigned int, FILE*)) 00117 { 00118 register int last,this; 00119 register int copy, bytes; 00120 register unsigned int *rect, *rectstart, *temp; 00121 int y; 00122 00123 for (y = 0; y < ibuf->y; y++) { 00124 bytes = ibuf->x - 1; 00125 rectstart = rect = ibuf->rect + (y * ibuf->x); 00126 last = *rect++; 00127 this = *rect++; 00128 copy = last^this; 00129 while (bytes > 0){ 00130 if (copy){ 00131 do{ 00132 last = this; 00133 this = *rect++; 00134 if (last == this){ 00135 if (this == rect[-3]){ /* three the same? */ 00136 bytes --; /* set bytes */ 00137 break; 00138 } 00139 } 00140 }while (--bytes != 0); 00141 00142 copy = rect-rectstart; 00143 copy --; 00144 if (bytes) copy -= 2; 00145 00146 temp = rect; 00147 rect = rectstart; 00148 00149 while (copy){ 00150 last = copy; 00151 if (copy>=128) last = 128; 00152 copy -= last; 00153 if (fputc(last-1,file) == EOF) return(0); 00154 do{ 00155 if (out(*rect++,file) == EOF) return(0); 00156 }while(--last != 0); 00157 } 00158 rectstart = rect; 00159 rect = temp; 00160 last = this; 00161 00162 copy = FALSE; 00163 } else { 00164 while (*rect++ == this){ /* seek for first different byte */ 00165 if (--bytes == 0) break; /* oor end of line */ 00166 } 00167 rect --; 00168 copy = rect-rectstart; 00169 rectstart = rect; 00170 bytes --; 00171 this = *rect++; 00172 00173 while (copy){ 00174 if (copy>128){ 00175 if (fputc(255,file) == EOF) return(0); 00176 copy -= 128; 00177 } else { 00178 if (copy == 1){ 00179 if (fputc(0,file) == EOF) return(0); 00180 } else if (fputc(127 + copy,file) == EOF) return(0); 00181 copy = 0; 00182 } 00183 if (out(last,file) == EOF) return(0); 00184 } 00185 copy=TRUE; 00186 } 00187 } 00188 } 00189 return (1); 00190 } 00191 00192 static int dumptarga(struct ImBuf * ibuf, FILE * file) 00193 { 00194 int size; 00195 uchar *rect; 00196 00197 if (ibuf == NULL) return (0); 00198 if (ibuf->rect == NULL) return (0); 00199 00200 size = ibuf->x * ibuf->y; 00201 rect = (uchar *) ibuf->rect; 00202 00203 if (ibuf->planes <= 8) { 00204 while(size > 0){ 00205 if (putc(*rect, file) == EOF) return (0); 00206 size--; 00207 rect += 4; 00208 } 00209 } else if (ibuf->planes <= 16) { 00210 while(size > 0){ 00211 putc(rect[0], file); 00212 if (putc(rect[1], file) == EOF) return (0); 00213 size--; 00214 rect += 4; 00215 } 00216 } else if (ibuf->planes <= 24) { 00217 while(size > 0){ 00218 putc(rect[2], file); 00219 putc(rect[1], file); 00220 if (putc(rect[0], file) == EOF) return (0); 00221 size--; 00222 rect += 4; 00223 } 00224 } else if (ibuf->planes <= 32) { 00225 while(size > 0){ 00226 putc(rect[2], file); 00227 putc(rect[1], file); 00228 putc(rect[0], file); 00229 if (putc(rect[3], file) == EOF) return (0); 00230 size--; 00231 rect += 4; 00232 } 00233 } else return (0); 00234 00235 return (1); 00236 } 00237 00238 00239 int imb_savetarga(struct ImBuf * ibuf, const char *name, int flags) 00240 { 00241 char buf[20]= {0}; 00242 FILE *fildes; 00243 short ok = 0; 00244 00245 (void)flags; /* unused */ 00246 00247 buf[16] = (ibuf->planes + 0x7 ) & ~0x7; 00248 if (ibuf->planes > 8 ){ 00249 buf[2] = 10; 00250 } else{ 00251 buf[2] = 11; 00252 } 00253 00254 if (ibuf->ftype == RAWTGA) buf[2] &= ~8; 00255 00256 buf[8] = 0; 00257 buf[9] = 0; 00258 buf[10] = 0; 00259 buf[11] = 0; 00260 00261 buf[12] = ibuf->x & 0xff; 00262 buf[13] = ibuf->x >> 8; 00263 buf[14] = ibuf->y & 0xff; 00264 buf[15] = ibuf->y >> 8; 00265 00266 /* Don't forget to indicate that your 32 bit 00267 * targa uses 8 bits for the alpha channel! */ 00268 if (ibuf->planes==32) { 00269 buf[17] |= 0x08; 00270 } 00271 fildes = fopen(name,"wb"); 00272 if (!fildes) return 0; 00273 00274 if (fwrite(buf, 1, 18,fildes) != 18) { 00275 fclose(fildes); 00276 return (0); 00277 } 00278 00279 if (ibuf->ftype == RAWTGA) { 00280 ok = dumptarga(ibuf, fildes); 00281 } else { 00282 switch((ibuf->planes + 7) >> 3){ 00283 case 1: 00284 ok = makebody_tga(ibuf, fildes, tga_out1); 00285 break; 00286 case 2: 00287 ok = makebody_tga(ibuf, fildes, tga_out2); 00288 break; 00289 case 3: 00290 ok = makebody_tga(ibuf, fildes, tga_out3); 00291 break; 00292 case 4: 00293 ok = makebody_tga(ibuf, fildes, tga_out4); 00294 break; 00295 } 00296 } 00297 00298 fclose(fildes); 00299 return (ok); 00300 } 00301 00302 00303 static int checktarga(TARGA *tga, unsigned char *mem) 00304 { 00305 tga->numid = mem[0]; 00306 tga->maptyp = mem[1]; 00307 tga->imgtyp = mem[2]; 00308 00309 tga->maporig = GSS(mem+3); 00310 tga->mapsize = GSS(mem+5); 00311 tga->mapbits = mem[7]; 00312 tga->xorig = GSS(mem+8); 00313 tga->yorig = GSS(mem+10); 00314 tga->xsize = GSS(mem+12); 00315 tga->ysize = GSS(mem+14); 00316 tga->pixsize = mem[16]; 00317 tga->imgdes = mem[17]; 00318 00319 if (tga->maptyp > 1) return(0); 00320 switch (tga->imgtyp){ 00321 case 1: /* raw cmap */ 00322 case 2: /* raw rgb */ 00323 case 3: /* raw b&w */ 00324 case 9: /* cmap */ 00325 case 10: /* rgb */ 00326 case 11: /* b&w */ 00327 break; 00328 default: 00329 return(0); 00330 } 00331 if (tga->mapsize && tga->mapbits > 32) return(0); 00332 if (tga->xsize <= 0 || tga->xsize >= 8192) return(0); 00333 if (tga->ysize <= 0 || tga->ysize >= 8192) return(0); 00334 if (tga->pixsize > 32) return(0); 00335 if (tga->pixsize == 0) return(0); 00336 return(1); 00337 } 00338 00339 int imb_is_a_targa(unsigned char *buf) 00340 { 00341 TARGA tga; 00342 00343 return checktarga(&tga, buf); 00344 } 00345 00346 static void complete_partial_load(struct ImBuf *ibuf, unsigned int *rect) 00347 { 00348 int size = (ibuf->x * ibuf->y) - (rect - ibuf->rect); 00349 if(size) { 00350 printf("decodetarga: incomplete file, %.1f%% missing\n", 100*((float)size / (ibuf->x * ibuf->y))); 00351 00352 /* not essential but makes displaying partially rendered TGA's less ugly */ 00353 memset(rect, 0, size); 00354 } 00355 else { 00356 /* shouldnt happen */ 00357 printf("decodetarga: incomplete file, all pixels written\n"); 00358 } 00359 } 00360 00361 static void decodetarga(struct ImBuf *ibuf, unsigned char *mem, size_t mem_size, int psize) 00362 { 00363 unsigned char *mem_end = mem+mem_size; 00364 int count, col, size; 00365 unsigned int *rect; 00366 uchar * cp = (uchar *) &col; 00367 00368 if (ibuf == NULL) return; 00369 if (ibuf->rect == NULL) return; 00370 00371 size = ibuf->x * ibuf->y; 00372 rect = ibuf->rect; 00373 00374 /* set alpha */ 00375 cp[0] = 0xff; 00376 cp[1] = cp[2] = 0; 00377 00378 while(size > 0){ 00379 count = *mem++; 00380 00381 if(mem>mem_end) 00382 goto partial_load; 00383 00384 if (count >= 128) { 00385 /*if (count == 128) printf("TARGA: 128 in file !\n");*/ 00386 count -= 127; 00387 00388 if (psize & 2){ 00389 if (psize & 1){ 00390 /* order = bgra */ 00391 cp[0] = mem[3]; 00392 cp[1] = mem[0]; 00393 cp[2] = mem[1]; 00394 cp[3] = mem[2]; 00395 /*col = (mem[3] << 24) + (mem[0] << 16) + (mem[1] << 8) + mem[2];*/ 00396 mem += 4; 00397 } else{ 00398 cp[1] = mem[0]; 00399 cp[2] = mem[1]; 00400 cp[3] = mem[2]; 00401 /*col = 0xff000000 + (mem[0] << 16) + (mem[1] << 8) + mem[2];*/ 00402 mem += 3; 00403 } 00404 } else{ 00405 if (psize & 1){ 00406 cp[0] = mem[0]; 00407 cp[1] = mem[1]; 00408 mem += 2; 00409 } else{ 00410 col = *mem++; 00411 } 00412 } 00413 00414 size -= count; 00415 if (size >= 0) { 00416 while (count > 0) { 00417 *rect++ = col; 00418 count--; 00419 } 00420 } 00421 } else{ 00422 count ++; 00423 size -= count; 00424 if (size >= 0) { 00425 while (count > 0){ 00426 if (psize & 2){ 00427 if (psize & 1){ 00428 /* order = bgra */ 00429 cp[0] = mem[3]; 00430 cp[1] = mem[0]; 00431 cp[2] = mem[1]; 00432 cp[3] = mem[2]; 00433 /*col = (mem[3] << 24) + (mem[0] << 16) + (mem[1] << 8) + mem[2];*/ 00434 mem += 4; 00435 } else{ 00436 cp[1] = mem[0]; 00437 cp[2] = mem[1]; 00438 cp[3] = mem[2]; 00439 /*col = 0xff000000 + (mem[0] << 16) + (mem[1] << 8) + mem[2];*/ 00440 mem += 3; 00441 } 00442 } else{ 00443 if (psize & 1){ 00444 cp[0] = mem[0]; 00445 cp[1] = mem[1]; 00446 mem += 2; 00447 } else{ 00448 col = *mem++; 00449 } 00450 } 00451 *rect++ = col; 00452 count --; 00453 00454 if(mem>mem_end) 00455 goto partial_load; 00456 } 00457 00458 if(mem>mem_end) 00459 goto partial_load; 00460 } 00461 } 00462 } 00463 if (size) { 00464 printf("decodetarga: count would overwrite %d pixels\n", -size); 00465 } 00466 return; 00467 00468 partial_load: 00469 complete_partial_load(ibuf, rect); 00470 } 00471 00472 static void ldtarga(struct ImBuf * ibuf,unsigned char * mem, size_t mem_size, int psize) 00473 { 00474 unsigned char *mem_end = mem+mem_size; 00475 int col,size; 00476 unsigned int *rect; 00477 uchar * cp = (uchar *) &col; 00478 00479 if (ibuf == NULL) return; 00480 if (ibuf->rect == NULL) return; 00481 00482 size = ibuf->x * ibuf->y; 00483 rect = ibuf->rect; 00484 00485 /* set alpha */ 00486 cp[0] = 0xff; 00487 cp[1] = cp[2] = 0; 00488 00489 while(size > 0){ 00490 if(mem>mem_end) 00491 goto partial_load; 00492 00493 if (psize & 2){ 00494 if (psize & 1){ 00495 /* order = bgra */ 00496 cp[0] = mem[3]; 00497 cp[1] = mem[0]; 00498 cp[2] = mem[1]; 00499 cp[3] = mem[2]; 00500 /*col = (mem[3] << 24) + (mem[0] << 16) + (mem[1] << 8) + mem[2];*/ 00501 mem += 4; 00502 } else{ 00503 /* set alpha for 24 bits colors */ 00504 cp[1] = mem[0]; 00505 cp[2] = mem[1]; 00506 cp[3] = mem[2]; 00507 /*col = 0xff000000 + (mem[0] << 16) + (mem[1] << 8) + mem[2];*/ 00508 mem += 3; 00509 } 00510 } else{ 00511 if (psize & 1){ 00512 cp[0] = mem[0]; 00513 cp[1] = mem[1]; 00514 mem += 2; 00515 } else{ 00516 col = *mem++; 00517 } 00518 } 00519 *rect++ = col; 00520 size--; 00521 } 00522 return; 00523 00524 partial_load: 00525 complete_partial_load(ibuf, rect); 00526 } 00527 00528 00529 struct ImBuf *imb_loadtarga(unsigned char *mem, size_t mem_size, int flags) 00530 { 00531 TARGA tga; 00532 struct ImBuf * ibuf; 00533 int col, count, size; 00534 unsigned int *rect, *cmap= NULL /*, mincol= 0*/, maxcol= 0; 00535 uchar * cp = (uchar *) &col; 00536 00537 if (checktarga(&tga,mem) == 0) return(NULL); 00538 00539 if (flags & IB_test) ibuf = IMB_allocImBuf(tga.xsize,tga.ysize,tga.pixsize, 0); 00540 else ibuf = IMB_allocImBuf(tga.xsize,tga.ysize,(tga.pixsize + 0x7) & ~0x7, IB_rect); 00541 00542 if (ibuf == NULL) return(NULL); 00543 ibuf->ftype = TGA; 00544 ibuf->profile = IB_PROFILE_SRGB; 00545 mem = mem + 18 + tga.numid; 00546 00547 cp[0] = 0xff; 00548 cp[1] = cp[2] = 0; 00549 00550 if (tga.mapsize){ 00551 /* load color map */ 00552 /*mincol = tga.maporig;*/ /*UNUSED*/ 00553 maxcol = tga.mapsize; 00554 cmap = MEM_callocN(sizeof(unsigned int)*maxcol, "targa cmap"); 00555 00556 for (count = 0 ; count < maxcol ; count ++) { 00557 switch (tga.mapbits >> 3) { 00558 case 4: 00559 cp[0] = mem[3]; 00560 cp[1] = mem[0]; 00561 cp[2] = mem[1]; 00562 cp[3] = mem[2]; 00563 mem += 4; 00564 break; 00565 case 3: 00566 cp[1] = mem[0]; 00567 cp[2] = mem[1]; 00568 cp[3] = mem[2]; 00569 mem += 3; 00570 break; 00571 case 2: 00572 cp[1] = mem[1]; 00573 cp[0] = mem[0]; 00574 mem += 2; 00575 break; 00576 case 1: 00577 col = *mem++; 00578 break; 00579 } 00580 cmap[count] = col; 00581 } 00582 00583 size = 0; 00584 for (col = maxcol - 1; col > 0; col >>= 1) size++; 00585 ibuf->planes = size; 00586 00587 if (tga.mapbits != 32) { /* set alpha bits */ 00588 cmap[0] &= BIG_LONG(0x00ffffffl); 00589 } 00590 } 00591 00592 if (flags & IB_test) return (ibuf); 00593 00594 if (tga.imgtyp != 1 && tga.imgtyp != 9) { /* happens sometimes (beuh) */ 00595 if(cmap) { 00596 MEM_freeN(cmap); 00597 cmap= NULL; 00598 } 00599 } 00600 00601 switch(tga.imgtyp){ 00602 case 1: 00603 case 2: 00604 case 3: 00605 if (tga.pixsize <= 8) ldtarga(ibuf,mem,mem_size,0); 00606 else if (tga.pixsize <= 16) ldtarga(ibuf,mem,mem_size,1); 00607 else if (tga.pixsize <= 24) ldtarga(ibuf,mem,mem_size,2); 00608 else if (tga.pixsize <= 32) ldtarga(ibuf,mem,mem_size,3); 00609 break; 00610 case 9: 00611 case 10: 00612 case 11: 00613 if (tga.pixsize <= 8) decodetarga(ibuf,mem,mem_size,0); 00614 else if (tga.pixsize <= 16) decodetarga(ibuf,mem,mem_size,1); 00615 else if (tga.pixsize <= 24) decodetarga(ibuf,mem,mem_size,2); 00616 else if (tga.pixsize <= 32) decodetarga(ibuf,mem,mem_size,3); 00617 break; 00618 } 00619 00620 if(cmap) { 00621 /* apply color map */ 00622 rect = ibuf->rect; 00623 for(size = ibuf->x * ibuf->y; size>0; --size, ++rect) { 00624 col = *rect; 00625 if (col >= 0 && col < maxcol) *rect = cmap[col]; 00626 } 00627 00628 MEM_freeN(cmap); 00629 } 00630 00631 if (tga.pixsize == 16) { 00632 rect = ibuf->rect; 00633 for (size = ibuf->x * ibuf->y; size > 0; --size, ++rect){ 00634 col = *rect; 00635 cp = (uchar*)rect; 00636 mem = (uchar*)&col; 00637 00638 cp[3] = ((mem[1] << 1) & 0xf8); 00639 cp[2] = ((mem[0] & 0xe0) >> 2) + ((mem[1] & 0x03) << 6); 00640 cp[1] = ((mem[0] << 3) & 0xf8); 00641 cp[1] += cp[1] >> 5; 00642 cp[2] += cp[2] >> 5; 00643 cp[3] += cp[3] >> 5; 00644 cp[0] = 0xff; 00645 } 00646 ibuf->planes = 24; 00647 } 00648 00649 if (tga.imgtyp == 3 || tga.imgtyp == 11){ 00650 uchar *crect; 00651 unsigned int *lrect, col; 00652 00653 crect = (uchar *) ibuf->rect; 00654 lrect = (unsigned int *) ibuf->rect; 00655 00656 for (size = ibuf->x * ibuf->y; size > 0; size --){ 00657 col = *lrect++; 00658 00659 crect[0] = 255; 00660 crect[1] = crect[2] = crect[3] = col; 00661 crect += 4; 00662 } 00663 } 00664 00665 if (tga.imgdes & 0x20) IMB_flipy(ibuf); 00666 00667 if (ibuf && ibuf->rect) 00668 IMB_convert_rgba_to_abgr(ibuf); 00669 00670 return(ibuf); 00671 }