Blender V2.61 - r43446
|
00001 00004 /* 00005 * Dpx image file format library routines. 00006 * 00007 * Copyright 1999 - 2002 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 "dpxfile.h" 00026 #include "dpxlib.h" 00027 00028 #include <stdio.h> 00029 #include <math.h> 00030 #include <stdlib.h> 00031 #include <time.h> /* strftime() */ 00032 #include <sys/types.h> 00033 #ifdef WIN32 00034 #include <winsock.h> 00035 #else 00036 #include <netinet/in.h> /* htonl() */ 00037 #endif 00038 #include <string.h> /* memset */ 00039 #include "cin_debug_stuff.h" 00040 #include "logmemfile.h" 00041 00042 static void 00043 fillDpxChannelInfo(DpxFile* dpx, DpxChannelInformation* chan, int des) { 00044 00045 (void)dpx; /* unused */ 00046 00047 chan->signage = 0; 00048 chan->ref_low_data = htonl(0); 00049 chan->ref_low_quantity = htonf(0.0); 00050 chan->ref_high_data = htonl(1023); 00051 chan->ref_high_quantity = htonf(2.046); 00052 chan->designator1 = des; 00053 chan->transfer_characteristics = 0; 00054 chan->colourimetry = 0; 00055 chan->bits_per_pixel = 10; 00056 chan->packing = htons(1); 00057 chan->encoding = 0; 00058 chan->data_offset = 0; 00059 chan->line_padding = htonl(0); 00060 chan->channel_padding = htonl(0); 00061 chan->description[0] = 0; 00062 } 00063 00064 static void 00065 dumpDpxChannelInfo(DpxChannelInformation* chan) { 00066 d_printf(" Signage %ld", (intptr_t)ntohl(chan->signage)); 00067 d_printf(" Ref low data %ld\n", (intptr_t)ntohl(chan->ref_low_data)); 00068 d_printf(" Ref low quantity %f\n", ntohf(chan->ref_low_quantity)); 00069 d_printf(" Ref high data %ld\n", (intptr_t)ntohl(chan->ref_high_data)); 00070 d_printf(" Ref high quantity %f\n", ntohf(chan->ref_high_quantity)); 00071 d_printf(" Designator1: %d,", chan->designator1); 00072 d_printf(" Bits per pixel %d\n", chan->bits_per_pixel); 00073 d_printf(" Packing: %d,", ntohs(chan->packing)); 00074 d_printf(" Data Offset: %ld,", (intptr_t)ntohl(chan->data_offset)); 00075 } 00076 00077 static void 00078 fillDpxFileInfo( 00079 DpxFile* dpx, DpxFileInformation* fileInfo, const char* filename) { 00080 00081 time_t fileClock; 00082 struct tm* fileTime; 00083 00084 /* Note: always write files in network order */ 00085 /* By the spec, it shouldn't matter, but ... */ 00086 00087 fileInfo->magic_num = htonl(DPX_FILE_MAGIC); 00088 fileInfo->offset = htonl(dpx->imageOffset); 00089 strcpy(fileInfo->vers, "v1.0"); 00090 fileInfo->file_size = htonl(dpx->imageOffset + 00091 pixelsToLongs(dpx->height * dpx->width * dpx->depth) * 4); 00092 fileInfo->ditto_key = 0; 00093 fileInfo->gen_hdr_size = htonl( 00094 sizeof(DpxFileInformation) + 00095 sizeof(DpxImageInformation) + 00096 sizeof(DpxOriginationInformation)); 00097 fileInfo->ind_hdr_size = htonl(sizeof(DpxMPIInformation)); 00098 fileInfo->user_data_size = 0; 00099 strncpy(fileInfo->file_name, filename, 99); 00100 fileInfo->file_name[99] = 0; 00101 00102 fileClock = time(0); 00103 fileTime = localtime(&fileClock); 00104 strftime(fileInfo->create_date, 24, "%Y:%m:%d:%H:%M:%S%Z", fileTime); 00105 /* Question: is %Z in strftime guaranteed to return 3 chars? */ 00106 fileInfo->create_date[23] = 0; 00107 00108 strcpy(fileInfo->creator, "David's DPX writer"); 00109 fileInfo->project[0] = 0; 00110 fileInfo->copyright[0] = 0; 00111 fileInfo->key = 0xFFFFFFFF; /* same in any byte order */ 00112 } 00113 00114 static void 00115 dumpDpxFileInfo(DpxFileInformation* fileInfo) { 00116 d_printf("\n--File Information--\n"); 00117 d_printf("Magic: %8.8lX\n", (unsigned long)ntohl(fileInfo->magic_num)); 00118 d_printf("Image Offset %ld\n", (intptr_t)ntohl(fileInfo->offset)); 00119 d_printf("Version \"%s\"\n", fileInfo->vers); 00120 d_printf("File size %ld\n", (intptr_t)ntohl(fileInfo->file_size)); 00121 d_printf("Ditto key %ld\n", (intptr_t)ntohl(fileInfo->ditto_key)); 00122 d_printf("Generic Header size %ld\n", (intptr_t)ntohl(fileInfo->gen_hdr_size)); 00123 d_printf("Industry Header size %ld\n", (intptr_t)ntohl(fileInfo->ind_hdr_size)); 00124 d_printf("User Data size %ld\n", (intptr_t)ntohl(fileInfo->user_data_size)); 00125 d_printf("File name \"%s\"\n", fileInfo->file_name); 00126 d_printf("Creation date \"%s\"\n", fileInfo->create_date); 00127 d_printf("Creator \"%s\"\n", fileInfo->creator); 00128 d_printf("Project \"%s\"\n", fileInfo->project); 00129 d_printf("Copyright \"%s\"\n", fileInfo->copyright); 00130 d_printf("Key %ld\n", (intptr_t)ntohl(fileInfo->key)); 00131 } 00132 00133 static void 00134 fillDpxImageInfo( 00135 DpxFile* dpx, DpxImageInformation* imageInfo) { 00136 imageInfo->orientation = 0; 00137 imageInfo->channels_per_image = htons(1); 00138 imageInfo->pixels_per_line = htonl(dpx->width); 00139 imageInfo->lines_per_image = htonl(dpx->height); 00140 00141 if (dpx->depth == 1) { 00142 fillDpxChannelInfo(dpx, &imageInfo->channel[0], 0); 00143 00144 } else if (dpx->depth == 3) { 00145 fillDpxChannelInfo(dpx, &imageInfo->channel[0], 50); 00146 } 00147 } 00148 00149 static void 00150 dumpDpxImageInfo(DpxImageInformation* imageInfo) { 00151 00152 int n; 00153 int i; 00154 d_printf("\n--Image Information--\n"); 00155 d_printf("Image orientation %d,", ntohs(imageInfo->orientation)); 00156 n = ntohs(imageInfo->channels_per_image); 00157 d_printf("Channels %d\n", n); 00158 d_printf("Pixels per line %ld\n", (intptr_t)ntohl(imageInfo->pixels_per_line)); 00159 d_printf("Lines per image %ld\n", (intptr_t)ntohl(imageInfo->lines_per_image)); 00160 for (i = 0; i < n; ++i) { 00161 d_printf(" --Channel %d--\n", i); 00162 dumpDpxChannelInfo(&imageInfo->channel[i]); 00163 } 00164 } 00165 00166 static void 00167 fillDpxOriginationInfo( 00168 DpxFile* dpx, DpxOriginationInformation* originInfo, DpxFileInformation* fileInfo) 00169 { 00170 /* unused */ 00171 (void)dpx; 00172 (void)originInfo; 00173 (void)fileInfo; 00174 } 00175 00176 static void 00177 dumpDpxOriginationInfo(DpxOriginationInformation* originInfo) { 00178 d_printf("\n--Origination Information--\n"); 00179 d_printf("X offset %ld\n", (intptr_t)ntohl(originInfo->x_offset)); 00180 d_printf("Y offset %ld\n", (intptr_t)ntohl(originInfo->y_offset)); 00181 d_printf("X centre %f\n", ntohf(originInfo->x_centre)); 00182 d_printf("Y centre %f\n", ntohf(originInfo->y_centre)); 00183 d_printf("Original X %ld\n", (intptr_t)ntohl(originInfo->x_original_size)); 00184 d_printf("Original Y %ld\n", (intptr_t)ntohl(originInfo->y_original_size)); 00185 d_printf("File name \"%s\"\n", originInfo->file_name); 00186 d_printf("Creation time \"%s\"\n", originInfo->creation_time); 00187 d_printf("Input device \"%s\"\n", originInfo->input_device); 00188 d_printf("Serial number \"%s\"\n", originInfo->input_serial_number); 00189 } 00190 00191 static void 00192 initDpxMainHeader(DpxFile* dpx, DpxMainHeader* header, const char* shortFilename) { 00193 memset(header, 0, sizeof(DpxMainHeader)); 00194 fillDpxFileInfo(dpx, &header->fileInfo, shortFilename); 00195 fillDpxImageInfo(dpx, &header->imageInfo); 00196 fillDpxOriginationInfo(dpx, &header->originInfo, &header->fileInfo); 00197 #if 0 00198 fillDpxMPIInfo(dpx, &header->filmHeader); 00199 #endif 00200 } 00201 00202 static void 00203 dumpDpxMainHeader(DpxMainHeader* header) { 00204 dumpDpxFileInfo(&header->fileInfo); 00205 dumpDpxImageInfo(&header->imageInfo); 00206 dumpDpxOriginationInfo(&header->originInfo); 00207 #if 0 00208 dumpDpxMPIInformation(&header->filmHeader); 00209 #endif 00210 } 00211 00212 static int verbose = 0; 00213 void 00214 dpxSetVerbose(int verbosity) { 00215 verbose = verbosity; 00216 } 00217 00218 static void 00219 verboseMe(DpxFile* dpx) { 00220 00221 d_printf("size %d x %d x %d\n", dpx->width, dpx->height, dpx->depth); 00222 d_printf("ImageStart %d, lineBufferLength %d, implied length %d\n", 00223 dpx->imageOffset, dpx->lineBufferLength * 4, 00224 dpx->imageOffset + pixelsToLongs(dpx->width * dpx->depth * dpx->height) * 4); 00225 } 00226 00227 int 00228 dpxGetRowBytes(DpxFile* dpx, unsigned short* row, int y) { 00229 00230 /* Note: this code is bizarre because DPX files can wrap */ 00231 /* packed longwords across line boundaries!!!! */ 00232 00233 size_t readLongs; 00234 unsigned int longIndex; 00235 int numPixels = dpx->width * dpx->depth; 00236 int pixelIndex; 00237 00238 /* only seek if not reading consecutive lines */ 00239 /* this is not quite right yet, need to account for leftovers */ 00240 if (y != dpx->fileYPos) { 00241 int lineOffset = pixelsToLongs(y * dpx->width * dpx->depth) * 4; 00242 if (verbose) d_printf("Seek in getRowBytes\n"); 00243 if (logimage_fseek(dpx, dpx->imageOffset + lineOffset, SEEK_SET) != 0) { 00244 if (verbose) d_printf("Couldn't seek to line %d at %d\n", y, dpx->imageOffset + lineOffset); 00245 return 1; 00246 } 00247 dpx->fileYPos = y; 00248 } 00249 00250 /* read enough longwords */ 00251 readLongs = pixelsToLongs(numPixels - dpx->pixelBufferUsed); 00252 if (logimage_fread(dpx->lineBuffer, 4, readLongs, dpx) != readLongs) { 00253 if (verbose) d_printf("Couldn't read line %d length %d\n", y, (int)readLongs * 4); 00254 return 1; 00255 } 00256 ++dpx->fileYPos; 00257 00258 /* convert longwords to pixels */ 00259 pixelIndex = dpx->pixelBufferUsed; 00260 00261 /* this is just strange */ 00262 if (dpx->depth == 1) { 00263 for (longIndex = 0; longIndex < readLongs; ++longIndex) { 00264 unsigned int t = ntohl(dpx->lineBuffer[longIndex]); 00265 dpx->pixelBuffer[pixelIndex] = t & 0x3ff; 00266 t = t >> 10; 00267 dpx->pixelBuffer[pixelIndex+1] = t & 0x3ff; 00268 t = t >> 10; 00269 dpx->pixelBuffer[pixelIndex+2] = t & 0x3ff; 00270 pixelIndex += 3; 00271 } 00272 } else /* if (dpx->depth == 3) */ { 00273 for (longIndex = 0; longIndex < readLongs; ++longIndex) { 00274 unsigned int t = ntohl(dpx->lineBuffer[longIndex]); 00275 t = t >> 2; 00276 dpx->pixelBuffer[pixelIndex+2] = t & 0x3ff; 00277 t = t >> 10; 00278 dpx->pixelBuffer[pixelIndex+1] = t & 0x3ff; 00279 t = t >> 10; 00280 dpx->pixelBuffer[pixelIndex] = t & 0x3ff; 00281 pixelIndex += 3; 00282 } 00283 } 00284 dpx->pixelBufferUsed = pixelIndex; 00285 00286 /* extract required pixels */ 00287 for (pixelIndex = 0; pixelIndex < numPixels; ++pixelIndex) { 00288 if(dpx->params.doLogarithm) 00289 row[pixelIndex] = dpx->lut10_16[dpx->pixelBuffer[pixelIndex]]; 00290 else 00291 row[pixelIndex] = dpx->pixelBuffer[pixelIndex] << 6; 00292 } 00293 00294 /* save remaining pixels */ 00295 while (pixelIndex < dpx->pixelBufferUsed) { 00296 dpx->pixelBuffer[pixelIndex - numPixels] = dpx->pixelBuffer[pixelIndex]; 00297 ++pixelIndex; 00298 } 00299 dpx->pixelBufferUsed -= numPixels; 00300 00301 /* done! */ 00302 return 0; 00303 } 00304 00305 int 00306 dpxSetRowBytes(DpxFile* dpx, const unsigned short* row, int y) { 00307 00308 /* Note: this code is bizarre because DPX files can wrap */ 00309 /* packed longwords across line boundaries!!!! */ 00310 00311 size_t writeLongs; 00312 int longIndex; 00313 int numPixels = dpx->width * dpx->depth; 00314 int pixelIndex; 00315 int pixelIndex2; 00316 00317 /* only seek if not reading consecutive lines */ 00318 /* this is not quite right yet */ 00319 if (y != dpx->fileYPos) { 00320 int lineOffset = pixelsToLongs(y * dpx->width * dpx->depth) * 4; 00321 if (verbose) d_printf("Seek in getRowBytes\n"); 00322 if (logimage_fseek(dpx, dpx->imageOffset + lineOffset, SEEK_SET) != 0) { 00323 if (verbose) d_printf("Couldn't seek to line %d at %d\n", y, dpx->imageOffset + lineOffset); 00324 return 1; 00325 } 00326 dpx->fileYPos = y; 00327 } 00328 00329 /* put new pixels into pixelBuffer */ 00330 for (pixelIndex = 0; pixelIndex < numPixels; ++pixelIndex) { 00331 if(dpx->params.doLogarithm) 00332 dpx->pixelBuffer[dpx->pixelBufferUsed + pixelIndex] = dpx->lut16_16[row[pixelIndex]]; 00333 else 00334 dpx->pixelBuffer[dpx->pixelBufferUsed + pixelIndex] = row[pixelIndex] >> 6; 00335 } 00336 dpx->pixelBufferUsed += numPixels; 00337 00338 /* pack into longwords */ 00339 writeLongs = dpx->pixelBufferUsed / 3; 00340 /* process whole line at image end */ 00341 if (dpx->fileYPos == (dpx->height - 1)) { 00342 writeLongs = pixelsToLongs(dpx->pixelBufferUsed); 00343 } 00344 pixelIndex = 0; 00345 if (dpx->depth == 1) { 00346 for (longIndex = 0; longIndex < writeLongs; ++longIndex) { 00347 unsigned int t = dpx->pixelBuffer[pixelIndex] | 00348 (dpx->pixelBuffer[pixelIndex+1] << 10) | 00349 (dpx->pixelBuffer[pixelIndex+2] << 20); 00350 dpx->lineBuffer[longIndex] = htonl(t); 00351 pixelIndex += 3; 00352 } 00353 } else { 00354 for (longIndex = 0; longIndex < writeLongs; ++longIndex) { 00355 unsigned int t = dpx->pixelBuffer[pixelIndex+2] << 2 | 00356 (dpx->pixelBuffer[pixelIndex+1] << 12) | 00357 (dpx->pixelBuffer[pixelIndex] << 22); 00358 dpx->lineBuffer[longIndex] = htonl(t); 00359 pixelIndex += 3; 00360 } 00361 } 00362 00363 /* write them */ 00364 if (fwrite(dpx->lineBuffer, 4, writeLongs, dpx->file) != writeLongs) { 00365 if (verbose) d_printf("Couldn't write line %d length %d\n", y, (int)writeLongs * 4); 00366 return 1; 00367 } 00368 ++dpx->fileYPos; 00369 00370 /* save remaining pixels */ 00371 pixelIndex2 = 0; 00372 while (pixelIndex < dpx->pixelBufferUsed) { 00373 dpx->pixelBuffer[pixelIndex2] = dpx->pixelBuffer[pixelIndex]; 00374 ++pixelIndex; 00375 ++pixelIndex2; 00376 } 00377 dpx->pixelBufferUsed = pixelIndex2; 00378 00379 return 0; 00380 } 00381 00382 #define LFMEMFILE 0 00383 #define LFREALFILE 1 00384 00385 static DpxFile* 00386 intern_dpxOpen(int mode, const char* bytestuff, int bufsize) { 00387 00388 DpxMainHeader header; 00389 const char *filename = bytestuff; 00390 DpxFile* dpx = (DpxFile*)malloc(sizeof(DpxFile)); 00391 00392 if (dpx == 0) { 00393 if (verbose) d_printf("Failed to malloc dpx file structure.\n"); 00394 return 0; 00395 } 00396 00397 /* for close routine */ 00398 dpx->file = 0; 00399 dpx->lineBuffer = 0; 00400 dpx->pixelBuffer = 0; 00401 00402 if (mode == LFREALFILE) { 00403 filename = bytestuff; 00404 dpx->file = fopen(filename, "rb"); 00405 if (dpx->file == 0) { 00406 if (verbose) d_printf("Failed to open file \"%s\".\n", filename); 00407 dpxClose(dpx); 00408 return 0; 00409 } 00410 dpx->membuffer = 0; 00411 dpx->memcursor = 0; 00412 dpx->membuffersize = 0; 00413 } else if (mode == LFMEMFILE) { 00414 dpx->membuffer = (unsigned char *)bytestuff; 00415 dpx->memcursor = (unsigned char *)bytestuff; 00416 dpx->membuffersize = bufsize; 00417 } 00418 00419 dpx->reading = 1; 00420 00421 if (logimage_fread(&header, sizeof(header), 1, dpx) == 0) { 00422 if (verbose) d_printf("Not enough data for header in \"%s\".\n", filename); 00423 dpxClose(dpx); 00424 return 0; 00425 } 00426 00427 /* let's assume dpx files are always network order */ 00428 if (header.fileInfo.magic_num != ntohl(DPX_FILE_MAGIC)) { 00429 if (verbose) d_printf("Bad magic number %8.8lX in \"%s\".\n", 00430 (uintptr_t)ntohl(header.fileInfo.magic_num), filename); 00431 dpxClose(dpx); 00432 return 0; 00433 } 00434 00435 if (ntohs(header.imageInfo.channel[0].packing) != 1) { 00436 if (verbose) d_printf("Unknown packing %d\n", header.imageInfo.channel[0].packing); 00437 dpxClose(dpx); 00438 return 0; 00439 } 00440 00441 00442 dpx->width = ntohl(header.imageInfo.pixels_per_line); 00443 dpx->height = ntohl(header.imageInfo.lines_per_image); 00444 dpx->depth = ntohs(header.imageInfo.channels_per_image); 00445 /* Another DPX vs Cineon wierdness */ 00446 if (dpx->depth == 1) { 00447 switch (header.imageInfo.channel[0].designator1) { 00448 case 50: dpx->depth = 3; break; 00449 case 51: dpx->depth = 4; break; 00450 case 52: dpx->depth = 4; break; 00451 default: break; 00452 } 00453 } 00454 /* dpx->bitsPerPixel = 10; */ 00455 dpx->bitsPerPixel = header.imageInfo.channel[0].bits_per_pixel; 00456 if (dpx->bitsPerPixel != 10) { 00457 if (verbose) d_printf("Don't support depth: %d\n", dpx->bitsPerPixel); 00458 dpxClose(dpx); 00459 return 0; 00460 } 00461 00462 dpx->imageOffset = ntohl(header.fileInfo.offset); 00463 dpx->lineBufferLength = pixelsToLongs(dpx->width * dpx->depth); 00464 dpx->lineBuffer = malloc(dpx->lineBufferLength * 4); 00465 if (dpx->lineBuffer == 0) { 00466 if (verbose) d_printf("Couldn't malloc line buffer of size %d\n", dpx->lineBufferLength * 4); 00467 dpxClose(dpx); 00468 return 0; 00469 } 00470 00471 /* could have 2 pixels left over */ 00472 dpx->pixelBuffer = malloc((dpx->lineBufferLength * 3 + 2) * sizeof(unsigned short)); 00473 if (dpx->pixelBuffer == 0) { 00474 if (verbose) d_printf("Couldn't malloc pixel buffer of size %d\n", 00475 (dpx->width * dpx->depth + 2 + 2) * (int)sizeof(unsigned short)); 00476 dpxClose(dpx); 00477 return 0; 00478 } 00479 dpx->pixelBufferUsed = 0; 00480 00481 if (logimage_fseek(dpx, dpx->imageOffset, SEEK_SET) != 0) { 00482 if (verbose) d_printf("Couldn't seek to image data start at %d\n", dpx->imageOffset); 00483 dpxClose(dpx); 00484 return 0; 00485 } 00486 dpx->fileYPos = 0; 00487 00488 logImageGetByteConversionDefaults(&dpx->params); 00489 /* The SMPTE define this code: 00490 * 0 - User-defined 00491 * 1 - Printing density 00492 * 2 - Linear 00493 * 3 - Logarithmic 00494 * 4 - Unspecified video 00495 * 5 - SMPTE 240M 00496 * 6 - CCIR 709-1 00497 * 7 - CCIR 601-2 system B or G 00498 * 8 - CCIR 601-2 system M 00499 * 9 - NTSC composite video 00500 * 10 - PAL composite video 00501 * 11 - Z linear 00502 * 12 - homogeneous 00503 * 00504 * Note that transfer_characteristics is U8, don't need 00505 * check the byte order. 00506 */ 00507 00508 switch (header.imageInfo.channel[0].transfer_characteristics) { 00509 case 1: 00510 case 2: /* linear */ 00511 dpx->params.doLogarithm= 0; 00512 break; 00513 00514 case 3: 00515 dpx->params.doLogarithm= 1; 00516 break; 00517 00518 /* TODO - Unsupported, but for now just load them, 00519 * colors may look wrong, but can solve color conversion later 00520 */ 00521 case 4: 00522 case 5: 00523 case 6: 00524 case 7: 00525 case 8: 00526 case 9: 00527 case 10: 00528 case 11: 00529 case 12: 00530 if (verbose) d_printf("Un-supported Transfer Characteristics: %d using linear color conversion\n", header.imageInfo.channel[0].transfer_characteristics); 00531 dpx->params.doLogarithm= 0; 00532 break; 00533 default: 00534 if (verbose) d_printf("Un-supported Transfer Characteristics: %d\n", header.imageInfo.channel[0].transfer_characteristics); 00535 dpxClose(dpx); 00536 return 0; 00537 break; 00538 } 00539 setupLut(dpx); 00540 00541 dpx->getRow = &dpxGetRowBytes; 00542 dpx->setRow = 0; 00543 dpx->close = &dpxClose; 00544 00545 if (verbose) { 00546 verboseMe(dpx); 00547 } 00548 00549 return dpx; 00550 } 00551 00552 DpxFile* 00553 dpxOpen(const char *filename) { 00554 return intern_dpxOpen(LFREALFILE, filename, 0); 00555 } 00556 00557 DpxFile* 00558 dpxOpenFromMem(unsigned char *buffer, unsigned int size) { 00559 return intern_dpxOpen(LFMEMFILE, (const char *) buffer, size); 00560 } 00561 00562 int 00563 dpxIsMemFileCineon(void *buffer) { 00564 int magicnum = 0; 00565 magicnum = *((int*)buffer); 00566 if (magicnum == ntohl(DPX_FILE_MAGIC)) return 1; 00567 else return 0; 00568 } 00569 00570 DpxFile* 00571 dpxCreate(const char* filename, int width, int height, int depth) { 00572 00573 /* Note: always write files in network order */ 00574 /* By the spec, it shouldn't matter, but ... */ 00575 00576 DpxMainHeader header; 00577 const char* shortFilename = 0; 00578 00579 DpxFile* dpx = (DpxFile*)malloc(sizeof(DpxFile)); 00580 if (dpx == 0) { 00581 if (verbose) d_printf("Failed to malloc dpx file structure.\n"); 00582 return 0; 00583 } 00584 00585 memset(&header, 0, sizeof(header)); 00586 00587 /* for close routine */ 00588 dpx->file = 0; 00589 dpx->lineBuffer = 0; 00590 dpx->pixelBuffer = 0; 00591 00592 dpx->file = fopen(filename, "wb"); 00593 if (dpx->file == 0) { 00594 if (verbose) d_printf("Couldn't open file %s\n", filename); 00595 dpxClose(dpx); 00596 return 0; 00597 } 00598 dpx->reading = 0; 00599 00600 dpx->width = width; 00601 dpx->height = height; 00602 dpx->depth = depth; 00603 dpx->bitsPerPixel = 10; 00604 dpx->imageOffset = sizeof(DpxMainHeader); 00605 00606 dpx->lineBufferLength = pixelsToLongs(dpx->width * dpx->depth); 00607 dpx->lineBuffer = malloc(dpx->lineBufferLength * 4); 00608 if (dpx->lineBuffer == 0) { 00609 if (verbose) d_printf("Couldn't malloc line buffer of size %d\n", dpx->lineBufferLength * 4); 00610 dpxClose(dpx); 00611 return 0; 00612 } 00613 00614 dpx->pixelBuffer = malloc((dpx->lineBufferLength * 3 + 2) * sizeof(unsigned short)); 00615 if (dpx->pixelBuffer == 0) { 00616 if (verbose) d_printf("Couldn't malloc pixel buffer of size %d\n", 00617 (dpx->width * dpx->depth + 2 + 2) * (int)sizeof(unsigned short)); 00618 dpxClose(dpx); 00619 return 0; 00620 } 00621 dpx->pixelBufferUsed = 0; 00622 00623 /* find trailing part of filename */ 00624 shortFilename = strrchr(filename, '/'); 00625 if (shortFilename == 0) { 00626 shortFilename = filename; 00627 } else { 00628 ++shortFilename; 00629 } 00630 initDpxMainHeader(dpx, &header, shortFilename); 00631 logImageGetByteConversionDefaults(&dpx->params); 00632 /* Need set the file type before write the header! 00633 * 2 - Linear 00634 * 3 - Logarithmic 00635 * 00636 * Note that transfer characteristics is U8, don't need 00637 * check the byte order. 00638 */ 00639 if (dpx->params.doLogarithm == 0) 00640 header.imageInfo.channel[0].transfer_characteristics= 2; 00641 else 00642 header.imageInfo.channel[0].transfer_characteristics= 3; 00643 00644 if (fwrite(&header, sizeof(header), 1, dpx->file) == 0) { 00645 if (verbose) d_printf("Couldn't write image header\n"); 00646 dpxClose(dpx); 00647 return 0; 00648 } 00649 dpx->fileYPos = 0; 00650 setupLut(dpx); 00651 00652 dpx->getRow = 0; 00653 dpx->setRow = &dpxSetRowBytes; 00654 dpx->close = &dpxClose; 00655 00656 return dpx; 00657 } 00658 00659 void 00660 dpxClose(DpxFile* dpx) { 00661 00662 if (dpx == 0) { 00663 return; 00664 } 00665 00666 if (dpx->file) { 00667 fclose(dpx->file); 00668 dpx->file = 0; 00669 } 00670 00671 if (dpx->lineBuffer) { 00672 free(dpx->lineBuffer); 00673 dpx->lineBuffer = 0; 00674 } 00675 00676 if (dpx->pixelBuffer) { 00677 free(dpx->pixelBuffer); 00678 dpx->pixelBuffer = 0; 00679 } 00680 00681 free(dpx); 00682 } 00683 00684 void 00685 dpxDump(const char* filename) { 00686 00687 DpxMainHeader header; 00688 FILE* file; 00689 00690 file = fopen(filename, "rb"); 00691 if (file == 0) { 00692 d_printf("Failed to open file \"%s\".\n", filename); 00693 return; 00694 } 00695 00696 if (fread(&header, sizeof(header), 1, file) == 0) { 00697 d_printf("Not enough data for header in \"%s\".\n", filename); 00698 fclose(file); 00699 return; 00700 } 00701 00702 fclose(file); 00703 dumpDpxMainHeader(&header); 00704 }