Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDalai Felinto <dfelinto@gmail.com>2013-10-09 01:17:24 +0400
committerDalai Felinto <dfelinto@gmail.com>2013-10-09 01:17:24 +0400
commit4abb8fde95260e692b3cd5b5b2f8bcd1d1f3be3b (patch)
tree9c3d68aa7abd18ddfef5b3af643b8a7556903e18 /source/blender/imbuf/intern/readimage.c
parent590f58d45583f36522ffbcebd68b4a6c921bebeb (diff)
Photoshop PSD support
We now support the combined layer of Photoshop files (stored as layer 0 in the file). This way users can keep their files as multilayer PSD and Blender always handle them as flat images. For perfect alpha this requires an OpenImageIO update: https://github.com/OpenImageIO/oiio/commit/342cc2633ff590a3bb278481c61ae798c7148361 Photoshop sample files: https://github.com/OpenImageIO/oiio-images Brecht has some pending fixes to push for OIIO as well, so we may as well wait to update our libraries. What works: =========== * 8bit images (with or without alpha) * 16bits images (alpha discarded) * Photoshop files saved with 'Maximum Compatibility' * Cycles, Blender internal, BGE (and player) Known limitations (due to OIIO dependency): ========================= * Images with less than 4 channels show a wrong thumbnail (bug may be in OIIO) * Packed images are not supported * We do not write PSD files. Note: old Blenders have support for PSD via Quicktime library. But due to license issues this was discontinued. Many thanks for Brecht van Lommel for reviewing the patch, suggesting multiple improvements and to help solving the alpha issue.
Diffstat (limited to 'source/blender/imbuf/intern/readimage.c')
-rw-r--r--source/blender/imbuf/intern/readimage.c134
1 files changed, 86 insertions, 48 deletions
diff --git a/source/blender/imbuf/intern/readimage.c b/source/blender/imbuf/intern/readimage.c
index d73fa9a7ab7..6988687e4ed 100644
--- a/source/blender/imbuf/intern/readimage.c
+++ b/source/blender/imbuf/intern/readimage.c
@@ -56,6 +56,53 @@
#include "IMB_colormanagement.h"
#include "IMB_colormanagement_intern.h"
+static void imb_handle_alpha(ImBuf *ibuf, int flags, char colorspace[IM_MAX_SPACE], char effective_colorspace[IM_MAX_SPACE])
+{
+ int alpha_flags;
+
+ if (colorspace) {
+ if (ibuf->rect) {
+ /* byte buffer is never internally converted to some standard space,
+ * store pointer to it's color space descriptor instead
+ */
+ ibuf->rect_colorspace = colormanage_colorspace_get_named(effective_colorspace);
+ }
+
+ BLI_strncpy(colorspace, effective_colorspace, IM_MAX_SPACE);
+ }
+
+ if (flags & IB_alphamode_detect)
+ alpha_flags = ibuf->flags & IB_alphamode_premul;
+ else
+ alpha_flags = flags & IB_alphamode_premul;
+
+ if (flags & IB_ignore_alpha) {
+ IMB_rectfill_alpha(ibuf, 1.0f);
+ }
+ else {
+ if (alpha_flags & IB_alphamode_premul) {
+ if (ibuf->rect) {
+ IMB_unpremultiply_alpha(ibuf);
+ }
+ else {
+ /* pass, floats are expected to be premul */
+ }
+ }
+ else {
+ if (ibuf->rect_float) {
+ IMB_premultiply_alpha(ibuf);
+ }
+ else {
+ /* pass, bytes are expected to be straight */
+ }
+ }
+ }
+
+ /* OCIO_TODO: in some cases it's faster to do threaded conversion,
+ * but how to distinguish such cases */
+ colormanage_imbuf_make_linear(ibuf, effective_colorspace);
+}
+
ImBuf *IMB_ibImageFromMemory(unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE], const char *descr)
{
ImBuf *ibuf;
@@ -70,54 +117,36 @@ ImBuf *IMB_ibImageFromMemory(unsigned char *mem, size_t size, int flags, char co
if (colorspace)
BLI_strncpy(effective_colorspace, colorspace, sizeof(effective_colorspace));
- for (type = IMB_FILE_TYPES; type->is_a; type++) {
+ for (type = IMB_FILE_TYPES; type < IMB_FILE_TYPES_LAST; type++) {
if (type->load) {
ibuf = type->load(mem, size, flags, effective_colorspace);
if (ibuf) {
- int alpha_flags;
-
- if (colorspace) {
- if (ibuf->rect) {
- /* byte buffer is never internally converted to some standard space,
- * store pointer to it's color space descriptor instead
- */
- ibuf->rect_colorspace = colormanage_colorspace_get_named(effective_colorspace);
- }
-
- BLI_strncpy(colorspace, effective_colorspace, IM_MAX_SPACE);
- }
-
- if (flags & IB_alphamode_detect)
- alpha_flags = ibuf->flags & IB_alphamode_premul;
- else
- alpha_flags = flags & IB_alphamode_premul;
-
- if (flags & IB_ignore_alpha) {
- IMB_rectfill_alpha(ibuf, 1.0f);
- }
- else {
- if (alpha_flags & IB_alphamode_premul) {
- if (ibuf->rect) {
- IMB_unpremultiply_alpha(ibuf);
- }
- else {
- /* pass, floats are expected to be premul */
- }
- }
- else {
- if (ibuf->rect_float) {
- IMB_premultiply_alpha(ibuf);
- }
- else {
- /* pass, bytes are expected to be straight */
- }
- }
- }
-
- /* OCIO_TODO: in some cases it's faster to do threaded conversion,
- * but how to distinguish such cases */
- colormanage_imbuf_make_linear(ibuf, effective_colorspace);
+ imb_handle_alpha(ibuf, flags, colorspace, effective_colorspace);
+ return ibuf;
+ }
+ }
+ }
+
+ if ((flags & IB_test) == 0)
+ fprintf(stderr, "%s: unknown fileformat (%s)\n", __func__, descr);
+
+ return NULL;
+}
+
+static ImBuf *IMB_ibImageFromFile(const char *filepath, int flags, char colorspace[IM_MAX_SPACE], const char *descr)
+{
+ ImBuf *ibuf;
+ ImFileType *type;
+ char effective_colorspace[IM_MAX_SPACE] = "";
+
+ if (colorspace)
+ BLI_strncpy(effective_colorspace, colorspace, sizeof(effective_colorspace));
+ for (type = IMB_FILE_TYPES; type < IMB_FILE_TYPES_LAST; type++) {
+ if (type->load_filepath) {
+ ibuf = type->load_filepath(filepath, flags, effective_colorspace);
+ if (ibuf) {
+ imb_handle_alpha(ibuf, flags, colorspace, effective_colorspace);
return ibuf;
}
}
@@ -129,7 +158,13 @@ ImBuf *IMB_ibImageFromMemory(unsigned char *mem, size_t size, int flags, char co
return NULL;
}
-ImBuf *IMB_loadifffile(int file, int flags, char colorspace[IM_MAX_SPACE], const char *descr)
+static bool imb_is_filepath_format(const char *filepath)
+{
+ /* return true if this is one of the formats that can't be loaded from memory */
+ return BLI_testextensie_array(filepath, imb_ext_image_filepath_only);
+}
+
+ImBuf *IMB_loadifffile(int file, const char *filepath, int flags, char colorspace[IM_MAX_SPACE], const char *descr)
{
ImBuf *ibuf;
unsigned char *mem;
@@ -137,6 +172,9 @@ ImBuf *IMB_loadifffile(int file, int flags, char colorspace[IM_MAX_SPACE], const
if (file == -1) return NULL;
+ if (imb_is_filepath_format(filepath))
+ return IMB_ibImageFromFile(filepath, flags, colorspace, descr);
+
size = BLI_file_descriptor_size(file);
mem = mmap(NULL, size, PROT_READ, MAP_SHARED, file, 0);
@@ -179,7 +217,7 @@ ImBuf *IMB_loadiffname(const char *filepath, int flags, char colorspace[IM_MAX_S
file = BLI_open(filepath_tx, O_BINARY | O_RDONLY, 0);
if (file < 0) return NULL;
- ibuf = IMB_loadifffile(file, flags, colorspace, filepath_tx);
+ ibuf = IMB_loadifffile(file, filepath, flags, colorspace, filepath_tx);
if (ibuf) {
BLI_strncpy(ibuf->name, filepath, sizeof(ibuf->name));
@@ -206,7 +244,7 @@ ImBuf *IMB_testiffname(const char *filepath, int flags)
file = BLI_open(filepath_tx, O_BINARY | O_RDONLY, 0);
if (file < 0) return NULL;
- ibuf = IMB_loadifffile(file, flags | IB_test | IB_multilayer, colorspace, filepath_tx);
+ ibuf = IMB_loadifffile(file, filepath, flags | IB_test | IB_multilayer, colorspace, filepath_tx);
if (ibuf) {
BLI_strncpy(ibuf->name, filepath, sizeof(ibuf->name));
@@ -234,7 +272,7 @@ static void imb_loadtilefile(ImBuf *ibuf, int file, int tx, int ty, unsigned int
return;
}
- for (type = IMB_FILE_TYPES; type->is_a; type++)
+ for (type = IMB_FILE_TYPES; type < IMB_FILE_TYPES_LAST; type++)
if (type->load_tile && type->ftype(type, ibuf))
type->load_tile(ibuf, mem, size, tx, ty, rect);