Blender  V3.3
logImageCore.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 1999-2001 David Hodson <hodsond@acm.org>. */
3 
10 #include "logImageCore.h"
11 #include "cineonlib.h"
12 #include "dpxlib.h"
13 #include "logmemfile.h"
14 
15 #include <math.h>
16 #include <stdlib.h>
17 #include <string.h>
18 
19 #include "BLI_fileops.h"
20 #include "BLI_utildefines.h"
21 
22 #include "IMB_imbuf.h"
23 
24 #include "MEM_guardedalloc.h"
25 
26 /*
27  * Declaration of static functions
28  */
29 
30 static int logImageSetData8(LogImageFile *logImage, LogImageElement logElement, float *data);
31 static int logImageSetData10(LogImageFile *logImage, LogImageElement logElement, float *data);
32 static int logImageSetData12(LogImageFile *logImage, LogImageElement logElement, float *data);
33 static int logImageSetData16(LogImageFile *logImage, LogImageElement logElement, float *data);
34 static int logImageElementGetData(LogImageFile *logImage, LogImageElement logElement, float *data);
35 static int logImageElementGetData1(LogImageFile *logImage,
36  LogImageElement logElement,
37  float *data);
38 static int logImageElementGetData8(LogImageFile *logImage,
39  LogImageElement logElement,
40  float *data);
41 static int logImageElementGetData10(LogImageFile *logImage,
42  LogImageElement logElement,
43  float *data);
44 static int logImageElementGetData10Packed(LogImageFile *logImage,
45  LogImageElement logElement,
46  float *data);
47 static int logImageElementGetData12(LogImageFile *logImage,
48  LogImageElement logElement,
49  float *data);
50 static int logImageElementGetData12Packed(LogImageFile *logImage,
51  LogImageElement logElement,
52  float *data);
53 static int logImageElementGetData16(LogImageFile *logImage,
54  LogImageElement logElement,
55  float *data);
56 static int convertLogElementToRGBA(float *src,
57  float *dst,
58  LogImageFile *logImage,
59  LogImageElement logElement,
60  int dstIsLinearRGB);
61 static int convertRGBAToLogElement(float *src,
62  float *dst,
63  LogImageFile *logImage,
64  LogImageElement logElement,
65  int srcIsLinearRGB);
66 
67 /*
68  * For debug purpose
69  */
70 
71 static int verbose = 0;
72 
73 void logImageSetVerbose(int verbosity)
74 {
75  verbose = verbosity;
76  cineonSetVerbose(verbosity);
77  dpxSetVerbose(verbosity);
78 }
79 
80 /*
81  * IO stuff
82  */
83 
84 int logImageIsDpx(const void *buffer, const unsigned int size)
85 {
86  unsigned int magicNum;
87  if (size < sizeof(magicNum)) {
88  return 0;
89  }
90  magicNum = *(unsigned int *)buffer;
91  return (magicNum == DPX_FILE_MAGIC || magicNum == swap_uint(DPX_FILE_MAGIC, 1));
92 }
93 
94 int logImageIsCineon(const void *buffer, const unsigned int size)
95 {
96  unsigned int magicNum;
97  if (size < sizeof(magicNum)) {
98  return 0;
99  }
100  magicNum = *(unsigned int *)buffer;
101  return (magicNum == CINEON_FILE_MAGIC || magicNum == swap_uint(CINEON_FILE_MAGIC, 1));
102 }
103 
104 LogImageFile *logImageOpenFromFile(const char *filepath, int cineon)
105 {
106  unsigned int magicNum;
107  FILE *f = BLI_fopen(filepath, "rb");
108 
109  (void)cineon;
110 
111  if (f == NULL) {
112  return NULL;
113  }
114 
115  if (fread(&magicNum, sizeof(magicNum), 1, f) != 1) {
116  fclose(f);
117  return NULL;
118  }
119 
120  fclose(f);
121 
122  if (logImageIsDpx(&magicNum, sizeof(magicNum))) {
123  return dpxOpen((const unsigned char *)filepath, 0, 0);
124  }
125  if (logImageIsCineon(&magicNum, sizeof(magicNum))) {
126  return cineonOpen((const unsigned char *)filepath, 0, 0);
127  }
128 
129  return NULL;
130 }
131 
132 LogImageFile *logImageOpenFromMemory(const unsigned char *buffer, unsigned int size)
133 {
134  if (logImageIsDpx(buffer, size)) {
135  return dpxOpen(buffer, 1, size);
136  }
137  if (logImageIsCineon(buffer, size)) {
138  return cineonOpen(buffer, 1, size);
139  }
140 
141  return NULL;
142 }
143 
144 LogImageFile *logImageCreate(const char *filepath,
145  int cineon,
146  int width,
147  int height,
148  int bitsPerSample,
149  int isLogarithmic,
150  int hasAlpha,
151  int referenceWhite,
152  int referenceBlack,
153  float gamma,
154  const char *creator)
155 {
156  /* referenceWhite, referenceBlack and gamma values are only supported for DPX file */
157  if (cineon) {
158  return cineonCreate(filepath, width, height, bitsPerSample, creator);
159  }
160 
161  return dpxCreate(filepath,
162  width,
163  height,
164  bitsPerSample,
165  isLogarithmic,
166  hasAlpha,
167  referenceWhite,
168  referenceBlack,
169  gamma,
170  creator);
171 
172  return NULL;
173 }
174 
176 {
177  if (logImage != NULL) {
178  if (logImage->file) {
179  fclose(logImage->file);
180  logImage->file = NULL;
181  }
182  MEM_freeN(logImage);
183  }
184 }
185 
186 void logImageGetSize(LogImageFile *logImage, int *width, int *height, int *depth)
187 {
188  *width = logImage->width;
189  *height = logImage->height;
190  *depth = logImage->depth;
191 }
192 
193 /*
194  * Helper
195  */
196 
197 size_t getRowLength(size_t width, LogImageElement logElement)
198 {
199  /* return the row length in bytes according to width and packing method */
200  switch (logElement.bitsPerSample) {
201  case 1:
202  return ((width * logElement.depth - 1) / 32 + 1) * 4;
203 
204  case 8:
205  return ((width * logElement.depth - 1) / 4 + 1) * 4;
206 
207  case 10:
208  if (logElement.packing == 0) {
209  return ((width * logElement.depth * 10 - 1) / 32 + 1) * 4;
210  }
211  else if (ELEM(logElement.packing, 1, 2)) {
212  return ((width * logElement.depth - 1) / 3 + 1) * 4;
213  }
214  break;
215  case 12:
216  if (logElement.packing == 0) {
217  return ((width * logElement.depth * 12 - 1) / 32 + 1) * 4;
218  }
219  else if (ELEM(logElement.packing, 1, 2)) {
220  return width * logElement.depth * 2;
221  }
222  break;
223  case 16:
224  return width * logElement.depth * 2;
225  }
226  return 0;
227 }
228 
229 /*
230  * Data writing
231  */
232 
233 int logImageSetDataRGBA(LogImageFile *logImage, float *data, int dataIsLinearRGB)
234 {
235  float *elementData;
236  int returnValue;
237 
238  elementData = (float *)imb_alloc_pixels(
239  logImage->width, logImage->height, logImage->depth, sizeof(float), __func__);
240  if (elementData == NULL) {
241  return 1;
242  }
243 
245  data, elementData, logImage, logImage->element[0], dataIsLinearRGB) != 0) {
246  MEM_freeN(elementData);
247  return 1;
248  }
249 
250  switch (logImage->element[0].bitsPerSample) {
251  case 8:
252  returnValue = logImageSetData8(logImage, logImage->element[0], elementData);
253  break;
254 
255  case 10:
256  returnValue = logImageSetData10(logImage, logImage->element[0], elementData);
257  break;
258 
259  case 12:
260  returnValue = logImageSetData12(logImage, logImage->element[0], elementData);
261  break;
262 
263  case 16:
264  returnValue = logImageSetData16(logImage, logImage->element[0], elementData);
265  break;
266 
267  default:
268  returnValue = 1;
269  break;
270  }
271 
272  MEM_freeN(elementData);
273  return returnValue;
274 }
275 
276 static int logImageSetData8(LogImageFile *logImage, LogImageElement logElement, float *data)
277 {
278  size_t rowLength = getRowLength(logImage->width, logElement);
279  unsigned char *row;
280 
281  row = (unsigned char *)MEM_mallocN(rowLength, __func__);
282  if (row == NULL) {
283  if (verbose) {
284  printf("DPX/Cineon: Cannot allocate row.\n");
285  }
286  return 1;
287  }
288  memset(row, 0, rowLength);
289 
290  for (size_t y = 0; y < logImage->height; y++) {
291  for (size_t x = 0; x < logImage->width * logImage->depth; x++) {
292  row[x] = (unsigned char)float_uint(data[y * logImage->width * logImage->depth + x], 255);
293  }
294 
295  if (logimage_fwrite(row, rowLength, 1, logImage) == 0) {
296  if (verbose) {
297  printf("DPX/Cineon: Error while writing file.\n");
298  }
299  MEM_freeN(row);
300  return 1;
301  }
302  }
303  MEM_freeN(row);
304  return 0;
305 }
306 
307 static int logImageSetData10(LogImageFile *logImage, LogImageElement logElement, float *data)
308 {
309  size_t rowLength = getRowLength(logImage->width, logElement);
310  unsigned int pixel, index;
311  unsigned int *row;
312 
313  row = (unsigned int *)MEM_mallocN(rowLength, __func__);
314  if (row == NULL) {
315  if (verbose) {
316  printf("DPX/Cineon: Cannot allocate row.\n");
317  }
318  return 1;
319  }
320 
321  for (size_t y = 0; y < logImage->height; y++) {
322  int offset = 22;
323  index = 0;
324  pixel = 0;
325 
326  for (size_t x = 0; x < logImage->width * logImage->depth; x++) {
327  pixel |= (unsigned int)float_uint(data[y * logImage->width * logImage->depth + x], 1023)
328  << offset;
329  offset -= 10;
330  if (offset < 0) {
331  row[index] = swap_uint(pixel, logImage->isMSB);
332  index++;
333  pixel = 0;
334  offset = 22;
335  }
336  }
337  if (pixel != 0) {
338  row[index] = swap_uint(pixel, logImage->isMSB);
339  }
340 
341  if (logimage_fwrite(row, rowLength, 1, logImage) == 0) {
342  if (verbose) {
343  printf("DPX/Cineon: Error while writing file.\n");
344  }
345  MEM_freeN(row);
346  return 1;
347  }
348  }
349  MEM_freeN(row);
350  return 0;
351 }
352 
353 static int logImageSetData12(LogImageFile *logImage, LogImageElement logElement, float *data)
354 {
355  size_t rowLength = getRowLength(logImage->width, logElement);
356  unsigned short *row;
357 
358  row = (unsigned short *)MEM_mallocN(rowLength, __func__);
359  if (row == NULL) {
360  if (verbose) {
361  printf("DPX/Cineon: Cannot allocate row.\n");
362  }
363  return 1;
364  }
365 
366  for (size_t y = 0; y < logImage->height; y++) {
367  for (size_t x = 0; x < logImage->width * logImage->depth; x++) {
368  row[x] = swap_ushort(
369  ((unsigned short)float_uint(data[y * logImage->width * logImage->depth + x], 4095)) << 4,
370  logImage->isMSB);
371  }
372 
373  if (logimage_fwrite(row, rowLength, 1, logImage) == 0) {
374  if (verbose) {
375  printf("DPX/Cineon: Error while writing file.\n");
376  }
377  MEM_freeN(row);
378  return 1;
379  }
380  }
381  MEM_freeN(row);
382  return 0;
383 }
384 
385 static int logImageSetData16(LogImageFile *logImage, LogImageElement logElement, float *data)
386 {
387  size_t rowLength = getRowLength(logImage->width, logElement);
388  unsigned short *row;
389 
390  row = (unsigned short *)MEM_mallocN(rowLength, __func__);
391  if (row == NULL) {
392  if (verbose) {
393  printf("DPX/Cineon: Cannot allocate row.\n");
394  }
395  return 1;
396  }
397 
398  for (size_t y = 0; y < logImage->height; y++) {
399  for (size_t x = 0; x < logImage->width * logImage->depth; x++) {
400  row[x] = swap_ushort(
401  (unsigned short)float_uint(data[y * logImage->width * logImage->depth + x], 65535),
402  logImage->isMSB);
403  }
404 
405  if (logimage_fwrite(row, rowLength, 1, logImage) == 0) {
406  if (verbose) {
407  printf("DPX/Cineon: Error while writing file.\n");
408  }
409  MEM_freeN(row);
410  return 1;
411  }
412  }
413  MEM_freeN(row);
414  return 0;
415 }
416 
417 /*
418  * Data reading
419  */
420 
421 int logImageGetDataRGBA(LogImageFile *logImage, float *data, int dataIsLinearRGB)
422 {
423  /* Fills data with 32 bits float RGBA values */
424  int i, j, returnValue, sortedElementData[8], hasAlpha;
425  float *elementData[8];
426  float *elementData_ptr[8];
427  float *mergedData;
428  unsigned int sampleIndex;
429  LogImageElement mergedElement;
430 
431  /* Determine the depth of the picture and if there's a separate alpha element.
432  * If the element is supported, load it into an unsigned ints array. */
433  memset(&elementData, 0, 8 * sizeof(float *));
434  hasAlpha = 0;
435 
436  for (i = 0; i < logImage->numElements; i++) {
437  /* descriptor_Depth and descriptor_Composite are not supported */
439  /* Allocate memory */
440  elementData[i] = imb_alloc_pixels(
441  logImage->width, logImage->height, logImage->element[i].depth, sizeof(float), __func__);
442  if (elementData[i] == NULL) {
443  if (verbose) {
444  printf("DPX/Cineon: Cannot allocate memory for elementData[%d]\n.", i);
445  }
446  for (j = 0; j < i; j++) {
447  if (elementData[j] != NULL) {
448  MEM_freeN(elementData[j]);
449  }
450  }
451  return 1;
452  }
453  elementData_ptr[i] = elementData[i];
454 
455  /* Load data */
456  if (logImageElementGetData(logImage, logImage->element[i], elementData[i]) != 0) {
457  if (verbose) {
458  printf("DPX/Cineon: Cannot read elementData[%d]\n.", i);
459  }
460  for (j = 0; j < i; j++) {
461  if (elementData[j] != NULL) {
462  MEM_freeN(elementData[j]);
463  }
464  }
465  return 1;
466  }
467  }
468 
469  if (logImage->element[i].descriptor == descriptor_Alpha) {
470  hasAlpha = 1;
471  }
472  }
473 
474  /* Only one element, easy case, no need to do anything. */
475  if (logImage->numElements == 1) {
476  returnValue = convertLogElementToRGBA(
477  elementData[0], data, logImage, logImage->element[0], dataIsLinearRGB);
478  MEM_freeN(elementData[0]);
479  }
480  else {
481  /* The goal here is to merge every elements into only one
482  * to recreate a classic 16 bits RGB, RGBA or YCbCr element.
483  * Unsupported elements are skipped (depth, composite) */
484 
485  memcpy(&mergedElement, &logImage->element[0], sizeof(LogImageElement));
486  mergedElement.descriptor = -1;
487  mergedElement.depth = logImage->depth;
488  memset(&sortedElementData, -1, sizeof(int[8]));
489 
490  /* Try to know how to assemble the elements */
491  for (i = 0; i < logImage->numElements; i++) {
492  switch (logImage->element[i].descriptor) {
493  case descriptor_Red:
494  case descriptor_RGB:
495  if (hasAlpha == 0) {
496  mergedElement.descriptor = descriptor_RGB;
497  }
498  else {
499  mergedElement.descriptor = descriptor_RGBA;
500  }
501 
502  sortedElementData[0] = i;
503  break;
504 
505  case descriptor_Green:
506  if (hasAlpha == 0) {
507  mergedElement.descriptor = descriptor_RGB;
508  }
509  else {
510  mergedElement.descriptor = descriptor_RGBA;
511  }
512 
513  sortedElementData[1] = i;
514  break;
515 
516  case descriptor_Blue:
517  if (hasAlpha == 0) {
518  mergedElement.descriptor = descriptor_RGB;
519  }
520  else {
521  mergedElement.descriptor = descriptor_RGBA;
522  }
523 
524  sortedElementData[2] = i;
525  break;
526 
527  case descriptor_Alpha:
528  /* Alpha component is always the last one */
529  sortedElementData[mergedElement.depth - 1] = i;
530  break;
531 
533  if (mergedElement.descriptor == -1) {
534  if (hasAlpha == 0) {
535  mergedElement.descriptor = descriptor_Luminance;
536  }
537  else {
538  mergedElement.descriptor = descriptor_YA;
539  }
540  }
541  else if (mergedElement.descriptor == descriptor_Chrominance) {
542  if (mergedElement.depth == 2) {
543  mergedElement.descriptor = descriptor_CbYCrY;
544  }
545  else if (mergedElement.depth == 3) {
546  if (hasAlpha == 0) {
547  mergedElement.descriptor = descriptor_CbYCr;
548  }
549  else {
550  mergedElement.descriptor = descriptor_CbYACrYA;
551  }
552  }
553  else if (mergedElement.depth == 4) {
554  mergedElement.descriptor = descriptor_CbYCrA;
555  }
556  }
557 
558  /* Y component always in 1 except if it's alone or with alpha */
559  if (mergedElement.depth == 1 || (mergedElement.depth == 2 && hasAlpha == 1)) {
560  sortedElementData[0] = i;
561  }
562  else {
563  sortedElementData[1] = i;
564  }
565  break;
566 
568  if (mergedElement.descriptor == -1) {
569  mergedElement.descriptor = descriptor_Chrominance;
570  }
571  else if (mergedElement.descriptor == descriptor_Luminance) {
572  if (mergedElement.depth == 2) {
573  mergedElement.descriptor = descriptor_CbYCrY;
574  }
575  else if (mergedElement.depth == 3) {
576  if (hasAlpha == 0) {
577  mergedElement.descriptor = descriptor_CbYCr;
578  }
579  else {
580  mergedElement.descriptor = descriptor_CbYACrYA;
581  }
582  }
583  else if (mergedElement.depth == 4) {
584  mergedElement.descriptor = descriptor_CbYCrA;
585  }
586  }
587 
588  /* Cb and Cr always in 0 or 2 */
589  if (sortedElementData[0] == -1) {
590  sortedElementData[0] = i;
591  }
592  else {
593  sortedElementData[2] = i;
594  }
595  break;
596 
597  case descriptor_CbYCr:
598  if (hasAlpha == 0) {
599  mergedElement.descriptor = descriptor_CbYCr;
600  }
601  else {
602  mergedElement.descriptor = descriptor_CbYCrA;
603  }
604 
605  sortedElementData[0] = i;
606  break;
607 
608  case descriptor_RGBA:
609  case descriptor_ABGR:
610  case descriptor_CbYACrYA:
611  case descriptor_CbYCrY:
612  case descriptor_CbYCrA:
613  /* I don't think these ones can be seen in a planar image */
614  mergedElement.descriptor = logImage->element[i].descriptor;
615  sortedElementData[0] = i;
616  break;
617 
618  case descriptor_Depth:
620  /* Not supported */
621  break;
622  }
623  }
624 
625  mergedData = (float *)imb_alloc_pixels(
626  logImage->width, logImage->height, mergedElement.depth, sizeof(float), __func__);
627  if (mergedData == NULL) {
628  if (verbose) {
629  printf("DPX/Cineon: Cannot allocate mergedData.\n");
630  }
631  for (i = 0; i < logImage->numElements; i++) {
632  if (elementData[i] != NULL) {
633  MEM_freeN(elementData[i]);
634  }
635  }
636  return 1;
637  }
638 
639  sampleIndex = 0;
640  while (sampleIndex < logImage->width * logImage->height * mergedElement.depth) {
641  for (i = 0; i < logImage->numElements; i++) {
642  for (j = 0; j < logImage->element[sortedElementData[i]].depth; j++) {
643  mergedData[sampleIndex++] = *(elementData_ptr[sortedElementData[i]]++);
644  }
645  }
646  }
647 
648  /* Done with elements data, clean-up */
649  for (i = 0; i < logImage->numElements; i++) {
650  if (elementData[i] != NULL) {
651  MEM_freeN(elementData[i]);
652  }
653  }
654 
655  returnValue = convertLogElementToRGBA(
656  mergedData, data, logImage, mergedElement, dataIsLinearRGB);
657  MEM_freeN(mergedData);
658  }
659  return returnValue;
660 }
661 
662 static int logImageElementGetData(LogImageFile *logImage, LogImageElement logElement, float *data)
663 {
664  switch (logElement.bitsPerSample) {
665  case 1:
666  return logImageElementGetData1(logImage, logElement, data);
667 
668  case 8:
669  return logImageElementGetData8(logImage, logElement, data);
670 
671  case 10:
672  if (logElement.packing == 0) {
673  return logImageElementGetData10Packed(logImage, logElement, data);
674  }
675  else if (ELEM(logElement.packing, 1, 2)) {
676  return logImageElementGetData10(logImage, logElement, data);
677  }
678  break;
679 
680  case 12:
681  if (logElement.packing == 0) {
682  return logImageElementGetData12Packed(logImage, logElement, data);
683  }
684  else if (ELEM(logElement.packing, 1, 2)) {
685  return logImageElementGetData12(logImage, logElement, data);
686  }
687  break;
688 
689  case 16:
690  return logImageElementGetData16(logImage, logElement, data);
691  }
692  /* format not supported */
693  return 1;
694 }
695 
696 static int logImageElementGetData1(LogImageFile *logImage, LogImageElement logElement, float *data)
697 {
698  unsigned int pixel;
699 
700  /* seek at the right place */
701  if (logimage_fseek(logImage, logElement.dataOffset, SEEK_SET) != 0) {
702  if (verbose) {
703  printf("DPX/Cineon: Couldn't seek at %d\n", logElement.dataOffset);
704  }
705  return 1;
706  }
707 
708  /* read 1 bit data padded to 32 bits */
709  for (size_t y = 0; y < logImage->height; y++) {
710  for (size_t x = 0; x < logImage->width * logElement.depth; x += 32) {
711  if (logimage_read_uint(&pixel, logImage) != 0) {
712  if (verbose) {
713  printf("DPX/Cineon: EOF reached\n");
714  }
715  return 1;
716  }
717  pixel = swap_uint(pixel, logImage->isMSB);
718  for (int offset = 0; offset < 32 && x + offset < logImage->width; offset++) {
719  data[y * logImage->width * logElement.depth + x + offset] = (float)((pixel >> offset) &
720  0x01);
721  }
722  }
723  }
724  return 0;
725 }
726 
727 static int logImageElementGetData8(LogImageFile *logImage, LogImageElement logElement, float *data)
728 {
729  size_t rowLength = getRowLength(logImage->width, logElement);
730  unsigned char pixel;
731 
732  /* extract required pixels */
733  for (size_t y = 0; y < logImage->height; y++) {
734  /* 8 bits are 32-bits padded so we need to seek at each row */
735  if (logimage_fseek(logImage, logElement.dataOffset + y * rowLength, SEEK_SET) != 0) {
736  if (verbose) {
737  printf("DPX/Cineon: Couldn't seek at %d\n", (int)(logElement.dataOffset + y * rowLength));
738  }
739  return 1;
740  }
741 
742  for (size_t x = 0; x < logImage->width * logElement.depth; x++) {
743  if (logimage_read_uchar(&pixel, logImage) != 0) {
744  if (verbose) {
745  printf("DPX/Cineon: EOF reached\n");
746  }
747  return 1;
748  }
749  data[y * logImage->width * logElement.depth + x] = (float)pixel / 255.0f;
750  }
751  }
752  return 0;
753 }
754 
756  LogImageElement logElement,
757  float *data)
758 {
759  unsigned int pixel;
760 
761  /* seek to data */
762  if (logimage_fseek(logImage, logElement.dataOffset, SEEK_SET) != 0) {
763  if (verbose) {
764  printf("DPX/Cineon: Couldn't seek at %d\n", logElement.dataOffset);
765  }
766  return 1;
767  }
768 
769  if (logImage->depth == 1 && logImage->srcFormat == format_DPX) {
770  for (size_t y = 0; y < logImage->height; y++) {
771  int offset = 32;
772  for (size_t x = 0; x < logImage->width * logElement.depth; x++) {
773  /* we need to read the next long */
774  if (offset >= 30) {
775  if (logElement.packing == 1) {
776  offset = 2;
777  }
778  else if (logElement.packing == 2) {
779  offset = 0;
780  }
781 
782  if (logimage_read_uint(&pixel, logImage) != 0) {
783  if (verbose) {
784  printf("DPX/Cineon: EOF reached\n");
785  }
786  return 1;
787  }
788  pixel = swap_uint(pixel, logImage->isMSB);
789  }
790  data[y * logImage->width * logElement.depth + x] = (float)((pixel >> offset) & 0x3ff) /
791  1023.0f;
792  offset += 10;
793  }
794  }
795  }
796  else {
797  for (size_t y = 0; y < logImage->height; y++) {
798  int offset = -1;
799  for (size_t x = 0; x < logImage->width * logElement.depth; x++) {
800  /* we need to read the next long */
801  if (offset < 0) {
802  if (logElement.packing == 1) {
803  offset = 22;
804  }
805  else if (logElement.packing == 2) {
806  offset = 20;
807  }
808 
809  if (logimage_read_uint(&pixel, logImage) != 0) {
810  if (verbose) {
811  printf("DPX/Cineon: EOF reached\n");
812  }
813  return 1;
814  }
815  pixel = swap_uint(pixel, logImage->isMSB);
816  }
817  data[y * logImage->width * logElement.depth + x] = (float)((pixel >> offset) & 0x3ff) /
818  1023.0f;
819  offset -= 10;
820  }
821  }
822  }
823 
824  return 0;
825 }
826 
828  LogImageElement logElement,
829  float *data)
830 {
831  size_t rowLength = getRowLength(logImage->width, logElement);
832  unsigned int pixel, oldPixel;
833 
834  /* converting bytes to pixels */
835  for (size_t y = 0; y < logImage->height; y++) {
836  /* seek to data */
837  if (logimage_fseek(logImage, y * rowLength + logElement.dataOffset, SEEK_SET) != 0) {
838  if (verbose) {
839  printf("DPX/Cineon: Couldn't seek at %u\n",
840  (unsigned int)(y * rowLength + logElement.dataOffset));
841  }
842  return 1;
843  }
844 
845  oldPixel = 0;
846  int offset = 0;
847  int offset2 = 0;
848 
849  for (size_t x = 0; x < logImage->width * logElement.depth; x++) {
850  if (offset2 != 0) {
851  offset = 10 - offset2;
852  offset2 = 0;
853  oldPixel = 0;
854  }
855  else if (offset == 32) {
856  offset = 0;
857  }
858  else if (offset + 10 > 32) {
859  /* next pixel is on two different longs */
860  oldPixel = (pixel >> offset);
861  offset2 = 32 - offset;
862  offset = 0;
863  }
864 
865  if (offset == 0) {
866  /* we need to read the next long */
867  if (logimage_read_uint(&pixel, logImage) != 0) {
868  if (verbose) {
869  printf("DPX/Cineon: EOF reached\n");
870  }
871  return 1;
872  }
873  pixel = swap_uint(pixel, logImage->isMSB);
874  }
875  data[y * logImage->width * logElement.depth + x] =
876  (float)((((pixel << offset2) >> offset) & 0x3ff) | oldPixel) / 1023.0f;
877  offset += 10;
878  }
879  }
880  return 0;
881 }
882 
884  LogImageElement logElement,
885  float *data)
886 {
887  unsigned int sampleIndex;
888  unsigned int numSamples = logImage->width * logImage->height * logElement.depth;
889  unsigned short pixel;
890 
891  /* seek to data */
892  if (logimage_fseek(logImage, logElement.dataOffset, SEEK_SET) != 0) {
893  if (verbose) {
894  printf("DPX/Cineon: Couldn't seek at %d\n", logElement.dataOffset);
895  }
896  return 1;
897  }
898 
899  /* convert bytes to pixels */
900  sampleIndex = 0;
901 
902  for (sampleIndex = 0; sampleIndex < numSamples; sampleIndex++) {
903  if (logimage_read_ushort(&pixel, logImage) != 0) {
904  if (verbose) {
905  printf("DPX/Cineon: EOF reached\n");
906  }
907  return 1;
908  }
909  pixel = swap_ushort(pixel, logImage->isMSB);
910 
911  if (logElement.packing == 1) { /* padded to the right */
912  data[sampleIndex] = (float)(pixel >> 4) / 4095.0f;
913  }
914  else if (logElement.packing == 2) { /* padded to the left */
915  data[sampleIndex] = (float)pixel / 4095.0f;
916  }
917  }
918  return 0;
919 }
920 
922  LogImageElement logElement,
923  float *data)
924 {
925  size_t rowLength = getRowLength(logImage->width, logElement);
926  unsigned int pixel, oldPixel;
927 
928  /* converting bytes to pixels */
929  for (size_t y = 0; y < logImage->height; y++) {
930  /* seek to data */
931  if (logimage_fseek(logImage, y * rowLength + logElement.dataOffset, SEEK_SET) != 0) {
932  if (verbose) {
933  printf("DPX/Cineon: Couldn't seek at %u\n",
934  (unsigned int)(y * rowLength + logElement.dataOffset));
935  }
936  return 1;
937  }
938 
939  oldPixel = 0;
940  int offset = 0;
941  int offset2 = 0;
942 
943  for (size_t x = 0; x < logImage->width * logElement.depth; x++) {
944  if (offset2 != 0) {
945  offset = 12 - offset2;
946  offset2 = 0;
947  oldPixel = 0;
948  }
949  else if (offset == 32) {
950  offset = 0;
951  }
952  else if (offset + 12 > 32) {
953  /* next pixel is on two different longs */
954  oldPixel = (pixel >> offset);
955  offset2 = 32 - offset;
956  offset = 0;
957  }
958 
959  if (offset == 0) {
960  /* we need to read the next long */
961  if (logimage_read_uint(&pixel, logImage) != 0) {
962  if (verbose) {
963  printf("DPX/Cineon: EOF reached\n");
964  }
965  return 1;
966  }
967  pixel = swap_uint(pixel, logImage->isMSB);
968  }
969  data[y * logImage->width * logElement.depth + x] =
970  (float)((((pixel << offset2) >> offset) & 0xfff) | oldPixel) / 4095.0f;
971  offset += 12;
972  }
973  }
974  return 0;
975 }
976 
978  LogImageElement logElement,
979  float *data)
980 {
981  unsigned int numSamples = logImage->width * logImage->height * logElement.depth;
982  unsigned int sampleIndex;
983  unsigned short pixel;
984 
985  /* seek to data */
986  if (logimage_fseek(logImage, logElement.dataOffset, SEEK_SET) != 0) {
987  if (verbose) {
988  printf("DPX/Cineon: Couldn't seek at %d\n", logElement.dataOffset);
989  }
990  return 1;
991  }
992 
993  for (sampleIndex = 0; sampleIndex < numSamples; sampleIndex++) {
994  if (logimage_read_ushort(&pixel, logImage) != 0) {
995  if (verbose) {
996  printf("DPX/Cineon: EOF reached\n");
997  }
998  return 1;
999  }
1000  pixel = swap_ushort(pixel, logImage->isMSB);
1001  data[sampleIndex] = (float)pixel / 65535.0f;
1002  }
1003 
1004  return 0;
1005 }
1006 
1007 /*
1008  * Color conversion
1009  */
1010 
1011 static int getYUVtoRGBMatrix(float *matrix, LogImageElement logElement)
1012 {
1013  float scaleY, scaleCbCr;
1014  float refHighData = (float)logElement.refHighData / logElement.maxValue;
1015  float refLowData = (float)logElement.refLowData / logElement.maxValue;
1016 
1017  scaleY = 1.0f / (refHighData - refLowData);
1018  scaleCbCr = scaleY * ((940.0f - 64.0f) / (960.0f - 64.0f));
1019 
1020  switch (logElement.transfer) {
1021  case 2: /* linear */
1022  matrix[0] = 1.0f * scaleY;
1023  matrix[1] = 1.0f * scaleCbCr;
1024  matrix[2] = 1.0f * scaleCbCr;
1025  matrix[3] = 1.0f * scaleY;
1026  matrix[4] = 1.0f * scaleCbCr;
1027  matrix[5] = 1.0f * scaleCbCr;
1028  matrix[6] = 1.0f * scaleY;
1029  matrix[7] = 1.0f * scaleCbCr;
1030  matrix[8] = 1.0f * scaleCbCr;
1031  return 0;
1032 
1033  case 5: /* SMPTE 240M */
1034  matrix[0] = 1.0000f * scaleY;
1035  matrix[1] = 0.0000f * scaleCbCr;
1036  matrix[2] = 1.5756f * scaleCbCr;
1037  matrix[3] = 1.0000f * scaleY;
1038  matrix[4] = -0.2253f * scaleCbCr;
1039  matrix[5] = -0.5000f * scaleCbCr;
1040  matrix[6] = 1.0000f * scaleY;
1041  matrix[7] = 1.8270f * scaleCbCr;
1042  matrix[8] = 0.0000f * scaleCbCr;
1043  return 0;
1044 
1045  case 6: /* CCIR 709-1 */
1046  matrix[0] = 1.000000f * scaleY;
1047  matrix[1] = 0.000000f * scaleCbCr;
1048  matrix[2] = 1.574800f * scaleCbCr;
1049  matrix[3] = 1.000000f * scaleY;
1050  matrix[4] = -0.187324f * scaleCbCr;
1051  matrix[5] = -0.468124f * scaleCbCr;
1052  matrix[6] = 1.000000f * scaleY;
1053  matrix[7] = 1.855600f * scaleCbCr;
1054  matrix[8] = 0.000000f * scaleCbCr;
1055  return 0;
1056 
1057  case 7: /* CCIR 601 */
1058  case 8: /* I'm not sure 7 and 8 should share the same matrix */
1059  matrix[0] = 1.000000f * scaleY;
1060  matrix[1] = 0.000000f * scaleCbCr;
1061  matrix[2] = 1.402000f * scaleCbCr;
1062  matrix[3] = 1.000000f * scaleY;
1063  matrix[4] = -0.344136f * scaleCbCr;
1064  matrix[5] = -0.714136f * scaleCbCr;
1065  matrix[6] = 1.000000f * scaleY;
1066  matrix[7] = 1.772000f * scaleCbCr;
1067  matrix[8] = 0.000000f * scaleCbCr;
1068  return 0;
1069 
1070  default:
1071  return 1;
1072  }
1073 }
1074 
1075 static float *getLinToLogLut(LogImageFile *logImage, LogImageElement logElement)
1076 {
1077  float *lut;
1078  float gain, negativeFilmGamma, offset, step;
1079  unsigned int lutsize = (unsigned int)(logElement.maxValue + 1);
1080  unsigned int i;
1081 
1082  lut = MEM_mallocN(sizeof(float) * lutsize, "getLinToLogLut");
1083 
1084  negativeFilmGamma = 0.6;
1085  step = logElement.refHighQuantity / logElement.maxValue;
1086  gain = logElement.maxValue /
1087  (1.0f - powf(10,
1088  (logImage->referenceBlack - logImage->referenceWhite) * step /
1089  negativeFilmGamma * logImage->gamma / 1.7f));
1090  offset = gain - logElement.maxValue;
1091 
1092  for (i = 0; i < lutsize; i++) {
1093  lut[i] = (logImage->referenceWhite +
1094  log10f(powf((i + offset) / gain, 1.7f / logImage->gamma)) /
1095  (step / negativeFilmGamma)) /
1096  logElement.maxValue;
1097  }
1098 
1099  return lut;
1100 }
1101 
1102 static float *getLogToLinLut(LogImageFile *logImage, LogImageElement logElement)
1103 {
1104  float *lut;
1105  float breakPoint, gain, kneeGain, kneeOffset, negativeFilmGamma, offset, step, softClip;
1106  /* float filmGamma; unused */
1107  unsigned int lutsize = (unsigned int)(logElement.maxValue + 1);
1108  unsigned int i;
1109 
1110  lut = MEM_mallocN(sizeof(float) * lutsize, "getLogToLinLut");
1111 
1112  /* Building the Log -> Lin LUT */
1113  step = logElement.refHighQuantity / logElement.maxValue;
1114  negativeFilmGamma = 0.6;
1115 
1116  /* these are default values */
1117  /* filmGamma = 2.2f; unused */
1118  softClip = 0;
1119 
1120  breakPoint = logImage->referenceWhite - softClip;
1121  gain = logElement.maxValue /
1122  (1.0f - powf(10,
1123  (logImage->referenceBlack - logImage->referenceWhite) * step /
1124  negativeFilmGamma * logImage->gamma / 1.7f));
1125  offset = gain - logElement.maxValue;
1126  kneeOffset = powf(10,
1127  (breakPoint - logImage->referenceWhite) * step / negativeFilmGamma *
1128  logImage->gamma / 1.7f) *
1129  gain -
1130  offset;
1131  kneeGain = (logElement.maxValue - kneeOffset) / powf(5 * softClip, softClip / 100);
1132 
1133  for (i = 0; i < lutsize; i++) {
1134  if (i < logImage->referenceBlack) {
1135  lut[i] = 0.0f;
1136  }
1137  else if (i > breakPoint) {
1138  lut[i] = (powf(i - breakPoint, softClip / 100) * kneeGain + kneeOffset) /
1139  logElement.maxValue;
1140  }
1141  else {
1142  lut[i] = (powf(10,
1143  ((float)i - logImage->referenceWhite) * step / negativeFilmGamma *
1144  logImage->gamma / 1.7f) *
1145  gain -
1146  offset) /
1147  logElement.maxValue;
1148  }
1149  }
1150 
1151  return lut;
1152 }
1153 
1154 static float *getLinToSrgbLut(LogImageElement logElement)
1155 {
1156  float col, *lut;
1157  unsigned int lutsize = (unsigned int)(logElement.maxValue + 1);
1158  unsigned int i;
1159 
1160  lut = MEM_mallocN(sizeof(float) * lutsize, "getLogToLinLut");
1161 
1162  for (i = 0; i < lutsize; i++) {
1163  col = (float)i / logElement.maxValue;
1164  if (col < 0.0031308f) {
1165  lut[i] = (col < 0.0f) ? 0.0f : col * 12.92f;
1166  }
1167  else {
1168  lut[i] = 1.055f * powf(col, 1.0f / 2.4f) - 0.055f;
1169  }
1170  }
1171 
1172  return lut;
1173 }
1174 
1175 static float *getSrgbToLinLut(LogImageElement logElement)
1176 {
1177  float col, *lut;
1178  unsigned int lutsize = (unsigned int)(logElement.maxValue + 1);
1179  unsigned int i;
1180 
1181  lut = MEM_mallocN(sizeof(float) * lutsize, "getLogToLinLut");
1182 
1183  for (i = 0; i < lutsize; i++) {
1184  col = (float)i / logElement.maxValue;
1185  if (col < 0.04045f) {
1186  lut[i] = (col < 0.0f) ? 0.0f : col * (1.0f / 12.92f);
1187  }
1188  else {
1189  lut[i] = powf((col + 0.055f) * (1.0f / 1.055f), 2.4f);
1190  }
1191  }
1192 
1193  return lut;
1194 }
1195 
1196 static int convertRGBA_RGB(float *src,
1197  float *dst,
1198  LogImageFile *logImage,
1199  LogImageElement logElement,
1200  int elementIsSource)
1201 {
1202  unsigned int i;
1203  float *src_ptr = src;
1204  float *dst_ptr = dst;
1205 
1206  switch (logElement.transfer) {
1207  case transfer_Unspecified:
1208  case transfer_UserDefined:
1209  case transfer_Linear:
1210  case transfer_Logarithmic: {
1211  for (i = 0; i < logImage->width * logImage->height; i++) {
1212  *(dst_ptr++) = *(src_ptr++);
1213  *(dst_ptr++) = *(src_ptr++);
1214  *(dst_ptr++) = *(src_ptr++);
1215  src_ptr++;
1216  }
1217 
1218  return 0;
1219  }
1220 
1221  case transfer_PrintingDensity: {
1222  float *lut;
1223 
1224  if (elementIsSource == 1) {
1225  lut = getLogToLinLut(logImage, logElement);
1226  }
1227  else {
1228  lut = getLinToLogLut(logImage, logElement);
1229  }
1230 
1231  for (i = 0; i < logImage->width * logImage->height; i++) {
1232  *(dst_ptr++) = lut[float_uint(*(src_ptr++), logElement.maxValue)];
1233  *(dst_ptr++) = lut[float_uint(*(src_ptr++), logElement.maxValue)];
1234  *(dst_ptr++) = lut[float_uint(*(src_ptr++), logElement.maxValue)];
1235  src_ptr++;
1236  }
1237 
1238  MEM_freeN(lut);
1239 
1240  return 0;
1241  }
1242 
1243  default:
1244  if (verbose) {
1245  printf("DPX/Cineon: Unknown transfer %d.\n", logElement.transfer);
1246  }
1247  return 1;
1248  }
1249 }
1250 
1251 static int convertRGB_RGBA(float *src,
1252  float *dst,
1253  LogImageFile *logImage,
1254  LogImageElement logElement,
1255  int elementIsSource)
1256 {
1257  unsigned int i;
1258  float *src_ptr = src;
1259  float *dst_ptr = dst;
1260 
1261  switch (logElement.transfer) {
1262  case transfer_Unspecified:
1263  case transfer_UserDefined:
1264  case transfer_Linear:
1265  case transfer_Logarithmic: {
1266  for (i = 0; i < logImage->width * logImage->height; i++) {
1267  *(dst_ptr++) = *(src_ptr++);
1268  *(dst_ptr++) = *(src_ptr++);
1269  *(dst_ptr++) = *(src_ptr++);
1270  *(dst_ptr++) = 1.0f;
1271  }
1272 
1273  return 0;
1274  }
1275 
1276  case transfer_PrintingDensity: {
1277  float *lut;
1278 
1279  if (elementIsSource == 1) {
1280  lut = getLogToLinLut(logImage, logElement);
1281  }
1282  else {
1283  lut = getLinToLogLut(logImage, logElement);
1284  }
1285 
1286  for (i = 0; i < logImage->width * logImage->height; i++) {
1287  *(dst_ptr++) = lut[float_uint(*(src_ptr++), logElement.maxValue)];
1288  *(dst_ptr++) = lut[float_uint(*(src_ptr++), logElement.maxValue)];
1289  *(dst_ptr++) = lut[float_uint(*(src_ptr++), logElement.maxValue)];
1290  *(dst_ptr++) = 1.0f;
1291  }
1292 
1293  MEM_freeN(lut);
1294 
1295  return 0;
1296  }
1297 
1298  default:
1299  if (verbose) {
1300  printf("DPX/Cineon: Unknown transfer %d.\n", logElement.transfer);
1301  }
1302  return 1;
1303  }
1304 }
1305 
1306 static int convertRGBA_RGBA(float *src,
1307  float *dst,
1308  LogImageFile *logImage,
1309  LogImageElement logElement,
1310  int elementIsSource)
1311 {
1312  unsigned int i;
1313  float *src_ptr = src;
1314  float *dst_ptr = dst;
1315 
1316  switch (logElement.transfer) {
1317  case transfer_UserDefined:
1318  case transfer_Linear:
1319  case transfer_Logarithmic: {
1320  memcpy(dst, src, 4 * (size_t)logImage->width * (size_t)logImage->height * sizeof(float));
1321  return 0;
1322  }
1323 
1324  case transfer_PrintingDensity: {
1325  float *lut;
1326 
1327  if (elementIsSource == 1) {
1328  lut = getLogToLinLut(logImage, logElement);
1329  }
1330  else {
1331  lut = getLinToLogLut(logImage, logElement);
1332  }
1333 
1334  for (i = 0; i < logImage->width * logImage->height; i++) {
1335  *(dst_ptr++) = lut[float_uint(*(src_ptr++), logElement.maxValue)];
1336  *(dst_ptr++) = lut[float_uint(*(src_ptr++), logElement.maxValue)];
1337  *(dst_ptr++) = lut[float_uint(*(src_ptr++), logElement.maxValue)];
1338  *(dst_ptr++) = *(src_ptr++);
1339  }
1340 
1341  MEM_freeN(lut);
1342 
1343  return 0;
1344  }
1345 
1346  default:
1347  return 1;
1348  }
1349 }
1350 
1351 static int convertABGR_RGBA(float *src,
1352  float *dst,
1353  LogImageFile *logImage,
1354  LogImageElement logElement,
1355  int elementIsSource)
1356 {
1357  unsigned int i;
1358  float *src_ptr = src;
1359  float *dst_ptr = dst;
1360 
1361  switch (logElement.transfer) {
1362  case transfer_UserDefined:
1363  case transfer_Linear:
1364  case transfer_Logarithmic: {
1365  for (i = 0; i < logImage->width * logImage->height; i++) {
1366  src_ptr += 4;
1367  *(dst_ptr++) = *(src_ptr--);
1368  *(dst_ptr++) = *(src_ptr--);
1369  *(dst_ptr++) = *(src_ptr--);
1370  *(dst_ptr++) = *(src_ptr--);
1371  src_ptr += 4;
1372  }
1373  return 0;
1374  }
1375 
1376  case transfer_PrintingDensity: {
1377  float *lut;
1378 
1379  if (elementIsSource == 1) {
1380  lut = getLogToLinLut(logImage, logElement);
1381  }
1382  else {
1383  lut = getLinToLogLut(logImage, logElement);
1384  }
1385 
1386  for (i = 0; i < logImage->width * logImage->height; i++) {
1387  src_ptr += 4;
1388  *(dst_ptr++) = lut[float_uint(*(src_ptr--), logElement.maxValue)];
1389  *(dst_ptr++) = lut[float_uint(*(src_ptr--), logElement.maxValue)];
1390  *(dst_ptr++) = lut[float_uint(*(src_ptr--), logElement.maxValue)];
1391  *(dst_ptr++) = *(src_ptr--);
1392  src_ptr += 4;
1393  }
1394 
1395  MEM_freeN(lut);
1396 
1397  return 0;
1398  }
1399 
1400  default:
1401  return 1;
1402  }
1403 }
1404 
1405 static int convertCbYCr_RGBA(float *src,
1406  float *dst,
1407  LogImageFile *logImage,
1408  LogImageElement logElement)
1409 {
1410  unsigned int i;
1411  float conversionMatrix[9], refLowData, y, cb, cr;
1412  float *src_ptr = src;
1413  float *dst_ptr = dst;
1414 
1415  if (getYUVtoRGBMatrix((float *)&conversionMatrix, logElement) != 0) {
1416  return 1;
1417  }
1418 
1419  refLowData = (float)logElement.refLowData / logElement.maxValue;
1420 
1421  for (i = 0; i < logImage->width * logImage->height; i++) {
1422  cb = *(src_ptr++) - 0.5f;
1423  y = *(src_ptr++) - refLowData;
1424  cr = *(src_ptr++) - 0.5f;
1425 
1426  *(dst_ptr++) = clamp_float(
1427  y * conversionMatrix[0] + cb * conversionMatrix[1] + cr * conversionMatrix[2], 0.0f, 1.0f);
1428  *(dst_ptr++) = clamp_float(
1429  y * conversionMatrix[3] + cb * conversionMatrix[4] + cr * conversionMatrix[5], 0.0f, 1.0f);
1430  *(dst_ptr++) = clamp_float(
1431  y * conversionMatrix[6] + cb * conversionMatrix[7] + cr * conversionMatrix[8], 0.0f, 1.0f);
1432  *(dst_ptr++) = 1.0f;
1433  }
1434  return 0;
1435 }
1436 
1437 static int convertCbYCrA_RGBA(float *src,
1438  float *dst,
1439  LogImageFile *logImage,
1440  LogImageElement logElement)
1441 {
1442  unsigned int i;
1443  float conversionMatrix[9], refLowData, y, cb, cr, a;
1444  float *src_ptr = src;
1445  float *dst_ptr = dst;
1446 
1447  if (getYUVtoRGBMatrix((float *)&conversionMatrix, logElement) != 0) {
1448  return 1;
1449  }
1450 
1451  refLowData = (float)logElement.refLowData / logElement.maxValue;
1452 
1453  for (i = 0; i < logImage->width * logImage->height; i++) {
1454  cb = *(src_ptr++) - 0.5f;
1455  y = *(src_ptr++) - refLowData;
1456  cr = *(src_ptr++) - 0.5f;
1457  a = *(src_ptr++);
1458 
1459  *(dst_ptr++) = clamp_float(
1460  y * conversionMatrix[0] + cb * conversionMatrix[1] + cr * conversionMatrix[2], 0.0f, 1.0f);
1461  *(dst_ptr++) = clamp_float(
1462  y * conversionMatrix[3] + cb * conversionMatrix[4] + cr * conversionMatrix[5], 0.0f, 1.0f);
1463  *(dst_ptr++) = clamp_float(
1464  y * conversionMatrix[6] + cb * conversionMatrix[7] + cr * conversionMatrix[8], 0.0f, 1.0f);
1465  *(dst_ptr++) = a;
1466  }
1467  return 0;
1468 }
1469 
1470 static int convertCbYCrY_RGBA(float *src,
1471  float *dst,
1472  LogImageFile *logImage,
1473  LogImageElement logElement)
1474 {
1475  unsigned int i;
1476  float conversionMatrix[9], refLowData, y1, y2, cb, cr;
1477  float *src_ptr = src;
1478  float *dst_ptr = dst;
1479 
1480  if (getYUVtoRGBMatrix((float *)&conversionMatrix, logElement) != 0) {
1481  return 1;
1482  }
1483 
1484  refLowData = (float)logElement.refLowData / logElement.maxValue;
1485 
1486  for (i = 0; i < logImage->width * logImage->height / 2; i++) {
1487  cb = *(src_ptr++) - 0.5f;
1488  y1 = *(src_ptr++) - refLowData;
1489  cr = *(src_ptr++) - 0.5f;
1490  y2 = *(src_ptr++) - refLowData;
1491 
1492  *(dst_ptr++) = clamp_float(y1 * conversionMatrix[0] + cb * conversionMatrix[1] +
1493  cr * conversionMatrix[2],
1494  0.0f,
1495  1.0f);
1496  *(dst_ptr++) = clamp_float(y1 * conversionMatrix[3] + cb * conversionMatrix[4] +
1497  cr * conversionMatrix[5],
1498  0.0f,
1499  1.0f);
1500  *(dst_ptr++) = clamp_float(y1 * conversionMatrix[6] + cb * conversionMatrix[7] +
1501  cr * conversionMatrix[8],
1502  0.0f,
1503  1.0f);
1504  *(dst_ptr++) = 1.0f;
1505  *(dst_ptr++) = clamp_float(y2 * conversionMatrix[0] + cb * conversionMatrix[1] +
1506  cr * conversionMatrix[2],
1507  0.0f,
1508  1.0f);
1509  *(dst_ptr++) = clamp_float(y2 * conversionMatrix[3] + cb * conversionMatrix[4] +
1510  cr * conversionMatrix[5],
1511  0.0f,
1512  1.0f);
1513  *(dst_ptr++) = clamp_float(y2 * conversionMatrix[6] + cb * conversionMatrix[7] +
1514  cr * conversionMatrix[8],
1515  0.0f,
1516  1.0f);
1517  *(dst_ptr++) = 1.0f;
1518  }
1519  return 0;
1520 }
1521 
1522 static int convertCbYACrYA_RGBA(float *src,
1523  float *dst,
1524  LogImageFile *logImage,
1525  LogImageElement logElement)
1526 {
1527  unsigned int i;
1528  float conversionMatrix[9], refLowData, y1, y2, cb, cr, a1, a2;
1529  float *src_ptr = src;
1530  float *dst_ptr = dst;
1531 
1532  if (getYUVtoRGBMatrix((float *)&conversionMatrix, logElement) != 0) {
1533  return 1;
1534  }
1535 
1536  refLowData = (float)logElement.refLowData / logElement.maxValue;
1537 
1538  for (i = 0; i < logImage->width * logImage->height / 2; i++) {
1539  cb = *(src_ptr++) - 0.5f;
1540  y1 = *(src_ptr++) - refLowData;
1541  a1 = *(src_ptr++);
1542  cr = *(src_ptr++) - 0.5f;
1543  y2 = *(src_ptr++) - refLowData;
1544  a2 = *(src_ptr++);
1545 
1546  *(dst_ptr++) = clamp_float(y1 * conversionMatrix[0] + cb * conversionMatrix[1] +
1547  cr * conversionMatrix[2],
1548  0.0f,
1549  1.0f);
1550  *(dst_ptr++) = clamp_float(y1 * conversionMatrix[3] + cb * conversionMatrix[4] +
1551  cr * conversionMatrix[5],
1552  0.0f,
1553  1.0f);
1554  *(dst_ptr++) = clamp_float(y1 * conversionMatrix[6] + cb * conversionMatrix[7] +
1555  cr * conversionMatrix[8],
1556  0.0f,
1557  1.0f);
1558  *(dst_ptr++) = a1;
1559  *(dst_ptr++) = clamp_float(y2 * conversionMatrix[0] + cb * conversionMatrix[1] +
1560  cr * conversionMatrix[2],
1561  0.0f,
1562  1.0f);
1563  *(dst_ptr++) = clamp_float(y2 * conversionMatrix[3] + cb * conversionMatrix[4] +
1564  cr * conversionMatrix[5],
1565  0.0f,
1566  1.0f);
1567  *(dst_ptr++) = clamp_float(y2 * conversionMatrix[6] + cb * conversionMatrix[7] +
1568  cr * conversionMatrix[8],
1569  0.0f,
1570  1.0f);
1571  *(dst_ptr++) = a2;
1572  }
1573  return 0;
1574 }
1575 
1576 static int convertLuminance_RGBA(float *src,
1577  float *dst,
1578  LogImageFile *logImage,
1579  LogImageElement logElement)
1580 {
1581  unsigned int i;
1582  float conversionMatrix[9], value, refLowData;
1583  float *src_ptr = src;
1584  float *dst_ptr = dst;
1585 
1586  if (getYUVtoRGBMatrix((float *)&conversionMatrix, logElement) != 0) {
1587  return 1;
1588  }
1589 
1590  refLowData = (float)logElement.refLowData / logElement.maxValue;
1591 
1592  for (i = 0; i < logImage->width * logImage->height; i++) {
1593  value = clamp_float((*(src_ptr++) - refLowData) * conversionMatrix[0], 0.0f, 1.0f);
1594  *(dst_ptr++) = value;
1595  *(dst_ptr++) = value;
1596  *(dst_ptr++) = value;
1597  *(dst_ptr++) = 1.0f;
1598  }
1599  return 0;
1600 }
1601 
1602 static int convertYA_RGBA(float *src,
1603  float *dst,
1604  LogImageFile *logImage,
1605  LogImageElement logElement)
1606 {
1607  unsigned int i;
1608  float conversionMatrix[9], value, refLowData;
1609  float *src_ptr = src;
1610  float *dst_ptr = dst;
1611 
1612  if (getYUVtoRGBMatrix((float *)&conversionMatrix, logElement) != 0) {
1613  return 1;
1614  }
1615 
1616  refLowData = (float)logElement.refLowData / logElement.maxValue;
1617 
1618  for (i = 0; i < logImage->width * logImage->height; i++) {
1619  value = clamp_float((*(src_ptr++) - refLowData) * conversionMatrix[0], 0.0f, 1.0f);
1620  *(dst_ptr++) = value;
1621  *(dst_ptr++) = value;
1622  *(dst_ptr++) = value;
1623  *(dst_ptr++) = *(src_ptr++);
1624  }
1625  return 0;
1626 }
1627 
1629  float *src, float *dst, LogImageFile *logImage, LogImageElement logElement, int dstIsLinearRGB)
1630 {
1631  int rvalue;
1632  unsigned int i;
1633  float *src_ptr;
1634  float *dst_ptr;
1635 
1636  /* Convert data in src to linear RGBA in dst */
1637  switch (logElement.descriptor) {
1638  case descriptor_RGB:
1639  rvalue = convertRGB_RGBA(src, dst, logImage, logElement, 1);
1640  break;
1641 
1642  case descriptor_RGBA:
1643  rvalue = convertRGBA_RGBA(src, dst, logImage, logElement, 1);
1644  break;
1645 
1646  case descriptor_ABGR:
1647  rvalue = convertABGR_RGBA(src, dst, logImage, logElement, 1);
1648  break;
1649 
1650  case descriptor_Luminance:
1651  rvalue = convertLuminance_RGBA(src, dst, logImage, logElement);
1652  break;
1653 
1654  case descriptor_CbYCr:
1655  rvalue = convertCbYCr_RGBA(src, dst, logImage, logElement);
1656  break;
1657 
1658  case descriptor_CbYCrY:
1659  rvalue = convertCbYCrY_RGBA(src, dst, logImage, logElement);
1660  break;
1661 
1662  case descriptor_CbYACrYA:
1663  rvalue = convertCbYACrYA_RGBA(src, dst, logImage, logElement);
1664  break;
1665 
1666  case descriptor_CbYCrA:
1667  rvalue = convertCbYCrA_RGBA(src, dst, logImage, logElement);
1668  break;
1669 
1670  case descriptor_YA: /* this descriptor is for internal use only */
1671  rvalue = convertYA_RGBA(src, dst, logImage, logElement);
1672  break;
1673 
1674  default:
1675  return 1;
1676  }
1677 
1678  if (rvalue == 1) {
1679  return 1;
1680  }
1681  if (dstIsLinearRGB) {
1682  /* convert data from sRGB to Linear RGB via lut */
1683  float *lut = getSrgbToLinLut(logElement);
1684  src_ptr = dst; /* no error here */
1685  dst_ptr = dst;
1686  for (i = 0; i < logImage->width * logImage->height; i++) {
1687  *(dst_ptr++) = lut[float_uint(*(src_ptr++), logElement.maxValue)];
1688  *(dst_ptr++) = lut[float_uint(*(src_ptr++), logElement.maxValue)];
1689  *(dst_ptr++) = lut[float_uint(*(src_ptr++), logElement.maxValue)];
1690  dst_ptr++;
1691  src_ptr++;
1692  }
1693  MEM_freeN(lut);
1694  }
1695  return 0;
1696 }
1697 
1699  float *src, float *dst, LogImageFile *logImage, LogImageElement logElement, int srcIsLinearRGB)
1700 {
1701  unsigned int i;
1702  int rvalue;
1703  float *srgbSrc;
1704  float *srgbSrc_ptr;
1705  float *src_ptr = src;
1706  float *lut;
1707 
1708  if (srcIsLinearRGB != 0) {
1709  /* we need to convert src to sRGB */
1710  srgbSrc = (float *)imb_alloc_pixels(
1711  logImage->width, logImage->height, 4, sizeof(float), __func__);
1712  if (srgbSrc == NULL) {
1713  return 1;
1714  }
1715 
1716  memcpy(srgbSrc, src, 4 * (size_t)logImage->width * (size_t)logImage->height * sizeof(float));
1717  srgbSrc_ptr = srgbSrc;
1718 
1719  /* convert data from Linear RGB to sRGB via lut */
1720  lut = getLinToSrgbLut(logElement);
1721  for (i = 0; i < logImage->width * logImage->height; i++) {
1722  *(srgbSrc_ptr++) = lut[float_uint(*(src_ptr++), logElement.maxValue)];
1723  *(srgbSrc_ptr++) = lut[float_uint(*(src_ptr++), logElement.maxValue)];
1724  *(srgbSrc_ptr++) = lut[float_uint(*(src_ptr++), logElement.maxValue)];
1725  srgbSrc_ptr++;
1726  src_ptr++;
1727  }
1728  MEM_freeN(lut);
1729  }
1730  else {
1731  srgbSrc = src;
1732  }
1733 
1734  /* Convert linear RGBA data in src to format described by logElement in dst */
1735  switch (logElement.descriptor) {
1736  case descriptor_RGB:
1737  rvalue = convertRGBA_RGB(srgbSrc, dst, logImage, logElement, 0);
1738  break;
1739 
1740  case descriptor_RGBA:
1741  rvalue = convertRGBA_RGBA(srgbSrc, dst, logImage, logElement, 0);
1742  break;
1743 
1744  /* these ones are not supported for the moment */
1745  case descriptor_ABGR:
1746  case descriptor_Luminance:
1747  case descriptor_CbYCr:
1748  case descriptor_CbYCrY:
1749  case descriptor_CbYACrYA:
1750  case descriptor_CbYCrA:
1751  case descriptor_YA: /* this descriptor is for internal use only */
1752  default:
1753  rvalue = 1;
1754  break;
1755  }
1756 
1757  if (srcIsLinearRGB != 0) {
1758  MEM_freeN(srgbSrc);
1759  }
1760 
1761  return rvalue;
1762 }
typedef float(TangentPoint)[2]
File and directory operations.
FILE * BLI_fopen(const char *filepath, const char *mode) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: fileops.c:906
#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 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 y1
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei height
_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 width
void * imb_alloc_pixels(unsigned int x, unsigned int y, unsigned int channels, size_t typesize, const char *name)
Definition: allocimbuf.c:354
Read Guarded memory(de)allocation.
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
void cineonSetVerbose(int verbosity)
Definition: cineonlib.c:31
LogImageFile * cineonCreate(const char *filepath, int width, int height, int bitsPerSample, const char *creator)
Definition: cineonlib.c:352
LogImageFile * cineonOpen(const unsigned char *byteStuff, int fromMemory, size_t bufferSize)
Definition: cineonlib.c:125
#define CINEON_FILE_MAGIC
Definition: cineonlib.h:19
#define powf(x, y)
Definition: cuda/compat.h:103
SyclQueue void void * src
SyclQueue void void size_t num_bytes void
void dpxSetVerbose(int verbosity)
Definition: dpxlib.c:31
LogImageFile * dpxCreate(const char *filepath, int width, int height, int bitsPerSample, int hasAlpha, int isLogarithmic, int referenceWhite, int referenceBlack, float gamma, const char *creator)
Definition: dpxlib.c:409
LogImageFile * dpxOpen(const unsigned char *byteStuff, int fromMemory, size_t bufferSize)
Definition: dpxlib.c:123
#define DPX_FILE_MAGIC
Definition: dpxlib.h:20
uint col
ccl_global float * buffer
ccl_gpu_kernel_postfix ccl_global float int int int int float bool int offset
static int logImageElementGetData10Packed(LogImageFile *logImage, LogImageElement logElement, float *data)
Definition: logImageCore.c:827
static int convertRGBA_RGBA(float *src, float *dst, LogImageFile *logImage, LogImageElement logElement, int elementIsSource)
static float * getLinToLogLut(LogImageFile *logImage, LogImageElement logElement)
static int logImageElementGetData10(LogImageFile *logImage, LogImageElement logElement, float *data)
Definition: logImageCore.c:755
static int verbose
Definition: logImageCore.c:71
static int convertABGR_RGBA(float *src, float *dst, LogImageFile *logImage, LogImageElement logElement, int elementIsSource)
static int logImageElementGetData12Packed(LogImageFile *logImage, LogImageElement logElement, float *data)
Definition: logImageCore.c:921
LogImageFile * logImageCreate(const char *filepath, int cineon, int width, int height, int bitsPerSample, int isLogarithmic, int hasAlpha, int referenceWhite, int referenceBlack, float gamma, const char *creator)
Definition: logImageCore.c:144
static int logImageSetData12(LogImageFile *logImage, LogImageElement logElement, float *data)
Definition: logImageCore.c:353
static int convertRGBAToLogElement(float *src, float *dst, LogImageFile *logImage, LogImageElement logElement, int srcIsLinearRGB)
static float * getLinToSrgbLut(LogImageElement logElement)
static int logImageSetData16(LogImageFile *logImage, LogImageElement logElement, float *data)
Definition: logImageCore.c:385
void logImageSetVerbose(int verbosity)
Definition: logImageCore.c:73
static int logImageElementGetData1(LogImageFile *logImage, LogImageElement logElement, float *data)
Definition: logImageCore.c:696
int logImageIsCineon(const void *buffer, const unsigned int size)
Definition: logImageCore.c:94
static float * getSrgbToLinLut(LogImageElement logElement)
static int convertLogElementToRGBA(float *src, float *dst, LogImageFile *logImage, LogImageElement logElement, int dstIsLinearRGB)
static int convertCbYCrA_RGBA(float *src, float *dst, LogImageFile *logImage, LogImageElement logElement)
static int convertRGB_RGBA(float *src, float *dst, LogImageFile *logImage, LogImageElement logElement, int elementIsSource)
static int convertRGBA_RGB(float *src, float *dst, LogImageFile *logImage, LogImageElement logElement, int elementIsSource)
LogImageFile * logImageOpenFromMemory(const unsigned char *buffer, unsigned int size)
Definition: logImageCore.c:132
LogImageFile * logImageOpenFromFile(const char *filepath, int cineon)
Definition: logImageCore.c:104
static int logImageElementGetData(LogImageFile *logImage, LogImageElement logElement, float *data)
Definition: logImageCore.c:662
static int convertCbYACrYA_RGBA(float *src, float *dst, LogImageFile *logImage, LogImageElement logElement)
static int convertLuminance_RGBA(float *src, float *dst, LogImageFile *logImage, LogImageElement logElement)
static int logImageSetData10(LogImageFile *logImage, LogImageElement logElement, float *data)
Definition: logImageCore.c:307
static float * getLogToLinLut(LogImageFile *logImage, LogImageElement logElement)
void logImageClose(LogImageFile *logImage)
Definition: logImageCore.c:175
static int convertCbYCrY_RGBA(float *src, float *dst, LogImageFile *logImage, LogImageElement logElement)
static int logImageElementGetData16(LogImageFile *logImage, LogImageElement logElement, float *data)
Definition: logImageCore.c:977
int logImageIsDpx(const void *buffer, const unsigned int size)
Definition: logImageCore.c:84
static int logImageElementGetData12(LogImageFile *logImage, LogImageElement logElement, float *data)
Definition: logImageCore.c:883
size_t getRowLength(size_t width, LogImageElement logElement)
Definition: logImageCore.c:197
static int logImageSetData8(LogImageFile *logImage, LogImageElement logElement, float *data)
Definition: logImageCore.c:276
void logImageGetSize(LogImageFile *logImage, int *width, int *height, int *depth)
Definition: logImageCore.c:186
int logImageSetDataRGBA(LogImageFile *logImage, float *data, int dataIsLinearRGB)
Definition: logImageCore.c:233
int logImageGetDataRGBA(LogImageFile *logImage, float *data, int dataIsLinearRGB)
Definition: logImageCore.c:421
static int convertYA_RGBA(float *src, float *dst, LogImageFile *logImage, LogImageElement logElement)
static int convertCbYCr_RGBA(float *src, float *dst, LogImageFile *logImage, LogImageElement logElement)
static int logImageElementGetData8(LogImageFile *logImage, LogImageElement logElement, float *data)
Definition: logImageCore.c:727
static int getYUVtoRGBMatrix(float *matrix, LogImageElement logElement)
BLI_INLINE float clamp_float(float x, float low, float high)
Definition: logImageCore.h:259
@ format_DPX
Definition: logImageCore.h:39
@ descriptor_Chrominance
Definition: logImageCore.h:151
@ descriptor_CbYCr
Definition: logImageCore.h:159
@ descriptor_Red
Definition: logImageCore.h:146
@ descriptor_YA
Definition: logImageCore.h:169
@ descriptor_Composite
Definition: logImageCore.h:153
@ descriptor_Depth
Definition: logImageCore.h:152
@ descriptor_CbYCrA
Definition: logImageCore.h:160
@ descriptor_Luminance
Definition: logImageCore.h:150
@ descriptor_Green
Definition: logImageCore.h:147
@ descriptor_ABGR
Definition: logImageCore.h:156
@ descriptor_CbYCrY
Definition: logImageCore.h:157
@ descriptor_Blue
Definition: logImageCore.h:148
@ descriptor_RGB
Definition: logImageCore.h:154
@ descriptor_CbYACrYA
Definition: logImageCore.h:158
@ descriptor_Alpha
Definition: logImageCore.h:149
@ descriptor_RGBA
Definition: logImageCore.h:155
@ transfer_PrintingDensity
Definition: logImageCore.h:104
@ transfer_UserDefined
Definition: logImageCore.h:103
@ transfer_Linear
Definition: logImageCore.h:105
@ transfer_Logarithmic
Definition: logImageCore.h:106
@ transfer_Unspecified
Definition: logImageCore.h:107
BLI_INLINE unsigned short swap_ushort(unsigned short x, int swap)
Definition: logImageCore.h:204
BLI_INLINE unsigned int swap_uint(unsigned int x, int swap)
Definition: logImageCore.h:214
BLI_INLINE unsigned int float_uint(float value, unsigned int max)
Definition: logImageCore.h:272
int logimage_read_ushort(unsigned short *x, LogImageFile *logFile)
Definition: logmemfile.c:92
int logimage_read_uchar(unsigned char *x, LogImageFile *logFile)
Definition: logmemfile.c:80
int logimage_fseek(LogImageFile *logFile, intptr_t offset, int origin)
Definition: logmemfile.c:17
int logimage_read_uint(unsigned int *x, LogImageFile *logFile)
Definition: logmemfile.c:104
int logimage_fwrite(void *buffer, size_t size, unsigned int count, LogImageFile *logFile)
Definition: logmemfile.c:47
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:33
static unsigned a[3]
Definition: RandGen.cpp:78
unsigned int refLowData
Definition: logImageCore.h:50
float refHighQuantity
Definition: logImageCore.h:53
unsigned int refHighData
Definition: logImageCore.h:51
float referenceWhite
Definition: logImageCore.h:67
LogImageElement element[8]
Definition: logImageCore.h:63
float referenceBlack
Definition: logImageCore.h:66