static bool write_internal_bake_pixels( Image *image, BakePixel pixel_array[], float *buffer, const int width, const int height, const int margin, const bool is_clear, const bool is_noncolor) { ImBuf *ibuf; void *lock; bool is_float; char *mask_buffer = NULL; const size_t num_pixels = (size_t)width * (size_t)height; ibuf = BKE_image_acquire_ibuf(image, NULL, &lock); if (!ibuf) return false; if (margin > 0 || !is_clear) { mask_buffer = MEM_callocN(sizeof(char) * num_pixels, "Bake Mask"); RE_bake_mask_fill(pixel_array, num_pixels, mask_buffer); } is_float = (ibuf->flags & IB_rectfloat); /* colormanagement conversions */ if (!is_noncolor) { const char *from_colorspace; const char *to_colorspace; from_colorspace = IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_SCENE_LINEAR); if (is_float) to_colorspace = IMB_colormanagement_get_float_colorspace(ibuf); else to_colorspace = IMB_colormanagement_get_rect_colorspace(ibuf); if (from_colorspace != to_colorspace) IMB_colormanagement_transform(buffer, ibuf->x, ibuf->y, ibuf->channels, from_colorspace, to_colorspace, false); } /* populates the ImBuf */ if (is_clear) { if (is_float) { IMB_buffer_float_from_float( ibuf->rect_float, buffer, ibuf->channels, IB_PROFILE_LINEAR_RGB, IB_PROFILE_LINEAR_RGB, false, ibuf->x, ibuf->y, ibuf->x, ibuf->x); } else { IMB_buffer_byte_from_float( (unsigned char *) ibuf->rect, buffer, ibuf->channels, ibuf->dither, IB_PROFILE_SRGB, IB_PROFILE_SRGB, false, ibuf->x, ibuf->y, ibuf->x, ibuf->x); } } else { if (is_float) { IMB_buffer_float_from_float_mask( ibuf->rect_float, buffer, ibuf->channels, ibuf->x, ibuf->y, ibuf->x, ibuf->x, mask_buffer); } else { IMB_buffer_byte_from_float_mask( (unsigned char *) ibuf->rect, buffer, ibuf->channels, ibuf->dither, false, ibuf->x, ibuf->y, ibuf->x, ibuf->x, mask_buffer); } } /* margins */ if (margin > 0) RE_bake_margin(ibuf, mask_buffer, margin); ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID | IB_BITMAPDIRTY; if (ibuf->rect_float) ibuf->userflags |= IB_RECT_INVALID; /* force mipmap recalc */ if (ibuf->mipmap[0]) { ibuf->userflags |= IB_MIPMAP_INVALID; imb_freemipmapImBuf(ibuf); } BKE_image_release_ibuf(image, ibuf, NULL); if (mask_buffer) MEM_freeN(mask_buffer); return true; }
static bool write_external_bake_pixels( const char *filepath, BakePixel pixel_array[], float *buffer, const int width, const int height, const int margin, ImageFormatData *im_format, const bool is_noncolor) { ImBuf *ibuf = NULL; bool ok = false; bool is_float; is_float = im_format->depth > 8; /* create a new ImBuf */ ibuf = IMB_allocImBuf(width, height, im_format->planes, (is_float ? IB_rectfloat : IB_rect)); if (!ibuf) return false; /* populates the ImBuf */ if (is_float) { IMB_buffer_float_from_float( ibuf->rect_float, buffer, ibuf->channels, IB_PROFILE_LINEAR_RGB, IB_PROFILE_LINEAR_RGB, false, ibuf->x, ibuf->y, ibuf->x, ibuf->x); } else { if (!is_noncolor) { const char *from_colorspace = IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_SCENE_LINEAR); const char *to_colorspace = IMB_colormanagement_get_rect_colorspace(ibuf); IMB_colormanagement_transform(buffer, ibuf->x, ibuf->y, ibuf->channels, from_colorspace, to_colorspace, false); } IMB_buffer_byte_from_float( (unsigned char *) ibuf->rect, buffer, ibuf->channels, ibuf->dither, IB_PROFILE_SRGB, IB_PROFILE_SRGB, false, ibuf->x, ibuf->y, ibuf->x, ibuf->x); } /* margins */ if (margin > 0) { char *mask_buffer = NULL; const size_t num_pixels = (size_t)width * (size_t)height; mask_buffer = MEM_callocN(sizeof(char) * num_pixels, "Bake Mask"); RE_bake_mask_fill(pixel_array, num_pixels, mask_buffer); RE_bake_margin(ibuf, mask_buffer, margin); if (mask_buffer) MEM_freeN(mask_buffer); } if ((ok = BKE_imbuf_write(ibuf, filepath, im_format))) { #ifndef WIN32 chmod(filepath, S_IRUSR | S_IWUSR); #endif //printf("%s saving bake map: '%s'\n", __func__, filepath); } /* garbage collection */ IMB_freeImBuf(ibuf); return ok; }