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) * (int)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; }
static int imb_save_dpx_cineon(ImBuf *ibuf, const char *filename, int use_cineon, int flags) { LogImageByteConversionParameters conversion; const int width= ibuf->x; const int height= ibuf->y; const int depth= 3; LogImageFile* logImage; unsigned short* line, *pixel; int i, j; float *fline; float *fbuf; int is_alloc= 0; (void)flags; /* unused */ // cineon_conversion_parameters(&conversion); logImageGetByteConversionDefaults(&conversion); /* * Get the drawable for the current image... */ fbuf= IMB_float_profile_ensure(ibuf, conversion.doLogarithm ? IB_PROFILE_LINEAR_RGB : IB_PROFILE_NONE, &is_alloc); if (fbuf == NULL) { /* in the unlikely event that converting to a float buffer fails */ return 0; } logImageSetVerbose((G.f & G_DEBUG) ? 1:0); logImage = logImageCreate(filename, use_cineon, width, height, depth); if (!logImage) return 0; if(logImageSetByteConversion(logImage, &conversion)==0) { printf("error setting args\n"); } 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 = &fbuf[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.0f) fpix2[0] = 1.0f; else if (fpix2[0]<0.0f) fpix2[0]= 0.0f; if (fpix2[1]>=1.0f) fpix2[1] = 1.0f; else if (fpix2[1]<0.0f) fpix2[1]= 0.0f; if (fpix2[2]>=1.0f) fpix2[2] = 1.0f; else if (fpix2[2]<0.0f) fpix2[2]= 0.0f; 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); if(is_alloc) { MEM_freeN(fbuf); } 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 = 0; 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", (uintptr_t)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) * (int)sizeof(unsigned short)); cineonClose(cineon); return 0; } cineon->pixelBufferUsed = 0; i = cineon->imageOffset; 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; }