IMB_metadata improvements
- Metadata handling is now separate from `ImBuf *`, allowing it to be used with a generic `IDProperty *`. - Merged `IMB_metadata_add_field()` and `IMB_metadata_change_field()` into a more robust `IMB_metadata_set_field()`. This new function doesn't return any status (it now always succeeds, and the previously existing return value was never checked anyway). - Removed `IMB_metadata_del_field()` as it was never actually used anywhere. - Use `IMB_metadata_ensure()` instead of having `IMB_metadata_set_field()` create the containing `IDProperty` for you. - Deduplicated function declarations, moved `intern/IMB_metadata.h` out of `intern/`. Note that this does mean that we have some extra `#include "IMB_metadata.h"` lines now, as the metadata functions are no longer declared in `IMB_imbuf.h`. - Deduplicated function declarations, all metadata-related declarations are now in imbuf/IMB_metadata.h. Part of: https://developer.blender.org/D2273 Reviewed by: @campbellbarton
This commit is contained in:
parent
f0f6c96a92
commit
b0a767b85b
|
@ -46,6 +46,7 @@
|
|||
#include "IMB_imbuf_types.h"
|
||||
#include "IMB_imbuf.h"
|
||||
#include "IMB_moviecache.h"
|
||||
#include "IMB_metadata.h"
|
||||
|
||||
#ifdef WITH_OPENEXR
|
||||
# include "intern/openexr/openexr_multi.h"
|
||||
|
@ -2172,27 +2173,31 @@ void BKE_stamp_data_free(struct StampData *stamp_data)
|
|||
}
|
||||
|
||||
/* wrap for callback only */
|
||||
static void metadata_change_field(void *data, const char *propname, char *propvalue, int UNUSED(len))
|
||||
static void metadata_set_field(void *data, const char *propname, char *propvalue, int UNUSED(len))
|
||||
{
|
||||
IMB_metadata_change_field(data, propname, propvalue);
|
||||
/* We know it is an ImBuf* because that's what we pass to BKE_stamp_info_callback. */
|
||||
struct ImBuf *imbuf = data;
|
||||
IMB_metadata_set_field(imbuf->metadata, propname, propvalue);
|
||||
}
|
||||
|
||||
static void metadata_get_field(void *data, const char *propname, char *propvalue, int len)
|
||||
{
|
||||
IMB_metadata_get_field(data, propname, propvalue, len);
|
||||
/* We know it is an ImBuf* because that's what we pass to BKE_stamp_info_callback. */
|
||||
struct ImBuf *imbuf = data;
|
||||
IMB_metadata_get_field(imbuf->metadata, propname, propvalue, len);
|
||||
}
|
||||
|
||||
void BKE_imbuf_stamp_info(RenderResult *rr, struct ImBuf *ibuf)
|
||||
{
|
||||
struct StampData *stamp_data = rr->stamp_data;
|
||||
|
||||
BKE_stamp_info_callback(ibuf, stamp_data, metadata_change_field, false);
|
||||
IMB_metadata_ensure(&ibuf->metadata);
|
||||
BKE_stamp_info_callback(ibuf, stamp_data, metadata_set_field, false);
|
||||
}
|
||||
|
||||
void BKE_stamp_info_from_imbuf(RenderResult *rr, struct ImBuf *ibuf)
|
||||
{
|
||||
struct StampData *stamp_data = rr->stamp_data;
|
||||
|
||||
IMB_metadata_ensure(&ibuf->metadata);
|
||||
BKE_stamp_info_callback(ibuf, stamp_data, metadata_get_field, true);
|
||||
}
|
||||
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
#include "IMB_imbuf_types.h"
|
||||
#include "IMB_imbuf.h"
|
||||
#include "IMB_colormanagement.h"
|
||||
#include "IMB_metadata.h"
|
||||
|
||||
#include "BLI_math_color_blend.h"
|
||||
|
||||
|
|
|
@ -84,6 +84,7 @@
|
|||
#include "IMB_imbuf.h"
|
||||
#include "IMB_imbuf_types.h"
|
||||
#include "IMB_colormanagement.h"
|
||||
#include "IMB_metadata.h"
|
||||
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_sound.h"
|
||||
|
|
|
@ -63,6 +63,7 @@
|
|||
|
||||
#include "IMB_imbuf.h"
|
||||
#include "IMB_imbuf_types.h"
|
||||
#include "IMB_metadata.h"
|
||||
|
||||
#include "UI_interface.h"
|
||||
#include "UI_interface_icons.h"
|
||||
|
@ -2138,7 +2139,7 @@ static const char *meta_data_list[] =
|
|||
|
||||
BLI_INLINE bool metadata_is_valid(ImBuf *ibuf, char *r_str, short index, int offset)
|
||||
{
|
||||
return (IMB_metadata_get_field(ibuf, meta_data_list[index], r_str + offset, MAX_METADATA_STR - offset) && r_str[0]);
|
||||
return (IMB_metadata_get_field(ibuf->metadata, meta_data_list[index], r_str + offset, MAX_METADATA_STR - offset) && r_str[0]);
|
||||
}
|
||||
|
||||
static void metadata_draw_imbuf(ImBuf *ibuf, const rctf *rect, int fontid, const bool is_top)
|
||||
|
|
|
@ -73,6 +73,7 @@ set(SRC
|
|||
IMB_colormanagement.h
|
||||
IMB_imbuf.h
|
||||
IMB_imbuf_types.h
|
||||
IMB_metadata.h
|
||||
IMB_moviecache.h
|
||||
IMB_thumbs.h
|
||||
intern/IMB_allocimbuf.h
|
||||
|
@ -81,7 +82,6 @@ set(SRC
|
|||
intern/IMB_filetype.h
|
||||
intern/IMB_filter.h
|
||||
intern/IMB_indexer.h
|
||||
intern/IMB_metadata.h
|
||||
intern/imbuf.h
|
||||
|
||||
# orphan include
|
||||
|
|
|
@ -566,22 +566,6 @@ void buf_rectfill_area(unsigned char *rect, float *rectf, int width, int height,
|
|||
const float col[4], struct ColorManagedDisplay *display,
|
||||
int x1, int y1, int x2, int y2);
|
||||
|
||||
/**
|
||||
*
|
||||
* \attention Defined in metadata.c
|
||||
*/
|
||||
/** read the field from the image info into the field
|
||||
* \param img - the ImBuf that contains the image data
|
||||
* \param key - the key of the field
|
||||
* \param value - the data in the field, first one found with key is returned,
|
||||
* memory has to be allocated by user.
|
||||
* \param len - length of value buffer allocated by user.
|
||||
* \return - 1 (true) if ImageInfo present and value for the key found, 0 (false) otherwise
|
||||
*/
|
||||
bool IMB_metadata_get_field(struct ImBuf *img, const char *key, char *value, const size_t len);
|
||||
bool IMB_metadata_change_field(struct ImBuf *img, const char *key, const char *field);
|
||||
void IMB_metadata_copy(struct ImBuf *dimb, struct ImBuf *simb);
|
||||
|
||||
/* exported for image tools in blender, to quickly allocate 32 bits rect */
|
||||
void *imb_alloc_pixels(unsigned int x,
|
||||
unsigned int y,
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
|
@ -33,7 +33,9 @@
|
|||
#ifndef __IMB_METADATA_H__
|
||||
#define __IMB_METADATA_H__
|
||||
|
||||
struct anim;
|
||||
struct ImBuf;
|
||||
struct IDProperty;
|
||||
|
||||
/** The metadata is a list of key/value pairs (both char *) that can me
|
||||
* saved in the header of several image formats.
|
||||
|
@ -41,26 +43,35 @@ struct ImBuf;
|
|||
* 'Software' and 'Description' (png standard) we'll use keys within the
|
||||
* Blender namespace, so should be called 'Blender::StampInfo' or 'Blender::FrameNum'
|
||||
* etc...
|
||||
*
|
||||
* The keys & values are stored in ID properties, in the group "metadata".
|
||||
*/
|
||||
|
||||
/** Ensure that the metadata property is a valid IDProperty object.
|
||||
* This is a no-op when *metadata != NULL.
|
||||
*/
|
||||
void IMB_metadata_ensure(struct IDProperty **metadata);
|
||||
void IMB_metadata_free(struct IDProperty *metadata);
|
||||
|
||||
/* free blender ImMetaData struct */
|
||||
void IMB_metadata_free(struct ImBuf *img);
|
||||
/** Read the field from the image info into the field.
|
||||
* \param metadata - the IDProperty that contains the metadata
|
||||
* \param key - the key of the field
|
||||
* \param value - the data in the field, first one found with key is returned,
|
||||
* memory has to be allocated by user.
|
||||
* \param len - length of value buffer allocated by user.
|
||||
* \return - 1 (true) if metadata is present and value for the key found, 0 (false) otherwise
|
||||
*/
|
||||
bool IMB_metadata_get_field(struct IDProperty *metadata, const char *key, char *value, const size_t len);
|
||||
|
||||
/** set user data in the ImMetaData struct, which has to be allocated with IMB_metadata_create
|
||||
* before calling this function.
|
||||
* \param img - the ImBuf that contains the image data
|
||||
/** Set user data in the metadata.
|
||||
* If the field already exists its value is overwritten, otherwise the field
|
||||
* will be added with the given value.
|
||||
* \param metadata - the IDProperty that contains the metadata
|
||||
* \param key - the key of the field
|
||||
* \param value - the data to be written to the field. zero terminated string
|
||||
* \return - 1 (true) if ImageInfo present, 0 (false) otherwise
|
||||
*/
|
||||
bool IMB_metadata_add_field(struct ImBuf *img, const char *key, const char *value);
|
||||
void IMB_metadata_set_field(struct IDProperty *metadata, const char *key, const char *value);
|
||||
|
||||
/** delete the key/field par in the ImMetaData struct.
|
||||
* \param img - the ImBuf that contains the image data
|
||||
* \param key - the key of the field
|
||||
* \return - 1 (true) if delete the key/field, 0 (false) otherwise
|
||||
*/
|
||||
bool IMB_metadata_del_field(struct ImBuf *img, const char *key);
|
||||
void IMB_metadata_copy(struct ImBuf *dimb, struct ImBuf *simb);
|
||||
|
||||
#endif /* __IMB_METADATA_H__ */
|
|
@ -219,7 +219,7 @@ void IMB_freeImBuf(ImBuf *ibuf)
|
|||
IMB_freezbufImBuf(ibuf);
|
||||
IMB_freezbuffloatImBuf(ibuf);
|
||||
freeencodedbufferImBuf(ibuf);
|
||||
IMB_metadata_free(ibuf);
|
||||
IMB_metadata_free(ibuf->metadata);
|
||||
colormanage_cache_free(ibuf);
|
||||
|
||||
if (ibuf->dds_data.data != NULL) {
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
#include "IMB_filetype.h"
|
||||
#include "IMB_filter.h"
|
||||
#include "IMB_moviecache.h"
|
||||
#include "IMB_metadata.h"
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
|
|
|
@ -382,7 +382,8 @@ static ImBuf *ibJpegImageFromCinfo(struct jpeg_decompress_struct *cinfo, int fla
|
|||
* the information when we write
|
||||
* it back to disk.
|
||||
*/
|
||||
IMB_metadata_add_field(ibuf, "None", str);
|
||||
IMB_metadata_ensure(&ibuf->metadata);
|
||||
IMB_metadata_set_field(ibuf->metadata, "None", str);
|
||||
ibuf->flags |= IB_metadata;
|
||||
MEM_freeN(str);
|
||||
goto next_stamp_marker;
|
||||
|
@ -408,7 +409,8 @@ static ImBuf *ibJpegImageFromCinfo(struct jpeg_decompress_struct *cinfo, int fla
|
|||
|
||||
*value = '\0'; /* need finish the key string */
|
||||
value++;
|
||||
IMB_metadata_add_field(ibuf, key, value);
|
||||
IMB_metadata_ensure(&ibuf->metadata);
|
||||
IMB_metadata_set_field(ibuf->metadata, key, value);
|
||||
ibuf->flags |= IB_metadata;
|
||||
MEM_freeN(str);
|
||||
next_stamp_marker:
|
||||
|
|
|
@ -45,97 +45,69 @@
|
|||
|
||||
#include "IMB_metadata.h"
|
||||
|
||||
#define METADATA_MAX_VALUE_LENGTH 1024
|
||||
|
||||
|
||||
void IMB_metadata_free(struct ImBuf *img)
|
||||
void IMB_metadata_ensure(struct IDProperty **metadata)
|
||||
{
|
||||
if (!img)
|
||||
return;
|
||||
if (!img->metadata) {
|
||||
if (*metadata != NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
IDP_FreeProperty(img->metadata);
|
||||
MEM_freeN(img->metadata);
|
||||
IDPropertyTemplate val;
|
||||
*metadata = IDP_New(IDP_GROUP, &val, "metadata");
|
||||
}
|
||||
|
||||
bool IMB_metadata_get_field(struct ImBuf *img, const char *key, char *field, const size_t len)
|
||||
void IMB_metadata_free(struct IDProperty *metadata)
|
||||
{
|
||||
if (metadata == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
IDP_FreeProperty(metadata);
|
||||
MEM_freeN(metadata);
|
||||
}
|
||||
|
||||
bool IMB_metadata_get_field(struct IDProperty *metadata, const char *key, char *field, const size_t len)
|
||||
{
|
||||
IDProperty *prop;
|
||||
|
||||
bool retval = false;
|
||||
|
||||
if (!img)
|
||||
return false;
|
||||
if (!img->metadata)
|
||||
if (metadata == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
prop = IDP_GetPropertyFromGroup(img->metadata, key);
|
||||
prop = IDP_GetPropertyFromGroup(metadata, key);
|
||||
|
||||
if (prop && prop->type == IDP_STRING) {
|
||||
BLI_strncpy(field, IDP_String(prop), len);
|
||||
retval = true;
|
||||
return true;
|
||||
}
|
||||
return retval;
|
||||
return false;
|
||||
}
|
||||
|
||||
void IMB_metadata_copy(struct ImBuf *dimb, struct ImBuf *simb)
|
||||
{
|
||||
BLI_assert(dimb != simb);
|
||||
if (simb->metadata) {
|
||||
IMB_metadata_free(dimb);
|
||||
IMB_metadata_free(dimb->metadata);
|
||||
dimb->metadata = IDP_CopyProperty(simb->metadata);
|
||||
}
|
||||
}
|
||||
|
||||
bool IMB_metadata_add_field(struct ImBuf *img, const char *key, const char *value)
|
||||
void IMB_metadata_set_field(struct IDProperty *metadata, const char *key, const char *value)
|
||||
{
|
||||
IDProperty *prop;
|
||||
BLI_assert(metadata);
|
||||
IDProperty *prop = IDP_GetPropertyFromGroup(metadata, key);
|
||||
|
||||
if (!img)
|
||||
return false;
|
||||
|
||||
if (!img->metadata) {
|
||||
IDPropertyTemplate val;
|
||||
img->metadata = IDP_New(IDP_GROUP, &val, "metadata");
|
||||
if (prop != NULL && prop->type != IDP_STRING) {
|
||||
IDP_FreeFromGroup(metadata, prop);
|
||||
prop = NULL;
|
||||
}
|
||||
|
||||
prop = IDP_NewString(value, key, 512);
|
||||
return IDP_AddToGroup(img->metadata, prop);
|
||||
}
|
||||
|
||||
bool IMB_metadata_del_field(struct ImBuf *img, const char *key)
|
||||
{
|
||||
IDProperty *prop;
|
||||
|
||||
if ((!img) || (!img->metadata))
|
||||
return false;
|
||||
|
||||
prop = IDP_GetPropertyFromGroup(img->metadata, key);
|
||||
|
||||
if (prop) {
|
||||
IDP_FreeFromGroup(img->metadata, prop);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IMB_metadata_change_field(struct ImBuf *img, const char *key, const char *field)
|
||||
{
|
||||
IDProperty *prop;
|
||||
|
||||
if (!img)
|
||||
return false;
|
||||
|
||||
prop = (img->metadata) ? IDP_GetPropertyFromGroup(img->metadata, key) : NULL;
|
||||
|
||||
if (!prop) {
|
||||
return (IMB_metadata_add_field(img, key, field));
|
||||
}
|
||||
else if (prop->type == IDP_STRING) {
|
||||
IDP_AssignString(prop, field, 1024);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
if (prop == NULL) {
|
||||
prop = IDP_NewString(value, key, METADATA_MAX_VALUE_LENGTH);
|
||||
IDP_AddToGroup(metadata, prop);
|
||||
}
|
||||
|
||||
IDP_AssignString(prop, value, METADATA_MAX_VALUE_LENGTH);
|
||||
}
|
||||
|
|
|
@ -1790,12 +1790,13 @@ struct ImBuf *imb_load_openexr(const unsigned char *mem, size_t size, int flags,
|
|||
const Header & header = file->header(0);
|
||||
Header::ConstIterator iter;
|
||||
|
||||
IMB_metadata_ensure(&ibuf->metadata);
|
||||
for (iter = header.begin(); iter != header.end(); iter++) {
|
||||
const StringAttribute *attrib = file->header(0).findTypedAttribute <StringAttribute> (iter.name());
|
||||
|
||||
/* not all attributes are string attributes so we might get some NULLs here */
|
||||
if (attrib) {
|
||||
IMB_metadata_add_field(ibuf, iter.name(), attrib->value().c_str());
|
||||
IMB_metadata_set_field(ibuf->metadata, iter.name(), attrib->value().c_str());
|
||||
ibuf->flags |= IB_metadata;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -759,8 +759,9 @@ ImBuf *imb_loadpng(const unsigned char *mem, size_t size, int flags, char colors
|
|||
if (flags & IB_metadata) {
|
||||
png_text *text_chunks;
|
||||
int count = png_get_text(png_ptr, info_ptr, &text_chunks, NULL);
|
||||
IMB_metadata_ensure(&ibuf->metadata);
|
||||
for (int i = 0; i < count; i++) {
|
||||
IMB_metadata_add_field(ibuf, text_chunks[i].key, text_chunks[i].text);
|
||||
IMB_metadata_set_field(ibuf->metadata, text_chunks[i].key, text_chunks[i].text);
|
||||
ibuf->flags |= IB_metadata;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -430,16 +430,17 @@ static ImBuf *thumb_create_ex(
|
|||
IMB_scaleImBuf(img, ex, ey);
|
||||
}
|
||||
BLI_snprintf(desc, sizeof(desc), "Thumbnail for %s", uri);
|
||||
IMB_metadata_change_field(img, "Description", desc);
|
||||
IMB_metadata_change_field(img, "Software", "Blender");
|
||||
IMB_metadata_change_field(img, "Thumb::URI", uri);
|
||||
IMB_metadata_change_field(img, "Thumb::MTime", mtime);
|
||||
IMB_metadata_ensure(&img->metadata);
|
||||
IMB_metadata_set_field(img->metadata, "Software", "Blender");
|
||||
IMB_metadata_set_field(img->metadata, "Thumb::URI", uri);
|
||||
IMB_metadata_set_field(img->metadata, "Description", desc);
|
||||
IMB_metadata_set_field(img->metadata, "Thumb::MTime", mtime);
|
||||
if (use_hash) {
|
||||
IMB_metadata_change_field(img, "X-Blender::Hash", hash);
|
||||
IMB_metadata_set_field(img->metadata, "X-Blender::Hash", hash);
|
||||
}
|
||||
if (ELEM(source, THB_SOURCE_IMAGE, THB_SOURCE_BLEND, THB_SOURCE_FONT)) {
|
||||
IMB_metadata_change_field(img, "Thumb::Image::Width", cwidth);
|
||||
IMB_metadata_change_field(img, "Thumb::Image::Height", cheight);
|
||||
IMB_metadata_set_field(img->metadata, "Thumb::Image::Width", cwidth);
|
||||
IMB_metadata_set_field(img->metadata, "Thumb::Image::Height", cheight);
|
||||
}
|
||||
img->ftype = IMB_FTYPE_PNG;
|
||||
img->planes = 32;
|
||||
|
@ -589,7 +590,7 @@ ImBuf *IMB_thumb_manage(const char *org_path, ThumbSize size, ThumbSource source
|
|||
|
||||
const bool use_hash = thumbhash_from_path(file_path, source, thumb_hash);
|
||||
|
||||
if (IMB_metadata_get_field(img, "Thumb::MTime", mtime, sizeof(mtime))) {
|
||||
if (IMB_metadata_get_field(img->metadata, "Thumb::MTime", mtime, sizeof(mtime))) {
|
||||
regenerate = (st.st_mtime != atol(mtime));
|
||||
}
|
||||
else {
|
||||
|
@ -598,7 +599,7 @@ ImBuf *IMB_thumb_manage(const char *org_path, ThumbSize size, ThumbSource source
|
|||
}
|
||||
|
||||
if (use_hash && !regenerate) {
|
||||
if (IMB_metadata_get_field(img, "X-Blender::Hash", thumb_hash_curr, sizeof(thumb_hash_curr))) {
|
||||
if (IMB_metadata_get_field(img->metadata, "X-Blender::Hash", thumb_hash_curr, sizeof(thumb_hash_curr))) {
|
||||
regenerate = !STREQ(thumb_hash, thumb_hash_curr);
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -84,6 +84,7 @@
|
|||
#include "IMB_colormanagement.h"
|
||||
#include "IMB_imbuf.h"
|
||||
#include "IMB_imbuf_types.h"
|
||||
#include "IMB_metadata.h"
|
||||
|
||||
#include "RE_engine.h"
|
||||
#include "RE_pipeline.h"
|
||||
|
|
Loading…
Reference in New Issue