forked from bartvdbraak/blender
Images: support packing edited images as OpenEXR or PNG.
This way float and multilayer images can now be packed without data loss. This removes the as_png option and always uses the appropriate file format depending on the image contents.
This commit is contained in:
parent
690ed63eb5
commit
64bcdd65bf
@ -132,7 +132,7 @@ class SaveDirty(Operator):
|
||||
" can't be re-packed" %
|
||||
(image.name, image.library.filepath))
|
||||
else:
|
||||
image.pack(as_png=True)
|
||||
image.pack()
|
||||
else:
|
||||
filepath = bpy.path.abspath(image.filepath,
|
||||
library=image.library)
|
||||
|
@ -228,18 +228,12 @@ class IMAGE_MT_image(Menu):
|
||||
layout.menu("IMAGE_MT_image_invert")
|
||||
|
||||
if not show_render:
|
||||
if not ima.packed_file:
|
||||
layout.separator()
|
||||
layout.separator()
|
||||
if ima.packed_file:
|
||||
layout.operator("image.pack", text="Repack")
|
||||
else:
|
||||
layout.operator("image.pack", text="Pack")
|
||||
|
||||
# Only for dirty && specific image types, perhaps
|
||||
# this could be done in operator poll too.
|
||||
if ima.is_dirty:
|
||||
if ima.source in {'FILE', 'GENERATED'} and ima.type != 'OPEN_EXR_MULTILAYER':
|
||||
if ima.packed_file:
|
||||
layout.separator()
|
||||
layout.operator("image.pack", text="Pack As PNG").as_png = True
|
||||
|
||||
|
||||
class IMAGE_MT_image_invert(Menu):
|
||||
bl_label = "Invert"
|
||||
|
@ -720,11 +720,10 @@ Image *BKE_image_add_from_imbuf(Main *bmain, ImBuf *ibuf, const char *name)
|
||||
return ima;
|
||||
}
|
||||
|
||||
/* Pack image buffer to memory as PNG. */
|
||||
/* Pack image buffer to memory as PNG or EXR. */
|
||||
static bool image_memorypack_imbuf(Image *ima, ImBuf *ibuf, const char *filepath)
|
||||
{
|
||||
ibuf->ftype = IMB_FTYPE_PNG;
|
||||
ibuf->planes = R_IMF_PLANES_RGBA;
|
||||
ibuf->ftype = (ibuf->rect_float) ? IMB_FTYPE_OPENEXR : IMB_FTYPE_PNG;
|
||||
|
||||
IMB_saveiff(ibuf, filepath, IB_rect | IB_mem);
|
||||
|
||||
|
@ -2569,14 +2569,10 @@ void IMAGE_OT_invert(wmOperatorType *ot)
|
||||
static bool image_pack_test(bContext *C, wmOperator *op)
|
||||
{
|
||||
Image *ima = CTX_data_edit_image(C);
|
||||
const bool as_png = RNA_boolean_get(op->ptr, "as_png");
|
||||
|
||||
if (!ima) {
|
||||
return 0;
|
||||
}
|
||||
if (!as_png && BKE_image_has_packedfile(ima)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ima->source == IMA_SRC_SEQUENCE || ima->source == IMA_SRC_MOVIE) {
|
||||
BKE_report(op->reports, RPT_ERROR, "Packing movies or image sequences not supported");
|
||||
@ -2590,19 +2586,12 @@ static int image_pack_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
struct Main *bmain = CTX_data_main(C);
|
||||
Image *ima = CTX_data_edit_image(C);
|
||||
ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
|
||||
const bool as_png = RNA_boolean_get(op->ptr, "as_png");
|
||||
|
||||
if (!image_pack_test(C, op)) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
if (!as_png && (ibuf && (ibuf->userflags & IB_BITMAPDIRTY))) {
|
||||
BKE_report(op->reports, RPT_ERROR, "Cannot pack edited image from disk, only as internal PNG");
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
if (as_png) {
|
||||
if (BKE_image_is_dirty(ima)) {
|
||||
BKE_image_memorypack(ima);
|
||||
}
|
||||
else {
|
||||
@ -2611,46 +2600,9 @@ static int image_pack_exec(bContext *C, wmOperator *op)
|
||||
|
||||
WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, ima);
|
||||
|
||||
BKE_image_release_ibuf(ima, ibuf, NULL);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
static int image_pack_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
|
||||
{
|
||||
Image *ima = CTX_data_edit_image(C);
|
||||
ImBuf *ibuf;
|
||||
uiPopupMenu *pup;
|
||||
uiLayout *layout;
|
||||
const bool as_png = RNA_boolean_get(op->ptr, "as_png");
|
||||
|
||||
if (!image_pack_test(C, op)) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
|
||||
|
||||
if (!as_png && (ibuf && (ibuf->userflags & IB_BITMAPDIRTY))) {
|
||||
pup = UI_popup_menu_begin(C, IFACE_("OK"), ICON_QUESTION);
|
||||
layout = UI_popup_menu_layout(pup);
|
||||
uiItemBooleanO(layout,
|
||||
IFACE_("Can't pack edited image from disk, pack as internal PNG?"),
|
||||
ICON_NONE,
|
||||
op->idname,
|
||||
"as_png",
|
||||
1);
|
||||
UI_popup_menu_end(C, pup);
|
||||
|
||||
BKE_image_release_ibuf(ima, ibuf, NULL);
|
||||
|
||||
return OPERATOR_INTERFACE;
|
||||
}
|
||||
|
||||
BKE_image_release_ibuf(ima, ibuf, NULL);
|
||||
|
||||
return image_pack_exec(C, op);
|
||||
}
|
||||
|
||||
void IMAGE_OT_pack(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
@ -2660,13 +2612,9 @@ void IMAGE_OT_pack(wmOperatorType *ot)
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec = image_pack_exec;
|
||||
ot->invoke = image_pack_invoke;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
||||
/* properties */
|
||||
RNA_def_boolean(ot->srna, "as_png", 0, "Pack As PNG", "Pack image as lossless PNG");
|
||||
}
|
||||
|
||||
/********************* unpack operator *********************/
|
||||
|
@ -146,35 +146,23 @@ static void rna_Image_save(Image *image, Main *bmain, bContext *C, ReportList *r
|
||||
WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, image);
|
||||
}
|
||||
|
||||
static void rna_Image_pack(Image *image,
|
||||
Main *bmain,
|
||||
bContext *C,
|
||||
ReportList *reports,
|
||||
bool as_png,
|
||||
const char *data,
|
||||
int data_len)
|
||||
static void rna_Image_pack(
|
||||
Image *image, Main *bmain, bContext *C, ReportList *reports, const char *data, int data_len)
|
||||
{
|
||||
ImBuf *ibuf = BKE_image_acquire_ibuf(image, NULL, NULL);
|
||||
BKE_image_free_packedfiles(image);
|
||||
|
||||
if (!as_png && (ibuf && (ibuf->userflags & IB_BITMAPDIRTY))) {
|
||||
BKE_report(reports, RPT_ERROR, "Cannot pack edited image from disk, only as internal PNG");
|
||||
if (data) {
|
||||
char *data_dup = MEM_mallocN(sizeof(*data_dup) * (size_t)data_len, __func__);
|
||||
memcpy(data_dup, data, (size_t)data_len);
|
||||
BKE_image_packfiles_from_mem(reports, image, data_dup, (size_t)data_len);
|
||||
}
|
||||
else if (BKE_image_is_dirty(image)) {
|
||||
BKE_image_memorypack(image);
|
||||
}
|
||||
else {
|
||||
BKE_image_free_packedfiles(image);
|
||||
if (as_png) {
|
||||
BKE_image_memorypack(image);
|
||||
}
|
||||
else if (data) {
|
||||
char *data_dup = MEM_mallocN(sizeof(*data_dup) * (size_t)data_len, __func__);
|
||||
memcpy(data_dup, data, (size_t)data_len);
|
||||
BKE_image_packfiles_from_mem(reports, image, data_dup, (size_t)data_len);
|
||||
}
|
||||
else {
|
||||
BKE_image_packfiles(reports, image, ID_BLEND_PATH(bmain, &image->id));
|
||||
}
|
||||
BKE_image_packfiles(reports, image, ID_BLEND_PATH(bmain, &image->id));
|
||||
}
|
||||
|
||||
BKE_image_release_ibuf(image, ibuf, NULL);
|
||||
WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, image);
|
||||
}
|
||||
|
||||
@ -339,8 +327,6 @@ void RNA_api_image(StructRNA *srna)
|
||||
func = RNA_def_function(srna, "pack", "rna_Image_pack");
|
||||
RNA_def_function_ui_description(func, "Pack an image as embedded data into the .blend file");
|
||||
RNA_def_function_flag(func, FUNC_USE_MAIN | FUNC_USE_CONTEXT | FUNC_USE_REPORTS);
|
||||
RNA_def_boolean(
|
||||
func, "as_png", 0, "as_png", "Pack the image as PNG (needed for generated/dirty images)");
|
||||
parm = RNA_def_property(func, "data", PROP_STRING, PROP_BYTESTRING);
|
||||
RNA_def_property_ui_text(parm, "data", "Raw data (bytes, exact content of the embedded file)");
|
||||
RNA_def_int(func,
|
||||
|
Loading…
Reference in New Issue
Block a user