Blender  V2.93
iris.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17  * All rights reserved.
18  */
19 
24 #include <string.h>
25 
26 #include "BLI_fileops.h"
27 #include "BLI_utildefines.h"
28 
29 #include "MEM_guardedalloc.h"
30 
31 #include "IMB_filetype.h"
32 #include "IMB_imbuf.h"
33 #include "IMB_imbuf_types.h"
34 #include "imbuf.h"
35 
36 #include "IMB_colormanagement.h"
38 
39 #define IMAGIC 0732
40 
41 typedef struct {
42  ushort imagic; /* stuff saved on disk . . */
50  uchar _pad1[4];
51  char name[80];
53  uchar _pad2[404];
54 } IMAGE;
55 
56 #define HEADER_SIZE 512
57 
58 BLI_STATIC_ASSERT(sizeof(IMAGE) == HEADER_SIZE, "Invalid header size");
59 
60 #define RINTLUM (79)
61 #define GINTLUM (156)
62 #define BINTLUM (21)
63 
64 #define ILUM(r, g, b) ((int)(RINTLUM * (r) + GINTLUM * (g) + BINTLUM * (b)) >> 8)
65 
66 #define OFFSET_R 0 /* this is byte order dependent */
67 #define OFFSET_G 1
68 #define OFFSET_B 2
69 // #define OFFSET_A 3
70 
71 #define CHANOFFSET(z) (3 - (z)) /* this is byte order dependent */
72 
73 // #define TYPEMASK 0xff00
74 #define BPPMASK 0x00ff
75 // #define ITYPE_VERBATIM 0x0000 // UNUSED
76 #define ITYPE_RLE 0x0100
77 #define ISRLE(type) (((type)&0xff00) == ITYPE_RLE)
78 // #define ISVERBATIM(type) (((type) & 0xff00) == ITYPE_VERBATIM)
79 #define BPP(type) ((type)&BPPMASK)
80 #define RLE(bpp) (ITYPE_RLE | (bpp))
81 // #define VERBATIM(bpp) (ITYPE_VERBATIM | (bpp)) // UNUSED
82 // #define IBUFSIZE(pixels) ((pixels + (pixels >> 6)) << 2) // UNUSED
83 // #define RLE_NOP 0x00
84 
85 /* local struct for mem access */
86 typedef struct MFileOffset {
87  const uchar *_file_data;
90 
91 #define MFILE_DATA(inf) ((void)0, ((inf)->_file_data + (inf)->_file_offset))
92 #define MFILE_STEP(inf, step) \
93  { \
94  (inf)->_file_offset += step; \
95  } \
96  ((void)0)
97 #define MFILE_SEEK(inf, pos) \
98  { \
99  (inf)->_file_offset = pos; \
100  } \
101  ((void)0)
102 
103 /* error flags */
104 #define DIRTY_FLAG_EOF (1 << 0)
105 #define DIRTY_FLAG_ENCODING (1 << 1)
106 
107 /* funcs */
108 static void readheader(MFileOffset *inf, IMAGE *image);
109 static int writeheader(FILE *outf, IMAGE *image);
110 
111 static ushort getshort(MFileOffset *inf);
112 static uint getlong(MFileOffset *mofs);
113 static void putshort(FILE *outf, ushort val);
114 static int putlong(FILE *outf, uint val);
115 static int writetab(FILE *outf, uint *tab, int len);
116 static void readtab(MFileOffset *inf, uint *tab, int len);
117 
118 static int expandrow(
119  uchar *optr, const uchar *optr_end, const uchar *iptr, const uchar *iptr_end, int z);
120 static int expandrow2(
121  float *optr, const float *optr_end, const uchar *iptr, const uchar *iptr_end, int z);
122 static void interleaverow(uchar *lptr, const uchar *cptr, int z, int n);
123 static void interleaverow2(float *lptr, const uchar *cptr, int z, int n);
124 static int compressrow(uchar *lbuf, uchar *rlebuf, int z, int cnt);
125 static void lumrow(const uchar *rgbptr, uchar *lumptr, int n);
126 
127 /*
128  * byte order independent read/write of shorts and ints.
129  */
130 
132 {
133  const uchar *buf;
134 
135  buf = MFILE_DATA(inf);
136  MFILE_STEP(inf, 2);
137 
138  return ((ushort)buf[0] << 8) + ((ushort)buf[1] << 0);
139 }
140 
141 static uint getlong(MFileOffset *mofs)
142 {
143  const uchar *buf;
144 
145  buf = MFILE_DATA(mofs);
146  MFILE_STEP(mofs, 4);
147 
148  return ((uint)buf[0] << 24) + ((uint)buf[1] << 16) + ((uint)buf[2] << 8) + ((uint)buf[3] << 0);
149 }
150 
151 static void putshort(FILE *outf, ushort val)
152 {
153  uchar buf[2];
154 
155  buf[0] = (val >> 8);
156  buf[1] = (val >> 0);
157  fwrite(buf, 2, 1, outf);
158 }
159 
160 static int putlong(FILE *outf, uint val)
161 {
162  uchar buf[4];
163 
164  buf[0] = (val >> 24);
165  buf[1] = (val >> 16);
166  buf[2] = (val >> 8);
167  buf[3] = (val >> 0);
168  return fwrite(buf, 4, 1, outf);
169 }
170 
171 static void readheader(MFileOffset *inf, IMAGE *image)
172 {
173  memset(image, 0, sizeof(IMAGE));
174  image->imagic = getshort(inf);
175  image->type = getshort(inf);
176  image->dim = getshort(inf);
177  image->xsize = getshort(inf);
178  image->ysize = getshort(inf);
179  image->zsize = getshort(inf);
180 }
181 
182 static int writeheader(FILE *outf, IMAGE *image)
183 {
184  IMAGE t = {0};
185 
186  fwrite(&t, sizeof(IMAGE), 1, outf);
187  fseek(outf, 0, SEEK_SET);
188  putshort(outf, image->imagic);
189  putshort(outf, image->type);
190  putshort(outf, image->dim);
191  putshort(outf, image->xsize);
192  putshort(outf, image->ysize);
193  putshort(outf, image->zsize);
194  putlong(outf, image->min);
195  putlong(outf, image->max);
196  putlong(outf, 0);
197  return fwrite("no name", 8, 1, outf);
198 }
199 
200 static int writetab(FILE *outf, uint *tab, int len)
201 {
202  int r = 0;
203 
204  while (len) {
205  r = putlong(outf, *tab++);
206  len -= 4;
207  }
208  return r;
209 }
210 
211 static void readtab(MFileOffset *inf, uint *tab, int len)
212 {
213  while (len) {
214  *tab++ = getlong(inf);
215  len -= 4;
216  }
217 }
218 
219 static void test_endian_zbuf(struct ImBuf *ibuf)
220 {
221  int len;
222  int *zval;
223 
224  if (BIG_LONG(1) == 1) {
225  return;
226  }
227  if (ibuf->zbuf == NULL) {
228  return;
229  }
230 
231  len = ibuf->x * ibuf->y;
232  zval = ibuf->zbuf;
233 
234  while (len--) {
235  zval[0] = BIG_LONG(zval[0]);
236  zval++;
237  }
238 }
239 
240 /* from misc_util: flip the bytes from x */
241 #define GS(x) (((uchar *)(x))[0] << 8 | ((uchar *)(x))[1])
242 
243 /* this one is only def-ed once, strangely... */
244 #define GSS(x) (((uchar *)(x))[1] << 8 | ((uchar *)(x))[0])
245 
246 bool imb_is_a_iris(const uchar *mem, size_t size)
247 {
248  if (size < 2) {
249  return false;
250  }
251  return ((GS(mem) == IMAGIC) || (GSS(mem) == IMAGIC));
252 }
253 
254 /*
255  * longimagedata -
256  * read in a B/W RGB or RGBA iris image file and return a
257  * pointer to an array of ints.
258  */
259 
260 struct ImBuf *imb_loadiris(const uchar *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE])
261 {
262  uint *base, *lptr = NULL;
263  float *fbase, *fptr = NULL;
264  uint *zbase, *zptr;
265  const uchar *rledat;
266  const uchar *mem_end = mem + size;
267  MFileOffset _inf_data = {mem, 0}, *inf = &_inf_data;
268  IMAGE image;
269  int bpp, rle, cur, badorder;
270  ImBuf *ibuf = NULL;
271  uchar dirty_flag = 0;
272 
273  if (!imb_is_a_iris(mem, size)) {
274  return NULL;
275  }
276 
277  /* Could pe part of the magic check above,
278  * by convention this check only requests the size needed to read it's magic though. */
279  if (size < HEADER_SIZE) {
280  return NULL;
281  }
282 
283  /* OCIO_TODO: only tested with 1 byte per pixel, not sure how to test with other settings */
285 
286  readheader(inf, &image);
287  if (image.imagic != IMAGIC) {
288  fprintf(stderr, "longimagedata: bad magic number in image file\n");
289  return NULL;
290  }
291 
292  rle = ISRLE(image.type);
293  bpp = BPP(image.type);
294  if (!ELEM(bpp, 1, 2)) {
295  fprintf(stderr, "longimagedata: image must have 1 or 2 byte per pix chan\n");
296  return NULL;
297  }
298  if ((uint)image.zsize > 8) {
299  fprintf(stderr, "longimagedata: channels over 8 not supported\n");
300  return NULL;
301  }
302 
303  const int xsize = image.xsize;
304  const int ysize = image.ysize;
305  const int zsize = image.zsize;
306 
307  if (flags & IB_test) {
308  ibuf = IMB_allocImBuf(image.xsize, image.ysize, 8 * image.zsize, 0);
309  if (ibuf) {
310  ibuf->ftype = IMB_FTYPE_IMAGIC;
311  }
312  return ibuf;
313  }
314 
315  if (rle) {
316  size_t tablen = (size_t)ysize * (size_t)zsize * sizeof(int);
317  MFILE_SEEK(inf, HEADER_SIZE);
318 
319  uint *starttab = MEM_mallocN(tablen, "iris starttab");
320  uint *lengthtab = MEM_mallocN(tablen, "iris endtab");
321 
322 #define MFILE_CAPACITY_AT_PTR_OK_OR_FAIL(p) \
323  if (UNLIKELY((p) > mem_end)) { \
324  dirty_flag |= DIRTY_FLAG_EOF; \
325  goto fail_rle; \
326  } \
327  ((void)0)
328 
329  MFILE_CAPACITY_AT_PTR_OK_OR_FAIL(MFILE_DATA(inf) + ((4 * 2) * tablen));
330 
331  readtab(inf, starttab, tablen);
332  readtab(inf, lengthtab, tablen);
333 
334  /* check data order */
335  cur = 0;
336  badorder = 0;
337  for (size_t y = 0; y < ysize; y++) {
338  for (size_t z = 0; z < zsize; z++) {
339  if (starttab[y + z * ysize] < cur) {
340  badorder = 1;
341  break;
342  }
343  cur = starttab[y + z * ysize];
344  }
345  if (badorder) {
346  break;
347  }
348  }
349 
350  if (bpp == 1) {
351 
352  ibuf = IMB_allocImBuf(xsize, ysize, 8 * zsize, IB_rect);
353  if (!ibuf) {
354  goto fail_rle;
355  }
356  if (ibuf->planes > 32) {
357  ibuf->planes = 32;
358  }
359  base = ibuf->rect;
360  zbase = (uint *)ibuf->zbuf;
361 
362  if (badorder) {
363  for (size_t z = 0; z < zsize; z++) {
364  lptr = base;
365  for (size_t y = 0; y < ysize; y++) {
366  MFILE_SEEK(inf, starttab[y + z * ysize]);
367  rledat = MFILE_DATA(inf);
368  MFILE_STEP(inf, lengthtab[y + z * ysize]);
369  const uchar *rledat_next = MFILE_DATA(inf);
370  uint *lptr_next = lptr + xsize;
372  dirty_flag |= expandrow((uchar *)lptr, (uchar *)lptr_next, rledat, rledat_next, 3 - z);
373  lptr = lptr_next;
374  }
375  }
376  }
377  else {
378  lptr = base;
379  zptr = zbase;
380  for (size_t y = 0; y < ysize; y++) {
381 
382  uint *lptr_next = lptr + xsize;
383  uint *zptr_next = zptr + xsize;
384 
385  for (size_t z = 0; z < zsize; z++) {
386  MFILE_SEEK(inf, starttab[y + z * ysize]);
387  rledat = MFILE_DATA(inf);
388  MFILE_STEP(inf, lengthtab[y + z * ysize]);
389  const uchar *rledat_next = MFILE_DATA(inf);
391  if (z < 4) {
392  dirty_flag |= expandrow(
393  (uchar *)lptr, (uchar *)lptr_next, rledat, rledat_next, 3 - z);
394  }
395  else if (z < 8) {
396  dirty_flag |= expandrow(
397  (uchar *)zptr, (uchar *)zptr_next, rledat, rledat_next, 7 - z);
398  }
399  }
400  lptr = lptr_next;
401  zptr = zptr_next;
402  }
403  }
404  }
405  else { /* bpp == 2 */
406 
407  ibuf = IMB_allocImBuf(xsize, ysize, 32, (flags & IB_rect) | IB_rectfloat);
408  if (!ibuf) {
409  goto fail_rle;
410  }
411 
412  fbase = ibuf->rect_float;
413 
414  if (badorder) {
415  for (size_t z = 0; z < zsize; z++) {
416  fptr = fbase;
417  for (size_t y = 0; y < ysize; y++) {
418  MFILE_SEEK(inf, starttab[y + z * ysize]);
419  rledat = MFILE_DATA(inf);
420  MFILE_STEP(inf, lengthtab[y + z * ysize]);
421  const uchar *rledat_next = MFILE_DATA(inf);
423  float *fptr_next = fptr + (xsize * 4);
424  dirty_flag |= expandrow2(fptr, fptr_next, rledat, rledat_next, 3 - z);
425  fptr = fptr_next;
426  }
427  }
428  }
429  else {
430  fptr = fbase;
431  float *fptr_next = fptr + (xsize * 4);
432 
433  for (size_t y = 0; y < ysize; y++) {
434 
435  for (size_t z = 0; z < zsize; z++) {
436  MFILE_SEEK(inf, starttab[y + z * ysize]);
437  rledat = MFILE_DATA(inf);
438  MFILE_STEP(inf, lengthtab[y + z * ysize]);
439  const uchar *rledat_next = MFILE_DATA(inf);
441  dirty_flag |= expandrow2(fptr, fptr_next, rledat, rledat_next, 3 - z);
442  }
443  fptr = fptr_next;
444  }
445  }
446  }
447 #undef MFILE_CAPACITY_AT_PTR_OK_OR_FAIL
448  fail_rle:
449  MEM_freeN(starttab);
450  MEM_freeN(lengthtab);
451 
452  if (!ibuf) {
453  return NULL;
454  }
455  }
456  else {
457 
458 #define MFILE_CAPACITY_AT_PTR_OK_OR_FAIL(p) \
459  if (UNLIKELY((p) > mem_end)) { \
460  dirty_flag |= DIRTY_FLAG_EOF; \
461  goto fail_uncompressed; \
462  } \
463  ((void)0)
464 
465  if (bpp == 1) {
466 
467  ibuf = IMB_allocImBuf(xsize, ysize, 8 * zsize, IB_rect);
468  if (!ibuf) {
469  goto fail_uncompressed;
470  }
471  if (ibuf->planes > 32) {
472  ibuf->planes = 32;
473  }
474 
475  base = ibuf->rect;
476  zbase = (uint *)ibuf->zbuf;
477 
478  MFILE_SEEK(inf, HEADER_SIZE);
479  rledat = MFILE_DATA(inf);
480 
481  for (size_t z = 0; z < zsize; z++) {
482 
483  if (z < 4) {
484  lptr = base;
485  }
486  else if (z < 8) {
487  lptr = zbase;
488  }
489 
490  for (size_t y = 0; y < ysize; y++) {
491  const uchar *rledat_next = rledat + xsize;
492  const int z_ofs = 3 - z;
493  MFILE_CAPACITY_AT_PTR_OK_OR_FAIL(rledat_next + z_ofs);
494  interleaverow((uchar *)lptr, rledat, z_ofs, xsize);
495  rledat = rledat_next;
496  lptr += xsize;
497  }
498  }
499  }
500  else { /* bpp == 2 */
501 
502  ibuf = IMB_allocImBuf(xsize, ysize, 32, (flags & IB_rect) | IB_rectfloat);
503  if (!ibuf) {
504  goto fail_uncompressed;
505  }
506 
507  fbase = ibuf->rect_float;
508 
509  MFILE_SEEK(inf, HEADER_SIZE);
510  rledat = MFILE_DATA(inf);
511 
512  for (size_t z = 0; z < zsize; z++) {
513 
514  fptr = fbase;
515 
516  for (size_t y = 0; y < ysize; y++) {
517  const uchar *rledat_next = rledat + xsize * 2;
518  const int z_ofs = 3 - z;
519  MFILE_CAPACITY_AT_PTR_OK_OR_FAIL(rledat_next + z_ofs);
520  interleaverow2(fptr, rledat, z_ofs, xsize);
521  rledat = rledat_next;
522  fptr += xsize * 4;
523  }
524  }
525  }
526 #undef MFILE_CAPACITY_AT_PTR_OK_OR_FAIL
527  fail_uncompressed:
528  if (!ibuf) {
529  return NULL;
530  }
531  }
532 
533  if (bpp == 1) {
534  uchar *rect;
535 
536  if (image.zsize == 1) {
537  rect = (uchar *)ibuf->rect;
538  for (size_t x = (size_t)ibuf->x * (size_t)ibuf->y; x > 0; x--) {
539  rect[0] = 255;
540  rect[1] = rect[2] = rect[3];
541  rect += 4;
542  }
543  }
544  else if (image.zsize == 2) {
545  /* grayscale with alpha */
546  rect = (uchar *)ibuf->rect;
547  for (size_t x = (size_t)ibuf->x * (size_t)ibuf->y; x > 0; x--) {
548  rect[0] = rect[2];
549  rect[1] = rect[2] = rect[3];
550  rect += 4;
551  }
552  }
553  else if (image.zsize == 3) {
554  /* add alpha */
555  rect = (uchar *)ibuf->rect;
556  for (size_t x = (size_t)ibuf->x * (size_t)ibuf->y; x > 0; x--) {
557  rect[0] = 255;
558  rect += 4;
559  }
560  }
561  }
562  else { /* bpp == 2 */
563 
564  if (image.zsize == 1) {
565  fbase = ibuf->rect_float;
566  for (size_t x = (size_t)ibuf->x * (size_t)ibuf->y; x > 0; x--) {
567  fbase[0] = 1;
568  fbase[1] = fbase[2] = fbase[3];
569  fbase += 4;
570  }
571  }
572  else if (image.zsize == 2) {
573  /* grayscale with alpha */
574  fbase = ibuf->rect_float;
575  for (size_t x = (size_t)ibuf->x * (size_t)ibuf->y; x > 0; x--) {
576  fbase[0] = fbase[2];
577  fbase[1] = fbase[2] = fbase[3];
578  fbase += 4;
579  }
580  }
581  else if (image.zsize == 3) {
582  /* add alpha */
583  fbase = ibuf->rect_float;
584  for (size_t x = (size_t)ibuf->x * (size_t)ibuf->y; x > 0; x--) {
585  fbase[0] = 1;
586  fbase += 4;
587  }
588  }
589 
590  if (flags & IB_rect) {
591  IMB_rect_from_float(ibuf);
592  }
593  }
594 
595  if (dirty_flag) {
596  fprintf(stderr, "longimagedata: corrupt file content (%d)\n", dirty_flag);
597  }
598  ibuf->ftype = IMB_FTYPE_IMAGIC;
599 
600  test_endian_zbuf(ibuf);
601 
602  if (ibuf->rect) {
604  }
605 
606  return ibuf;
607 }
608 
609 /* static utility functions for longimagedata */
610 
611 static void interleaverow(uchar *lptr, const uchar *cptr, int z, int n)
612 {
613  lptr += z;
614  while (n--) {
615  *lptr = *cptr++;
616  lptr += 4;
617  }
618 }
619 
620 static void interleaverow2(float *lptr, const uchar *cptr, int z, int n)
621 {
622  lptr += z;
623  while (n--) {
624  *lptr = ((cptr[0] << 8) | (cptr[1] << 0)) / (float)0xFFFF;
625  cptr += 2;
626  lptr += 4;
627  }
628 }
629 
630 static int expandrow2(
631  float *optr, const float *optr_end, const uchar *iptr, const uchar *iptr_end, int z)
632 {
633  ushort pixel, count;
634  float pixel_f;
635 
636 #define EXPAND_CAPACITY_AT_INPUT_OK_OR_FAIL(iptr_next) \
637  if (UNLIKELY(iptr_next > iptr_end)) { \
638  goto fail; \
639  } \
640  ((void)0)
641 
642 #define EXPAND_CAPACITY_AT_OUTPUT_OK_OR_FAIL(optr_next) \
643  if (UNLIKELY(optr_next > optr_end)) { \
644  goto fail; \
645  } \
646  ((void)0)
647 
648  optr += z;
649  optr_end += z;
650  while (1) {
651  const uchar *iptr_next = iptr + 2;
653  pixel = (iptr[0] << 8) | (iptr[1] << 0);
654  iptr = iptr_next;
655 
656  if (!(count = (pixel & 0x7f))) {
657  return false;
658  }
659  const float *optr_next = optr + count;
661  if (pixel & 0x80) {
662  iptr_next = iptr + (count * 2);
664  while (count >= 8) {
665  optr[0 * 4] = ((iptr[0] << 8) | (iptr[1] << 0)) / (float)0xFFFF;
666  optr[1 * 4] = ((iptr[2] << 8) | (iptr[3] << 0)) / (float)0xFFFF;
667  optr[2 * 4] = ((iptr[4] << 8) | (iptr[5] << 0)) / (float)0xFFFF;
668  optr[3 * 4] = ((iptr[6] << 8) | (iptr[7] << 0)) / (float)0xFFFF;
669  optr[4 * 4] = ((iptr[8] << 8) | (iptr[9] << 0)) / (float)0xFFFF;
670  optr[5 * 4] = ((iptr[10] << 8) | (iptr[11] << 0)) / (float)0xFFFF;
671  optr[6 * 4] = ((iptr[12] << 8) | (iptr[13] << 0)) / (float)0xFFFF;
672  optr[7 * 4] = ((iptr[14] << 8) | (iptr[15] << 0)) / (float)0xFFFF;
673  optr += 8 * 4;
674  iptr += 8 * 2;
675  count -= 8;
676  }
677  while (count--) {
678  *optr = ((iptr[0] << 8) | (iptr[1] << 0)) / (float)0xFFFF;
679  iptr += 2;
680  optr += 4;
681  }
682  BLI_assert(iptr == iptr_next);
683  }
684  else {
685  iptr_next = iptr + 2;
687  pixel_f = ((iptr[0] << 8) | (iptr[1] << 0)) / (float)0xFFFF;
688  iptr = iptr_next;
689 
690  while (count >= 8) {
691  optr[0 * 4] = pixel_f;
692  optr[1 * 4] = pixel_f;
693  optr[2 * 4] = pixel_f;
694  optr[3 * 4] = pixel_f;
695  optr[4 * 4] = pixel_f;
696  optr[5 * 4] = pixel_f;
697  optr[6 * 4] = pixel_f;
698  optr[7 * 4] = pixel_f;
699  optr += 8 * 4;
700  count -= 8;
701  }
702  while (count--) {
703  *optr = pixel_f;
704  optr += 4;
705  }
706  BLI_assert(iptr == iptr_next);
707  }
708  BLI_assert(optr == optr_next);
709  }
710  return false;
711 
712 #undef EXPAND_CAPACITY_AT_INPUT_OK_OR_FAIL
713 #undef EXPAND_CAPACITY_AT_OUTPUT_OK_OR_FAIL
714 fail:
715  return DIRTY_FLAG_ENCODING;
716 }
717 
718 static int expandrow(
719  uchar *optr, const uchar *optr_end, const uchar *iptr, const uchar *iptr_end, int z)
720 {
721  uchar pixel, count;
722 
723 #define EXPAND_CAPACITY_AT_INPUT_OK_OR_FAIL(iptr_next) \
724  if (UNLIKELY(iptr_next > iptr_end)) { \
725  goto fail; \
726  } \
727  ((void)0)
728 
729 #define EXPAND_CAPACITY_AT_OUTPUT_OK_OR_FAIL(optr_next) \
730  if (UNLIKELY(optr_next > optr_end)) { \
731  goto fail; \
732  } \
733  ((void)0)
734 
735  optr += z;
736  optr_end += z;
737  while (1) {
738  const uchar *iptr_next = iptr + 1;
740  pixel = *iptr;
741  iptr = iptr_next;
742  if (!(count = (pixel & 0x7f))) {
743  return false;
744  }
745  const uchar *optr_next = optr + ((int)count * 4);
747 
748  if (pixel & 0x80) {
749  iptr_next = iptr + count;
751  while (count >= 8) {
752  optr[0 * 4] = iptr[0];
753  optr[1 * 4] = iptr[1];
754  optr[2 * 4] = iptr[2];
755  optr[3 * 4] = iptr[3];
756  optr[4 * 4] = iptr[4];
757  optr[5 * 4] = iptr[5];
758  optr[6 * 4] = iptr[6];
759  optr[7 * 4] = iptr[7];
760  optr += 8 * 4;
761  iptr += 8;
762  count -= 8;
763  }
764  while (count--) {
765  *optr = *iptr++;
766  optr += 4;
767  }
768  BLI_assert(iptr == iptr_next);
769  }
770  else {
771  iptr_next = iptr + 1;
773  pixel = *iptr++;
774  while (count >= 8) {
775  optr[0 * 4] = pixel;
776  optr[1 * 4] = pixel;
777  optr[2 * 4] = pixel;
778  optr[3 * 4] = pixel;
779  optr[4 * 4] = pixel;
780  optr[5 * 4] = pixel;
781  optr[6 * 4] = pixel;
782  optr[7 * 4] = pixel;
783  optr += 8 * 4;
784  count -= 8;
785  }
786  while (count--) {
787  *optr = pixel;
788  optr += 4;
789  }
790  BLI_assert(iptr == iptr_next);
791  }
792  BLI_assert(optr == optr_next);
793  }
794 
795  return false;
796 
797 #undef EXPAND_CAPACITY_AT_INPUT_OK_OR_FAIL
798 #undef EXPAND_CAPACITY_AT_OUTPUT_OK_OR_FAIL
799 fail:
800  return DIRTY_FLAG_ENCODING;
801 }
802 
815 static bool output_iris(uint *lptr, int xsize, int ysize, int zsize, const char *name, int *zptr)
816 {
817  FILE *outf;
818  IMAGE *image;
819  int tablen, y, z, pos, len = 0;
820  uint *starttab, *lengthtab;
821  uchar *rlebuf;
822  uint *lumbuf;
823  int rlebuflen, goodwrite;
824 
825  goodwrite = 1;
826  outf = BLI_fopen(name, "wb");
827  if (!outf) {
828  return 0;
829  }
830 
831  tablen = ysize * zsize * sizeof(int);
832 
833  image = (IMAGE *)MEM_mallocN(sizeof(IMAGE), "iris image");
834  starttab = (uint *)MEM_mallocN(tablen, "iris starttab");
835  lengthtab = (uint *)MEM_mallocN(tablen, "iris lengthtab");
836  rlebuflen = 1.05 * xsize + 10;
837  rlebuf = (uchar *)MEM_mallocN(rlebuflen, "iris rlebuf");
838  lumbuf = (uint *)MEM_mallocN(xsize * sizeof(int), "iris lumbuf");
839 
840  memset(image, 0, sizeof(IMAGE));
841  image->imagic = IMAGIC;
842  image->type = RLE(1);
843  if (zsize > 1) {
844  image->dim = 3;
845  }
846  else {
847  image->dim = 2;
848  }
849  image->xsize = xsize;
850  image->ysize = ysize;
851  image->zsize = zsize;
852  image->min = 0;
853  image->max = 255;
854  goodwrite *= writeheader(outf, image);
855  fseek(outf, HEADER_SIZE + (2 * tablen), SEEK_SET);
856  pos = HEADER_SIZE + (2 * tablen);
857 
858  for (y = 0; y < ysize; y++) {
859  for (z = 0; z < zsize; z++) {
860 
861  if (zsize == 1) {
862  lumrow((uchar *)lptr, (uchar *)lumbuf, xsize);
863  len = compressrow((uchar *)lumbuf, rlebuf, CHANOFFSET(z), xsize);
864  }
865  else {
866  if (z < 4) {
867  len = compressrow((uchar *)lptr, rlebuf, CHANOFFSET(z), xsize);
868  }
869  else if (z < 8 && zptr) {
870  len = compressrow((uchar *)zptr, rlebuf, CHANOFFSET(z - 4), xsize);
871  }
872  }
873  if (len > rlebuflen) {
874  fprintf(stderr, "output_iris: rlebuf is too small - bad poop\n");
875  exit(1);
876  }
877  goodwrite *= fwrite(rlebuf, len, 1, outf);
878  starttab[y + z * ysize] = pos;
879  lengthtab[y + z * ysize] = len;
880  pos += len;
881  }
882  lptr += xsize;
883  if (zptr) {
884  zptr += xsize;
885  }
886  }
887 
888  fseek(outf, HEADER_SIZE, SEEK_SET);
889  goodwrite *= writetab(outf, starttab, tablen);
890  goodwrite *= writetab(outf, lengthtab, tablen);
891  MEM_freeN(image);
892  MEM_freeN(starttab);
893  MEM_freeN(lengthtab);
894  MEM_freeN(rlebuf);
895  MEM_freeN(lumbuf);
896  fclose(outf);
897  if (goodwrite) {
898  return 1;
899  }
900 
901  fprintf(stderr, "output_iris: not enough space for image!!\n");
902  return 0;
903 }
904 
905 /* static utility functions for output_iris */
906 
907 static void lumrow(const uchar *rgbptr, uchar *lumptr, int n)
908 {
909  lumptr += CHANOFFSET(0);
910  while (n--) {
911  *lumptr = ILUM(rgbptr[OFFSET_R], rgbptr[OFFSET_G], rgbptr[OFFSET_B]);
912  lumptr += 4;
913  rgbptr += 4;
914  }
915 }
916 
917 static int compressrow(uchar *lbuf, uchar *rlebuf, int z, int cnt)
918 {
919  uchar *iptr, *ibufend, *sptr, *optr;
920  short todo, cc;
921  int count;
922 
923  lbuf += z;
924  iptr = lbuf;
925  ibufend = iptr + cnt * 4;
926  optr = rlebuf;
927 
928  while (iptr < ibufend) {
929  sptr = iptr;
930  iptr += 8;
931  while ((iptr < ibufend) && ((iptr[-8] != iptr[-4]) || (iptr[-4] != iptr[0]))) {
932  iptr += 4;
933  }
934  iptr -= 8;
935  count = (iptr - sptr) / 4;
936  while (count) {
937  todo = count > 126 ? 126 : count;
938  count -= todo;
939  *optr++ = 0x80 | todo;
940  while (todo > 8) {
941  optr[0] = sptr[0 * 4];
942  optr[1] = sptr[1 * 4];
943  optr[2] = sptr[2 * 4];
944  optr[3] = sptr[3 * 4];
945  optr[4] = sptr[4 * 4];
946  optr[5] = sptr[5 * 4];
947  optr[6] = sptr[6 * 4];
948  optr[7] = sptr[7 * 4];
949 
950  optr += 8;
951  sptr += 8 * 4;
952  todo -= 8;
953  }
954  while (todo--) {
955  *optr++ = *sptr;
956  sptr += 4;
957  }
958  }
959  sptr = iptr;
960  cc = *iptr;
961  iptr += 4;
962  while ((iptr < ibufend) && (*iptr == cc)) {
963  iptr += 4;
964  }
965  count = (iptr - sptr) / 4;
966  while (count) {
967  todo = count > 126 ? 126 : count;
968  count -= todo;
969  *optr++ = todo;
970  *optr++ = cc;
971  }
972  }
973  *optr++ = 0;
974  return optr - (uchar *)rlebuf;
975 }
976 
977 bool imb_saveiris(struct ImBuf *ibuf, const char *filepath, int flags)
978 {
979  short zsize;
980 
981  zsize = (ibuf->planes + 7) >> 3;
982  if (flags & IB_zbuf && ibuf->zbuf != NULL) {
983  zsize = 8;
984  }
985 
987  test_endian_zbuf(ibuf);
988 
989  const bool ok = output_iris(ibuf->rect, ibuf->x, ibuf->y, zsize, filepath, ibuf->zbuf);
990 
991  /* restore! Quite clumsy, 2 times a switch... maybe better a malloc ? */
993  test_endian_zbuf(ibuf);
994 
995  return ok;
996 }
#define BLI_assert(a)
Definition: BLI_assert.h:58
File and directory operations.
FILE * BLI_fopen(const char *filename, const char *mode) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: fileops.c:1003
unsigned char uchar
Definition: BLI_sys_types.h:86
unsigned int uint
Definition: BLI_sys_types.h:83
unsigned short ushort
Definition: BLI_sys_types.h:84
#define ELEM(...)
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble z
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble GLdouble r _GL_VOID_RET _GL_VOID GLfloat GLfloat r _GL_VOID_RET _GL_VOID GLint GLint r _GL_VOID_RET _GL_VOID GLshort GLshort r _GL_VOID_RET _GL_VOID GLdouble GLdouble r
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
@ COLOR_ROLE_DEFAULT_BYTE
struct ImBuf * IMB_allocImBuf(unsigned int x, unsigned int y, unsigned char planes, unsigned int flags)
Definition: allocimbuf.c:478
void IMB_rect_from_float(struct ImBuf *ibuf)
Definition: divers.c:720
#define IM_MAX_SPACE
Definition: IMB_imbuf.h:65
void IMB_convert_rgba_to_abgr(struct ImBuf *ibuf)
Definition: imageprocess.c:45
Contains defines and structs used throughout the imbuf module.
@ IB_zbuf
@ IB_rectfloat
@ IB_test
@ IB_rect
Read Guarded memory(de)allocation.
Group RGB to Bright Vector Camera Vector Combine Material Light Line Style Layer Add Ambient Diffuse Glossy Refraction Transparent Toon Principled Hair Volume Principled Light Particle Volume Image Sky Noise Wave Voronoi Brick Texture Vector Combine Vertex Separate Vector White RGB Map Separate Set IMAGE
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
void colorspace_set_default_role(char *colorspace, int size, int role)
uint pos
@ IMB_FTYPE_IMAGIC
#define BIG_LONG
Definition: imbuf.h:59
int count
#define ILUM(r, g, b)
Definition: iris.c:64
#define OFFSET_R
Definition: iris.c:66
static int writetab(FILE *outf, uint *tab, int len)
Definition: iris.c:200
#define DIRTY_FLAG_ENCODING
Definition: iris.c:105
struct ImBuf * imb_loadiris(const uchar *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE])
Definition: iris.c:260
bool imb_saveiris(struct ImBuf *ibuf, const char *filepath, int flags)
Definition: iris.c:977
static void interleaverow(uchar *lptr, const uchar *cptr, int z, int n)
Definition: iris.c:611
struct MFileOffset MFileOffset
bool imb_is_a_iris(const uchar *mem, size_t size)
Definition: iris.c:246
#define BPP(type)
Definition: iris.c:79
static int expandrow2(float *optr, const float *optr_end, const uchar *iptr, const uchar *iptr_end, int z)
Definition: iris.c:630
static void putshort(FILE *outf, ushort val)
Definition: iris.c:151
static uint getlong(MFileOffset *mofs)
Definition: iris.c:141
#define EXPAND_CAPACITY_AT_OUTPUT_OK_OR_FAIL(optr_next)
#define HEADER_SIZE
Definition: iris.c:56
static void lumrow(const uchar *rgbptr, uchar *lumptr, int n)
Definition: iris.c:907
#define ISRLE(type)
Definition: iris.c:77
static int writeheader(FILE *outf, IMAGE *image)
Definition: iris.c:182
static int expandrow(uchar *optr, const uchar *optr_end, const uchar *iptr, const uchar *iptr_end, int z)
Definition: iris.c:718
#define OFFSET_B
Definition: iris.c:68
#define GSS(x)
Definition: iris.c:244
#define CHANOFFSET(z)
Definition: iris.c:71
static bool output_iris(uint *lptr, int xsize, int ysize, int zsize, const char *name, int *zptr)
Definition: iris.c:815
#define OFFSET_G
Definition: iris.c:67
static ushort getshort(MFileOffset *inf)
Definition: iris.c:131
#define MFILE_STEP(inf, step)
Definition: iris.c:92
static void test_endian_zbuf(struct ImBuf *ibuf)
Definition: iris.c:219
static void readtab(MFileOffset *inf, uint *tab, int len)
Definition: iris.c:211
static void interleaverow2(float *lptr, const uchar *cptr, int z, int n)
Definition: iris.c:620
#define GS(x)
Definition: iris.c:241
BLI_STATIC_ASSERT(sizeof(IMAGE)==HEADER_SIZE, "Invalid header size")
#define MFILE_DATA(inf)
Definition: iris.c:91
static int compressrow(uchar *lbuf, uchar *rlebuf, int z, int cnt)
Definition: iris.c:917
#define MFILE_CAPACITY_AT_PTR_OK_OR_FAIL(p)
static int putlong(FILE *outf, uint val)
Definition: iris.c:160
#define EXPAND_CAPACITY_AT_INPUT_OK_OR_FAIL(iptr_next)
#define IMAGIC
Definition: iris.c:39
#define MFILE_SEEK(inf, pos)
Definition: iris.c:97
#define RLE(bpp)
Definition: iris.c:80
static void readheader(MFileOffset *inf, IMAGE *image)
Definition: iris.c:171
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:47
Definition: iris.c:41
uint colormap
Definition: iris.c:52
ushort ysize
Definition: iris.c:46
ushort xsize
Definition: iris.c:45
uint max
Definition: iris.c:49
ushort imagic
Definition: iris.c:42
ushort type
Definition: iris.c:43
uint min
Definition: iris.c:48
ushort dim
Definition: iris.c:44
ushort zsize
Definition: iris.c:47
unsigned char planes
char name[IMB_FILENAME_SIZE]
enum eImbFileType ftype
unsigned int * rect
float * rect_float
int * zbuf
uint _file_offset
Definition: iris.c:88
const uchar * _file_data
Definition: iris.c:87
uint len