Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/imbuf/intern/cineon/cineonlib.c')
-rw-r--r--source/blender/imbuf/intern/cineon/cineonlib.c1010
1 files changed, 280 insertions, 730 deletions
diff --git a/source/blender/imbuf/intern/cineon/cineonlib.c b/source/blender/imbuf/intern/cineon/cineonlib.c
index 894e3a93b4b..92a984378db 100644
--- a/source/blender/imbuf/intern/cineon/cineonlib.c
+++ b/source/blender/imbuf/intern/cineon/cineonlib.c
@@ -1,21 +1,23 @@
/*
- * Cineon image file format library routines.
+ * Cineon image file format library routines.
*
- * Copyright 1999,2000,2001 David Hodson <hodsond@acm.org>
+ * Copyright 1999,2000,2001 David Hodson <hodsond@acm.org>
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
*
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Julien Enche.
*
*/
@@ -23,800 +25,348 @@
* \ingroup imbcineon
*/
+
#include "cineonlib.h"
-#include "cineonfile.h"
+#include "logmemfile.h"
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
-#include <time.h> /* strftime() */
+#include <time.h>
#include <sys/types.h>
-#ifdef WIN32
-#include <winsock.h>
-#else
-#include <netinet/in.h> /* htonl() */
-#endif
-#include <string.h> /* memset */
-
-#include "BLI_utildefines.h"
-#include "BLI_fileops.h"
-
-#include "cin_debug_stuff.h"
-#include "logmemfile.h"
-
-static void
-fillCineonFileInfo(CineonFile* cineon, CineonFileInformation* fileInfo, const char* filename) {
+#include <string.h>
- time_t fileClock;
- struct tm* fileTime;
-
- fileInfo->magic_num = htonl(CINEON_FILE_MAGIC);
- fileInfo->image_offset = htonl(cineon->imageOffset);
- fileInfo->gen_hdr_size = htonl(
- sizeof(CineonFileInformation) +
- sizeof(CineonImageInformation) +
- sizeof(CineonFormatInformation) +
- sizeof(CineonOriginationInformation));
- fileInfo->ind_hdr_size = 0;
- fileInfo->user_data_size = 0;
- fileInfo->file_size = htonl(cineon->imageOffset + cineon->height * cineon->lineBufferLength);
- strcpy(fileInfo->vers, "V4.5");
- strncpy(fileInfo->file_name, filename, 99);
- fileInfo->file_name[99] = 0;
-
- fileClock = time(0);
- fileTime = localtime(&fileClock);
- strftime(fileInfo->create_date, 12, "%Y:%m:%d", fileTime);
- /* Question: is %Z in strftime guaranteed to return 3 chars? */
- strftime(fileInfo->create_time, 12, "%H:%M:%S%Z", fileTime);
- fileInfo->create_time[11] = 0;
-}
-
-static void
-dumpCineonFileInfo(CineonFileInformation* fileInfo) {
- d_printf("\n--File Information--\n");
- d_printf("Magic: %8.8lX\n", (uintptr_t)ntohl(fileInfo->magic_num));
- d_printf("Image Offset %ld\n", (intptr_t)ntohl(fileInfo->image_offset));
- d_printf("Generic Header size %ld\n", (intptr_t)ntohl(fileInfo->gen_hdr_size));
- d_printf("Industry Header size %ld\n", (intptr_t)ntohl(fileInfo->ind_hdr_size));
- d_printf("User Data size %ld\n", (intptr_t)ntohl(fileInfo->user_data_size));
- d_printf("File size %ld\n", (intptr_t)ntohl(fileInfo->file_size));
- d_printf("Version \"%s\"\n", fileInfo->vers);
- d_printf("File name \"%s\"\n", fileInfo->file_name);
- d_printf("Creation date \"%s\"\n", fileInfo->create_date);
- d_printf("Creation time \"%s\"\n", fileInfo->create_time);
-}
-
-static void
-fillCineonChannelInfo(CineonFile* cineon, CineonChannelInformation* chan, int des) {
-
- chan->designator1 = 0;
- chan->designator2 = des;
- chan->bits_per_pixel = 10;
- chan->pixels_per_line = htonl(cineon->width);
- chan->lines_per_image = htonl(cineon->height);
- chan->ref_low_data = htonl(0);
- chan->ref_low_quantity = htonf(0.0);
- chan->ref_high_data = htonl(1023);
- chan->ref_high_quantity = htonf(2.046);
-}
-
-static void
-dumpCineonChannelInfo(CineonChannelInformation* chan) {
- d_printf(" Metric selector: %d", chan->designator1);
- switch (chan->designator1) {
- case 0: d_printf(" (Universal)\n"); break;
- default: d_printf(" (Vendor specific)\n"); break;
- }
- d_printf(" Metric: %d,", chan->designator2);
- switch (chan->designator2) {
- case 0: d_printf(" B&W (printing density?)\n"); break;
- case 1: d_printf(" Red printing density\n"); break;
- case 2: d_printf(" Green printing density\n"); break;
- case 3: d_printf(" Blue printing density\n"); break;
- case 4: d_printf(" Red CCIR XA/11\n"); break;
- case 5: d_printf(" Green CCIR XA/11\n"); break;
- case 6: d_printf(" Blue CCIR XA/11\n"); break;
- default: d_printf(" (unknown)\n"); break;
- }
- d_printf(" Bits per pixel %d\n", chan->bits_per_pixel);
- d_printf(" Pixels per line %ld\n", (intptr_t)ntohl(chan->pixels_per_line));
- d_printf(" Lines per image %ld\n", (intptr_t)ntohl(chan->lines_per_image));
- d_printf(" Ref low data %ld\n", (intptr_t)ntohl(chan->ref_low_data));
- d_printf(" Ref low quantity %f\n", ntohf(chan->ref_low_quantity));
- d_printf(" Ref high data %ld\n", (intptr_t)ntohl(chan->ref_high_data));
- d_printf(" Ref high quantity %f\n", ntohf(chan->ref_high_quantity));
-}
-
-static void
-fillCineonImageInfo(CineonFile* cineon, CineonImageInformation* imageInfo) {
-
- imageInfo->orientation = 0;
- imageInfo->channels_per_image = cineon->depth;
-
- if (cineon->depth == 1) {
- fillCineonChannelInfo(cineon, &imageInfo->channel[0], 0);
-
- }
- else if (cineon->depth == 3) {
- fillCineonChannelInfo(cineon, &imageInfo->channel[0], 1);
- fillCineonChannelInfo(cineon, &imageInfo->channel[1], 2);
- fillCineonChannelInfo(cineon, &imageInfo->channel[2], 3);
- }
-
- imageInfo->white_point_x = htonf(undefined());
- imageInfo->white_point_y = htonf(undefined());
- imageInfo->red_primary_x = htonf(undefined());
- imageInfo->red_primary_y = htonf(undefined());
- imageInfo->green_primary_x = htonf(undefined());
- imageInfo->green_primary_y = htonf(undefined());
- imageInfo->blue_primary_x = htonf(undefined());
- imageInfo->blue_primary_y = htonf(undefined());
-
- strcpy(imageInfo->label, "David's Cineon writer.");
-
-}
-
-static void
-dumpCineonImageInfo(CineonImageInformation* imageInfo) {
-
- int i;
- d_printf("\n--Image Information--\n");
- d_printf("Image orientation %d,", imageInfo->orientation);
- switch (imageInfo->orientation) {
- case 0: d_printf(" LRTB\n"); break;
- case 1: d_printf(" LRBT\n"); break;
- case 2: d_printf(" RLTB\n"); break;
- case 3: d_printf(" RLBT\n"); break;
- case 4: d_printf(" TBLR\n"); break;
- case 5: d_printf(" TBRL\n"); break;
- case 6: d_printf(" BTLR\n"); break;
- case 7: d_printf(" BTRL\n"); break;
- default: d_printf(" (unknown)\n"); break;
- }
- d_printf("Channels %d\n", imageInfo->channels_per_image);
- for (i = 0; i < imageInfo->channels_per_image; ++i) {
- d_printf(" --Channel %d--\n", i);
- dumpCineonChannelInfo(&imageInfo->channel[i]);
- }
-
- d_printf("White point x %f\n", ntohf(imageInfo->white_point_x));
- d_printf("White point y %f\n", ntohf(imageInfo->white_point_y));
- d_printf("Red primary x %f\n", ntohf(imageInfo->red_primary_x));
- d_printf("Red primary y %f\n", ntohf(imageInfo->red_primary_y));
- d_printf("Green primary x %f\n", ntohf(imageInfo->green_primary_x));
- d_printf("Green primary y %f\n", ntohf(imageInfo->green_primary_y));
- d_printf("Blue primary x %f\n", ntohf(imageInfo->blue_primary_x));
- d_printf("Blue primary y %f\n", ntohf(imageInfo->blue_primary_y));
- d_printf("Label \"%s\"\n", imageInfo->label);
-}
-
-static void
-fillCineonFormatInfo(CineonFile* cineon, CineonFormatInformation* formatInfo) {
-
- (void)cineon; /* unused */
-
- formatInfo->interleave = 0;
- formatInfo->packing = 5;
- formatInfo->signage = 0;
- formatInfo->sense = 0;
- formatInfo->line_padding = htonl(0);
- formatInfo->channel_padding = htonl(0);
-}
-
-static void
-dumpCineonFormatInfo(CineonFormatInformation* formatInfo) {
- d_printf("\n--Format Information--\n");
- d_printf("Interleave %d,", formatInfo->interleave);
- switch (formatInfo->interleave) {
- case 0: d_printf(" pixel interleave\n"); break;
- case 1: d_printf(" line interleave\n"); break;
- case 2: d_printf(" channel interleave\n"); break;
- default: d_printf(" (unknown)\n"); break;
- }
- d_printf("Packing %d,", formatInfo->packing);
- if (formatInfo->packing & 0x80) {
- d_printf(" multi pixel,");
- }
- else {
- d_printf(" single pixel,");
- }
- switch (formatInfo->packing & 0x7F) {
- case 0: d_printf(" tight\n"); break;
- case 1: d_printf(" byte packed left\n"); break;
- case 2: d_printf(" byte packed right\n"); break;
- case 3: d_printf(" word packed left\n"); break;
- case 4: d_printf(" word packed right\n"); break;
- case 5: d_printf(" long packed left\n"); break;
- case 6: d_printf(" long packed right\n"); break;
- default: d_printf(" (unknown)\n"); break;
- }
- d_printf("Sign %d,", formatInfo->signage);
- if (formatInfo->signage) {
- d_printf(" signed\n");
- }
- else {
- d_printf(" unsigned\n");
- }
- d_printf("Sense %d,", formatInfo->signage);
- if (formatInfo->signage) {
- d_printf(" negative\n");
- }
- else {
- d_printf(" positive\n");
- }
- d_printf("End of line padding %ld\n", (intptr_t)ntohl(formatInfo->line_padding));
- d_printf("End of channel padding %ld\n", (intptr_t)ntohl(formatInfo->channel_padding));
-}
-
-static void
-fillCineonOriginationInfo(CineonFile* cineon,
- CineonOriginationInformation* originInfo, CineonFileInformation* fileInfo) {
-
- (void)cineon; /* unused */
-
- originInfo->x_offset = htonl(0);
- originInfo->y_offset = htonl(0);
- strcpy(originInfo->file_name, fileInfo->file_name);
- strcpy(originInfo->create_date, fileInfo->create_date);
- strcpy(originInfo->create_time, fileInfo->create_time);
- strncpy(originInfo->input_device, "David's Cineon writer", 64);
- strncpy(originInfo->model_number, "Software", 32);
- strncpy(originInfo->serial_number, "001", 32);
- originInfo->x_input_samples_per_mm = htonf(undefined());
- originInfo->y_input_samples_per_mm = htonf(undefined());
- /* this should probably be undefined, too */
- originInfo->input_device_gamma = htonf(1.0);
-}
-
-static void
-dumpCineonOriginationInfo(CineonOriginationInformation* originInfo) {
- d_printf("\n--Origination Information--\n");
- d_printf("X offset %ld\n", (intptr_t)ntohl(originInfo->x_offset));
- d_printf("Y offset %ld\n", (intptr_t)ntohl(originInfo->y_offset));
- d_printf("File name \"%s\"\n", originInfo->file_name);
- d_printf("Creation date \"%s\"\n", originInfo->create_date);
- d_printf("Creation time \"%s\"\n", originInfo->create_time);
- d_printf("Input device \"%s\"\n", originInfo->input_device);
- d_printf("Model number \"%s\"\n", originInfo->model_number);
- d_printf("Serial number \"%s\"\n", originInfo->serial_number);
- d_printf("Samples per mm in x %f\n", ntohf(originInfo->x_input_samples_per_mm));
- d_printf("Samples per mm in y %f\n", ntohf(originInfo->y_input_samples_per_mm));
- d_printf("Input device gamma %f\n", ntohf(originInfo->input_device_gamma));
-}
-
-static int
-initCineonGenericHeader(CineonFile* cineon, CineonGenericHeader* header, const char* imagename) {
-
- fillCineonFileInfo(cineon, &header->fileInfo, imagename);
- fillCineonImageInfo(cineon, &header->imageInfo);
- fillCineonFormatInfo(cineon, &header->formatInfo);
- fillCineonOriginationInfo(cineon, &header->originInfo, &header->fileInfo);
+#include "BLI_fileops.h"
- return 0;
-}
+#include "MEM_guardedalloc.h"
-static void
-UNUSED_FUNCTION(dumpCineonGenericHeader)(CineonGenericHeader* header) {
- dumpCineonFileInfo(&header->fileInfo);
- dumpCineonImageInfo(&header->imageInfo);
- dumpCineonFormatInfo(&header->formatInfo);
- dumpCineonOriginationInfo(&header->originInfo);
-}
+/*
+ * For debug purpose
+ */
static int verbose = 0;
-void
-cineonSetVerbose(int verbosity) {
- verbose = verbosity;
-}
-
-static void
-verboseMe(CineonFile* cineon) {
-
- d_printf("size %d x %d x %d\n", cineon->width, cineon->height, cineon->depth);
- d_printf("ImageStart %d, lineBufferLength %d, implied length %d\n",
- cineon->imageOffset, cineon->lineBufferLength * 4,
- cineon->imageOffset + cineon->lineBufferLength * 4 * cineon->height);
-}
-
-int
-cineonGetRowBytes(CineonFile* cineon, unsigned short* row, int y) {
-
- int longsRead;
- int pixelIndex;
- int longIndex;
- int numPixels = cineon->width * cineon->depth;
-
-
- /* only seek if not reading consecutive lines */
- if (y != cineon->fileYPos) {
- int lineOffset = cineon->imageOffset + y * cineon->lineBufferLength * 4;
- if (verbose) d_printf("Seek in getRowBytes\n");
- if (logimage_fseek(cineon, lineOffset, SEEK_SET) != 0) {
- if (verbose) d_printf("Couldn't seek to line %d at %d\n", y, lineOffset);
- return 1;
- }
- cineon->fileYPos = y;
- }
-
- longsRead = logimage_fread(cineon->lineBuffer, 4, cineon->lineBufferLength, cineon);
- if (longsRead != cineon->lineBufferLength) {
- if (verbose) {
- d_printf("Couldn't read line %d length %d\n", y, cineon->lineBufferLength * 4);
- perror("cineonGetRowBytes");
- }
-
- return 1;
- }
-
- /* remember where we left the car, honey */
- ++cineon->fileYPos;
-
- /* convert longwords to pixels */
- pixelIndex = 0;
- for (longIndex = 0; longIndex < cineon->lineBufferLength; ++longIndex) {
- unsigned int t = ntohl(cineon->lineBuffer[longIndex]);
- t = t >> 2;
- cineon->pixelBuffer[pixelIndex+2] = (unsigned short) t & 0x3ff;
- t = t >> 10;
- cineon->pixelBuffer[pixelIndex+1] = (unsigned short) t & 0x3ff;
- t = t >> 10;
- cineon->pixelBuffer[pixelIndex] = (unsigned short) t & 0x3ff;
- pixelIndex += 3;
- }
-
- /* extract required pixels */
- for (pixelIndex = 0; pixelIndex < numPixels; ++pixelIndex) {
- if (cineon->params.doLogarithm)
- row[pixelIndex] = cineon->lut10_16[cineon->pixelBuffer[pixelIndex]];
- else
- row[pixelIndex] = cineon->pixelBuffer[pixelIndex] << 6;
- }
-
- return 0;
-}
-
-int
-cineonSetRowBytes(CineonFile* cineon, const unsigned short* row, int y) {
-
- int pixelIndex;
- int numPixels = cineon->width * cineon->depth;
- int longIndex;
- int longsWritten;
-
- /* put new pixels into pixelBuffer */
- for (pixelIndex = 0; pixelIndex < numPixels; ++pixelIndex) {
- if (cineon->params.doLogarithm)
- cineon->pixelBuffer[pixelIndex] = cineon->lut16_16[row[pixelIndex]];
- else
- cineon->pixelBuffer[pixelIndex] = row[pixelIndex] >> 6;
- }
-
- /* pack into longwords */
- pixelIndex = 0;
- for (longIndex = 0; longIndex < cineon->lineBufferLength; ++longIndex) {
- unsigned int t =
- (cineon->pixelBuffer[pixelIndex] << 22) |
- (cineon->pixelBuffer[pixelIndex+1] << 12) |
- (cineon->pixelBuffer[pixelIndex+2] << 2);
- cineon->lineBuffer[longIndex] = htonl(t);
- pixelIndex += 3;
- }
-
- /* only seek if not reading consecutive lines */
- if (y != cineon->fileYPos) {
- int lineOffset = cineon->imageOffset + y * cineon->lineBufferLength * 4;
- if (verbose) d_printf("Seek in setRowBytes\n");
- if (logimage_fseek(cineon, lineOffset, SEEK_SET) != 0) {
- if (verbose) d_printf("Couldn't seek to line %d at %d\n", y, lineOffset);
- return 1;
- }
- cineon->fileYPos = y;
- }
-
- longsWritten = fwrite(cineon->lineBuffer, 4, cineon->lineBufferLength, cineon->file);
- if (longsWritten != cineon->lineBufferLength) {
- if (verbose) d_printf("Couldn't write line %d length %d\n", y, cineon->lineBufferLength * 4);
- return 1;
- }
-
- ++cineon->fileYPos;
-
- return 0;
-}
-
-int
-cineonGetRow(CineonFile* cineon, unsigned short* row, int y) {
-
- int longsRead;
- int pixelIndex;
- int longIndex;
-/* int numPixels = cineon->width * cineon->depth;
-*/
- /* only seek if not reading consecutive lines */
- if (y != cineon->fileYPos) {
- int lineOffset = cineon->imageOffset + y * cineon->lineBufferLength * 4;
- if (verbose) d_printf("Seek in getRow\n");
- if (logimage_fseek(cineon, lineOffset, SEEK_SET) != 0) {
- if (verbose) d_printf("Couldn't seek to line %d at %d\n", y, lineOffset);
- return 1;
- }
- cineon->fileYPos = y;
- }
-
- longsRead = logimage_fread(cineon->lineBuffer, 4, cineon->lineBufferLength, cineon);
- if (longsRead != cineon->lineBufferLength) {
- if (verbose) d_printf("Couldn't read line %d length %d\n", y, cineon->lineBufferLength * 4);
- return 1;
- }
- /* remember where we left the car, honey */
- ++cineon->fileYPos;
-
- /* convert longwords to pixels */
- pixelIndex = 0;
- for (longIndex = 0; longIndex < cineon->lineBufferLength; ++longIndex) {
- unsigned int t = ntohl(cineon->lineBuffer[longIndex]);
- t = t >> 2;
- row[pixelIndex+2] = (unsigned short) t & 0x3ff;
- t = t >> 10;
- row[pixelIndex+1] = (unsigned short) t & 0x3ff;
- t = t >> 10;
- row[pixelIndex] = (unsigned short) t & 0x3ff;
- pixelIndex += 3;
- }
-
- return 0;
+void cineonSetVerbose(int verbosity) {
+ verbose = verbosity;
}
-int
-cineonSetRow(CineonFile* cineon, const unsigned short* row, int y) {
-
- int pixelIndex;
-/* int numPixels = cineon->width * cineon->depth;
-*/ int longIndex;
- int longsWritten;
-
- /* pack into longwords */
- pixelIndex = 0;
- for (longIndex = 0; longIndex < cineon->lineBufferLength; ++longIndex) {
- unsigned int t =
- (row[pixelIndex] << 22) |
- (row[pixelIndex+1] << 12) |
- (row[pixelIndex+2] << 2);
- cineon->lineBuffer[longIndex] = htonl(t);
- pixelIndex += 3;
- }
-
- /* only seek if not reading consecutive lines */
- if (y != cineon->fileYPos) {
- int lineOffset = cineon->imageOffset + y * cineon->lineBufferLength * 4;
- if (verbose) d_printf("Seek in setRowBytes\n");
- if (logimage_fseek(cineon, lineOffset, SEEK_SET) != 0) {
- if (verbose) d_printf("Couldn't seek to line %d at %d\n", y, lineOffset);
- return 1;
- }
- cineon->fileYPos = y;
- }
-
- longsWritten = fwrite(cineon->lineBuffer, 4, cineon->lineBufferLength, cineon->file);
- if (longsWritten != cineon->lineBufferLength) {
- if (verbose) d_printf("Couldn't write line %d length %d\n", y, cineon->lineBufferLength * 4);
- return 1;
- }
-
- ++cineon->fileYPos;
+static void fillCineonMainHeader(LogImageFile *cineon, CineonMainHeader *header,
+ const char *filename, const char *creator)
+{
+ time_t fileClock;
+ struct tm *fileTime;
+ int i;
- return 0;
+ memset(header, 0, sizeof(CineonMainHeader));
+
+ /* --- File header --- */
+ header->fileHeader.magic_num = swap_uint(CINEON_FILE_MAGIC, cineon->isMSB);
+ header->fileHeader.offset = swap_uint(cineon->element[0].dataOffset, cineon->isMSB);
+ header->fileHeader.gen_hdr_size = swap_uint(sizeof(CineonFileHeader) + sizeof(CineonImageHeader) +
+ sizeof(CineonOriginationHeader), cineon->isMSB);
+ header->fileHeader.ind_hdr_size = 0;
+ header->fileHeader.user_data_size = 0;
+ header->fileHeader.file_size = swap_uint(cineon->element[0].dataOffset + cineon->height * getRowLength(cineon->width, cineon->element[0]), cineon->isMSB);
+ strcpy(header->fileHeader.version, "v4.5");
+ strncpy(header->fileHeader.file_name, filename, 99);
+ header->fileHeader.file_name[99] = 0;
+ fileClock = time(0);
+ fileTime = localtime(&fileClock);
+ strftime(header->fileHeader.creation_date, 12, "%Y:%m:%d", fileTime);
+ strftime(header->fileHeader.creation_time, 12, "%H:%M:%S%Z", fileTime);
+ header->fileHeader.creation_time[11] = 0;
+
+ /* --- Image header --- */
+ header->imageHeader.orientation = 0;
+ header->imageHeader.elements_per_image = cineon->depth;
+
+ for (i = 0; i < 3; i++) {
+ header->imageHeader.element[i].descriptor1 = 0;
+ header->imageHeader.element[i].descriptor2 = i;
+ header->imageHeader.element[i].bits_per_sample = cineon->element[0].bitsPerSample;
+ header->imageHeader.element[i].pixels_per_line = swap_uint(cineon->width, cineon->isMSB);
+ header->imageHeader.element[i].lines_per_image = swap_uint(cineon->height, cineon->isMSB);
+ header->imageHeader.element[i].ref_low_data = swap_uint(cineon->element[0].refLowData, cineon->isMSB);
+ header->imageHeader.element[i].ref_low_quantity = swap_float(cineon->element[0].refLowQuantity, cineon->isMSB);
+ header->imageHeader.element[i].ref_high_data = swap_uint(cineon->element[0].refHighData, cineon->isMSB);
+ header->imageHeader.element[i].ref_high_quantity = swap_float(cineon->element[0].refHighQuantity, cineon->isMSB);
+ }
+
+ header->imageHeader.white_point_x = swap_float(0.0f, cineon->isMSB);
+ header->imageHeader.white_point_y = swap_float(0.0f, cineon->isMSB);
+ header->imageHeader.red_primary_x = swap_float(0.0f, cineon->isMSB);
+ header->imageHeader.red_primary_y = swap_float(0.0f, cineon->isMSB);
+ header->imageHeader.green_primary_x = swap_float(0.0f, cineon->isMSB);
+ header->imageHeader.green_primary_y = swap_float(0.0f, cineon->isMSB);
+ header->imageHeader.blue_primary_x = swap_float(0.0f, cineon->isMSB);
+ header->imageHeader.blue_primary_y = swap_float(0.0f, cineon->isMSB);
+ strncpy(header->imageHeader.label, creator, 199);
+ header->imageHeader.label[199] = 0;
+ header->imageHeader.interleave = 0;
+ header->imageHeader.data_sign = 0;
+ header->imageHeader.sense = 0;
+ header->imageHeader.line_padding = swap_uint(0, cineon->isMSB);
+ header->imageHeader.element_padding = swap_uint(0, cineon->isMSB);
+
+ switch (cineon->element[0].packing) {
+ case 0:
+ header->imageHeader.packing = 0;
+ break;
+
+ case 1:
+ header->imageHeader.packing = 5;
+ break;
+
+ case 2:
+ header->imageHeader.packing = 6;
+ break;
+ }
+
+ /* --- Origination header --- */
+ /* we leave it blank */
+
+ /* --- Film header --- */
+ /* we leave it blank */
}
-CineonFile*
-cineonOpen(const char* filename) {
-
- CineonGenericHeader header;
+LogImageFile *cineonOpen(const unsigned char *byteStuff, int fromMemory, size_t bufferSize)
+{
+ CineonMainHeader header;
+ LogImageFile *cineon = (LogImageFile*)MEM_mallocN(sizeof(LogImageFile), __func__);
+ char *filename = (char*)byteStuff;
+ int i;
+ unsigned int dataOffset;
- CineonFile* cineon = (CineonFile* )malloc(sizeof(CineonFile));
if (cineon == 0) {
- if (verbose) d_printf("Failed to malloc cineon file structure.\n");
+ if (verbose) printf("Cineon: Failed to malloc cineon file structure.\n");
return 0;
}
+ /* zero the header */
+ memset(&header, 0, sizeof(CineonMainHeader));
+
/* for close routine */
cineon->file = 0;
- cineon->lineBuffer = 0;
- cineon->pixelBuffer = 0;
- cineon->membuffer = 0;
- cineon->memcursor = 0;
- cineon->membuffersize = 0;
-
- cineon->file = BLI_fopen(filename, "rb");
- if (cineon->file == 0) {
- if (verbose) d_printf("Failed to open file \"%s\".\n", filename);
- cineonClose(cineon);
- return 0;
- }
- cineon->reading = 1;
- if (logimage_fread(&header, sizeof(CineonGenericHeader), 1, cineon) == 0) {
- if (verbose) d_printf("Not enough data for header in \"%s\".\n", filename);
- cineonClose(cineon);
+ if (fromMemory == 0) {
+ /* byteStuff is then the filename */
+ cineon->file = BLI_fopen(filename, "rb");
+ if (cineon->file == 0) {
+ if (verbose) printf("Cineon: Failed to open file \"%s\".\n", filename);
+ logImageClose(cineon);
+ return 0;
+ }
+ /* not used in this case */
+ cineon->memBuffer = 0;
+ cineon->memCursor = 0;
+ cineon->memBufferSize = 0;
+ } else {
+ cineon->memBuffer = (unsigned char*)byteStuff;
+ cineon->memCursor = (unsigned char*)byteStuff;
+ cineon->memBufferSize = bufferSize;
+ }
+
+ if (logimage_fread(&header, sizeof(header), 1, cineon) == 0) {
+ if (verbose) printf("Cineon: Not enough data for header in \"%s\".\n", byteStuff);
+ logImageClose(cineon);
return 0;
}
- /* let's assume cineon files are always network order */
- if (header.fileInfo.magic_num != ntohl(CINEON_FILE_MAGIC)) {
- if (verbose) d_printf("Bad magic number %8.8lX in \"%s\".\n",
- (uintptr_t)ntohl(header.fileInfo.magic_num), filename);
- cineonClose(cineon);
+ /* endianness determination */
+ if (header.fileHeader.magic_num == swap_uint(CINEON_FILE_MAGIC, 1)) {
+ cineon->isMSB = 1;
+ if (verbose) printf("Cineon: File is MSB.\n");
+ } else if (header.fileHeader.magic_num == CINEON_FILE_MAGIC) {
+ cineon->isMSB = 0;
+ if (verbose) printf("Cineon: File is LSB.\n");
+ } else {
+ if (verbose) printf("Cineon: Bad magic number %lu in \"%s\".\n",
+ (uintptr_t)header.fileHeader.magic_num, byteStuff);
+ logImageClose(cineon);
return 0;
}
- if (header.formatInfo.packing != 5) {
- if (verbose) d_printf("Can't understand packing %d\n", header.formatInfo.packing);
- cineonClose(cineon);
- return 0;
- }
+ cineon->width = swap_uint(header.imageHeader.element[0].pixels_per_line, cineon->isMSB);
+ cineon->height = swap_uint(header.imageHeader.element[0].lines_per_image, cineon->isMSB);
+ cineon->depth = header.imageHeader.elements_per_image;
+ cineon->srcFormat = format_Cineon;
- cineon->width = ntohl(header.imageInfo.channel[0].pixels_per_line);
- cineon->height = ntohl(header.imageInfo.channel[0].lines_per_image);
- cineon->depth = header.imageInfo.channels_per_image;
- /* cineon->bitsPerPixel = 10; */
- cineon->bitsPerPixel = header.imageInfo.channel[0].bits_per_pixel;
- cineon->imageOffset = ntohl(header.fileInfo.image_offset);
-
- cineon->lineBufferLength = pixelsToLongs(cineon->width * cineon->depth);
- cineon->lineBuffer = malloc(cineon->lineBufferLength * 4);
- if (cineon->lineBuffer == 0) {
- if (verbose) d_printf("Couldn't malloc line buffer of size %d\n", cineon->lineBufferLength * 4);
- cineonClose(cineon);
+ if (header.imageHeader.interleave == 0)
+ cineon->numElements = 1;
+ else if (header.imageHeader.interleave == 2)
+ cineon->numElements = header.imageHeader.elements_per_image;
+ else {
+ if (verbose) printf("Cineon: Data interleave not supported: %d\n", header.imageHeader.interleave);
return 0;
}
- cineon->pixelBuffer = malloc(cineon->lineBufferLength * 3 * sizeof(unsigned short));
- if (cineon->pixelBuffer == 0) {
- if (verbose) d_printf("Couldn't malloc pixel buffer of size %d\n",
- (cineon->width * cineon->depth) * (int)sizeof(unsigned short));
- cineonClose(cineon);
- return 0;
+ if (cineon->depth == 1) {
+ /* Grayscale image */
+ cineon->element[0].descriptor = descriptor_Luminance;
+ cineon->element[0].transfer = transfer_Linear;
+ cineon->element[0].depth = 1;
}
- cineon->pixelBufferUsed = 0;
-
- if (logimage_fseek(cineon, cineon->imageOffset, SEEK_SET) != 0) {
- if (verbose) d_printf("Couldn't seek to image data at %d\n", cineon->imageOffset);
- cineonClose(cineon);
- return 0;
+ else if (cineon->depth == 3) {
+ /* RGB image */
+ if (cineon->numElements == 1) {
+ cineon->element[0].descriptor = descriptor_RGB;
+ cineon->element[0].transfer = transfer_PrintingDensity;
+ cineon->element[0].depth = 3;
+ }
+ else if (cineon->numElements == 3) {
+ cineon->element[0].descriptor = descriptor_Red;
+ cineon->element[0].transfer = transfer_PrintingDensity;
+ cineon->element[0].depth = 1;
+ cineon->element[1].descriptor = descriptor_Green;
+ cineon->element[1].transfer = transfer_PrintingDensity;
+ cineon->element[1].depth = 1;
+ cineon->element[2].descriptor = descriptor_Blue;
+ cineon->element[2].transfer = transfer_PrintingDensity;
+ cineon->element[2].depth = 1;
+ }
}
- cineon->fileYPos = 0;
-
- logImageGetByteConversionDefaults(&cineon->params);
- setupLut(cineon);
-
- cineon->getRow = &cineonGetRowBytes;
- cineon->setRow = 0;
- cineon->close = &cineonClose;
-
- if (verbose) {
- verboseMe(cineon);
+ else {
+ if (verbose) printf("Cineon: Cineon image depth unsupported: %d\n", cineon->depth);
+ return 0;
}
- return cineon;
-}
+ dataOffset = swap_uint(header.fileHeader.offset, cineon->isMSB);
-int cineonIsMemFileCineon(unsigned char *mem)
-{
- unsigned int num;
- memcpy(&num, mem, sizeof(unsigned int));
-
- if (num != ntohl(CINEON_FILE_MAGIC)) {
- return 0;
- }
- else return 1;
-}
+ for (i = 0; i < cineon->numElements; i++) {
+ cineon->element[i].bitsPerSample = header.imageHeader.element[i].bits_per_sample;
+ cineon->element[i].maxValue = powf(2, cineon->element[i].bitsPerSample) - 1.0f;
+ cineon->element[i].refLowData = swap_uint(header.imageHeader.element[i].ref_low_data, cineon->isMSB);
+ cineon->element[i].refLowQuantity = swap_float(header.imageHeader.element[i].ref_low_quantity, cineon->isMSB);
+ cineon->element[i].refHighData = swap_uint(header.imageHeader.element[i].ref_high_data, cineon->isMSB);
+ cineon->element[i].refHighQuantity = swap_float(header.imageHeader.element[i].ref_high_quantity, cineon->isMSB);
-CineonFile*
-cineonOpenFromMem(unsigned char *mem, unsigned int size) {
+ switch (header.imageHeader.packing) {
+ case 0:
+ cineon->element[i].packing = 0;
+ break;
- CineonGenericHeader header;
-
- CineonFile* cineon = (CineonFile* )malloc(sizeof(CineonFile));
- if (cineon == 0) {
- if (verbose) d_printf("Failed to malloc cineon file structure.\n");
- return 0;
- }
+ case 5:
+ cineon->element[i].packing = 1;
+ break;
- /* for close routine */
- cineon->file = 0;
- cineon->lineBuffer = 0;
- cineon->pixelBuffer = 0;
- cineon->membuffer = mem;
- cineon->membuffersize = size;
- cineon->memcursor = mem;
-
- cineon->file = 0;
- cineon->reading = 1;
- verbose = 0;
- if (size < sizeof(CineonGenericHeader)) {
- if (verbose) d_printf("Not enough data for header!\n");
- cineonClose(cineon);
- return 0;
- }
+ case 6:
+ cineon->element[i].packing = 2;
+ break;
- logimage_fread(&header, sizeof(CineonGenericHeader), 1, cineon);
+ default:
+ /* Not supported */
+ if (verbose) printf("Cineon: packing unsupported: %d\n", header.imageHeader.packing);
+ return 0;
+ }
- /* let's assume cineon files are always network order */
- if (header.fileInfo.magic_num != ntohl(CINEON_FILE_MAGIC)) {
- if (verbose) d_printf("Bad magic number %8.8lX in\n", (uintptr_t)ntohl(header.fileInfo.magic_num));
+ if (cineon->element[i].refLowData == CINEON_UNDEFINED_U32 || isnan(cineon->element[i].refLowData))
+ cineon->element[i].refLowData = 0;
- cineonClose(cineon);
- return 0;
- }
+ if (cineon->element[i].refHighData == CINEON_UNDEFINED_U32 || isnan(cineon->element[i].refHighData))
+ cineon->element[i].refHighData = (unsigned int)cineon->element[i].maxValue;
- if (header.formatInfo.packing != 5) {
- if (verbose) d_printf("Can't understand packing %d\n", header.formatInfo.packing);
- cineonClose(cineon);
- return 0;
- }
+ if (cineon->element[i].refLowQuantity == CINEON_UNDEFINED_R32 || isnan(cineon->element[i].refLowQuantity))
+ cineon->element[i].refLowQuantity = 0.0f;
- cineon->width = ntohl(header.imageInfo.channel[0].pixels_per_line);
- cineon->height = ntohl(header.imageInfo.channel[0].lines_per_image);
- cineon->depth = header.imageInfo.channels_per_image;
- /* cineon->bitsPerPixel = 10; */
- cineon->bitsPerPixel = header.imageInfo.channel[0].bits_per_pixel;
- cineon->imageOffset = ntohl(header.fileInfo.image_offset);
-
- cineon->lineBufferLength = pixelsToLongs(cineon->width * cineon->depth);
- cineon->lineBuffer = malloc(cineon->lineBufferLength * 4);
- if (cineon->lineBuffer == 0) {
- if (verbose) d_printf("Couldn't malloc line buffer of size %d\n", cineon->lineBufferLength * 4);
- cineonClose(cineon);
- return 0;
- }
+ if (cineon->element[i].refHighQuantity == CINEON_UNDEFINED_R32 || isnan(cineon->element[i].refHighQuantity)) {
+ if (cineon->element[i].transfer == transfer_PrintingDensity)
+ cineon->element[i].refHighQuantity = 2.048f;
+ else
+ cineon->element[i].refHighQuantity = cineon->element[i].maxValue;
+ }
- cineon->pixelBuffer = malloc(cineon->lineBufferLength * 3 * sizeof(unsigned short));
- if (cineon->pixelBuffer == 0) {
- if (verbose) d_printf("Couldn't malloc pixel buffer of size %d\n",
- (cineon->width * cineon->depth) * (int)sizeof(unsigned short));
- cineonClose(cineon);
- return 0;
- }
- cineon->pixelBufferUsed = 0;
-
- if (logimage_fseek(cineon, cineon->imageOffset, SEEK_SET) != 0) {
- if (verbose) d_printf("Couldn't seek to image data at %d\n", cineon->imageOffset);
- cineonClose(cineon);
- return 0;
+ cineon->element[i].dataOffset = dataOffset;
+ dataOffset += cineon->height * getRowLength(cineon->width, cineon->element[i]);
}
-
- cineon->fileYPos = 0;
-
- logImageGetByteConversionDefaults(&cineon->params);
- setupLut(cineon);
- cineon->getRow = &cineonGetRowBytes;
- cineon->setRow = 0;
- cineon->close = &cineonClose;
+ cineon->referenceBlack = 95.0f / 1023.0f * cineon->element[0].maxValue;
+ cineon->referenceWhite = 685.0f / 1023.0f * cineon->element[0].maxValue;
+ cineon->gamma = 1.7f;
if (verbose) {
- verboseMe(cineon);
- }
+ printf("size %d x %d x %d elements\n", cineon->width, cineon->height, cineon->numElements);
+ for (i = 0; i < cineon->numElements; i++) {
+ printf(" Element %d:\n", i);
+ printf(" Bits per sample: %d\n", cineon->element[i].bitsPerSample);
+ printf(" Depth: %d\n", cineon->element[i].depth);
+ printf(" Transfer characteristics: %d\n", cineon->element[i].transfer);
+ printf(" Packing: %d\n", cineon->element[i].packing);
+ printf(" Descriptor: %d\n", cineon->element[i].descriptor);
+ printf(" Data offset: %u\n", cineon->element[i].dataOffset);
+ printf(" Reference low data: %u\n", cineon->element[i].refLowData);
+ printf(" Reference low quantity: %f\n", cineon->element[i].refLowQuantity);
+ printf(" Reference high data: %u\n", cineon->element[i].refHighData);
+ printf(" Reference high quantity: %f\n", cineon->element[i].refHighQuantity);
+ printf("\n");
+ }
+ printf("Gamma: %f\n", cineon->gamma);
+ printf("Reference black: %f\n", cineon->referenceBlack);
+ printf("Reference white: %f\n", cineon->referenceWhite);
+ printf("----------------------------\n");
+ }
return cineon;
}
+LogImageFile *cineonCreate(const char *filename, int width, int height, int bitsPerSample, const char *creator)
+{
+ CineonMainHeader header;
+ const char *shortFilename = 0;
+ /* unsigned char pad[6044]; */
-int
-cineonGetSize(const CineonFile* cineon, int* width, int* height, int* depth) {
- *width = cineon->width;
- *height = cineon->height;
- *depth = cineon->depth;
- return 0;
-}
-
-CineonFile*
-cineonCreate(const char* filename, int width, int height, int depth) {
-
- /* Note: always write files in network order */
- /* By the spec, it shouldn't matter, but ... */
-
- CineonGenericHeader header;
- const char* shortFilename = 0;
-
- CineonFile* cineon = (CineonFile*)malloc(sizeof(CineonFile));
+ LogImageFile *cineon = (LogImageFile*)MEM_mallocN(sizeof(LogImageFile), __func__);
if (cineon == 0) {
- if (verbose) d_printf("Failed to malloc cineon file structure.\n");
+ if (verbose) printf("cineon: Failed to malloc cineon file structure.\n");
return 0;
}
- memset(&header, 0, sizeof(header));
-
- /* for close routine */
- cineon->file = 0;
- cineon->lineBuffer = 0;
- cineon->pixelBuffer = 0;
-
- cineon->file = BLI_fopen(filename, "wb");
- if (cineon->file == 0) {
- if (verbose) d_printf("Couldn't open file %s\n", filename);
- cineonClose(cineon);
+ /* Only 10 bits Cineon are supported */
+ if (bitsPerSample != 10) {
+ if (verbose) printf("cineon: Only 10 bits Cineon are supported.\n");
+ logImageClose(cineon);
return 0;
}
- cineon->reading = 0;
cineon->width = width;
cineon->height = height;
- cineon->depth = depth;
- cineon->bitsPerPixel = 10;
- cineon->imageOffset = sizeof(CineonGenericHeader);
-
- cineon->lineBufferLength = pixelsToLongs(cineon->width * cineon->depth);
- cineon->lineBuffer = malloc(cineon->lineBufferLength * 4);
- if (cineon->lineBuffer == 0) {
- if (verbose) d_printf("Couldn't malloc line buffer of size %d\n", cineon->lineBufferLength * 4);
- cineonClose(cineon);
- return 0;
- }
+ cineon->element[0].bitsPerSample = 10;
+ cineon->element[0].dataOffset = sizeof(CineonMainHeader);
+ cineon->element[0].maxValue = 1023;
+ cineon->isMSB = 1;
+ cineon->numElements = 1;
+ cineon->element[0].packing = 1;
+ cineon->depth = 3;
+ cineon->element[0].depth = 3;
+ cineon->element[0].descriptor = descriptor_RGB;
+ cineon->element[0].transfer = transfer_PrintingDensity;
+ cineon->element[0].refHighQuantity = 2.048f;
+ cineon->element[0].refLowQuantity = 0;
+ cineon->element[0].refLowData = 0;
+ cineon->element[0].refHighData = cineon->element[0].maxValue;
+ cineon->referenceWhite = 685.0f;
+ cineon->referenceBlack = 95.0f;
+ cineon->gamma = 1.7f;
- cineon->pixelBuffer = malloc(cineon->lineBufferLength * 3 * sizeof(unsigned short));
- if (cineon->pixelBuffer == 0) {
- if (verbose) d_printf("Couldn't malloc pixel buffer of size %d\n",
- (cineon->width * cineon->depth) * (int)sizeof(unsigned short));
- cineonClose(cineon);
- return 0;
- }
- cineon->pixelBufferUsed = 0;
-
- /* find trailing part of filename */
shortFilename = strrchr(filename, '/');
- if (shortFilename == 0) {
+ if (shortFilename == 0)
shortFilename = filename;
- }
- else {
- ++shortFilename;
- }
+ else
+ shortFilename++;
- if (initCineonGenericHeader(cineon, &header, shortFilename) != 0) {
- cineonClose(cineon);
+ cineon->file = BLI_fopen(filename, "wb");
+ if (cineon->file == 0) {
+ if (verbose) printf("cineon: Couldn't open file %s\n", filename);
+ logImageClose(cineon);
return 0;
}
+ fillCineonMainHeader(cineon, &header, shortFilename, creator);
+
if (fwrite(&header, sizeof(header), 1, cineon->file) == 0) {
- if (verbose) d_printf("Couldn't write image header\n");
- cineonClose(cineon);
+ if (verbose) printf("cineon: Couldn't write image header\n");
+ logImageClose(cineon);
return 0;
}
- cineon->fileYPos = 0;
-
- logImageGetByteConversionDefaults(&cineon->params);
- setupLut(cineon);
-
- cineon->getRow = 0;
- cineon->setRow = &cineonSetRowBytes;
- cineon->close = &cineonClose;
return cineon;
}
-
-void
-cineonClose(CineonFile* cineon) {
-
- if (cineon == 0) {
- return;
- }
-
- if (cineon->file) {
- fclose(cineon->file);
- cineon->file = 0;
- }
-
- if (cineon->lineBuffer) {
- free(cineon->lineBuffer);
- cineon->lineBuffer = 0;
- }
-
- if (cineon->pixelBuffer) {
- free(cineon->pixelBuffer);
- cineon->pixelBuffer = 0;
- }
-
- free(cineon);
-}