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; }
static int imb_save_dpx_cineon(ImBuf *ibuf, const char *filename, int use_cineon, int flags) { LogImageFile *logImage; float *fbuf; float *fbuf_ptr; unsigned char *rect_ptr; int x, y, depth, bitspersample, rvalue; if (flags & IB_mem) { printf("DPX/Cineon: saving in memory is not supported.\n"); return 0; } logImageSetVerbose((G.f & G_DEBUG) ? 1 : 0); depth = (ibuf->planes + 7) >> 3; if (depth > 4 || depth < 3) { printf("DPX/Cineon: unsupported depth: %d for file: '%s'\n", depth, filename); return 0; } if (ibuf->ftype & CINEON_10BIT) bitspersample = 10; else if (ibuf->ftype & CINEON_12BIT) bitspersample = 12; else if (ibuf->ftype & CINEON_16BIT) bitspersample = 16; else bitspersample = 8; logImage = logImageCreate(filename, use_cineon, ibuf->x, ibuf->y, bitspersample, (depth == 4), (ibuf->ftype & CINEON_LOG), -1, -1, -1, "Blender"); if (logImage == NULL) { printf("DPX/Cineon: error creating file.\n"); return 0; } if (ibuf->rect_float != NULL && bitspersample != 8) { /* don't use the float buffer to save 8 bpp picture to prevent color banding * (there's no dithering algorithm behing the logImageSetDataRGBA function) */ fbuf = (float *)MEM_mallocN(ibuf->x * ibuf->y * 4 * sizeof(float), "fbuf in imb_save_dpx_cineon"); for (y = 0; y < ibuf->y; y++) { float *dst_ptr = fbuf + 4 * ((ibuf->y - y - 1) * ibuf->x); float *src_ptr = ibuf->rect_float + 4 * (y * ibuf->x); memcpy(dst_ptr, src_ptr, 4 * ibuf->x * sizeof(float)); } rvalue = (logImageSetDataRGBA(logImage, fbuf, 1) == 0); MEM_freeN(fbuf); } else { if (ibuf->rect == NULL) IMB_rect_from_float(ibuf); fbuf = (float *)MEM_mallocN(ibuf->x * ibuf->y * 4 * sizeof(float), "fbuf in imb_save_dpx_cineon"); if (fbuf == NULL) { printf("DPX/Cineon: error allocating memory.\n"); logImageClose(logImage); return 0; } for (y = 0; y < ibuf->y; y++) { for (x = 0; x < ibuf->x; x++) { fbuf_ptr = fbuf + 4 * ((ibuf->y - y - 1) * ibuf->x + x); rect_ptr = (unsigned char *)ibuf->rect + 4 * (y * ibuf->x + x); fbuf_ptr[0] = (float)rect_ptr[0] / 255.0f; fbuf_ptr[1] = (float)rect_ptr[1] / 255.0f; fbuf_ptr[2] = (float)rect_ptr[2] / 255.0f; fbuf_ptr[3] = (depth == 4) ? ((float)rect_ptr[3] / 255.0f) : 1.0f; } } rvalue = (logImageSetDataRGBA(logImage, fbuf, 0) == 0); MEM_freeN(fbuf); } logImageClose(logImage); return rvalue; }