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, *upix; int width, height, depth; float *frow; logImageSetVerbose((G.f & G_DEBUG) ? 1:0); 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); row = MEM_mallocN(sizeof(unsigned short)*width*depth, "row in cineon_dpx.c"); frow = ibuf->rect_float+width*height*4; for (y = 0; y < height; y++) { logImageGetRowBytes(image, row, y); /* checks image->params.doLogarithm and convert */ upix = row; frow -= width*4; for (x=0; x<width; x++) { *(frow++) = ((float)*(upix++)) / 65535.0f; *(frow++) = ((float)*(upix++)) / 65535.0f; *(frow++) = ((float)*(upix++)) / 65535.0f; *(frow++) = 1.0f; } frow -= width*4; } MEM_freeN(row); logImageClose(image); if (flags & IB_rect) { IMB_rect_from_float(ibuf); } return ibuf; }
static struct ImBuf *imb_load_dpx_cineon(unsigned char *mem, size_t size, int use_cineon, int flags, char colorspace[IM_MAX_SPACE]) { ImBuf *ibuf; LogImageFile *image; int width, height, depth; colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_FLOAT); logImageSetVerbose((G.f & G_DEBUG) ? 1 : 0); image = logImageOpenFromMemory(mem, size); if (image == 0) { printf("DPX/Cineon: error opening image.\n"); return 0; } logImageGetSize(image, &width, &height, &depth); if (width == 0 || height == 0) { logImageClose(image); return 0; } ibuf = IMB_allocImBuf(width, height, 32, IB_rectfloat | flags); if (ibuf == 0) { logImageClose(image); return 0; } if (logImageGetDataRGBA(image, ibuf->rect_float, 1) != 0) { /* Conversion not possible (probably because the format is unsupported) */ logImageClose(image); MEM_freeN(ibuf); return 0; } logImageClose(image); ibuf->ftype = use_cineon ? CINEON : DPX; IMB_flipy(ibuf); if (flags & IB_rect) IMB_rect_from_float(ibuf); if (flags & IB_alphamode_detect) ibuf->flags |= IB_alphamode_premul; return ibuf; }
static struct ImBuf *imb_load_dpx_cineon(unsigned char *mem, size_t size, int use_cineon, int flags, char colorspace[IM_MAX_SPACE]) { ImBuf *ibuf; LogImageFile *image; int width, height, depth; colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_FLOAT); logImageSetVerbose((G.f & G_DEBUG) ? 1 : 0); image = logImageOpenFromMemory(mem, size); if (image == NULL) { printf("DPX/Cineon: error opening image.\n"); return NULL; } logImageGetSize(image, &width, &height, &depth); ibuf = IMB_allocImBuf(width, height, 32, IB_rectfloat | flags); if (ibuf == NULL) { logImageClose(image); return NULL; } if (!(flags & IB_test)) { if (logImageGetDataRGBA(image, ibuf->rect_float, 1) != 0) { logImageClose(image); IMB_freeImBuf(ibuf); return NULL; } IMB_flipy(ibuf); } logImageClose(image); ibuf->ftype = use_cineon ? CINEON : DPX; if (flags & IB_alphamode_detect) ibuf->flags |= IB_alphamode_premul; return ibuf; }
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; }