|
Blender
V2.59
|
00001 /* 00002 * 00003 * ***** BEGIN GPL LICENSE BLOCK ***** 00004 * 00005 * This program is free software; you can redistribute it and/or 00006 * modify it under the terms of the GNU General Public License 00007 * as published by the Free Software Foundation; either version 2 00008 * of the License, or (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License 00016 * along with this program; if not, write to the Free Software Foundation, 00017 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00018 * 00019 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. 00020 * All rights reserved. 00021 * 00022 * The Original Code is: all of this file. 00023 * 00024 * Contributor(s): none yet. 00025 * 00026 * ***** END GPL LICENSE BLOCK ***** 00027 * iris.c 00028 * 00029 * $Id: iris.c 35336 2011-03-03 17:58:06Z campbellbarton $ 00030 */ 00031 00037 #include <string.h> 00038 00039 #include "BLI_blenlib.h" 00040 #include "MEM_guardedalloc.h" 00041 00042 #include "imbuf.h" 00043 #include "IMB_imbuf_types.h" 00044 #include "IMB_imbuf.h" 00045 #include "IMB_allocimbuf.h" 00046 #include "IMB_filetype.h" 00047 00048 typedef struct { 00049 unsigned short imagic; /* stuff saved on disk . . */ 00050 unsigned short type; 00051 unsigned short dim; 00052 unsigned short xsize; 00053 unsigned short ysize; 00054 unsigned short zsize; 00055 unsigned int min; 00056 unsigned int max; 00057 unsigned int wastebytes; 00058 char name[80]; 00059 unsigned int colormap; 00060 00061 int file; /* stuff used in core only */ 00062 unsigned short flags; 00063 short dorev; 00064 short x; 00065 short y; 00066 short z; 00067 short cnt; 00068 unsigned short *ptr; 00069 unsigned short *base; 00070 unsigned short *tmpbuf; 00071 unsigned int offset; 00072 unsigned int rleend; /* for rle images */ 00073 unsigned int *rowstart; /* for rle images */ 00074 int *rowsize; /* for rle images */ 00075 } IMAGE; 00076 00077 #define RINTLUM (79) 00078 #define GINTLUM (156) 00079 #define BINTLUM (21) 00080 00081 #define ILUM(r,g,b) ((int)(RINTLUM*(r)+GINTLUM*(g)+BINTLUM*(b))>>8) 00082 00083 #define OFFSET_R 0 /* this is byte order dependent */ 00084 #define OFFSET_G 1 00085 #define OFFSET_B 2 00086 #define OFFSET_A 3 00087 00088 #define CHANOFFSET(z) (3-(z)) /* this is byte order dependent */ 00089 00090 #define TYPEMASK 0xff00 00091 #define BPPMASK 0x00ff 00092 #define ITYPE_VERBATIM 0x0000 00093 #define ITYPE_RLE 0x0100 00094 #define ISRLE(type) (((type) & 0xff00) == ITYPE_RLE) 00095 #define ISVERBATIM(type) (((type) & 0xff00) == ITYPE_VERBATIM) 00096 #define BPP(type) ((type) & BPPMASK) 00097 #define RLE(bpp) (ITYPE_RLE | (bpp)) 00098 #define VERBATIM(bpp) (ITYPE_VERBATIM | (bpp)) 00099 #define IBUFSIZE(pixels) ((pixels+(pixels>>6))<<2) 00100 #define RLE_NOP 0x00 00101 00102 /* funcs */ 00103 static void readheader(FILE *inf, IMAGE *image); 00104 static int writeheader(FILE *outf, IMAGE *image); 00105 00106 static unsigned short getshort(FILE *inf); 00107 static unsigned int getlong(FILE *inf); 00108 static void putshort(FILE *outf, unsigned short val); 00109 static int putlong(FILE *outf, unsigned int val); 00110 static int writetab(FILE *outf, unsigned int *tab, int len); 00111 static void readtab(FILE *inf, unsigned int *tab, int len); 00112 00113 static void expandrow(unsigned char *optr, unsigned char *iptr, int z); 00114 static void expandrow2(float *optr, unsigned char *iptr, int z); 00115 static void interleaverow(unsigned char *lptr, unsigned char *cptr, int z, int n); 00116 static void interleaverow2(float *lptr, unsigned char *cptr, int z, int n); 00117 static int compressrow(unsigned char *lbuf, unsigned char *rlebuf, int z, int cnt); 00118 static void lumrow(unsigned char *rgbptr, unsigned char *lumptr, int n); 00119 00120 /* 00121 * byte order independent read/write of shorts and ints. 00122 * 00123 */ 00124 00125 static uchar * file_data; 00126 static int file_offset; 00127 00128 static unsigned short getshort(FILE *inf) 00129 { 00130 unsigned char * buf; 00131 (void)inf; /* unused */ 00132 00133 buf = file_data + file_offset; 00134 file_offset += 2; 00135 00136 return (buf[0]<<8)+(buf[1]<<0); 00137 } 00138 00139 static unsigned int getlong(FILE *inf) 00140 { 00141 unsigned char * buf; 00142 (void)inf; /* unused */ 00143 00144 buf = file_data + file_offset; 00145 file_offset += 4; 00146 00147 return (buf[0]<<24)+(buf[1]<<16)+(buf[2]<<8)+(buf[3]<<0); 00148 } 00149 00150 static void putshort(FILE *outf, unsigned short val) 00151 { 00152 unsigned char buf[2]; 00153 00154 buf[0] = (val>>8); 00155 buf[1] = (val>>0); 00156 fwrite(buf,2,1,outf); 00157 } 00158 00159 static int putlong(FILE *outf, unsigned int val) 00160 { 00161 unsigned char buf[4]; 00162 00163 buf[0] = (val>>24); 00164 buf[1] = (val>>16); 00165 buf[2] = (val>>8); 00166 buf[3] = (val>>0); 00167 return fwrite(buf,4,1,outf); 00168 } 00169 00170 static void readheader(FILE *inf, IMAGE *image) 00171 { 00172 memset(image, 0, sizeof(IMAGE)); 00173 image->imagic = getshort(inf); 00174 image->type = getshort(inf); 00175 image->dim = getshort(inf); 00176 image->xsize = getshort(inf); 00177 image->ysize = getshort(inf); 00178 image->zsize = getshort(inf); 00179 } 00180 00181 static int writeheader(FILE *outf, IMAGE *image) 00182 { 00183 IMAGE t= {0}; 00184 00185 fwrite(&t,sizeof(IMAGE),1,outf); 00186 fseek(outf,0,SEEK_SET); 00187 putshort(outf,image->imagic); 00188 putshort(outf,image->type); 00189 putshort(outf,image->dim); 00190 putshort(outf,image->xsize); 00191 putshort(outf,image->ysize); 00192 putshort(outf,image->zsize); 00193 putlong(outf,image->min); 00194 putlong(outf,image->max); 00195 putlong(outf,0); 00196 return fwrite("no name",8,1,outf); 00197 } 00198 00199 static int writetab(FILE *outf, unsigned int *tab, int len) 00200 { 00201 int r = 0; 00202 00203 while(len) { 00204 r = putlong(outf,*tab++); 00205 len -= 4; 00206 } 00207 return r; 00208 } 00209 00210 static void readtab(FILE *inf, unsigned int *tab, int len) 00211 { 00212 while(len) { 00213 *tab++ = getlong(inf); 00214 len -= 4; 00215 } 00216 } 00217 00218 static void test_endian_zbuf(struct ImBuf *ibuf) 00219 { 00220 int len; 00221 int *zval; 00222 00223 if( BIG_LONG(1) == 1 ) return; 00224 if(ibuf->zbuf == NULL) return; 00225 00226 len= ibuf->x*ibuf->y; 00227 zval= ibuf->zbuf; 00228 00229 while(len--) { 00230 zval[0]= BIG_LONG(zval[0]); 00231 zval++; 00232 } 00233 } 00234 00235 /* from misc_util: flip the bytes from x */ 00236 #define GS(x) (((unsigned char *)(x))[0] << 8 | ((unsigned char *)(x))[1]) 00237 00238 /* this one is only def-ed once, strangely... */ 00239 #define GSS(x) (((uchar *)(x))[1] << 8 | ((uchar *)(x))[0]) 00240 00241 int imb_is_a_iris(unsigned char *mem) 00242 { 00243 return ((GS(mem) == IMAGIC) || (GSS(mem) == IMAGIC)); 00244 } 00245 00246 /* 00247 * longimagedata - 00248 * read in a B/W RGB or RGBA iris image file and return a 00249 * pointer to an array of ints. 00250 * 00251 */ 00252 00253 struct ImBuf *imb_loadiris(unsigned char *mem, size_t size, int flags) 00254 { 00255 unsigned int *base, *lptr = NULL; 00256 float *fbase, *fptr = NULL; 00257 unsigned int *zbase, *zptr; 00258 unsigned char *rledat; 00259 unsigned int *starttab, *lengthtab; 00260 FILE *inf = NULL; 00261 IMAGE image; 00262 int x, y, z, tablen; 00263 int xsize, ysize, zsize; 00264 int bpp, rle, cur, badorder; 00265 ImBuf * ibuf; 00266 00267 (void)size; /* unused */ 00268 00269 if(!imb_is_a_iris(mem)) return NULL; 00270 00271 /*printf("new iris\n");*/ 00272 00273 file_data = mem; 00274 file_offset = 0; 00275 00276 readheader(inf, &image); 00277 if(image.imagic != IMAGIC) { 00278 fprintf(stderr,"longimagedata: bad magic number in image file\n"); 00279 return(NULL); 00280 } 00281 00282 rle = ISRLE(image.type); 00283 bpp = BPP(image.type); 00284 if(bpp != 1 && bpp != 2) { 00285 fprintf(stderr,"longimagedata: image must have 1 or 2 byte per pix chan\n"); 00286 return(NULL); 00287 } 00288 00289 xsize = image.xsize; 00290 ysize = image.ysize; 00291 zsize = image.zsize; 00292 00293 if (flags & IB_test) { 00294 ibuf = IMB_allocImBuf(image.xsize, image.ysize, 8 * image.zsize, 0); 00295 if (ibuf) ibuf->ftype = IMAGIC; 00296 return(ibuf); 00297 } 00298 00299 if (rle) { 00300 00301 tablen = ysize*zsize*sizeof(int); 00302 starttab = (unsigned int *)MEM_mallocN(tablen, "iris starttab"); 00303 lengthtab = (unsigned int *)MEM_mallocN(tablen, "iris endtab"); 00304 file_offset = 512; 00305 00306 readtab(inf,starttab,tablen); 00307 readtab(inf,lengthtab,tablen); 00308 00309 /* check data order */ 00310 cur = 0; 00311 badorder = 0; 00312 for (y = 0; y<ysize; y++) { 00313 for (z = 0; z<zsize; z++) { 00314 if (starttab[y+z*ysize]<cur) { 00315 badorder = 1; 00316 break; 00317 } 00318 cur = starttab[y+z*ysize]; 00319 } 00320 if(badorder) 00321 break; 00322 } 00323 00324 if (bpp == 1) { 00325 00326 ibuf = IMB_allocImBuf(xsize, ysize, 8 * zsize, IB_rect); 00327 if (ibuf->depth > 32) ibuf->depth = 32; 00328 base = ibuf->rect; 00329 zbase = (unsigned int *)ibuf->zbuf; 00330 00331 if (badorder) { 00332 for(z=0; z<zsize; z++) { 00333 lptr = base; 00334 for(y=0; y<ysize; y++) { 00335 file_offset = starttab[y+z*ysize]; 00336 00337 rledat = file_data + file_offset; 00338 file_offset += lengthtab[y+z*ysize]; 00339 00340 expandrow((uchar *)lptr, rledat, 3-z); 00341 lptr += xsize; 00342 } 00343 } 00344 } else { 00345 lptr = base; 00346 zptr = zbase; 00347 for(y=0; y<ysize; y++) { 00348 00349 for(z=0; z<zsize; z++) { 00350 00351 file_offset = starttab[y+z*ysize]; 00352 00353 rledat = file_data + file_offset; 00354 file_offset += lengthtab[y+z*ysize]; 00355 00356 if(z<4) expandrow((uchar *)lptr, rledat, 3-z); 00357 else if(z<8) expandrow((uchar *)zptr, rledat, 7-z); 00358 } 00359 lptr += xsize; 00360 zptr += xsize; 00361 } 00362 } 00363 00364 00365 } else { /* bpp == 2 */ 00366 00367 ibuf = IMB_allocImBuf(xsize, ysize, 32, (flags & IB_rect)|IB_rectfloat); 00368 00369 fbase = ibuf->rect_float; 00370 00371 if (badorder) { 00372 for(z=0; z<zsize; z++) { 00373 fptr = fbase; 00374 for(y=0; y<ysize; y++) { 00375 file_offset = starttab[y+z*ysize]; 00376 00377 rledat = file_data + file_offset; 00378 file_offset += lengthtab[y+z*ysize]; 00379 00380 expandrow2(fptr, rledat, 3-z); 00381 fptr += xsize * 4; 00382 } 00383 } 00384 } else { 00385 fptr = fbase; 00386 00387 for(y=0; y<ysize; y++) { 00388 00389 for(z=0; z<zsize; z++) { 00390 00391 file_offset = starttab[y+z*ysize]; 00392 00393 rledat = file_data + file_offset; 00394 file_offset += lengthtab[y+z*ysize]; 00395 00396 expandrow2(fptr, rledat, 3-z); 00397 00398 } 00399 fptr += xsize * 4; 00400 } 00401 } 00402 } 00403 00404 MEM_freeN(starttab); 00405 MEM_freeN(lengthtab); 00406 00407 } else { 00408 if (bpp == 1) { 00409 00410 ibuf = IMB_allocImBuf(xsize, ysize, 8 * zsize, IB_rect); 00411 if (ibuf->depth > 32) ibuf->depth = 32; 00412 00413 base = ibuf->rect; 00414 zbase = (unsigned int *)ibuf->zbuf; 00415 00416 file_offset = 512; 00417 rledat = file_data + file_offset; 00418 00419 for(z = 0; z < zsize; z++) { 00420 00421 if(z<4) lptr = base; 00422 else if(z<8) lptr= zbase; 00423 00424 for(y = 0; y < ysize; y++) { 00425 00426 interleaverow((uchar *)lptr, rledat, 3-z, xsize); 00427 rledat += xsize; 00428 00429 lptr += xsize; 00430 } 00431 } 00432 00433 } else { /* bpp == 2 */ 00434 00435 ibuf = IMB_allocImBuf(xsize, ysize, 32, (flags & IB_rect)|IB_rectfloat); 00436 00437 fbase = ibuf->rect_float; 00438 00439 file_offset = 512; 00440 rledat = file_data + file_offset; 00441 00442 for(z = 0; z < zsize; z++) { 00443 00444 fptr = fbase; 00445 00446 for(y = 0; y < ysize; y++) { 00447 00448 interleaverow2(fptr, rledat, 3-z, xsize); 00449 rledat += xsize * 2; 00450 00451 fptr += xsize * 4; 00452 } 00453 } 00454 00455 } 00456 } 00457 00458 00459 if (bpp == 1) { 00460 uchar * rect; 00461 00462 if (image.zsize == 1){ 00463 rect = (uchar *) ibuf->rect; 00464 for (x = ibuf->x * ibuf->y; x > 0; x--) { 00465 rect[0] = 255; 00466 rect[1] = rect[2] = rect[3]; 00467 rect += 4; 00468 } 00469 } else if (image.zsize == 2){ 00470 /* grayscale with alpha */ 00471 rect = (uchar *) ibuf->rect; 00472 for (x = ibuf->x * ibuf->y; x > 0; x--) { 00473 rect[0] = rect[2]; 00474 rect[1] = rect[2] = rect[3]; 00475 rect += 4; 00476 } 00477 } else if (image.zsize == 3){ 00478 /* add alpha */ 00479 rect = (uchar *) ibuf->rect; 00480 for (x = ibuf->x * ibuf->y; x > 0; x--) { 00481 rect[0] = 255; 00482 rect += 4; 00483 } 00484 } 00485 00486 } else { /* bpp == 2 */ 00487 00488 if (image.zsize == 1){ 00489 fbase = ibuf->rect_float; 00490 for (x = ibuf->x * ibuf->y; x > 0; x--) { 00491 fbase[0] = 1; 00492 fbase[1] = fbase[2] = fbase[3]; 00493 fbase += 4; 00494 } 00495 } else if (image.zsize == 2){ 00496 /* grayscale with alpha */ 00497 fbase = ibuf->rect_float; 00498 for (x = ibuf->x * ibuf->y; x > 0; x--) { 00499 fbase[0] = fbase[2]; 00500 fbase[1] = fbase[2] = fbase[3]; 00501 fbase += 4; 00502 } 00503 } else if (image.zsize == 3){ 00504 /* add alpha */ 00505 fbase = ibuf->rect_float; 00506 for (x = ibuf->x * ibuf->y; x > 0; x--) { 00507 fbase[0] = 1; 00508 fbase += 4; 00509 } 00510 } 00511 00512 if (flags & IB_rect) { 00513 IMB_rect_from_float(ibuf); 00514 } 00515 00516 } 00517 00518 ibuf->ftype = IMAGIC; 00519 ibuf->profile = IB_PROFILE_SRGB; 00520 00521 test_endian_zbuf(ibuf); 00522 00523 if (ibuf) { 00524 if (ibuf->rect) 00525 IMB_convert_rgba_to_abgr(ibuf); 00526 } 00527 00528 return(ibuf); 00529 } 00530 00531 /* static utility functions for longimagedata */ 00532 00533 static void interleaverow(unsigned char *lptr, unsigned char *cptr, int z, int n) 00534 { 00535 lptr += z; 00536 while(n--) { 00537 *lptr = *cptr++; 00538 lptr += 4; 00539 } 00540 } 00541 00542 static void interleaverow2(float *lptr, unsigned char *cptr, int z, int n) 00543 { 00544 lptr += z; 00545 while(n--) { 00546 *lptr = ((cptr[0]<<8) | (cptr[1]<<0)) / (float)0xFFFF; 00547 cptr += 2; 00548 lptr += 4; 00549 } 00550 } 00551 00552 static void expandrow2(float *optr, unsigned char *iptr, int z) 00553 { 00554 unsigned short pixel, count; 00555 float pixel_f; 00556 00557 optr += z; 00558 while(1) { 00559 pixel = (iptr[0]<<8) | (iptr[1]<<0); 00560 iptr += 2; 00561 00562 if ( !(count = (pixel & 0x7f)) ) 00563 return; 00564 if(pixel & 0x80) { 00565 while(count>=8) { 00566 optr[0*4] = ((iptr[0]<<8) | (iptr[1]<<0))/(float)0xFFFF; 00567 optr[1*4] = ((iptr[2]<<8) | (iptr[3]<<0))/(float)0xFFFF; 00568 optr[2*4] = ((iptr[4]<<8) | (iptr[5]<<0))/(float)0xFFFF; 00569 optr[3*4] = ((iptr[6]<<8) | (iptr[7]<<0))/(float)0xFFFF; 00570 optr[4*4] = ((iptr[8]<<8) | (iptr[9]<<0))/(float)0xFFFF; 00571 optr[5*4] = ((iptr[10]<<8) | (iptr[11]<<0))/(float)0xFFFF; 00572 optr[6*4] = ((iptr[12]<<8) | (iptr[13]<<0))/(float)0xFFFF; 00573 optr[7*4] = ((iptr[14]<<8) | (iptr[15]<<0))/(float)0xFFFF; 00574 optr += 8*4; 00575 iptr += 8*2; 00576 count -= 8; 00577 } 00578 while(count--) { 00579 *optr = ((iptr[0]<<8) | (iptr[1]<<0))/(float)0xFFFF; 00580 iptr+=2; 00581 optr+=4; 00582 } 00583 } else { 00584 pixel_f = ((iptr[0]<<8) | (iptr[1]<<0))/(float)0xFFFF; 00585 iptr += 2; 00586 00587 while(count>=8) { 00588 optr[0*4] = pixel_f; 00589 optr[1*4] = pixel_f; 00590 optr[2*4] = pixel_f; 00591 optr[3*4] = pixel_f; 00592 optr[4*4] = pixel_f; 00593 optr[5*4] = pixel_f; 00594 optr[6*4] = pixel_f; 00595 optr[7*4] = pixel_f; 00596 optr += 8*4; 00597 count -= 8; 00598 } 00599 while(count--) { 00600 *optr = pixel_f; 00601 optr+=4; 00602 } 00603 } 00604 } 00605 } 00606 00607 static void expandrow(unsigned char *optr, unsigned char *iptr, int z) 00608 { 00609 unsigned char pixel, count; 00610 00611 optr += z; 00612 while(1) { 00613 pixel = *iptr++; 00614 if ( !(count = (pixel & 0x7f)) ) 00615 return; 00616 if(pixel & 0x80) { 00617 while(count>=8) { 00618 optr[0*4] = iptr[0]; 00619 optr[1*4] = iptr[1]; 00620 optr[2*4] = iptr[2]; 00621 optr[3*4] = iptr[3]; 00622 optr[4*4] = iptr[4]; 00623 optr[5*4] = iptr[5]; 00624 optr[6*4] = iptr[6]; 00625 optr[7*4] = iptr[7]; 00626 optr += 8*4; 00627 iptr += 8; 00628 count -= 8; 00629 } 00630 while(count--) { 00631 *optr = *iptr++; 00632 optr+=4; 00633 } 00634 } else { 00635 pixel = *iptr++; 00636 while(count>=8) { 00637 optr[0*4] = pixel; 00638 optr[1*4] = pixel; 00639 optr[2*4] = pixel; 00640 optr[3*4] = pixel; 00641 optr[4*4] = pixel; 00642 optr[5*4] = pixel; 00643 optr[6*4] = pixel; 00644 optr[7*4] = pixel; 00645 optr += 8*4; 00646 count -= 8; 00647 } 00648 while(count--) { 00649 *optr = pixel; 00650 optr+=4; 00651 } 00652 } 00653 } 00654 } 00655 00656 /* 00657 * output_iris - 00658 * copy an array of ints to an iris image file. Each int 00659 * represents one pixel. xsize and ysize specify the dimensions of 00660 * the pixel array. zsize specifies what kind of image file to 00661 * write out. if zsize is 1, the luminance of the pixels are 00662 * calculated, and a sinlge channel black and white image is saved. 00663 * If zsize is 3, an RGB image file is saved. If zsize is 4, an 00664 * RGBA image file is saved. 00665 * 00666 * Added: zbuf write 00667 */ 00668 00669 static int output_iris(unsigned int *lptr, int xsize, int ysize, int zsize, const char *name, int *zptr) 00670 { 00671 FILE *outf; 00672 IMAGE *image; 00673 int tablen, y, z, pos, len = 0; 00674 unsigned int *starttab, *lengthtab; 00675 unsigned char *rlebuf; 00676 unsigned int *lumbuf; 00677 int rlebuflen, goodwrite; 00678 00679 goodwrite = 1; 00680 outf = fopen(name, "wb"); 00681 if(!outf) return 0; 00682 00683 tablen = ysize*zsize*sizeof(int); 00684 00685 image = (IMAGE *)MEM_mallocN(sizeof(IMAGE), "iris image"); 00686 starttab = (unsigned int *)MEM_mallocN(tablen, "iris starttab"); 00687 lengthtab = (unsigned int *)MEM_mallocN(tablen, "iris lengthtab"); 00688 rlebuflen = 1.05*xsize+10; 00689 rlebuf = (unsigned char *)MEM_mallocN(rlebuflen, "iris rlebuf"); 00690 lumbuf = (unsigned int *)MEM_mallocN(xsize*sizeof(int), "iris lumbuf"); 00691 00692 memset(image, 0, sizeof(IMAGE)); 00693 image->imagic = IMAGIC; 00694 image->type = RLE(1); 00695 if(zsize>1) 00696 image->dim = 3; 00697 else 00698 image->dim = 2; 00699 image->xsize = xsize; 00700 image->ysize = ysize; 00701 image->zsize = zsize; 00702 image->min = 0; 00703 image->max = 255; 00704 goodwrite *= writeheader(outf,image); 00705 fseek(outf,512+2*tablen,SEEK_SET); 00706 pos = 512+2*tablen; 00707 00708 for (y = 0; y < ysize; y++) { 00709 for (z = 0; z < zsize; z++) { 00710 00711 if (zsize == 1) { 00712 lumrow((uchar *)lptr,(uchar *)lumbuf,xsize); 00713 len = compressrow((uchar *)lumbuf,rlebuf,CHANOFFSET(z),xsize); 00714 } 00715 else { 00716 if(z<4) { 00717 len = compressrow((uchar *)lptr, rlebuf,CHANOFFSET(z),xsize); 00718 } 00719 else if(z<8 && zptr) { 00720 len = compressrow((uchar *)zptr, rlebuf,CHANOFFSET(z-4),xsize); 00721 } 00722 } 00723 if(len>rlebuflen) { 00724 fprintf(stderr,"output_iris: rlebuf is too small - bad poop\n"); 00725 exit(1); 00726 } 00727 goodwrite *= fwrite(rlebuf, len, 1, outf); 00728 starttab[y+z*ysize] = pos; 00729 lengthtab[y+z*ysize] = len; 00730 pos += len; 00731 } 00732 lptr += xsize; 00733 if(zptr) zptr += xsize; 00734 } 00735 00736 fseek(outf,512,SEEK_SET); 00737 goodwrite *= writetab(outf,starttab,tablen); 00738 goodwrite *= writetab(outf,lengthtab,tablen); 00739 MEM_freeN(image); 00740 MEM_freeN(starttab); 00741 MEM_freeN(lengthtab); 00742 MEM_freeN(rlebuf); 00743 MEM_freeN(lumbuf); 00744 fclose(outf); 00745 if(goodwrite) 00746 return 1; 00747 else { 00748 fprintf(stderr,"output_iris: not enough space for image!!\n"); 00749 return 0; 00750 } 00751 } 00752 00753 /* static utility functions for output_iris */ 00754 00755 static void lumrow(unsigned char *rgbptr, unsigned char *lumptr, int n) 00756 { 00757 lumptr += CHANOFFSET(0); 00758 while(n--) { 00759 *lumptr = ILUM(rgbptr[OFFSET_R],rgbptr[OFFSET_G],rgbptr[OFFSET_B]); 00760 lumptr += 4; 00761 rgbptr += 4; 00762 } 00763 } 00764 00765 static int compressrow(unsigned char *lbuf, unsigned char *rlebuf, int z, int cnt) 00766 { 00767 unsigned char *iptr, *ibufend, *sptr, *optr; 00768 short todo, cc; 00769 int count; 00770 00771 lbuf += z; 00772 iptr = lbuf; 00773 ibufend = iptr+cnt*4; 00774 optr = rlebuf; 00775 00776 while(iptr<ibufend) { 00777 sptr = iptr; 00778 iptr += 8; 00779 while((iptr<ibufend)&& ((iptr[-8]!=iptr[-4])||(iptr[-4]!=iptr[0]))) 00780 iptr+=4; 00781 iptr -= 8; 00782 count = (iptr-sptr)/4; 00783 while(count) { 00784 todo = count>126 ? 126:count; 00785 count -= todo; 00786 *optr++ = 0x80|todo; 00787 while(todo>8) { 00788 optr[0] = sptr[0*4]; 00789 optr[1] = sptr[1*4]; 00790 optr[2] = sptr[2*4]; 00791 optr[3] = sptr[3*4]; 00792 optr[4] = sptr[4*4]; 00793 optr[5] = sptr[5*4]; 00794 optr[6] = sptr[6*4]; 00795 optr[7] = sptr[7*4]; 00796 00797 optr += 8; 00798 sptr += 8*4; 00799 todo -= 8; 00800 } 00801 while(todo--) { 00802 *optr++ = *sptr; 00803 sptr += 4; 00804 } 00805 } 00806 sptr = iptr; 00807 cc = *iptr; 00808 iptr += 4; 00809 while( (iptr<ibufend) && (*iptr == cc) ) 00810 iptr += 4; 00811 count = (iptr-sptr)/4; 00812 while(count) { 00813 todo = count>126 ? 126:count; 00814 count -= todo; 00815 *optr++ = todo; 00816 *optr++ = cc; 00817 } 00818 } 00819 *optr++ = 0; 00820 return optr - (unsigned char *)rlebuf; 00821 } 00822 00823 int imb_saveiris(struct ImBuf * ibuf, const char *name, int flags) 00824 { 00825 short zsize; 00826 int ret; 00827 00828 zsize = (ibuf->depth + 7) >> 3; 00829 if (flags & IB_zbuf && ibuf->zbuf != NULL) zsize = 8; 00830 00831 IMB_convert_rgba_to_abgr(ibuf); 00832 test_endian_zbuf(ibuf); 00833 00834 ret = output_iris(ibuf->rect, ibuf->x, ibuf->y, zsize, name, ibuf->zbuf); 00835 00836 /* restore! Quite clumsy, 2 times a switch... maybe better a malloc ? */ 00837 IMB_convert_rgba_to_abgr(ibuf); 00838 test_endian_zbuf(ibuf); 00839 00840 return(ret); 00841 } 00842