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