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
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/intern/image.c14
-rw-r--r--source/blender/blenkernel/intern/writeffmpeg.c1
-rw-r--r--source/blender/imbuf/IMB_imbuf_types.h5
-rw-r--r--source/blender/imbuf/SConscript1
-rw-r--r--source/blender/imbuf/intern/IMB_dpxcineon.h47
-rw-r--r--source/blender/imbuf/intern/Makefile4
-rw-r--r--source/blender/imbuf/intern/cineon/Makefile64
-rw-r--r--source/blender/imbuf/intern/cineon/README8
-rw-r--r--source/blender/imbuf/intern/cineon/cin_debug_stuff.h2
-rw-r--r--source/blender/imbuf/intern/cineon/cineon_dpx.c195
-rw-r--r--source/blender/imbuf/intern/cineon/cineonfile.h143
-rw-r--r--source/blender/imbuf/intern/cineon/cineonlib.c801
-rw-r--r--source/blender/imbuf/intern/cineon/cineonlib.h68
-rw-r--r--source/blender/imbuf/intern/cineon/dpxfile.h124
-rw-r--r--source/blender/imbuf/intern/cineon/dpxlib.c625
-rw-r--r--source/blender/imbuf/intern/cineon/dpxlib.h56
-rw-r--r--source/blender/imbuf/intern/cineon/logImageCore.c212
-rw-r--r--source/blender/imbuf/intern/cineon/logImageCore.h109
-rw-r--r--source/blender/imbuf/intern/cineon/logImageLib.c158
-rw-r--r--source/blender/imbuf/intern/cineon/logImageLib.h86
-rw-r--r--source/blender/imbuf/intern/cineon/logmemfile.c77
-rw-r--r--source/blender/imbuf/intern/cineon/logmemfile.h29
-rw-r--r--source/blender/imbuf/intern/readimage.c7
-rw-r--r--source/blender/imbuf/intern/util.c6
-rw-r--r--source/blender/imbuf/intern/writeimage.c9
-rw-r--r--source/blender/makesdna/DNA_scene_types.h2
-rw-r--r--source/blender/src/buttons_scene.c12
-rw-r--r--source/blender/src/filesel.c4
-rw-r--r--source/blender/src/writeimage.c6
29 files changed, 2869 insertions, 6 deletions
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index 2cafc4e94ce..9f19735da5b 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -357,6 +357,14 @@ void BKE_add_image_extension(char *string, int imtype)
extension= ".exr";
}
#endif
+ else if(imtype==R_CINEON){
+ if (!BLI_testextensie(string, ".cin"))
+ extension= ".cin";
+ }
+ else if(imtype==R_DPX){
+ if (!BLI_testextensie(string, ".dpx"))
+ extension= ".dpx";
+ }
else { /* targa default */
if(!BLI_testextensie(string, ".tga"))
extension= ".tga";
@@ -396,6 +404,12 @@ int BKE_write_ibuf(ImBuf *ibuf, char *name, int imtype, int subimtype, int quali
}
#endif
+ else if (imtype==R_CINEON) {
+ ibuf->ftype = CINEON;
+ }
+ else if (imtype==R_DPX) {
+ ibuf->ftype = DPX;
+ }
else if (imtype==R_TARGA) {
ibuf->ftype= TGA;
}
diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c
index 71f7f7c0294..c7ea4f55941 100644
--- a/source/blender/blenkernel/intern/writeffmpeg.c
+++ b/source/blender/blenkernel/intern/writeffmpeg.c
@@ -20,6 +20,7 @@
#include <string.h>
#include <stdio.h>
+#include <stdint.h>
#include <stdlib.h>
#include <ffmpeg/avformat.h>
#include <ffmpeg/avcodec.h>
diff --git a/source/blender/imbuf/IMB_imbuf_types.h b/source/blender/imbuf/IMB_imbuf_types.h
index db178841979..586dedc54e8 100644
--- a/source/blender/imbuf/IMB_imbuf_types.h
+++ b/source/blender/imbuf/IMB_imbuf_types.h
@@ -163,6 +163,9 @@ typedef enum {
#define OPENEXR_HALF (1 << 8 )
#define OPENEXR_COMPRESS (7)
+#define CINEON (1 << 21)
+#define DPX (1 << 20)
+
#define RAWTGA (TGA | 1)
#define JPG_STD (JPG | (0 << 8))
@@ -199,6 +202,8 @@ typedef enum {
#define IS_tga(x) (x->ftype & TGA)
#define IS_png(x) (x->ftype & PNG)
#define IS_openexr(x) (x->ftype & OPENEXR)
+#define IS_cineon(x) (x->ftype & CINEON)
+#define IS_dpx(x) (x->ftype & DPX)
#define IS_bmp(x) (x->ftype & BMP)
#define IS_tiff(x) (x->ftype & TIF)
#define IS_radhdr(x) (x->ftype & RADHDR)
diff --git a/source/blender/imbuf/SConscript b/source/blender/imbuf/SConscript
index 93041ab97cf..2cc67df9e0c 100644
--- a/source/blender/imbuf/SConscript
+++ b/source/blender/imbuf/SConscript
@@ -24,3 +24,4 @@ if env['WITH_BF_QUICKTIME']==1:
defs.append('WITH_QUICKTIME')
env.BlenderLib ( libname = 'bf_imbuf', sources = sources, includes = Split(incs), defines = defs, libtype=['core','player'], priority = [80, 40] )
+env.BlenderLib ( libname = "bf_imbuf_cineondpx" sources = cineon, includes = Split(cincs), defines = defs, libtype=['core', 'player'] priority = [81, 41] ) \ No newline at end of file
diff --git a/source/blender/imbuf/intern/IMB_dpxcineon.h b/source/blender/imbuf/intern/IMB_dpxcineon.h
new file mode 100644
index 00000000000..9846d018214
--- /dev/null
+++ b/source/blender/imbuf/intern/IMB_dpxcineon.h
@@ -0,0 +1,47 @@
+/*
+ * IMB_dpxcineon.h
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+/**
+ * \file IMB_dpxcineon.h
+ * \ingroup imbuf
+ */
+#ifndef _IMB_DPX_CINEON_H
+#define _IMB_DPX_CINEON_H
+
+struct ImBuf;
+
+short imb_savecineon(struct ImBuf *buf, char *myfil, int flags);
+struct ImBuf *imb_loadcineon(unsigned char *mem, int size, int flags);
+int imb_is_cineon(void *buf);
+short imb_save_dpx(struct ImBuf *buf, char *myfile, int flags);
+struct ImBuf *imb_loaddpx(unsigned char *mem, int size, int flags);
+int imb_is_dpx(void *buf);
+
+#endif /*_IMB_DPX_CINEON_H*/
diff --git a/source/blender/imbuf/intern/Makefile b/source/blender/imbuf/intern/Makefile
index 19040abd5f6..f51844aad96 100644
--- a/source/blender/imbuf/intern/Makefile
+++ b/source/blender/imbuf/intern/Makefile
@@ -39,8 +39,10 @@ include nan_subdirs.mk
include nan_compile.mk
include nan_definitions.mk
+DIRS = cineon
+
ifeq ($(WITH_OPENEXR), true)
- DIRS = openexr
+ DIRS += openexr
CFLAGS += -DWITH_OPENEXR
endif
diff --git a/source/blender/imbuf/intern/cineon/Makefile b/source/blender/imbuf/intern/cineon/Makefile
new file mode 100644
index 00000000000..596a6647093
--- /dev/null
+++ b/source/blender/imbuf/intern/cineon/Makefile
@@ -0,0 +1,64 @@
+#
+# $Id$
+#
+# ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+#
+# 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. The Blender
+# Foundation also sells licenses for use in proprietary software under
+# the Blender License. See http://www.blender.org/BL/ for information
+# about this.
+#
+# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): none yet.
+#
+# ***** END GPL/BL DUAL LICENSE BLOCK *****
+#
+#
+
+LIBNAME = cineon
+DIR = $(OCGDIR)/blender/imbuf/cineon
+SOURCEDIR = source/blender/imbuf/intern/cineon
+
+include nan_compile.mk
+include nan_definitions.mk
+
+ifeq ($(OS),$(findstring $(OS), "beos darwin freebsd linux openbsd solaris windows"))
+ CFLAGS += -funsigned-char
+endif
+
+CFLAGS += $(LEVEL_1_C_WARNINGS)
+
+CPPFLAGS += -I$(NAN_JPEG)/include
+CPPFLAGS += -I$(NAN_PNG)/include
+CPPFLAGS += -I$(NAN_ZLIB)/include
+CPPFLAGS += -I$(NAN_TIFF)/include
+CPPFLAGS += -I../../../include
+CPPFLAGS += -I../../../blenkernel
+CPPFLAGS += -I../../../blenlib
+CPPFLAGS += -I../../../avi
+CPPFLAGS += -I../../../quicktime
+# path to the guarded memory allocator
+CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include
+CPPFLAGS += -I$(NAN_MEMUTIL)/include
+# This is not really needed, but until /include is cleaned, it must be
+# there for proper compilation.
+# - No, it is also needed in antialias, for listbase (nzc)
+CPPFLAGS += -I../../../makesdna
+# external interface of this module
+CPPFLAGS += -I../..
diff --git a/source/blender/imbuf/intern/cineon/README b/source/blender/imbuf/intern/cineon/README
new file mode 100644
index 00000000000..5554e857c81
--- /dev/null
+++ b/source/blender/imbuf/intern/cineon/README
@@ -0,0 +1,8 @@
+Files:
+
+logImageLib.h, logImageLib.c: combined cineon/dpx image library
+dpxlib.h, dpxlib.c: dpx specific library
+dpxfile.h: dpx file structure
+cineonlib.h, cineonlib.c: cineon specific library
+cineonfile.h: cineon file structure
+logImageCore.h, logImageCore.c: log image routines common to cineon amd dpx
diff --git a/source/blender/imbuf/intern/cineon/cin_debug_stuff.h b/source/blender/imbuf/intern/cineon/cin_debug_stuff.h
new file mode 100644
index 00000000000..148e4e4be53
--- /dev/null
+++ b/source/blender/imbuf/intern/cineon/cin_debug_stuff.h
@@ -0,0 +1,2 @@
+#define d_printf printf
+
diff --git a/source/blender/imbuf/intern/cineon/cineon_dpx.c b/source/blender/imbuf/intern/cineon/cineon_dpx.c
new file mode 100644
index 00000000000..d3cf74f60a9
--- /dev/null
+++ b/source/blender/imbuf/intern/cineon/cineon_dpx.c
@@ -0,0 +1,195 @@
+/**
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ * cineon.c
+ * contributors: joeedh
+ * I hearby donate this code and all rights to the Blender Foundation.
+ * $Id$
+ */
+
+#include <stdio.h>
+#include <string.h> /*for memcpy*/
+
+#include "logImageLib.h"
+#include "cineonlib.h"
+#include "dpxlib.h"
+
+#include "IMB_imbuf_types.h"
+#include "IMB_imbuf.h"
+
+#include "MEM_guardedalloc.h"
+
+static struct ImBuf *imb_load_dpx_cineon(unsigned char *mem, int use_cineon, int size, int flags)
+{
+ ImBuf *ibuf;
+ LogImageFile *image;
+ int x, y;
+ unsigned short *row;
+ int width, height, depth;
+ float *frow;
+
+ image = logImageOpenFromMem(mem, size, use_cineon);
+
+ if (!image) {
+ printf("no image!\n");
+ return NULL;
+ }
+
+ logImageGetSize(image, &width, &height, &depth);
+
+ if (depth != 3) { /*need to do greyscale loading eventually.*/
+ logImageClose(image);
+ return NULL;
+ }
+ if (width == 0 && height == 0) {
+ logImageClose(image);
+ return NULL;
+ }
+
+ ibuf = IMB_allocImBuf(width, height, 32, IB_rectfloat | flags, 0);
+
+ row = MEM_mallocN(sizeof(unsigned short)*width*depth, "row in cineon_dpx.c");
+
+ for (y = 0; y < height; y++) {
+ unsigned int index = (width) * (height-y-1);
+ index = index * 4;
+
+ frow = &ibuf->rect_float[index];
+
+ logImageGetRowBytes(image, row, y);
+
+ for (x=0; x<width; x++) {
+ unsigned short *upix = &row[x*depth];
+ float *fpix = &frow[x*4];
+ fpix[0] = ((float)upix[0]) / 65535.0f;
+ fpix[1] = ((float)upix[1]) / 65535.0f;
+ fpix[2] = ((float)upix[2]) / 65535.0f;
+ fpix[3] = 1.0f;
+ }
+ }
+
+ MEM_freeN(row);
+ logImageClose(image);
+
+ if (flags & IB_rect) {
+ IMB_rect_from_float(ibuf);
+ }
+ return ibuf;
+}
+
+static int imb_save_dpx_cineon(ImBuf *buf, char *filename, int use_cineon, int flags)
+{
+ LogImageByteConversionParameters conversion;
+ int width, height, depth;
+ LogImageFile* logImage;
+ unsigned short* line, *pixel;
+ int i, j;
+ int index;
+ float *fline;
+
+ conversion.blackPoint = 95;
+ conversion.whitePoint = 685;
+ conversion.gamma = 1;
+ /*
+ * Get the drawable for the current image...
+ */
+
+ width = buf->x;
+ height = buf->y;
+ depth = 3;
+
+ if (!buf->rect_float) return 0;
+
+ logImageSetVerbose(0);
+ logImage = logImageCreate(filename, use_cineon, width, height, depth);
+
+ if (!logImage) return 0;
+
+ logImageSetByteConversion(logImage, &conversion);
+
+ index = 0;
+ line = MEM_mallocN(sizeof(unsigned short)*depth*width, "line");
+
+ /*note that image is flipped when sent to logImageSetRowBytes (see last passed parameter).*/
+ for (j = 0; j < height; ++j) {
+ fline = &buf->rect_float[width*j*4];
+ for (i=0; i<width; i++) {
+ float *fpix, fpix2[3];
+ /*we have to convert to cinepaint's 16-bit-per-channel here*/
+ pixel = &line[i*depth];
+ fpix = &fline[i*4];
+ memcpy(fpix2, fpix, sizeof(float)*3);
+
+ if (fpix2[0]>=1) fpix2[0] = 1;
+ if (fpix2[1]>=1) fpix2[1] = 1;
+ if (fpix2[2]>=1) fpix2[2] = 1;
+
+ pixel[0] = (unsigned short)(fpix2[0] * 65535.0f); /*float-float math is faster*/
+ pixel[1] = (unsigned short)(fpix2[1] * 65535.0f);
+ pixel[2] = (unsigned short)(fpix2[2] * 65535.0f);
+ }
+ logImageSetRowBytes(logImage, (const unsigned short*)line, height-1-j);
+ }
+ logImageClose(logImage);
+
+ MEM_freeN(line);
+ return 1;
+}
+
+short imb_savecineon(struct ImBuf *buf, char *myfile, int flags)
+{
+ return imb_save_dpx_cineon(buf, myfile, 1, flags);
+}
+
+
+int imb_is_cineon(void *buf)
+{
+ return cineonIsMemFileCineon(buf);
+}
+
+ImBuf *imb_loadcineon(unsigned char *mem, int size, int flags)
+{
+ if(imb_is_cineon(mem))
+ return imb_load_dpx_cineon(mem, 1, size, flags);
+ return NULL;
+}
+
+short imb_save_dpx(struct ImBuf *buf, char *myfile, int flags)
+{
+ return imb_save_dpx_cineon(buf, myfile, 0, flags);
+}
+
+short imb_is_dpx(void *buf)
+{
+ return dpxIsMemFileCineon(buf);
+}
+
+ImBuf *imb_loaddpx(unsigned char *mem, int size, int flags)
+{
+ if(imb_is_dpx(mem))
+ return imb_load_dpx_cineon(mem, 0, size, flags);
+ return NULL;
+}
diff --git a/source/blender/imbuf/intern/cineon/cineonfile.h b/source/blender/imbuf/intern/cineon/cineonfile.h
new file mode 100644
index 00000000000..7f6f1138902
--- /dev/null
+++ b/source/blender/imbuf/intern/cineon/cineonfile.h
@@ -0,0 +1,143 @@
+/*
+ * Cineon image file format library definitions.
+ * Cineon file format structures.
+ *
+ * This header file contains private details.
+ * User code should generally use cineonlib.h only.
+ *
+ * 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 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef _CINEON_FILE_H_
+#define _CINEON_FILE_H_
+
+#include "logImageCore.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+ U32 magic_num; /* magic number */
+ U32 image_offset; /* offset to image data in bytes */
+ U32 gen_hdr_size; /* generic header length in bytes */
+ U32 ind_hdr_size; /* industry header length in bytes */
+ U32 user_data_size; /* user-defined data length in bytes */
+ U32 file_size; /* file size in bytes */
+ ASCII vers[8]; /* which header format version is being used (v4.5) */
+ ASCII file_name[100]; /* image file name */
+ ASCII create_date[12]; /* file creation date */
+ ASCII create_time[12]; /* file creation time */
+ ASCII Reserved[36]; /* reserved field TBD (need to pad) */
+} CineonFileInformation;
+
+typedef struct {
+ U8 designator1;
+ U8 designator2;
+ U8 bits_per_pixel;
+ U8 filler;
+ U32 pixels_per_line;
+ U32 lines_per_image;
+ U32 ref_low_data; /* reference low data code value */
+ R32 ref_low_quantity; /* reference low quantity represented */
+ U32 ref_high_data; /* reference high data code value */
+ R32 ref_high_quantity;/* reference high quantity represented */
+} CineonChannelInformation;
+
+typedef struct {
+ U8 orientation; /* image orientation */
+ U8 channels_per_image;
+ U16 filler;
+ CineonChannelInformation channel[8];
+ R32 white_point_x;
+ R32 white_point_y;
+ R32 red_primary_x;
+ R32 red_primary_y;
+ R32 green_primary_x;
+ R32 green_primary_y;
+ R32 blue_primary_x;
+ R32 blue_primary_y;
+ ASCII label[200];
+ ASCII reserved[28];
+} CineonImageInformation;
+
+typedef struct {
+ U8 interleave;
+ U8 packing;
+ U8 signage;
+ U8 sense;
+ U32 line_padding;
+ U32 channel_padding;
+ ASCII reserved[20];
+} CineonFormatInformation;
+
+typedef struct {
+ S32 x_offset;
+ S32 y_offset;
+ ASCII file_name[100];
+ ASCII create_date[12]; /* file creation date */
+ ASCII create_time[12]; /* file creation time */
+ ASCII input_device[64];
+ ASCII model_number[32];
+ ASCII serial_number[32];
+ R32 x_input_samples_per_mm;
+ R32 y_input_samples_per_mm;
+ R32 input_device_gamma;
+ ASCII reserved[40];
+} CineonOriginationInformation;
+
+typedef struct {
+ CineonFileInformation fileInfo;
+ CineonImageInformation imageInfo;
+ CineonFormatInformation formatInfo;
+ CineonOriginationInformation originInfo;
+} CineonGenericHeader;
+
+typedef struct {
+ U8 filmCode;
+ U8 filmType;
+ U8 perfOffset;
+ U8 filler;
+ U32 keycodePrefix;
+ U32 keycodeCount;
+ ASCII format[32];
+ U32 framePosition; /* in sequence */
+ R32 frameRate; /* frames per second */
+ ASCII attribute[32];
+ ASCII slate[200];
+ ASCII reserved[740];
+} CineonMPISpecificInformation;
+
+#if 0
+/* create CineonFile from data in header */
+/* return 0 for OK */
+int readCineonGenericHeader(CineonFile* cineon, CineonGenericHeader* header);
+
+/* create header from data in CineonFile */
+int initCineonGenericHeader(
+ CineonFile* cineon, CineonGenericHeader* header, const char* imagename);
+
+/* Note: dump routine assumes network byte order */
+void dumpCineonGenericHeader(CineonGenericHeader* header);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CINEON_FILE_H_ */
diff --git a/source/blender/imbuf/intern/cineon/cineonlib.c b/source/blender/imbuf/intern/cineon/cineonlib.c
new file mode 100644
index 00000000000..5253646be4d
--- /dev/null
+++ b/source/blender/imbuf/intern/cineon/cineonlib.c
@@ -0,0 +1,801 @@
+/*
+ * Cineon image file format library routines.
+ *
+ * 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 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "cineonlib.h"
+#include "cineonfile.h"
+
+#include <stdio.h>
+#include <math.h>
+#include <stdlib.h>
+#include <time.h> /* strftime() */
+#include <sys/types.h>
+#ifdef WIN32
+#include <winsock.h>
+#else
+#include <netinet/in.h> /* htonl() */
+#endif
+#include <string.h> /* memset */
+#include "cin_debug_stuff.h"
+#include "logmemfile.h"
+
+static void
+fillCineonFileInfo(CineonFile* cineon, CineonFileInformation* fileInfo, const char* filename) {
+
+ 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", ntohl(fileInfo->magic_num));
+ d_printf("Image Offset %ld\n", ntohl(fileInfo->image_offset));
+ d_printf("Generic Header size %ld\n", ntohl(fileInfo->gen_hdr_size));
+ d_printf("Industry Header size %ld\n", ntohl(fileInfo->ind_hdr_size));
+ d_printf("User Data size %ld\n", ntohl(fileInfo->user_data_size));
+ d_printf("File size %ld\n", 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", ntohl(chan->pixels_per_line));
+ d_printf(" Lines per image %ld\n", ntohl(chan->lines_per_image));
+ d_printf(" Ref low data %ld\n", ntohl(chan->ref_low_data));
+ d_printf(" Ref low quantity %f\n", ntohf(chan->ref_low_quantity));
+ d_printf(" Ref high data %ld\n", 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) {
+
+ 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", ntohl(formatInfo->line_padding));
+ d_printf("End of channel padding %ld\n", ntohl(formatInfo->channel_padding));
+}
+
+static void
+fillCineonOriginationInfo(CineonFile* cineon,
+ CineonOriginationInformation* originInfo, CineonFileInformation* fileInfo) {
+
+ 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", ntohl(originInfo->x_offset));
+ d_printf("Y offset %ld\n", 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));
+}
+
+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);
+
+ return 0;
+}
+
+void
+dumpCineonGenericHeader(CineonGenericHeader* header) {
+ dumpCineonFileInfo(&header->fileInfo);
+ dumpCineonImageInfo(&header->imageInfo);
+ dumpCineonFormatInfo(&header->formatInfo);
+ dumpCineonOriginationInfo(&header->originInfo);
+}
+
+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) {
+ /* row[pixelIndex] = cineon->lut10[cineon->pixelBuffer[pixelIndex]]; */
+ 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) {
+ /* cineon->pixelBuffer[pixelIndex] = cineon->lut8[row[pixelIndex]]; */
+ 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;
+}
+
+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;
+
+ return 0;
+}
+
+CineonFile*
+cineonOpen(const char* filename) {
+
+ CineonGenericHeader header;
+
+ CineonFile* cineon = (CineonFile* )malloc(sizeof(CineonFile));
+ if (cineon == 0) {
+ if (verbose) d_printf("Failed to malloc cineon file structure.\n");
+ return 0;
+ }
+
+ /* for close routine */
+ cineon->file = 0;
+ cineon->lineBuffer = 0;
+ cineon->pixelBuffer = 0;
+ cineon->membuffer = 0;
+ cineon->memcursor = 0;
+ cineon->membuffersize = 0;
+
+ cineon->file = 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);
+ 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",
+ ntohl(header.fileInfo.magic_num), filename);
+ cineonClose(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 = 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;
+ }
+
+ 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) * 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->fileYPos = 0;
+
+ logImageGetByteConversionDefaults(&cineon->params);
+ setupLut(cineon);
+
+ cineon->getRow = &cineonGetRowBytes;
+ cineon->setRow = 0;
+ cineon->close = &cineonClose;
+
+ if (verbose) {
+ verboseMe(cineon);
+ }
+
+ return cineon;
+}
+
+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;
+}
+
+CineonFile*
+cineonOpenFromMem(unsigned char *mem, unsigned int size) {
+
+ CineonGenericHeader header;
+ int i;
+
+ CineonFile* cineon = (CineonFile* )malloc(sizeof(CineonFile));
+ if (cineon == 0) {
+ if (verbose) d_printf("Failed to malloc cineon file structure.\n");
+ return 0;
+ }
+
+ /* 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 = 1;
+ if (size < sizeof(CineonGenericHeader)) {
+ if (verbose) d_printf("Not enough data for header!\n");
+ cineonClose(cineon);
+ return 0;
+ }
+
+ logimage_fread(&header, sizeof(CineonGenericHeader), 1, cineon);
+
+ /* 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", ntohl(header.fileInfo.magic_num));
+
+ cineonClose(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 = 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;
+ }
+
+ 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) * sizeof(unsigned short));
+ cineonClose(cineon);
+ return 0;
+ }
+ cineon->pixelBufferUsed = 0;
+
+ i = cineon->imageOffset;
+
+ if (i >= size) {
+ if (verbose) d_printf("Couldn't seek to image data at %d\n", cineon->imageOffset);
+ cineonClose(cineon);
+ return 0;
+ }
+ cineon->fileYPos = 0;
+
+ logImageGetByteConversionDefaults(&cineon->params);
+ setupLut(cineon);
+
+ cineon->getRow = &cineonGetRowBytes;
+ cineon->setRow = 0;
+ cineon->close = &cineonClose;
+
+ if (verbose) {
+ verboseMe(cineon);
+ }
+
+ return cineon;
+}
+
+
+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));
+ if (cineon == 0) {
+ if (verbose) d_printf("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 = fopen(filename, "wb");
+ if (cineon->file == 0) {
+ if (verbose) d_printf("Couldn't open file %s\n", filename);
+ cineonClose(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->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) * sizeof(unsigned short));
+ cineonClose(cineon);
+ return 0;
+ }
+ cineon->pixelBufferUsed = 0;
+
+ /* find trailing part of filename */
+ shortFilename = strrchr(filename, '/');
+ if (shortFilename == 0) {
+ shortFilename = filename;
+ } else {
+ ++shortFilename;
+ }
+
+ if (initCineonGenericHeader(cineon, &header, shortFilename) != 0) {
+ cineonClose(cineon);
+ return 0;
+ }
+
+ if (fwrite(&header, sizeof(header), 1, cineon->file) == 0) {
+ if (verbose) d_printf("Couldn't write image header\n");
+ cineonClose(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);
+}
diff --git a/source/blender/imbuf/intern/cineon/cineonlib.h b/source/blender/imbuf/intern/cineon/cineonlib.h
new file mode 100644
index 00000000000..87fc7add9a6
--- /dev/null
+++ b/source/blender/imbuf/intern/cineon/cineonlib.h
@@ -0,0 +1,68 @@
+/*
+ * Cineon image file format library definitions.
+ * Also handles DPX files (almost)
+ *
+ * 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 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef _CINEON_LIB_H_
+#define _CINEON_LIB_H_
+
+#include "logImageCore.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Cineon image structure. You don't care what this is.
+ */
+
+typedef struct _Log_Image_File_t_ CineonFile;
+
+/* int functions return 0 for OK */
+
+void cineonSetVerbose(int);
+
+CineonFile* cineonOpenFromMem(unsigned char *mem, unsigned int size);
+
+CineonFile* cineonOpen(const char* filename);
+int cineonGetSize(const CineonFile* cineon, int* xsize, int* ysize, int* channels);
+CineonFile* cineonCreate(const char* filename, int xsize, int ysize, int channels);
+int cineonIsMemFileCineon(unsigned char *mem);
+
+/* get / set header block NYI */
+int cineonGetHeader(CineonFile*, int*, void**);
+int cineonSetHeader(CineonFile*, int, void*);
+
+/* get/set scanline of converted bytes */
+int cineonGetRowBytes(CineonFile* cineon, unsigned short* row, int y);
+int cineonSetRowBytes(CineonFile* cineon, const unsigned short* row, int y);
+
+/* get/set scanline of unconverted shorts */
+int cineonGetRow(CineonFile* cineon, unsigned short* row, int y);
+int cineonSetRow(CineonFile* cineon, const unsigned short* row, int y);
+
+/* closes file and deletes data */
+void cineonClose(CineonFile* cineon);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CINEON_LIB_H_ */
diff --git a/source/blender/imbuf/intern/cineon/dpxfile.h b/source/blender/imbuf/intern/cineon/dpxfile.h
new file mode 100644
index 00000000000..94145500910
--- /dev/null
+++ b/source/blender/imbuf/intern/cineon/dpxfile.h
@@ -0,0 +1,124 @@
+/*
+ * Cineon image file format library definitions.
+ * Dpx file format structures.
+ *
+ * This header file contains private details.
+ * User code should generally use cineonlib.h only.
+ *
+ * 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 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef _DPX_FILE_H_
+#define _DPX_FILE_H_
+
+#include "logImageCore.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+ U32 magic_num; /* magic number */
+ U32 offset; /* offset to image data in bytes */
+ ASCII vers[8]; /* which header format version is being used (v1.0) */
+ U32 file_size; /* file size in bytes */
+ U32 ditto_key; /* I bet some people use this */
+ U32 gen_hdr_size; /* generic header length in bytes */
+ U32 ind_hdr_size; /* industry header length in bytes */
+ U32 user_data_size; /* user-defined data length in bytes */
+ ASCII file_name[100]; /* image file name */
+ ASCII create_date[24]; /* file creation date, yyyy:mm:dd:hh:mm:ss:LTZ */
+ ASCII creator[100];
+ ASCII project[200];
+ ASCII copyright[200];
+ U32 key; /* encryption key, FFFFFFF = unencrypted */
+ ASCII Reserved[104]; /* reserved field TBD (need to pad) */
+} DpxFileInformation;
+
+typedef struct {
+ U32 signage;
+ U32 ref_low_data; /* reference low data code value */
+ R32 ref_low_quantity; /* reference low quantity represented */
+ U32 ref_high_data; /* reference high data code value */
+ R32 ref_high_quantity;/* reference high quantity represented */
+ U8 designator1;
+ U8 transfer_characteristics;
+ U8 colourimetry;
+ U8 bits_per_pixel;
+ U16 packing;
+ U16 encoding;
+ U32 data_offset;
+ U32 line_padding;
+ U32 channel_padding;
+ ASCII description[32];
+} DpxChannelInformation;
+
+typedef struct {
+ U16 orientation;
+ U16 channels_per_image;
+ U32 pixels_per_line;
+ U32 lines_per_image;
+ DpxChannelInformation channel[8];
+ ASCII reserved[52];
+} DpxImageInformation;
+
+typedef struct {
+ U32 x_offset;
+ U32 y_offset;
+ R32 x_centre;
+ R32 y_centre;
+ U32 x_original_size;
+ U32 y_original_size;
+ ASCII file_name[100];
+ ASCII creation_time[24];
+ ASCII input_device[32];
+ ASCII input_serial_number[32];
+ U16 border_validity[4];
+ U32 pixel_aspect_ratio[2]; /* h:v */
+ ASCII reserved[28];
+} DpxOriginationInformation;
+
+typedef struct {
+ ASCII film_manufacturer_id[2];
+ ASCII film_type[2];
+ ASCII edge_code_perforation_offset[2];
+ ASCII edge_code_prefix[6];
+ ASCII edge_code_count[4];
+ ASCII film_format[32];
+ U32 frame_position;
+ U32 sequence_length;
+ U32 held_count;
+ R32 frame_rate;
+ R32 shutter_angle;
+ ASCII frame_identification[32];
+ ASCII slate_info[100];
+ ASCII reserved[56];
+} DpxMPIInformation;
+
+typedef struct {
+ DpxFileInformation fileInfo;
+ DpxImageInformation imageInfo;
+ DpxOriginationInformation originInfo;
+ DpxMPIInformation filmHeader;
+} DpxMainHeader;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _DPX_FILE_H_ */
diff --git a/source/blender/imbuf/intern/cineon/dpxlib.c b/source/blender/imbuf/intern/cineon/dpxlib.c
new file mode 100644
index 00000000000..bb12f9307e3
--- /dev/null
+++ b/source/blender/imbuf/intern/cineon/dpxlib.c
@@ -0,0 +1,625 @@
+/*
+ * Dpx image file format library routines.
+ *
+ * Copyright 1999 - 2002 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 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "dpxfile.h"
+#include "dpxlib.h"
+
+#include <stdio.h>
+#include <math.h>
+#include <stdlib.h>
+#include <time.h> /* strftime() */
+#include <sys/types.h>
+#ifdef WIN32
+#include <winsock.h>
+#else
+#include <netinet/in.h> /* htonl() */
+#endif
+#include <string.h> /* memset */
+#include "cin_debug_stuff.h"
+#include "logmemfile.h"
+
+static void
+fillDpxChannelInfo(DpxFile* dpx, DpxChannelInformation* chan, int des) {
+
+ chan->signage = 0;
+ 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);
+ chan->designator1 = des;
+ chan->transfer_characteristics = 0;
+ chan->colourimetry = 0;
+ chan->bits_per_pixel = 10;
+ chan->packing = htons(1);
+ chan->encoding = 0;
+ chan->data_offset = 0;
+ chan->line_padding = htonl(0);
+ chan->channel_padding = htonl(0);
+ chan->description[0] = 0;
+}
+
+static void
+dumpDpxChannelInfo(DpxChannelInformation* chan) {
+ d_printf(" Signage %ld", ntohl(chan->signage));
+ d_printf(" Ref low data %ld\n", ntohl(chan->ref_low_data));
+ d_printf(" Ref low quantity %f\n", ntohf(chan->ref_low_quantity));
+ d_printf(" Ref high data %ld\n", ntohl(chan->ref_high_data));
+ d_printf(" Ref high quantity %f\n", ntohf(chan->ref_high_quantity));
+ d_printf(" Designator1: %d,", chan->designator1);
+ d_printf(" Bits per pixel %d\n", chan->bits_per_pixel);
+ d_printf(" Packing: %d,", ntohs(chan->packing));
+ d_printf(" Data Offset: %ld,", ntohl(chan->data_offset));
+}
+
+static void
+fillDpxFileInfo(
+ DpxFile* dpx, DpxFileInformation* fileInfo, const char* filename) {
+
+ time_t fileClock;
+ struct tm* fileTime;
+
+ /* Note: always write files in network order */
+ /* By the spec, it shouldn't matter, but ... */
+
+ fileInfo->magic_num = htonl(DPX_FILE_MAGIC);
+ fileInfo->offset = htonl(dpx->imageOffset);
+ strcpy(fileInfo->vers, "v1.0");
+ fileInfo->file_size = htonl(dpx->imageOffset +
+ pixelsToLongs(dpx->height * dpx->width * dpx->depth) * 4);
+ fileInfo->ditto_key = 0;
+ fileInfo->gen_hdr_size = htonl(
+ sizeof(DpxFileInformation) +
+ sizeof(DpxImageInformation) +
+ sizeof(DpxOriginationInformation));
+ fileInfo->ind_hdr_size = htonl(sizeof(DpxMPIInformation));
+ fileInfo->user_data_size = 0;
+ strncpy(fileInfo->file_name, filename, 99);
+ fileInfo->file_name[99] = 0;
+
+ fileClock = time(0);
+ fileTime = localtime(&fileClock);
+ strftime(fileInfo->create_date, 24, "%Y:%m:%d:%H:%M:%S%Z", fileTime);
+ /* Question: is %Z in strftime guaranteed to return 3 chars? */
+ fileInfo->create_date[23] = 0;
+
+ strcpy(fileInfo->creator, "David's DPX writer");
+ fileInfo->project[0] = 0;
+ fileInfo->copyright[0] = 0;
+ fileInfo->key = 0xFFFFFFFF; /* same in any byte order */
+}
+
+static void
+dumpDpxFileInfo(DpxFileInformation* fileInfo) {
+ d_printf("\n--File Information--\n");
+ d_printf("Magic: %8.8lX\n", ntohl(fileInfo->magic_num));
+ d_printf("Image Offset %ld\n", ntohl(fileInfo->offset));
+ d_printf("Version \"%s\"\n", fileInfo->vers);
+ d_printf("File size %ld\n", ntohl(fileInfo->file_size));
+ d_printf("Ditto key %ld\n", ntohl(fileInfo->ditto_key));
+ d_printf("Generic Header size %ld\n", ntohl(fileInfo->gen_hdr_size));
+ d_printf("Industry Header size %ld\n", ntohl(fileInfo->ind_hdr_size));
+ d_printf("User Data size %ld\n", ntohl(fileInfo->user_data_size));
+ d_printf("File name \"%s\"\n", fileInfo->file_name);
+ d_printf("Creation date \"%s\"\n", fileInfo->create_date);
+ d_printf("Creator \"%s\"\n", fileInfo->creator);
+ d_printf("Project \"%s\"\n", fileInfo->project);
+ d_printf("Copyright \"%s\"\n", fileInfo->copyright);
+ d_printf("Key %ld\n", ntohl(fileInfo->key));
+}
+
+static void
+fillDpxImageInfo(
+ DpxFile* dpx, DpxImageInformation* imageInfo) {
+ imageInfo->orientation = 0;
+ imageInfo->channels_per_image = htons(1);
+ imageInfo->pixels_per_line = htonl(dpx->width);
+ imageInfo->lines_per_image = htonl(dpx->height);
+
+ if (dpx->depth == 1) {
+ fillDpxChannelInfo(dpx, &imageInfo->channel[0], 0);
+
+ } else if (dpx->depth == 3) {
+ fillDpxChannelInfo(dpx, &imageInfo->channel[0], 50);
+ }
+}
+
+static void
+dumpDpxImageInfo(DpxImageInformation* imageInfo) {
+
+ int n;
+ int i;
+ d_printf("\n--Image Information--\n");
+ d_printf("Image orientation %d,", ntohs(imageInfo->orientation));
+ n = ntohs(imageInfo->channels_per_image);
+ d_printf("Channels %d\n", n);
+ d_printf("Pixels per line %ld\n", ntohl(imageInfo->pixels_per_line));
+ d_printf("Lines per image %ld\n", ntohl(imageInfo->lines_per_image));
+ for (i = 0; i < n; ++i) {
+ d_printf(" --Channel %d--\n", i);
+ dumpDpxChannelInfo(&imageInfo->channel[i]);
+ }
+}
+
+static void
+fillDpxOriginationInfo(
+ DpxFile* dpx, DpxOriginationInformation* originInfo, DpxFileInformation* fileInfo) {
+}
+
+static void
+dumpDpxOriginationInfo(DpxOriginationInformation* originInfo) {
+ d_printf("\n--Origination Information--\n");
+ d_printf("X offset %ld\n", ntohl(originInfo->x_offset));
+ d_printf("Y offset %ld\n", ntohl(originInfo->y_offset));
+ d_printf("X centre %f\n", ntohf(originInfo->x_centre));
+ d_printf("Y centre %f\n", ntohf(originInfo->y_centre));
+ d_printf("Original X %ld\n", ntohl(originInfo->x_original_size));
+ d_printf("Original Y %ld\n", ntohl(originInfo->y_original_size));
+ d_printf("File name \"%s\"\n", originInfo->file_name);
+ d_printf("Creation time \"%s\"\n", originInfo->creation_time);
+ d_printf("Input device \"%s\"\n", originInfo->input_device);
+ d_printf("Serial number \"%s\"\n", originInfo->input_serial_number);
+}
+
+static void
+initDpxMainHeader(DpxFile* dpx, DpxMainHeader* header, const char* shortFilename) {
+ memset(header, 0, sizeof(DpxMainHeader));
+ fillDpxFileInfo(dpx, &header->fileInfo, shortFilename);
+ fillDpxImageInfo(dpx, &header->imageInfo);
+ fillDpxOriginationInfo(dpx, &header->originInfo, &header->fileInfo);
+#if 0
+ fillDpxMPIInfo(dpx, &header->filmHeader);
+#endif
+}
+
+static void
+dumpDpxMainHeader(DpxMainHeader* header) {
+ dumpDpxFileInfo(&header->fileInfo);
+ dumpDpxImageInfo(&header->imageInfo);
+ dumpDpxOriginationInfo(&header->originInfo);
+#if 0
+ dumpDpxMPIInformation(&header->filmHeader);
+#endif
+}
+
+static int verbose = 0;
+void
+dpxSetVerbose(int verbosity) {
+ verbose = verbosity;
+}
+
+static void
+verboseMe(DpxFile* dpx) {
+
+ d_printf("size %d x %d x %d\n", dpx->width, dpx->height, dpx->depth);
+ d_printf("ImageStart %d, lineBufferLength %d, implied length %d\n",
+ dpx->imageOffset, dpx->lineBufferLength * 4,
+ dpx->imageOffset + pixelsToLongs(dpx->width * dpx->depth * dpx->height) * 4);
+}
+
+int
+dpxGetRowBytes(DpxFile* dpx, unsigned short* row, int y) {
+
+ /* Note: this code is bizarre because DPX files can wrap */
+ /* packed longwords across line boundaries!!!! */
+
+ size_t readLongs;
+ unsigned int longIndex;
+ int numPixels = dpx->width * dpx->depth;
+ int pixelIndex;
+
+ /* only seek if not reading consecutive lines */
+ /* this is not quite right yet, need to account for leftovers */
+ if (y != dpx->fileYPos) {
+ int lineOffset = pixelsToLongs(y * dpx->width * dpx->depth) * 4;
+ if (verbose) d_printf("Seek in getRowBytes\n");
+ if (logimage_fseek(dpx, dpx->imageOffset + lineOffset, SEEK_SET) != 0) {
+ if (verbose) d_printf("Couldn't seek to line %d at %d\n", y, dpx->imageOffset + lineOffset);
+ return 1;
+ }
+ dpx->fileYPos = y;
+ }
+
+ /* read enough longwords */
+ readLongs = pixelsToLongs(numPixels - dpx->pixelBufferUsed);
+ if (logimage_fread(dpx->lineBuffer, 4, readLongs, dpx) != readLongs) {
+ if (verbose) d_printf("Couldn't read line %d length %d\n", y, readLongs * 4);
+ return 1;
+ }
+ ++dpx->fileYPos;
+
+ /* convert longwords to pixels */
+ pixelIndex = dpx->pixelBufferUsed;
+
+ /* this is just strange */
+ if (dpx->depth == 1) {
+ for (longIndex = 0; longIndex < readLongs; ++longIndex) {
+ unsigned int t = ntohl(dpx->lineBuffer[longIndex]);
+ dpx->pixelBuffer[pixelIndex] = t & 0x3ff;
+ t = t >> 10;
+ dpx->pixelBuffer[pixelIndex+1] = t & 0x3ff;
+ t = t >> 10;
+ dpx->pixelBuffer[pixelIndex+2] = t & 0x3ff;
+ pixelIndex += 3;
+ }
+ } else /* if (dpx->depth == 3) */ {
+ for (longIndex = 0; longIndex < readLongs; ++longIndex) {
+ unsigned int t = ntohl(dpx->lineBuffer[longIndex]);
+ t = t >> 2;
+ dpx->pixelBuffer[pixelIndex+2] = t & 0x3ff;
+ t = t >> 10;
+ dpx->pixelBuffer[pixelIndex+1] = t & 0x3ff;
+ t = t >> 10;
+ dpx->pixelBuffer[pixelIndex] = t & 0x3ff;
+ pixelIndex += 3;
+ }
+ }
+ dpx->pixelBufferUsed = pixelIndex;
+
+ /* extract required pixels */
+ for (pixelIndex = 0; pixelIndex < numPixels; ++pixelIndex) {
+ /* row[pixelIndex] = dpx->lut10[dpx->pixelBuffer[pixelIndex]]; */
+ row[pixelIndex] = dpx->pixelBuffer[pixelIndex] << 6;
+ }
+
+ /* save remaining pixels */
+ while (pixelIndex < dpx->pixelBufferUsed) {
+ dpx->pixelBuffer[pixelIndex - numPixels] = dpx->pixelBuffer[pixelIndex];
+ ++pixelIndex;
+ }
+ dpx->pixelBufferUsed -= numPixels;
+
+ /* done! */
+ return 0;
+}
+
+int
+dpxSetRowBytes(DpxFile* dpx, const unsigned short* row, int y) {
+
+ /* Note: this code is bizarre because DPX files can wrap */
+ /* packed longwords across line boundaries!!!! */
+
+ size_t writeLongs;
+ int longIndex;
+ int numPixels = dpx->width * dpx->depth;
+ int pixelIndex;
+ int pixelIndex2;
+
+ /* only seek if not reading consecutive lines */
+ /* this is not quite right yet */
+ if (y != dpx->fileYPos) {
+ int lineOffset = pixelsToLongs(y * dpx->width * dpx->depth) * 4;
+ if (verbose) d_printf("Seek in getRowBytes\n");
+ if (logimage_fseek(dpx, dpx->imageOffset + lineOffset, SEEK_SET) != 0) {
+ if (verbose) d_printf("Couldn't seek to line %d at %d\n", y, dpx->imageOffset + lineOffset);
+ return 1;
+ }
+ dpx->fileYPos = y;
+ }
+
+ /* put new pixels into pixelBuffer */
+ for (pixelIndex = 0; pixelIndex < numPixels; ++pixelIndex) {
+ /* dpx->pixelBuffer[dpx->pixelBufferUsed + pixelIndex] = dpx->lut8[row[pixelIndex]]; */
+ dpx->pixelBuffer[dpx->pixelBufferUsed + pixelIndex] = row[pixelIndex] >> 6;
+ }
+ dpx->pixelBufferUsed += numPixels;
+
+ /* pack into longwords */
+ writeLongs = dpx->pixelBufferUsed / 3;
+ /* process whole line at image end */
+ if (dpx->fileYPos == (dpx->height - 1)) {
+ writeLongs = pixelsToLongs(dpx->pixelBufferUsed);
+ }
+ pixelIndex = 0;
+ if (dpx->depth == 1) {
+ for (longIndex = 0; longIndex < writeLongs; ++longIndex) {
+ unsigned int t = dpx->pixelBuffer[pixelIndex] |
+ (dpx->pixelBuffer[pixelIndex+1] << 10) |
+ (dpx->pixelBuffer[pixelIndex+2] << 20);
+ dpx->lineBuffer[longIndex] = htonl(t);
+ pixelIndex += 3;
+ }
+ } else {
+ for (longIndex = 0; longIndex < writeLongs; ++longIndex) {
+ unsigned int t = dpx->pixelBuffer[pixelIndex+2] << 2 |
+ (dpx->pixelBuffer[pixelIndex+1] << 12) |
+ (dpx->pixelBuffer[pixelIndex] << 22);
+ dpx->lineBuffer[longIndex] = htonl(t);
+ pixelIndex += 3;
+ }
+ }
+
+ /* write them */
+ if (fwrite(dpx->lineBuffer, 4, writeLongs, dpx->file) != writeLongs) {
+ if (verbose) d_printf("Couldn't write line %d length %d\n", y, writeLongs * 4);
+ return 1;
+ }
+ ++dpx->fileYPos;
+
+ /* save remaining pixels */
+ pixelIndex2 = 0;
+ while (pixelIndex < dpx->pixelBufferUsed) {
+ dpx->pixelBuffer[pixelIndex2] = dpx->pixelBuffer[pixelIndex];
+ ++pixelIndex;
+ ++pixelIndex2;
+ }
+ dpx->pixelBufferUsed = pixelIndex2;
+
+ return 0;
+}
+
+#define LFMEMFILE 0
+#define LFREALFILE 1
+
+static DpxFile*
+intern_dpxOpen(int mode, const char* bytestuff, int bufsize) {
+
+ DpxMainHeader header;
+ const char *filename = bytestuff;
+ DpxFile* dpx = (DpxFile*)malloc(sizeof(DpxFile));
+
+ if (dpx == 0) {
+ if (verbose) d_printf("Failed to malloc dpx file structure.\n");
+ return 0;
+ }
+
+ /* for close routine */
+ dpx->file = 0;
+ dpx->lineBuffer = 0;
+ dpx->pixelBuffer = 0;
+
+ if (mode == LFREALFILE) {
+ filename = bytestuff;
+ dpx->file = fopen(filename, "rb");
+ if (dpx->file == 0) {
+ if (verbose) d_printf("Failed to open file \"%s\".\n", filename);
+ dpxClose(dpx);
+ return 0;
+ }
+ dpx->membuffer = 0;
+ dpx->memcursor = 0;
+ dpx->membuffersize = 0;
+ } else if (mode == LFMEMFILE) {
+ dpx->membuffer = (unsigned char *)bytestuff;
+ dpx->memcursor = (unsigned char *)bytestuff;
+ dpx->membuffersize = bufsize;
+ }
+
+ dpx->reading = 1;
+
+ if (logimage_fread(&header, sizeof(header), 1, dpx) == 0) {
+ if (verbose) d_printf("Not enough data for header in \"%s\".\n", filename);
+ dpxClose(dpx);
+ return 0;
+ }
+
+ /* let's assume dpx files are always network order */
+ if (header.fileInfo.magic_num != ntohl(DPX_FILE_MAGIC)) {
+ if (verbose) d_printf("Bad magic number %8.8lX in \"%s\".\n",
+ ntohl(header.fileInfo.magic_num), filename);
+ dpxClose(dpx);
+ return 0;
+ }
+
+ if (ntohs(header.imageInfo.channel[0].packing) != 1) {
+ if (verbose) d_printf("Unknown packing %d\n", header.imageInfo.channel[0].packing);
+ dpxClose(dpx);
+ return 0;
+ }
+
+
+ dpx->width = ntohl(header.imageInfo.pixels_per_line);
+ dpx->height = ntohl(header.imageInfo.lines_per_image);
+ dpx->depth = ntohs(header.imageInfo.channels_per_image);
+ /* Another DPX vs Cineon wierdness */
+ if (dpx->depth == 1) {
+ switch (header.imageInfo.channel[0].designator1) {
+ case 50: dpx->depth = 3; break;
+ case 51: dpx->depth = 4; break;
+ case 52: dpx->depth = 4; break;
+ default: break;
+ }
+ }
+ dpx->bitsPerPixel = 10;
+ /* dpx->bitsPerPixel = header.imageInfo.channel[0].bits_per_pixel; */
+ dpx->imageOffset = ntohl(header.fileInfo.offset);
+
+ dpx->lineBufferLength = pixelsToLongs(dpx->width * dpx->depth);
+ dpx->lineBuffer = malloc(dpx->lineBufferLength * 4);
+ if (dpx->lineBuffer == 0) {
+ if (verbose) d_printf("Couldn't malloc line buffer of size %d\n", dpx->lineBufferLength * 4);
+ dpxClose(dpx);
+ return 0;
+ }
+
+ /* could have 2 pixels left over */
+ dpx->pixelBuffer = malloc((dpx->lineBufferLength * 3 + 2) * sizeof(unsigned short));
+ if (dpx->pixelBuffer == 0) {
+ if (verbose) d_printf("Couldn't malloc pixel buffer of size %d\n",
+ (dpx->width * dpx->depth + 2 + 2) * sizeof(unsigned short));
+ dpxClose(dpx);
+ return 0;
+ }
+ dpx->pixelBufferUsed = 0;
+
+ if (logimage_fseek(dpx, dpx->imageOffset, SEEK_SET) != 0) {
+ if (verbose) d_printf("Couldn't seek to image data start at %d\n", dpx->imageOffset);
+ dpxClose(dpx);
+ return 0;
+ }
+ dpx->fileYPos = 0;
+
+ logImageGetByteConversionDefaults(&dpx->params);
+ setupLut(dpx);
+
+ dpx->getRow = &dpxGetRowBytes;
+ dpx->setRow = 0;
+ dpx->close = &dpxClose;
+
+ if (verbose) {
+ verboseMe(dpx);
+ }
+
+ return dpx;
+}
+
+DpxFile*
+dpxOpen(const char *filename) {
+ return intern_dpxOpen(LFREALFILE, filename, 0);
+}
+
+DpxFile*
+dpxOpenFromMem(unsigned char *buffer, unsigned int size) {
+ return intern_dpxOpen(LFMEMFILE, (const char *) buffer, size);
+}
+
+int
+dpxIsMemFileCineon(void *buffer) {
+ int magicnum = 0;
+ magicnum = *((int*)buffer);
+ if (magicnum == ntohl(DPX_FILE_MAGIC)) return 1;
+ else return 0;
+}
+
+DpxFile*
+dpxCreate(const char* filename, int width, int height, int depth) {
+
+ /* Note: always write files in network order */
+ /* By the spec, it shouldn't matter, but ... */
+
+ DpxMainHeader header;
+ const char* shortFilename = 0;
+
+ DpxFile* dpx = (DpxFile*)malloc(sizeof(DpxFile));
+ if (dpx == 0) {
+ if (verbose) d_printf("Failed to malloc dpx file structure.\n");
+ return 0;
+ }
+
+ memset(&header, 0, sizeof(header));
+
+ /* for close routine */
+ dpx->file = 0;
+ dpx->lineBuffer = 0;
+ dpx->pixelBuffer = 0;
+
+ dpx->file = fopen(filename, "wb");
+ if (dpx->file == 0) {
+ if (verbose) d_printf("Couldn't open file %s\n", filename);
+ dpxClose(dpx);
+ return 0;
+ }
+ dpx->reading = 0;
+
+ dpx->width = width;
+ dpx->height = height;
+ dpx->depth = depth;
+ dpx->bitsPerPixel = 10;
+ dpx->imageOffset = sizeof(DpxMainHeader);
+
+ dpx->lineBufferLength = pixelsToLongs(dpx->width * dpx->depth);
+ dpx->lineBuffer = malloc(dpx->lineBufferLength * 4);
+ if (dpx->lineBuffer == 0) {
+ if (verbose) d_printf("Couldn't malloc line buffer of size %d\n", dpx->lineBufferLength * 4);
+ dpxClose(dpx);
+ return 0;
+ }
+
+ dpx->pixelBuffer = malloc((dpx->lineBufferLength * 3 + 2) * sizeof(unsigned short));
+ if (dpx->pixelBuffer == 0) {
+ if (verbose) d_printf("Couldn't malloc pixel buffer of size %d\n",
+ (dpx->width * dpx->depth + 2 + 2) * sizeof(unsigned short));
+ dpxClose(dpx);
+ return 0;
+ }
+ dpx->pixelBufferUsed = 0;
+
+ /* find trailing part of filename */
+ shortFilename = strrchr(filename, '/');
+ if (shortFilename == 0) {
+ shortFilename = filename;
+ } else {
+ ++shortFilename;
+ }
+ initDpxMainHeader(dpx, &header, shortFilename);
+
+ if (fwrite(&header, sizeof(header), 1, dpx->file) == 0) {
+ if (verbose) d_printf("Couldn't write image header\n");
+ dpxClose(dpx);
+ return 0;
+ }
+ dpx->fileYPos = 0;
+
+ logImageGetByteConversionDefaults(&dpx->params);
+ setupLut(dpx);
+
+ dpx->getRow = 0;
+ dpx->setRow = &dpxSetRowBytes;
+ dpx->close = &dpxClose;
+
+ return dpx;
+}
+
+void
+dpxClose(DpxFile* dpx) {
+
+ if (dpx == 0) {
+ return;
+ }
+
+ if (dpx->file) {
+ fclose(dpx->file);
+ dpx->file = 0;
+ }
+
+ if (dpx->lineBuffer) {
+ free(dpx->lineBuffer);
+ dpx->lineBuffer = 0;
+ }
+
+ if (dpx->pixelBuffer) {
+ free(dpx->pixelBuffer);
+ dpx->pixelBuffer = 0;
+ }
+
+ free(dpx);
+}
+
+void
+dpxDump(const char* filename) {
+
+ DpxMainHeader header;
+ FILE* file;
+
+ file = fopen(filename, "rb");
+ if (file == 0) {
+ d_printf("Failed to open file \"%s\".\n", filename);
+ return;
+ }
+
+ if (fread(&header, sizeof(header), 1, file) == 0) {
+ d_printf("Not enough data for header in \"%s\".\n", filename);
+ fclose(file);
+ return;
+ }
+
+ fclose(file);
+ dumpDpxMainHeader(&header);
+}
diff --git a/source/blender/imbuf/intern/cineon/dpxlib.h b/source/blender/imbuf/intern/cineon/dpxlib.h
new file mode 100644
index 00000000000..25fe84e2296
--- /dev/null
+++ b/source/blender/imbuf/intern/cineon/dpxlib.h
@@ -0,0 +1,56 @@
+/*
+ * DPX image file format library definitions.
+ *
+ * Copyright 1999 - 2002 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 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef _DPX_LIB_H_
+#define _DPX_LIB_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "logImageCore.h"
+
+typedef struct _Log_Image_File_t_ DpxFile;
+
+/* int functions return 0 for OK */
+
+void dpxSetVerbose(int);
+
+DpxFile* dpxOpen(const char* filename);
+DpxFile* dpxCreate(const char* filename, int xsize, int ysize, int channels);
+DpxFile* dpxOpenFromMem(unsigned char *buffer, unsigned int size);
+int dpxIsMemFileCineon(void *buffer);
+
+/* get/set scanline of converted bytes */
+int dpxGetRowBytes(DpxFile* dpx, unsigned short* row, int y);
+int dpxSetRowBytes(DpxFile* dpx, const unsigned short* row, int y);
+
+/* closes file and deletes data */
+void dpxClose(DpxFile* dpx);
+
+/* dumps file to stdout */
+void dpxDump(const char* filename);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _DPX_LIB_H_ */
diff --git a/source/blender/imbuf/intern/cineon/logImageCore.c b/source/blender/imbuf/intern/cineon/logImageCore.c
new file mode 100644
index 00000000000..e88e9241443
--- /dev/null
+++ b/source/blender/imbuf/intern/cineon/logImageCore.c
@@ -0,0 +1,212 @@
+/*
+ * Cineon image file format library routines.
+ *
+ * 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 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "logImageCore.h"
+
+#include <time.h> /* strftime() */
+#include <math.h>
+/* Makes rint consistent in Windows and Linux: */
+#define rint(x) floor(x+0.5)
+
+#ifdef WIN32
+#include <winsock.h>
+#else
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <sys/param.h>
+#endif
+
+#if defined(__hpux)
+/* These are macros in hpux */
+#ifdef htonl
+#undef htonl
+#undef htons
+#undef ntohl
+#undef ntohs
+#endif
+unsigned int htonl(h) unsigned int h; { return(h); }
+unsigned short htons(h) unsigned short h; { return(h); }
+unsigned int ntohl(n) unsigned int n; { return(n); }
+unsigned short ntohs(n) unsigned short n; { return(n); }
+#endif
+
+
+/* obscure LogImage conversion */
+/* from 10 bit int to 0.0 - 1.0 */
+/* magic numbers left intact */
+static double
+convertTo(int inp, int white, float gamma) {
+ /* return pow(pow(10.0, ((inp - white) * 0.002 / 0.6)), gamma); */
+ return pow(10.0, (inp - white) * gamma * 0.002 / 0.6);
+}
+
+static double
+convertFrom(double inp, int white, float gamma) {
+ return white + log10(inp) / (gamma * 0.002 / 0.6);
+}
+
+/* set up the 10 bit to 8 bit and 8 bit to 10 bit tables */
+void
+setupLut(LogImageFile *logImage) {
+
+ int i;
+ double f_black;
+ double scale;
+
+ f_black = convertTo(logImage->params.blackPoint, logImage->params.whitePoint, logImage->params.gamma);
+ scale = 255.0 / (1.0 - f_black);
+
+ for (i = 0; i <= logImage->params.blackPoint; ++i) {
+ logImage->lut10[i] = 0;
+ }
+ for (; i < logImage->params.whitePoint; ++i) {
+ double f_i;
+ f_i = convertTo(i, logImage->params.whitePoint, logImage->params.gamma);
+ logImage->lut10[i] = (int)rint(scale * (f_i - f_black));
+ }
+ for (; i < 1024; ++i) {
+ logImage->lut10[i] = 255;
+ }
+
+ for (i = 0; i < 256; ++i) {
+ double f_i = f_black + (i / 255.0) * (1.0 - f_black);
+ logImage->lut8[i] = convertFrom(f_i, logImage->params.whitePoint, logImage->params.gamma);
+ }
+}
+
+/* how many longwords to hold this many pixels? */
+int
+pixelsToLongs(int numPixels) {
+ return (numPixels + 2) / 3;
+}
+
+/* byte reversed float */
+
+typedef union {
+ U32 i;
+ R32 f;
+} Hack;
+
+R32
+htonf(R32 f) {
+ Hack hack;
+ hack.f = f;
+ hack.i = htonl(hack.i);
+ return hack.f;
+}
+
+R32
+ntohf(R32 f) {
+ Hack hack;
+ hack.f = f;
+ hack.i = ntohl(hack.i);
+ return hack.f;
+}
+
+#define UNDEF_FLOAT 0x7F800000
+
+R32
+undefined() {
+ Hack hack;
+ hack.i = UNDEF_FLOAT;
+ return hack.f;
+}
+
+/* reverse an endian-swapped U16 */
+U16
+reverseU16(U16 value) {
+
+ union {
+ U16 whole;
+ char part[2];
+ } buff;
+ char temp;
+ buff.whole = value;
+ temp = buff.part[0];
+ buff.part[0] = buff.part[1];
+ buff.part[1] = temp;
+ return buff.whole;
+}
+
+/* reverse an endian-swapped U32 */
+U32
+reverseU32(U32 value) {
+
+ union {
+ U32 whole;
+ char part[4];
+ } buff;
+ char temp;
+ buff.whole = value;
+ temp = buff.part[0];
+ buff.part[0] = buff.part[3];
+ buff.part[3] = temp;
+ temp = buff.part[1];
+ buff.part[1] = buff.part[2];
+ buff.part[2] = temp;
+ return buff.whole;
+}
+
+/* reverse an endian-swapped R32 */
+R32
+reverseR32(R32 value) {
+
+ union {
+ R32 whole;
+ char part[4];
+ } buff;
+ char temp;
+ buff.whole = value;
+ temp = buff.part[0];
+ buff.part[0] = buff.part[3];
+ buff.part[3] = temp;
+ temp = buff.part[1];
+ buff.part[1] = buff.part[2];
+ buff.part[2] = temp;
+ return buff.whole;
+}
+
+#if 0
+/* bytes per line for images packed 3 10 bit pixels to 32 bits, 32 bit aligned */
+int
+bytesPerLine_10_4(int numPixels) {
+ return ((numPixels + 2) / 3) * 4;
+}
+
+void
+seekLine_noPadding(LogImageFile* logImage, int lineNumber) {
+ int fileOffset = bytesPerLine_10_4(lineNumber * logImage->width * logImage->depth);
+ int filePos = logImage->imageOffset + fileOffset;
+ if (fseek(logImage->file, filePos, SEEK_SET) != 0) {
+ /* complain? */
+ }
+}
+
+void
+seekLine_padding(LogImageFile* logImage, int lineNumber) {
+ int fileOffset = lineNumber * bytesPerLine_10_4(logImage->width * logImage->depth);
+ int filePos = logImage->imageOffset + fileOffset;
+ if (fseek(logImage->file, filePos, SEEK_SET) != 0) {
+ /* complain? */
+ }
+}
+#endif
diff --git a/source/blender/imbuf/intern/cineon/logImageCore.h b/source/blender/imbuf/intern/cineon/logImageCore.h
new file mode 100644
index 00000000000..1af18d5e3b8
--- /dev/null
+++ b/source/blender/imbuf/intern/cineon/logImageCore.h
@@ -0,0 +1,109 @@
+/*
+ * Cineon image file format library definitions.
+ * Cineon and DPX common structures.
+ *
+ * This header file contains private details.
+ * User code should generally use cineonlib.h and dpxlib.h only.
+ * Hmm. I thought the two formats would have more in common!
+ *
+ * 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 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef _LOG_IMAGE_CORE_H_
+#define _LOG_IMAGE_CORE_H_
+
+#include <stdio.h>
+#include "logImageLib.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+typedef int (GetRowFn)(LogImageFile* logImage, unsigned short* row, int lineNum);
+typedef int (SetRowFn)(LogImageFile* logImage, const unsigned short* row, int lineNum);
+typedef void (CloseFn)(LogImageFile* logImage);
+
+struct _Log_Image_File_t_
+{
+ /* specified in header */
+ int width;
+ int height;
+ int depth;
+ int bitsPerPixel;
+ int imageOffset;
+
+ /* file buffer, measured in longwords (4 byte) */
+ int lineBufferLength;
+ unsigned int* lineBuffer;
+
+ /* pixel buffer, holds 10 bit pixel values */
+ unsigned short* pixelBuffer;
+ int pixelBufferUsed;
+
+ /* io stuff */
+ FILE* file;
+ int reading;
+ int fileYPos;
+
+ /* byte conversion stuff */
+ LogImageByteConversionParameters params;
+#if 0
+ float gamma;
+ int blackPoint;
+ int whitePoint;
+#endif
+ unsigned char lut10[1024];
+ unsigned short lut8[256];
+
+ /* pixel access functions */
+ GetRowFn* getRow;
+ SetRowFn* setRow;
+ CloseFn* close;
+
+ unsigned char *membuffer;
+ unsigned long membuffersize;
+ unsigned char *memcursor;
+};
+
+void setupLut(LogImageFile*);
+
+int pixelsToLongs(int numPixels);
+
+/* typedefs used in original docs */
+/* note size assumptions! */
+
+typedef unsigned int U32;
+typedef unsigned short U16;
+typedef unsigned char U8;
+typedef signed int S32;
+typedef float R32;
+typedef char ASCII;
+
+R32 htonf(R32 f);
+R32 ntohf(R32 f);
+R32 undefined();
+U16 reverseU16(U16 value);
+U32 reverseU32(U32 value);
+R32 reverseR32(R32 value);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _LOG_IMAGE_CORE_H_ */
diff --git a/source/blender/imbuf/intern/cineon/logImageLib.c b/source/blender/imbuf/intern/cineon/logImageLib.c
new file mode 100644
index 00000000000..ff209d5ebd0
--- /dev/null
+++ b/source/blender/imbuf/intern/cineon/logImageLib.c
@@ -0,0 +1,158 @@
+/*
+ * Cineon and DPX image file format library routines.
+ *
+ * Copyright 1999 - 2002 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 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "cineonlib.h"
+#include "dpxlib.h"
+
+#include <stdio.h>
+#include <math.h>
+#include <stdlib.h>
+#include <time.h> /* strftime() */
+#include <sys/types.h>
+#ifdef WIN32
+#include <winsock.h>
+#else
+#include <netinet/in.h> /* htonl() */
+#endif
+#include <string.h> /* memset */
+
+#define MIN_GAMMA 0.01
+#define MAX_GAMMA 99.9
+#define DEFAULT_GAMMA 1.0
+#define DEFAULT_BLACK_POINT 95
+#define DEFAULT_WHITE_POINT 685
+
+void
+logImageSetVerbose(int verbosity) {
+ cineonSetVerbose(verbosity);
+ dpxSetVerbose(verbosity);
+}
+
+LogImageFile*
+logImageOpen(const char* filename, int cineon) {
+ if (cineon) {
+ return cineonOpen(filename);
+ } else {
+ return dpxOpen(filename);
+ }
+ return 0;
+}
+
+LogImageFile*
+logImageOpenFromMem(unsigned char *buffer, unsigned int size, int cineon) {
+ if (cineon) {
+ return cineonOpenFromMem(buffer, size);
+ } else {
+ return dpxOpenFromMem(buffer, size);
+ }
+ return 0;
+}
+
+LogImageFile*
+logImageCreate(const char* filename, int cineon, int width, int height, int depth) {
+ if (cineon) {
+ return cineonCreate(filename, width, height, depth);
+ } else {
+ return dpxCreate(filename, width, height, depth);
+ }
+ return 0;
+}
+
+int
+logImageGetSize(const LogImageFile* logImage, int* width, int* height, int* depth) {
+ *width = logImage->width;
+ *height = logImage->height;
+ *depth = logImage->depth;
+ return 0;
+}
+
+int
+logImageGetByteConversionDefaults(LogImageByteConversionParameters* params) {
+ params->gamma = DEFAULT_GAMMA;
+ params->blackPoint = DEFAULT_BLACK_POINT;
+ params->whitePoint = DEFAULT_WHITE_POINT;
+ return 0;
+}
+
+int
+logImageGetByteConversion(const LogImageFile* logImage, LogImageByteConversionParameters* params) {
+ params->gamma = logImage->params.gamma;
+ params->blackPoint = logImage->params.blackPoint;
+ params->whitePoint = logImage->params.whitePoint;
+ return 0;
+}
+
+int
+logImageSetByteConversion(LogImageFile* logImage, const LogImageByteConversionParameters* params) {
+ if ((params->gamma >= MIN_GAMMA) &&
+ (params->gamma <= MAX_GAMMA) &&
+ (params->blackPoint >= 0) &&
+ (params->blackPoint < params->whitePoint) &&
+ (params->whitePoint <= 1023)) {
+ logImage->params.gamma = params->gamma;
+ logImage->params.blackPoint = params->blackPoint;
+ logImage->params.whitePoint = params->whitePoint;
+ setupLut(logImage);
+ return 0;
+ }
+ return 1;
+}
+
+int
+logImageGetRowBytes(LogImageFile* logImage, unsigned short* row, int y) {
+ return logImage->getRow(logImage, row, y);
+}
+
+int
+logImageSetRowBytes(LogImageFile* logImage, const unsigned short* row, int y) {
+ return logImage->setRow(logImage, row, y);
+}
+
+void
+logImageClose(LogImageFile* logImage) {
+ logImage->close(logImage);
+}
+
+void
+logImageDump(const char* filename) {
+
+ U32 magic;
+
+ FILE* foo = fopen(filename, "rb");
+ if (foo == 0) {
+ return;
+ }
+
+ if (fread(&magic, sizeof(magic), 1, foo) == 0) {
+ fclose(foo);
+ return;
+ }
+
+ fclose(foo);
+
+ if (magic == ntohl(CINEON_FILE_MAGIC)) {
+#if 0
+ cineonDump(filename);
+#endif
+ } else if (magic == ntohl(DPX_FILE_MAGIC)) {
+ dpxDump(filename);
+ }
+}
diff --git a/source/blender/imbuf/intern/cineon/logImageLib.h b/source/blender/imbuf/intern/cineon/logImageLib.h
new file mode 100644
index 00000000000..ea45c675fe2
--- /dev/null
+++ b/source/blender/imbuf/intern/cineon/logImageLib.h
@@ -0,0 +1,86 @@
+/*
+ * Common library definitions for Cineon and DPX image files.
+ *
+ * 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 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef _LOG_IMAGE_LIB_H_
+#define _LOG_IMAGE_LIB_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Image structure. You don't care what this is.
+ */
+
+typedef struct _Log_Image_File_t_ LogImageFile;
+
+/*
+ * Magic numbers for normal and byte-swapped Cineon and Dpx files
+ */
+
+#define CINEON_FILE_MAGIC 0x802A5FD7
+#define DPX_FILE_MAGIC 0x53445058
+
+/*
+ * Image 8 bit <-> 10 bit conversion parameters.
+ */
+
+typedef struct {
+ float gamma;
+ int blackPoint;
+ int whitePoint;
+} LogImageByteConversionParameters;
+
+/* int functions return 0 for OK */
+
+void logImageSetVerbose(int);
+
+LogImageFile* logImageOpenFromMem(unsigned char *buffer, unsigned int size, int cineon);
+LogImageFile* logImageOpen(const char* filename, int cineon);
+int logImageGetSize(const LogImageFile* logImage, int* xsize, int* ysize, int* channels);
+LogImageFile* logImageCreate(const char* filename, int cineon, int xsize, int ysize, int channels);
+
+/* get / set header block NYI */
+int logImageGetHeader(LogImageFile*, int*, void**);
+int logImageSetHeader(LogImageFile*, int, void*);
+
+/* byte conversion routines for mapping logImage (usually) 10 bit values to 8 bit */
+/* see Kodak docs for details... */
+
+int logImageGetByteConversionDefaults(LogImageByteConversionParameters* params);
+int logImageGetByteConversion(const LogImageFile* logImage, LogImageByteConversionParameters* params);
+int logImageSetByteConversion(LogImageFile* logImage, const LogImageByteConversionParameters* params);
+
+/* get/set scanline of converted bytes */
+int logImageGetRowBytes(LogImageFile* logImage, unsigned short* row, int y);
+int logImageSetRowBytes(LogImageFile* logImage, const unsigned short* row, int y);
+
+/* closes file and deletes data */
+void logImageClose(LogImageFile* logImage);
+
+/* read file and dump header info */
+void logImageDump(const char* filename);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _LOG_IMAGE_LIB_H_ */
diff --git a/source/blender/imbuf/intern/cineon/logmemfile.c b/source/blender/imbuf/intern/cineon/logmemfile.c
new file mode 100644
index 00000000000..20359335933
--- /dev/null
+++ b/source/blender/imbuf/intern/cineon/logmemfile.c
@@ -0,0 +1,77 @@
+/*
+ * Cineon image file format library routines.
+ *
+ * Copyright 2006 Joseph Eagar (joeedh@gmail.com)
+ *
+ * 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.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "logImageCore.h"
+
+int logimage_fseek(void* logfile, long offsett, int origin)
+{
+ struct _Log_Image_File_t_ *file = (struct _Log_Image_File_t_*) logfile;
+ long offset = offsett;
+
+ if (file->file) fseek(file->file, offset, origin);
+ else { /*we're seeking in memory*/
+ if (origin==SEEK_SET) {
+ if (offset > file->membuffersize) return 1;
+ file->memcursor = file->membuffer + offset;
+ } else if (origin==SEEK_END) {
+ if (offset > file->membuffersize) return 1;
+ file->memcursor = (file->membuffer + file->membuffersize) - offset;
+ } else if (origin==SEEK_CUR) {
+ unsigned long pos = (unsigned long)file->membuffer - (unsigned long)file->memcursor;
+ if (pos + offset > file->membuffersize) return 1;
+ if (pos < 0) return 1;
+ file->memcursor += offset;
+ }
+ }
+ return 0;
+}
+
+int logimage_fwrite(void *buffer, unsigned int size, unsigned int count, void *logfile)
+{
+ struct _Log_Image_File_t_ *file = (struct _Log_Image_File_t_*) logfile;
+ if (file->file) return fwrite(buffer, size, count, file->file);
+ else { /*we're writing to memory*/
+ /*do nothing as this isn't supported yet*/
+ return count;
+ }
+}
+
+int logimage_fread(void *buffer, unsigned int size, unsigned int count, void *logfile)
+{
+ struct _Log_Image_File_t_ *file = (struct _Log_Image_File_t_*) logfile;
+ if (file->file) return fread(buffer, size, count, file->file);
+ else { /*we're reading from memory*/
+ int i;
+ /*we convert ot uchar just on the off chance some platform can't handle
+ pointer arithmetic with type (void*). */
+ unsigned char *buf = (unsigned char *) buffer;
+
+ for (i=0; i<count; i++) {
+ memcpy(buf, file->memcursor, size);
+ file->memcursor += size;
+ buf += size;
+ }
+ return count;
+ }
+}
diff --git a/source/blender/imbuf/intern/cineon/logmemfile.h b/source/blender/imbuf/intern/cineon/logmemfile.h
new file mode 100644
index 00000000000..6e82cf2b145
--- /dev/null
+++ b/source/blender/imbuf/intern/cineon/logmemfile.h
@@ -0,0 +1,29 @@
+/*
+ * Cineon image file format library routines.
+ *
+ * Copyright 2006 Joseph Eagar (joeedh@gmail.com)
+ *
+ * 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.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef _LOGMEMFILE_H
+#define _LOGMEMFILE_H
+
+int logimage_fseek(void* logfile, long offsett, int origin);
+int logimage_fwrite(void *buffer, unsigned int size, unsigned int count, void *logfile);
+int logimage_fread(void *buffer, unsigned int size, unsigned int count, void *logfile);
+
+#endif /* _LOGMEMFILE_H */
diff --git a/source/blender/imbuf/intern/readimage.c b/source/blender/imbuf/intern/readimage.c
index 23fe3f0a6d2..45ef191277b 100644
--- a/source/blender/imbuf/intern/readimage.c
+++ b/source/blender/imbuf/intern/readimage.c
@@ -52,6 +52,7 @@
#include "IMB_bmp.h"
#include "IMB_tiff.h"
#include "IMB_radiance_hdr.h"
+#include "IMB_dpxcineon.h"
#include "BKE_global.h"
#ifdef WITH_OPENEXR
@@ -134,6 +135,12 @@ ImBuf *IMB_ibImageFromMemory(int *mem, int size, int flags) {
ibuf = imb_loadtarga((uchar *)mem, flags);
if (ibuf) return(ibuf);
+ ibuf = imb_loaddpx((uchar *)mem, size, flags);
+ if (ibuf) return(ibuf);
+
+ ibuf = imb_loadcineon((uchar *)mem, size, flags);
+ if (ibuf) return(ibuf);
+
if (G.have_libtiff) {
ibuf = imb_loadtiff((uchar *)mem, size, flags);
if (ibuf) return(ibuf);
diff --git a/source/blender/imbuf/intern/util.c b/source/blender/imbuf/intern/util.c
index 56a03f56ce2..d741665f6ea 100644
--- a/source/blender/imbuf/intern/util.c
+++ b/source/blender/imbuf/intern/util.c
@@ -47,6 +47,7 @@
#include "IMB_bmp.h"
#include "IMB_tiff.h"
#include "IMB_radiance_hdr.h"
+#include "IMB_dpxcineon.h"
#include "IMB_anim.h"
@@ -117,7 +118,8 @@ static int IMB_ispic_name(char *name)
if (imb_is_a_openexr((uchar *)buf)) return(OPENEXR);
#endif
if (imb_is_a_tiff(buf)) return(TIF);
-
+ if (imb_is_dpx(buf)) return (DPX);
+ if (imb_is_cineon(buf)) return(CINEON);
/* radhdr: check if hdr format */
if (imb_is_a_hdr(buf)) return(RADHDR);
@@ -168,6 +170,7 @@ int IMB_ispic(char *filename)
|| BLI_testextensie(filename, ".pict")
|| BLI_testextensie(filename, ".pntg") //macpaint
|| BLI_testextensie(filename, ".qtif")
+ || BLI_testextensie(filename, ".cin")
|| BLI_testextensie(filename, ".sgi")) {
return IMB_ispic_name(filename);
} else {
@@ -181,6 +184,7 @@ int IMB_ispic(char *filename)
|| BLI_testextensie(filename, ".rgb")
|| BLI_testextensie(filename, ".bmp")
|| BLI_testextensie(filename, ".png")
+ || BLI_testextensie(filename, ".cin")
|| BLI_testextensie(filename, ".iff")
|| BLI_testextensie(filename, ".lbm")
|| BLI_testextensie(filename, ".sgi")) {
diff --git a/source/blender/imbuf/intern/writeimage.c b/source/blender/imbuf/intern/writeimage.c
index ae75de8f54f..2e922c65827 100644
--- a/source/blender/imbuf/intern/writeimage.c
+++ b/source/blender/imbuf/intern/writeimage.c
@@ -47,6 +47,7 @@
#include "IMB_allocimbuf.h"
+#include "IMB_dpxcineon.h"
#include "IMB_targa.h"
#include "IMB_jpeg.h"
#include "IMB_iris.h"
@@ -114,7 +115,13 @@ short IMB_saveiff(struct ImBuf *ibuf, char *name, int flags)
return imb_save_openexr(ibuf, name, flags);
}
#endif
-
+ if (IS_cineon(ibuf)) {
+ return imb_savecineon(ibuf, name, flags);
+
+ }
+ if (IS_dpx(ibuf)) {
+ return imb_save_dpx(ibuf, name, flags);
+ }
file = open(name, O_BINARY | O_RDWR | O_CREAT | O_TRUNC, 0666);
if (file < 0) return (FALSE);
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index 7e56b276d59..035dab4a683 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -477,6 +477,8 @@ typedef struct Scene {
#define R_OPENEXR 23
#define R_FFMPEG 24
#define R_FRAMESERVER 25
+#define R_CINEON 26
+#define R_DPX 27
/* subimtype, flag options for imtype */
#define R_OPENEXR_HALF 1
diff --git a/source/blender/src/buttons_scene.c b/source/blender/src/buttons_scene.c
index 778a0aa88d6..3de232c69ef 100644
--- a/source/blender/src/buttons_scene.c
+++ b/source/blender/src/buttons_scene.c
@@ -1101,7 +1101,9 @@ static char *imagetype_pup(void)
strcat(formatstring, "|%s %%x%d"); // add space for PNG
strcat(formatstring, "|%s %%x%d"); // add space for BMP
strcat(formatstring, "|%s %%x%d"); // add space for Radiance HDR
-
+ strcat(formatstring, "|%s %%x%d"); // add space for Cineon
+ strcat(formatstring, "|%s %%x%d"); // add space for DPX
+
#ifdef _WIN32
strcat(formatstring, "|%s %%x%d"); // add space for AVI Codec
#endif
@@ -1138,7 +1140,9 @@ static char *imagetype_pup(void)
"HamX", R_HAMX,
"Iris", R_IRIS,
"Iris + Zbuffer", R_IRIZ,
- "Radiance HDR", R_RADHDR
+ "Radiance HDR", R_RADHDR,
+ "Cineon", R_CINEON,
+ "DPX", R_DPX
#ifdef __sgi
,"Movie", R_MOVIE
#endif
@@ -1162,7 +1166,9 @@ static char *imagetype_pup(void)
"HamX", R_HAMX,
"Iris", R_IRIS,
"Iris + Zbuffer", R_IRIZ,
- "Radiance HDR", R_RADHDR
+ "Radiance HDR", R_RADHDR,
+ "Cineon", R_CINEON,
+ "DPX", R_DPX
#ifdef __sgi
,"Movie", R_MOVIE
#endif
diff --git a/source/blender/src/filesel.c b/source/blender/src/filesel.c
index f2e2fe216e0..003fee46173 100644
--- a/source/blender/src/filesel.c
+++ b/source/blender/src/filesel.c
@@ -523,6 +523,8 @@ void test_flags_file(SpaceFile *sfile)
|| BLI_testextensie(file->relname, ".pict")
|| BLI_testextensie(file->relname, ".pntg") //macpaint
|| BLI_testextensie(file->relname, ".qtif")
+ || BLI_testextensie(file->relname, ".cin")
+ || BLI_testextensie(file->relname, ".dpx")
|| BLI_testextensie(file->relname, ".sgi")) {
file->flags |= IMAGEFILE;
}
@@ -544,6 +546,8 @@ void test_flags_file(SpaceFile *sfile)
|| BLI_testextensie(file->relname, ".png")
|| BLI_testextensie(file->relname, ".iff")
|| BLI_testextensie(file->relname, ".lbm")
+ || BLI_testextensie(file->relname, ".cin")
+ || BLI_testextensie(file->relname, ".dpx")
|| BLI_testextensie(file->relname, ".sgi")) {
file->flags |= IMAGEFILE;
}
diff --git a/source/blender/src/writeimage.c b/source/blender/src/writeimage.c
index 547e12a8a73..6239f980335 100644
--- a/source/blender/src/writeimage.c
+++ b/source/blender/src/writeimage.c
@@ -177,6 +177,12 @@ void save_image_filesel_str(char *str)
strcpy(str, "Save OpenEXR");
break;
#endif
+ case R_CINEON:
+ strcpy(str, "Save Cineon");
+ break;
+ case R_DPX:
+ strcpy(str, "Save DPX");
+ break;
case R_RAWTGA:
strcpy(str, "Save Raw Targa");
break;