Blender  V2.59
logImageCore.c
Go to the documentation of this file.
00001 
00004 /*
00005  *       Cineon image file format library routines.
00006  *
00007  *       Copyright 1999,2000,2001 David Hodson <hodsond@acm.org>
00008  *
00009  *       This program is free software; you can redistribute it and/or modify it
00010  *       under the terms of the GNU General Public License as published by the Free
00011  *       Software Foundation; either version 2 of the License, or (at your option)
00012  *       any later version.
00013  *
00014  *       This program is distributed in the hope that it will be useful, but
00015  *       WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
00016  *       or FITNESS FOR A PARTICULAR PURPOSE.    See the GNU General Public License
00017  *       for more details.
00018  *
00019  *       You should have received a copy of the GNU General Public License
00020  *       along with this program; if not, write to the Free Software
00021  *       Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00022  *
00023  */
00024 
00025 #include "logImageCore.h"
00026 
00027 #include <time.h>                                /* strftime() */
00028 #include <math.h>
00029 /* Makes rint consistent in Windows and Linux: */
00030 #define rint(x) floor(x+0.5)
00031 
00032 #ifdef WIN32
00033 #include <winsock.h>
00034 #else
00035 #include <sys/types.h>
00036 #include <sys/socket.h>
00037 #include <netinet/in.h>
00038 #include <sys/param.h>
00039 #endif
00040 
00041 #if defined(__hpux)
00042 /* These are macros in hpux */
00043 #ifdef htonl
00044 #undef htonl
00045 #undef htons
00046 #undef ntohl
00047 #undef ntohs
00048 #endif
00049 unsigned int htonl(h) unsigned int h; { return(h); }
00050 unsigned short htons(h) unsigned short h; { return(h); }
00051 unsigned int ntohl(n) unsigned int n; { return(n); }
00052 unsigned short ntohs(n) unsigned short n; { return(n); }
00053 #endif
00054         
00055         
00056 /* obscure LogImage conversion */
00057 /* from 10 bit int to 0.0 - 1.0 */
00058 /* magic numbers left intact */
00059 static double
00060 convertTo(int inp, int white, float gamma) {
00061         /*      return pow(pow(10.0, ((inp - white) * 0.002 / 0.6)), gamma); */
00062         return pow(10.0, (inp - white) * gamma * 0.002 / 0.6);
00063 }
00064 
00065 static double
00066 convertFrom(double inp, int white, float gamma) {
00067         return white + log10(inp) / (gamma * 0.002 / 0.6);
00068 }
00069 
00070 /* set up the 10 bit to 8 bit and 8 bit to 10 bit tables */
00071 void
00072 setupLut(LogImageFile *logImage) {
00073 
00074         int i;
00075         double f_black;
00076         double scale;
00077 
00078         f_black = convertTo(logImage->params.blackPoint, logImage->params.whitePoint, logImage->params.gamma);
00079         scale = 255.0 / (1.0 - f_black);
00080 
00081         for (i = 0; i <= logImage->params.blackPoint; ++i) {
00082                 logImage->lut10[i] = 0;
00083         }
00084         for (; i < logImage->params.whitePoint; ++i) {
00085                 double f_i;
00086                 f_i = convertTo(i, logImage->params.whitePoint, logImage->params.gamma);
00087                 logImage->lut10[i] = (int)rint(scale * (f_i - f_black));
00088         }
00089         for (; i < 1024; ++i) {
00090                 logImage->lut10[i] = 255;
00091         }
00092 
00093         for (i = 0; i < 256; ++i) {
00094                 double f_i = f_black + (i / 255.0) * (1.0 - f_black);
00095                 logImage->lut8[i] = convertFrom(f_i, logImage->params.whitePoint, logImage->params.gamma);
00096         }
00097 }
00098 
00099 /* set up the 10 bit to 16 bit and 16 bit to 10 bit tables */
00100 void
00101 setupLut16(LogImageFile *logImage) {
00102 
00103         int i;
00104         double f_black;
00105         double scale;
00106 
00107         f_black = convertTo(logImage->params.blackPoint, logImage->params.whitePoint, logImage->params.gamma);
00108         scale = 65535.0 / (1.0 - f_black);
00109 
00110         for (i = 0; i <= logImage->params.blackPoint; ++i) {
00111                 logImage->lut10_16[i] = 0;
00112         }
00113         for (; i < logImage->params.whitePoint; ++i) {
00114                 double f_i;
00115                 f_i = convertTo(i, logImage->params.whitePoint, logImage->params.gamma);
00116                 logImage->lut10_16[i] = (int)rint(scale * (f_i - f_black));
00117         }
00118         for (; i < 1024; ++i) {
00119                 logImage->lut10_16[i] = 65535;
00120         }
00121 
00122         for (i = 0; i < 65536; ++i) {
00123                 double f_i = f_black + (i / 65535.0) * (1.0 - f_black);
00124                 logImage->lut16_16[i] = convertFrom(f_i, logImage->params.whitePoint, logImage->params.gamma);
00125         }
00126 }
00127 
00128 /* how many longwords to hold this many pixels? */
00129 int
00130 pixelsToLongs(int numPixels) {
00131         return (numPixels + 2) / 3;
00132 }
00133 
00134 /* byte reversed float */
00135 
00136 typedef union {
00137         U32 i;
00138         R32 f;
00139 } Hack;
00140 
00141 R32
00142 htonf(R32 f) {
00143         Hack hack;
00144         hack.f = f;
00145         hack.i = htonl(hack.i);
00146         return hack.f;
00147 }
00148 
00149 R32
00150 ntohf(R32 f) {
00151         Hack hack;
00152         hack.f = f;
00153         hack.i = ntohl(hack.i);
00154         return hack.f;
00155 }
00156 
00157 #define UNDEF_FLOAT 0x7F800000
00158 
00159 R32
00160 undefined(void) {
00161         Hack hack;
00162         hack.i = UNDEF_FLOAT;
00163         return hack.f;
00164 }
00165 
00166 /* reverse an endian-swapped U16 */
00167 U16
00168 reverseU16(U16 value) {
00169 
00170         union {
00171                 U16 whole;
00172                 char part[2];
00173         } buff;
00174         char temp;
00175         buff.whole = value;
00176         temp = buff.part[0];
00177         buff.part[0] = buff.part[1];
00178         buff.part[1] = temp;
00179         return buff.whole;
00180 }
00181 
00182 /* reverse an endian-swapped U32 */
00183 U32
00184 reverseU32(U32 value) {
00185 
00186         union {
00187                 U32 whole;
00188                 char part[4];
00189         } buff;
00190         char temp;
00191         buff.whole = value;
00192         temp = buff.part[0];
00193         buff.part[0] = buff.part[3];
00194         buff.part[3] = temp;
00195         temp = buff.part[1];
00196         buff.part[1] = buff.part[2];
00197         buff.part[2] = temp;
00198         return buff.whole;
00199 }
00200 
00201 /* reverse an endian-swapped R32 */
00202 R32
00203 reverseR32(R32 value) {
00204 
00205         union {
00206                 R32 whole;
00207                 char part[4];
00208         } buff;
00209         char temp;
00210         buff.whole = value;
00211         temp = buff.part[0];
00212         buff.part[0] = buff.part[3];
00213         buff.part[3] = temp;
00214         temp = buff.part[1];
00215         buff.part[1] = buff.part[2];
00216         buff.part[2] = temp;
00217         return buff.whole;
00218 }
00219 
00220 #if 0
00221 /* bytes per line for images packed 3 10 bit pixels to 32 bits, 32 bit aligned */
00222 int
00223 bytesPerLine_10_4(int numPixels) {
00224         return ((numPixels + 2) / 3) * 4;
00225 }
00226 
00227 void
00228 seekLine_noPadding(LogImageFile* logImage, int lineNumber) {
00229         int fileOffset = bytesPerLine_10_4(lineNumber * logImage->width * logImage->depth);
00230         int filePos = logImage->imageOffset + fileOffset;
00231         if (fseek(logImage->file, filePos, SEEK_SET) != 0) {
00232                 /* complain? */
00233         }
00234 }
00235 
00236 void
00237 seekLine_padding(LogImageFile* logImage, int lineNumber) {
00238         int fileOffset = lineNumber * bytesPerLine_10_4(logImage->width * logImage->depth);
00239         int filePos = logImage->imageOffset + fileOffset;
00240         if (fseek(logImage->file, filePos, SEEK_SET) != 0) {
00241                 /* complain? */
00242         }
00243 }
00244 #endif