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:
authorCampbell Barton <ideasman42@gmail.com>2019-04-17 07:17:24 +0300
committerCampbell Barton <ideasman42@gmail.com>2019-04-17 07:21:24 +0300
commite12c08e8d170b7ca40f204a5b0423c23a9fbc2c1 (patch)
tree8cf3453d12edb177a218ef8009357518ec6cab6a /source/blender/imbuf
parentb3dabc200a4b0399ec6b81f2ff2730d07b44fcaa (diff)
ClangFormat: apply to source, most of intern
Apply clang format as proposed in T53211. For details on usage and instructions for migrating branches without conflicts, see: https://wiki.blender.org/wiki/Tools/ClangFormat
Diffstat (limited to 'source/blender/imbuf')
-rw-r--r--source/blender/imbuf/CMakeLists.txt252
-rw-r--r--source/blender/imbuf/IMB_colormanagement.h321
-rw-r--r--source/blender/imbuf/IMB_imbuf.h450
-rw-r--r--source/blender/imbuf/IMB_imbuf_types.h401
-rw-r--r--source/blender/imbuf/IMB_metadata.h6
-rw-r--r--source/blender/imbuf/IMB_moviecache.h26
-rw-r--r--source/blender/imbuf/IMB_thumbs.h20
-rw-r--r--source/blender/imbuf/intern/IMB_anim.h127
-rw-r--r--source/blender/imbuf/intern/IMB_colormanagement_intern.h67
-rw-r--r--source/blender/imbuf/intern/IMB_filetype.h95
-rw-r--r--source/blender/imbuf/intern/IMB_indexer.h77
-rw-r--r--source/blender/imbuf/intern/allocimbuf.c746
-rw-r--r--source/blender/imbuf/intern/anim_movie.c2342
-rw-r--r--source/blender/imbuf/intern/bmp.c535
-rw-r--r--source/blender/imbuf/intern/cache.c559
-rw-r--r--source/blender/imbuf/intern/cineon/CMakeLists.txt36
-rw-r--r--source/blender/imbuf/intern/cineon/cineon_dpx.c266
-rw-r--r--source/blender/imbuf/intern/cineon/cineonlib.c688
-rw-r--r--source/blender/imbuf/intern/cineon/cineonlib.h158
-rw-r--r--source/blender/imbuf/intern/cineon/dpxlib.c905
-rw-r--r--source/blender/imbuf/intern/cineon/dpxlib.h197
-rw-r--r--source/blender/imbuf/intern/cineon/logImageCore.c2650
-rw-r--r--source/blender/imbuf/intern/cineon/logImageCore.h248
-rw-r--r--source/blender/imbuf/intern/cineon/logmemfile.c131
-rw-r--r--source/blender/imbuf/intern/cineon/logmemfile.h3
-rw-r--r--source/blender/imbuf/intern/colormanagement.c5103
-rw-r--r--source/blender/imbuf/intern/colormanagement_inline.c18
-rw-r--r--source/blender/imbuf/intern/dds/BlockDXT.cpp729
-rw-r--r--source/blender/imbuf/intern/dds/BlockDXT.h339
-rw-r--r--source/blender/imbuf/intern/dds/CMakeLists.txt52
-rw-r--r--source/blender/imbuf/intern/dds/Color.h116
-rw-r--r--source/blender/imbuf/intern/dds/ColorBlock.cpp592
-rw-r--r--source/blender/imbuf/intern/dds/ColorBlock.h59
-rw-r--r--source/blender/imbuf/intern/dds/Common.h27
-rw-r--r--source/blender/imbuf/intern/dds/DirectDrawSurface.cpp2186
-rw-r--r--source/blender/imbuf/intern/dds/DirectDrawSurface.h229
-rw-r--r--source/blender/imbuf/intern/dds/FlipDXT.cpp346
-rw-r--r--source/blender/imbuf/intern/dds/FlipDXT.h3
-rw-r--r--source/blender/imbuf/intern/dds/Image.cpp78
-rw-r--r--source/blender/imbuf/intern/dds/Image.h77
-rw-r--r--source/blender/imbuf/intern/dds/PixelFormat.h142
-rw-r--r--source/blender/imbuf/intern/dds/Stream.cpp107
-rw-r--r--source/blender/imbuf/intern/dds/Stream.h29
-rw-r--r--source/blender/imbuf/intern/dds/dds_api.cpp258
-rw-r--r--source/blender/imbuf/intern/dds/dds_api.h10
-rw-r--r--source/blender/imbuf/intern/divers.c1515
-rw-r--r--source/blender/imbuf/intern/filetype.c203
-rw-r--r--source/blender/imbuf/intern/filter.c1116
-rw-r--r--source/blender/imbuf/intern/imageprocess.c663
-rw-r--r--source/blender/imbuf/intern/imbuf.h5
-rw-r--r--source/blender/imbuf/intern/indexer.c2015
-rw-r--r--source/blender/imbuf/intern/iris.c1451
-rw-r--r--source/blender/imbuf/intern/jp2.c2008
-rw-r--r--source/blender/imbuf/intern/jpeg.c895
-rw-r--r--source/blender/imbuf/intern/metadata.c91
-rw-r--r--source/blender/imbuf/intern/module.c21
-rw-r--r--source/blender/imbuf/intern/moviecache.c696
-rw-r--r--source/blender/imbuf/intern/oiio/CMakeLists.txt40
-rw-r--r--source/blender/imbuf/intern/oiio/openimageio_api.cpp404
-rw-r--r--source/blender/imbuf/intern/oiio/openimageio_api.h9
-rw-r--r--source/blender/imbuf/intern/openexr/CMakeLists.txt30
-rw-r--r--source/blender/imbuf/intern/openexr/openexr_api.cpp3108
-rw-r--r--source/blender/imbuf/intern/openexr/openexr_api.h13
-rw-r--r--source/blender/imbuf/intern/openexr/openexr_multi.h93
-rw-r--r--source/blender/imbuf/intern/openexr/openexr_stub.cpp119
-rw-r--r--source/blender/imbuf/intern/png.c1357
-rw-r--r--source/blender/imbuf/intern/radiance_hdr.c639
-rw-r--r--source/blender/imbuf/intern/readimage.c382
-rw-r--r--source/blender/imbuf/intern/rectop.c1845
-rw-r--r--source/blender/imbuf/intern/rotate.c126
-rw-r--r--source/blender/imbuf/intern/scaling.c3106
-rw-r--r--source/blender/imbuf/intern/stereoimbuf.c2331
-rw-r--r--source/blender/imbuf/intern/targa.c1240
-rw-r--r--source/blender/imbuf/intern/thumbs.c1129
-rw-r--r--source/blender/imbuf/intern/thumbs_blend.c234
-rw-r--r--source/blender/imbuf/intern/thumbs_font.c67
-rw-r--r--source/blender/imbuf/intern/tiff.c1315
-rw-r--r--source/blender/imbuf/intern/util.c458
-rw-r--r--source/blender/imbuf/intern/writeimage.c66
79 files changed, 26198 insertions, 24398 deletions
diff --git a/source/blender/imbuf/CMakeLists.txt b/source/blender/imbuf/CMakeLists.txt
index a52c72f8ecd..b8d43b8e9c2 100644
--- a/source/blender/imbuf/CMakeLists.txt
+++ b/source/blender/imbuf/CMakeLists.txt
@@ -19,180 +19,180 @@
# ***** END GPL LICENSE BLOCK *****
set(INC
- .
- ../blenkernel
- ../blenlib
- ../blenloader
- ../makesdna
- ../makesrna
- ../../../intern/guardedalloc
- ../../../intern/memutil
+ .
+ ../blenkernel
+ ../blenlib
+ ../blenloader
+ ../makesdna
+ ../makesrna
+ ../../../intern/guardedalloc
+ ../../../intern/memutil
)
set(INC_SYS
- ${JPEG_INCLUDE_DIR}
- ${PNG_INCLUDE_DIRS}
- ${ZLIB_INCLUDE_DIRS}
+ ${JPEG_INCLUDE_DIR}
+ ${PNG_INCLUDE_DIRS}
+ ${ZLIB_INCLUDE_DIRS}
)
set(SRC
- intern/allocimbuf.c
- intern/anim_movie.c
- intern/bmp.c
- intern/cache.c
- intern/colormanagement.c
- intern/colormanagement_inline.c
- intern/divers.c
- intern/filetype.c
- intern/filter.c
- intern/imageprocess.c
- intern/indexer.c
- intern/iris.c
- intern/jpeg.c
- intern/metadata.c
- intern/module.c
- intern/moviecache.c
- intern/png.c
- intern/readimage.c
- intern/rectop.c
- intern/rotate.c
- intern/scaling.c
- intern/stereoimbuf.c
- intern/targa.c
- intern/thumbs.c
- intern/thumbs_blend.c
- intern/thumbs_font.c
- intern/util.c
- intern/writeimage.c
-
- IMB_colormanagement.h
- IMB_imbuf.h
- IMB_imbuf_types.h
- IMB_metadata.h
- IMB_moviecache.h
- IMB_thumbs.h
- intern/IMB_allocimbuf.h
- intern/IMB_anim.h
- intern/IMB_colormanagement_intern.h
- intern/IMB_filetype.h
- intern/IMB_filter.h
- intern/IMB_indexer.h
- intern/imbuf.h
-
- # orphan include
- ../../../intern/ffmpeg/ffmpeg_compat.h
+ intern/allocimbuf.c
+ intern/anim_movie.c
+ intern/bmp.c
+ intern/cache.c
+ intern/colormanagement.c
+ intern/colormanagement_inline.c
+ intern/divers.c
+ intern/filetype.c
+ intern/filter.c
+ intern/imageprocess.c
+ intern/indexer.c
+ intern/iris.c
+ intern/jpeg.c
+ intern/metadata.c
+ intern/module.c
+ intern/moviecache.c
+ intern/png.c
+ intern/readimage.c
+ intern/rectop.c
+ intern/rotate.c
+ intern/scaling.c
+ intern/stereoimbuf.c
+ intern/targa.c
+ intern/thumbs.c
+ intern/thumbs_blend.c
+ intern/thumbs_font.c
+ intern/util.c
+ intern/writeimage.c
+
+ IMB_colormanagement.h
+ IMB_imbuf.h
+ IMB_imbuf_types.h
+ IMB_metadata.h
+ IMB_moviecache.h
+ IMB_thumbs.h
+ intern/IMB_allocimbuf.h
+ intern/IMB_anim.h
+ intern/IMB_colormanagement_intern.h
+ intern/IMB_filetype.h
+ intern/IMB_filter.h
+ intern/IMB_indexer.h
+ intern/imbuf.h
+
+ # orphan include
+ ../../../intern/ffmpeg/ffmpeg_compat.h
)
set(LIB
- bf_blenkernel
- bf_blenlib
- bf_blenloader
- bf_intern_guardedalloc
- bf_intern_memutil
- bf_intern_opencolorio
+ bf_blenkernel
+ bf_blenlib
+ bf_blenloader
+ bf_intern_guardedalloc
+ bf_intern_memutil
+ bf_intern_opencolorio
)
if(WITH_IMAGE_OPENEXR)
- list(APPEND LIB
- bf_imbuf_openexr
- )
- add_definitions(-DWITH_OPENEXR)
+ list(APPEND LIB
+ bf_imbuf_openexr
+ )
+ add_definitions(-DWITH_OPENEXR)
else()
- list(APPEND SRC
- intern/openexr/openexr_stub.cpp
- )
+ list(APPEND SRC
+ intern/openexr/openexr_stub.cpp
+ )
endif()
if(WITH_IMAGE_TIFF)
- list(APPEND INC_SYS
- ${TIFF_INCLUDE_DIR}
- )
- list(APPEND SRC
- intern/tiff.c
- )
- add_definitions(-DWITH_TIFF)
+ list(APPEND INC_SYS
+ ${TIFF_INCLUDE_DIR}
+ )
+ list(APPEND SRC
+ intern/tiff.c
+ )
+ add_definitions(-DWITH_TIFF)
endif()
if(WITH_OPENIMAGEIO)
- list(APPEND LIB
- bf_imbuf_openimageio
- )
- add_definitions(-DWITH_OPENIMAGEIO)
+ list(APPEND LIB
+ bf_imbuf_openimageio
+ )
+ add_definitions(-DWITH_OPENIMAGEIO)
endif()
if(WITH_IMAGE_OPENJPEG)
- list(APPEND INC_SYS
- ${OPENJPEG_INCLUDE_DIRS}
- )
- list(APPEND SRC
- intern/jp2.c
- )
-
- add_definitions(-DWITH_OPENJPEG ${OPENJPEG_DEFINES})
+ list(APPEND INC_SYS
+ ${OPENJPEG_INCLUDE_DIRS}
+ )
+ list(APPEND SRC
+ intern/jp2.c
+ )
+
+ add_definitions(-DWITH_OPENJPEG ${OPENJPEG_DEFINES})
endif()
if(WITH_CODEC_AVI)
- list(APPEND INC
- ../avi
- )
- list(APPEND LIB
- bf_avi
- )
- add_definitions(-DWITH_AVI)
+ list(APPEND INC
+ ../avi
+ )
+ list(APPEND LIB
+ bf_avi
+ )
+ add_definitions(-DWITH_AVI)
endif()
if(WITH_CODEC_FFMPEG)
- list(APPEND INC
- ../../../intern/ffmpeg
- )
- list(APPEND INC_SYS
- ${FFMPEG_INCLUDE_DIRS}
- )
- add_definitions(-DWITH_FFMPEG)
-
- remove_strict_c_flags_file(
- intern/anim_movie.c
- intern/indexer.c
- intern/util.c
- )
+ list(APPEND INC
+ ../../../intern/ffmpeg
+ )
+ list(APPEND INC_SYS
+ ${FFMPEG_INCLUDE_DIRS}
+ )
+ add_definitions(-DWITH_FFMPEG)
+
+ remove_strict_c_flags_file(
+ intern/anim_movie.c
+ intern/indexer.c
+ intern/util.c
+ )
endif()
if(WITH_IMAGE_DDS)
- list(APPEND LIB
- bf_imbuf_dds
- )
- add_definitions(-DWITH_DDS)
+ list(APPEND LIB
+ bf_imbuf_dds
+ )
+ add_definitions(-DWITH_DDS)
endif()
if(WITH_IMAGE_CINEON)
- list(APPEND LIB
- bf_imbuf_cineon
- )
- add_definitions(-DWITH_CINEON)
+ list(APPEND LIB
+ bf_imbuf_cineon
+ )
+ add_definitions(-DWITH_CINEON)
endif()
if(WITH_IMAGE_HDR)
- list(APPEND SRC
- intern/radiance_hdr.c
- )
- add_definitions(-DWITH_HDR)
+ list(APPEND SRC
+ intern/radiance_hdr.c
+ )
+ add_definitions(-DWITH_HDR)
endif()
list(APPEND INC
- ../../../intern/opencolorio
+ ../../../intern/opencolorio
)
if(WIN32)
- list(APPEND INC
- ../../../intern/utfconv
- )
+ list(APPEND INC
+ ../../../intern/utfconv
+ )
endif()
# no need to compile object files for inline headers.
set_source_files_properties(
- intern/colormanagement_inline.c
- PROPERTIES HEADER_FILE_ONLY TRUE
+ intern/colormanagement_inline.c
+ PROPERTIES HEADER_FILE_ONLY TRUE
)
blender_add_lib(bf_imbuf "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/source/blender/imbuf/IMB_colormanagement.h b/source/blender/imbuf/IMB_colormanagement.h
index c042e17cf80..5978066f4a8 100644
--- a/source/blender/imbuf/IMB_colormanagement.h
+++ b/source/blender/imbuf/IMB_colormanagement.h
@@ -29,7 +29,6 @@
#define BCM_CONFIG_FILE "config.ocio"
-
struct ColorManagedColorspaceSettings;
struct ColorManagedDisplaySettings;
struct ColorManagedViewSettings;
@@ -47,8 +46,9 @@ struct ColorSpace;
void IMB_colormanagement_check_file_config(struct Main *bmain);
-void IMB_colormanagement_validate_settings(const struct ColorManagedDisplaySettings *display_settings,
- struct ColorManagedViewSettings *view_settings);
+void IMB_colormanagement_validate_settings(
+ const struct ColorManagedDisplaySettings *display_settings,
+ struct ColorManagedViewSettings *view_settings);
const char *IMB_colormanagement_role_colorspace_name_get(int role);
void IMB_colormanagement_check_is_data(struct ImBuf *ibuf, const char *name);
@@ -64,28 +64,65 @@ BLI_INLINE void IMB_colormangement_xyz_to_rgb(float rgb[3], const float xyz[3]);
BLI_INLINE void IMB_colormangement_rgb_to_xyz(float xyz[3], const float rgb[3]);
/* ** Color space transformation functions ** */
-void IMB_colormanagement_transform(float *buffer, int width, int height, int channels,
- const char *from_colorspace, const char *to_colorspace, bool predivide);
-void IMB_colormanagement_transform_threaded(float *buffer, int width, int height, int channels,
- const char *from_colorspace, const char *to_colorspace, bool predivide);
-void IMB_colormanagement_transform_byte(unsigned char *buffer, int width, int height, int channels,
- const char *from_colorspace, const char *to_colorspace);
-void IMB_colormanagement_transform_byte_threaded(unsigned char *buffer, int width, int height, int channels,
- const char *from_colorspace, const char *to_colorspace);
-void IMB_colormanagement_transform_from_byte(float *float_buffer, unsigned char *byte_buffer,
- int width, int height, int channels,
- const char *from_colorspace, const char *to_colorspace);
-void IMB_colormanagement_transform_from_byte_threaded(float *float_buffer, unsigned char *byte_buffer,
- int width, int height, int channels,
- const char *from_colorspace, const char *to_colorspace);
-void IMB_colormanagement_transform_v4(float pixel[4], const char *from_colorspace, const char *to_colorspace);
-
-void IMB_colormanagement_colorspace_to_scene_linear_v3(float pixel[3], struct ColorSpace *colorspace);
-void IMB_colormanagement_colorspace_to_scene_linear_v4(float pixel[4], bool predivide, struct ColorSpace *colorspace);
-
-void IMB_colormanagement_scene_linear_to_colorspace_v3(float pixel[3], struct ColorSpace *colorspace);
-
-void IMB_colormanagement_colorspace_to_scene_linear(float *buffer, int width, int height, int channels, struct ColorSpace *colorspace, bool predivide);
+void IMB_colormanagement_transform(float *buffer,
+ int width,
+ int height,
+ int channels,
+ const char *from_colorspace,
+ const char *to_colorspace,
+ bool predivide);
+void IMB_colormanagement_transform_threaded(float *buffer,
+ int width,
+ int height,
+ int channels,
+ const char *from_colorspace,
+ const char *to_colorspace,
+ bool predivide);
+void IMB_colormanagement_transform_byte(unsigned char *buffer,
+ int width,
+ int height,
+ int channels,
+ const char *from_colorspace,
+ const char *to_colorspace);
+void IMB_colormanagement_transform_byte_threaded(unsigned char *buffer,
+ int width,
+ int height,
+ int channels,
+ const char *from_colorspace,
+ const char *to_colorspace);
+void IMB_colormanagement_transform_from_byte(float *float_buffer,
+ unsigned char *byte_buffer,
+ int width,
+ int height,
+ int channels,
+ const char *from_colorspace,
+ const char *to_colorspace);
+void IMB_colormanagement_transform_from_byte_threaded(float *float_buffer,
+ unsigned char *byte_buffer,
+ int width,
+ int height,
+ int channels,
+ const char *from_colorspace,
+ const char *to_colorspace);
+void IMB_colormanagement_transform_v4(float pixel[4],
+ const char *from_colorspace,
+ const char *to_colorspace);
+
+void IMB_colormanagement_colorspace_to_scene_linear_v3(float pixel[3],
+ struct ColorSpace *colorspace);
+void IMB_colormanagement_colorspace_to_scene_linear_v4(float pixel[4],
+ bool predivide,
+ struct ColorSpace *colorspace);
+
+void IMB_colormanagement_scene_linear_to_colorspace_v3(float pixel[3],
+ struct ColorSpace *colorspace);
+
+void IMB_colormanagement_colorspace_to_scene_linear(float *buffer,
+ int width,
+ int height,
+ int channels,
+ struct ColorSpace *colorspace,
+ bool predivide);
void IMB_colormanagement_scene_linear_to_color_picking_v3(float pixel[3]);
void IMB_colormanagement_color_picking_to_scene_linear_v3(float pixel[3]);
@@ -93,44 +130,74 @@ void IMB_colormanagement_color_picking_to_scene_linear_v3(float pixel[3]);
void IMB_colormanagement_scene_linear_to_srgb_v3(float pixel[3]);
void IMB_colormanagement_srgb_to_scene_linear_v3(float pixel[3]);
-void IMB_colormanagement_scene_linear_to_display_v3(float pixel[3], struct ColorManagedDisplay *display);
-void IMB_colormanagement_display_to_scene_linear_v3(float pixel[3], struct ColorManagedDisplay *display);
-
-void IMB_colormanagement_pixel_to_display_space_v4(float result[4], const float pixel[4], const struct ColorManagedViewSettings *view_settings,
- const struct ColorManagedDisplaySettings *display_settings);
-
-void IMB_colormanagement_pixel_to_display_space_v3(float result[3], const float pixel[3], const struct ColorManagedViewSettings *view_settings,
- const struct ColorManagedDisplaySettings *display_settings);
-
-void IMB_colormanagement_imbuf_make_display_space(struct ImBuf *ibuf, const struct ColorManagedViewSettings *view_settings,
- const struct ColorManagedDisplaySettings *display_settings);
-
-struct ImBuf *IMB_colormanagement_imbuf_for_write(struct ImBuf *ibuf, bool save_as_render, bool allocate_result,
- const struct ColorManagedViewSettings *view_settings,
- const struct ColorManagedDisplaySettings *display_settings,
- struct ImageFormatData *image_format_data);
-
-void IMB_colormanagement_buffer_make_display_space(float *buffer, unsigned char *display_buffer,
- int width, int height, int channels, float dither,
- const struct ColorManagedViewSettings *view_settings,
- const struct ColorManagedDisplaySettings *display_settings);
+void IMB_colormanagement_scene_linear_to_display_v3(float pixel[3],
+ struct ColorManagedDisplay *display);
+void IMB_colormanagement_display_to_scene_linear_v3(float pixel[3],
+ struct ColorManagedDisplay *display);
+
+void IMB_colormanagement_pixel_to_display_space_v4(
+ float result[4],
+ const float pixel[4],
+ const struct ColorManagedViewSettings *view_settings,
+ const struct ColorManagedDisplaySettings *display_settings);
+
+void IMB_colormanagement_pixel_to_display_space_v3(
+ float result[3],
+ const float pixel[3],
+ const struct ColorManagedViewSettings *view_settings,
+ const struct ColorManagedDisplaySettings *display_settings);
+
+void IMB_colormanagement_imbuf_make_display_space(
+ struct ImBuf *ibuf,
+ const struct ColorManagedViewSettings *view_settings,
+ const struct ColorManagedDisplaySettings *display_settings);
+
+struct ImBuf *IMB_colormanagement_imbuf_for_write(
+ struct ImBuf *ibuf,
+ bool save_as_render,
+ bool allocate_result,
+ const struct ColorManagedViewSettings *view_settings,
+ const struct ColorManagedDisplaySettings *display_settings,
+ struct ImageFormatData *image_format_data);
+
+void IMB_colormanagement_buffer_make_display_space(
+ float *buffer,
+ unsigned char *display_buffer,
+ int width,
+ int height,
+ int channels,
+ float dither,
+ const struct ColorManagedViewSettings *view_settings,
+ const struct ColorManagedDisplaySettings *display_settings);
/* ** Public display buffers interfaces ** */
-void IMB_colormanagement_display_settings_from_ctx(const struct bContext *C,
- struct ColorManagedViewSettings **view_settings_r,
- struct ColorManagedDisplaySettings **display_settings_r);
-
-const char *IMB_colormanagement_get_display_colorspace_name(const struct ColorManagedViewSettings *view_settings,
- const struct ColorManagedDisplaySettings *display_settings);
-
-unsigned char *IMB_display_buffer_acquire(struct ImBuf *ibuf, const struct ColorManagedViewSettings *view_settings,
- const struct ColorManagedDisplaySettings *display_settings, void **cache_handle);
-unsigned char *IMB_display_buffer_acquire_ctx(const struct bContext *C, struct ImBuf *ibuf, void **cache_handle);
-
-void IMB_display_buffer_transform_apply(unsigned char *display_buffer, float *linear_buffer, int width, int height,
- int channels, const struct ColorManagedViewSettings *view_settings,
- const struct ColorManagedDisplaySettings *display_settings, bool predivide);
+void IMB_colormanagement_display_settings_from_ctx(
+ const struct bContext *C,
+ struct ColorManagedViewSettings **view_settings_r,
+ struct ColorManagedDisplaySettings **display_settings_r);
+
+const char *IMB_colormanagement_get_display_colorspace_name(
+ const struct ColorManagedViewSettings *view_settings,
+ const struct ColorManagedDisplaySettings *display_settings);
+
+unsigned char *IMB_display_buffer_acquire(
+ struct ImBuf *ibuf,
+ const struct ColorManagedViewSettings *view_settings,
+ const struct ColorManagedDisplaySettings *display_settings,
+ void **cache_handle);
+unsigned char *IMB_display_buffer_acquire_ctx(const struct bContext *C,
+ struct ImBuf *ibuf,
+ void **cache_handle);
+
+void IMB_display_buffer_transform_apply(unsigned char *display_buffer,
+ float *linear_buffer,
+ int width,
+ int height,
+ int channels,
+ const struct ColorManagedViewSettings *view_settings,
+ const struct ColorManagedDisplaySettings *display_settings,
+ bool predivide);
void IMB_display_buffer_release(void *cache_handle);
@@ -141,7 +208,7 @@ const char *IMB_colormanagement_display_get_default_name(void);
struct ColorManagedDisplay *IMB_colormanagement_display_get_named(const char *name);
const char *IMB_colormanagement_display_get_none_name(void);
const char *IMB_colormanagement_display_get_default_view_transform_name(
- struct ColorManagedDisplay *display);
+ struct ColorManagedDisplay *display);
/* ** View functions ** */
int IMB_colormanagement_view_get_named_index(const char *name);
@@ -156,46 +223,78 @@ int IMB_colormanagement_colorspace_get_named_index(const char *name);
const char *IMB_colormanagement_colorspace_get_indexed_name(int index);
const char *IMB_colormanagement_view_get_default_name(const char *display_name);
-void IMB_colormanagement_colorspace_from_ibuf_ftype(struct ColorManagedColorspaceSettings *colorspace_settings, struct ImBuf *ibuf);
+void IMB_colormanagement_colorspace_from_ibuf_ftype(
+ struct ColorManagedColorspaceSettings *colorspace_settings, struct ImBuf *ibuf);
/* ** RNA helper functions ** */
void IMB_colormanagement_display_items_add(struct EnumPropertyItem **items, int *totitem);
-void IMB_colormanagement_view_items_add(struct EnumPropertyItem **items, int *totitem, const char *display_name);
-void IMB_colormanagement_look_items_add(struct EnumPropertyItem **items, int *totitem, const char *view_name);
+void IMB_colormanagement_view_items_add(struct EnumPropertyItem **items,
+ int *totitem,
+ const char *display_name);
+void IMB_colormanagement_look_items_add(struct EnumPropertyItem **items,
+ int *totitem,
+ const char *view_name);
void IMB_colormanagement_colorspace_items_add(struct EnumPropertyItem **items, int *totitem);
/* ** Tile-based buffer management ** */
-void IMB_partial_display_buffer_update(struct ImBuf *ibuf, const float *linear_buffer, const unsigned char *buffer_byte,
- int stride, int offset_x, int offset_y,
+void IMB_partial_display_buffer_update(struct ImBuf *ibuf,
+ const float *linear_buffer,
+ const unsigned char *buffer_byte,
+ int stride,
+ int offset_x,
+ int offset_y,
const struct ColorManagedViewSettings *view_settings,
const struct ColorManagedDisplaySettings *display_settings,
- int xmin, int ymin, int xmax, int ymax,
+ int xmin,
+ int ymin,
+ int xmax,
+ int ymax,
bool copy_display_to_byte_buffer);
-void IMB_partial_display_buffer_update_threaded(struct ImBuf *ibuf,
- const float *linear_buffer,
- const unsigned char *buffer_byte,
- int stride,
- int offset_x, int offset_y,
- const struct ColorManagedViewSettings *view_settings,
- const struct ColorManagedDisplaySettings *display_settings,
- int xmin, int ymin, int xmax, int ymax,
- bool copy_display_to_byte_buffer);
-
-void IMB_partial_display_buffer_update_delayed(struct ImBuf *ibuf, int xmin, int ymin, int xmax, int ymax);
+void IMB_partial_display_buffer_update_threaded(
+ struct ImBuf *ibuf,
+ const float *linear_buffer,
+ const unsigned char *buffer_byte,
+ int stride,
+ int offset_x,
+ int offset_y,
+ const struct ColorManagedViewSettings *view_settings,
+ const struct ColorManagedDisplaySettings *display_settings,
+ int xmin,
+ int ymin,
+ int xmax,
+ int ymax,
+ bool copy_display_to_byte_buffer);
+
+void IMB_partial_display_buffer_update_delayed(
+ struct ImBuf *ibuf, int xmin, int ymin, int xmax, int ymax);
/* ** Pixel processor functions ** */
-struct ColormanageProcessor *IMB_colormanagement_display_processor_new(const struct ColorManagedViewSettings *view_settings,
- const struct ColorManagedDisplaySettings *display_settings);
-struct ColormanageProcessor *IMB_colormanagement_colorspace_processor_new(const char *from_colorspace, const char *to_colorspace);
-void IMB_colormanagement_processor_apply_v4(struct ColormanageProcessor *cm_processor, float pixel[4]);
-void IMB_colormanagement_processor_apply_v4_predivide(struct ColormanageProcessor *cm_processor, float pixel[4]);
-void IMB_colormanagement_processor_apply_v3(struct ColormanageProcessor *cm_processor, float pixel[3]);
-void IMB_colormanagement_processor_apply_pixel(struct ColormanageProcessor *cm_processor, float *pixel, int channels);
-void IMB_colormanagement_processor_apply(struct ColormanageProcessor *cm_processor, float *buffer, int width, int height,
- int channels, bool predivide);
+struct ColormanageProcessor *IMB_colormanagement_display_processor_new(
+ const struct ColorManagedViewSettings *view_settings,
+ const struct ColorManagedDisplaySettings *display_settings);
+struct ColormanageProcessor *IMB_colormanagement_colorspace_processor_new(
+ const char *from_colorspace, const char *to_colorspace);
+void IMB_colormanagement_processor_apply_v4(struct ColormanageProcessor *cm_processor,
+ float pixel[4]);
+void IMB_colormanagement_processor_apply_v4_predivide(struct ColormanageProcessor *cm_processor,
+ float pixel[4]);
+void IMB_colormanagement_processor_apply_v3(struct ColormanageProcessor *cm_processor,
+ float pixel[3]);
+void IMB_colormanagement_processor_apply_pixel(struct ColormanageProcessor *cm_processor,
+ float *pixel,
+ int channels);
+void IMB_colormanagement_processor_apply(struct ColormanageProcessor *cm_processor,
+ float *buffer,
+ int width,
+ int height,
+ int channels,
+ bool predivide);
void IMB_colormanagement_processor_apply_byte(struct ColormanageProcessor *cm_processor,
- unsigned char *buffer, int width, int height, int channels);
+ unsigned char *buffer,
+ int width,
+ int height,
+ int channels);
void IMB_colormanagement_processor_free(struct ColormanageProcessor *cm_processor);
/* ** OpenGL drawing routines using GLSL for color space transform ** */
@@ -203,37 +302,45 @@ void IMB_colormanagement_processor_free(struct ColormanageProcessor *cm_processo
/* Test if GLSL drawing is supported for combination of graphics card and this configuration */
bool IMB_colormanagement_support_glsl_draw(const struct ColorManagedViewSettings *view_settings);
/* Configures GLSL shader for conversion from scene linear to display space */
-bool IMB_colormanagement_setup_glsl_draw(const struct ColorManagedViewSettings *view_settings,
- const struct ColorManagedDisplaySettings *display_settings,
- float dither, bool predivide);
+bool IMB_colormanagement_setup_glsl_draw(
+ const struct ColorManagedViewSettings *view_settings,
+ const struct ColorManagedDisplaySettings *display_settings,
+ float dither,
+ bool predivide);
/* Same as above, but display space conversion happens from a specified space */
-bool IMB_colormanagement_setup_glsl_draw_from_space(const struct ColorManagedViewSettings *view_settings,
- const struct ColorManagedDisplaySettings *display_settings,
- struct ColorSpace *colorspace,
- float dither, bool predivide);
+bool IMB_colormanagement_setup_glsl_draw_from_space(
+ const struct ColorManagedViewSettings *view_settings,
+ const struct ColorManagedDisplaySettings *display_settings,
+ struct ColorSpace *colorspace,
+ float dither,
+ bool predivide);
/* Same as setup_glsl_draw, but color management settings are guessing from a given context */
-bool IMB_colormanagement_setup_glsl_draw_ctx(const struct bContext *C, float dither, bool predivide);
+bool IMB_colormanagement_setup_glsl_draw_ctx(const struct bContext *C,
+ float dither,
+ bool predivide);
/* Same as setup_glsl_draw_from_space, but color management settings are guessing from a given context */
-bool IMB_colormanagement_setup_glsl_draw_from_space_ctx(const struct bContext *C, struct ColorSpace *colorspace,
- float dither, bool predivide);
+bool IMB_colormanagement_setup_glsl_draw_from_space_ctx(const struct bContext *C,
+ struct ColorSpace *colorspace,
+ float dither,
+ bool predivide);
/* Finish GLSL-based display space conversion */
void IMB_colormanagement_finish_glsl_draw(void);
/* ** View transform ** */
void IMB_colormanagement_init_default_view_settings(
- struct ColorManagedViewSettings *view_settings,
- const struct ColorManagedDisplaySettings *display_settings);
+ struct ColorManagedViewSettings *view_settings,
+ const struct ColorManagedDisplaySettings *display_settings);
/* Roles */
enum {
- COLOR_ROLE_SCENE_LINEAR = 0,
- COLOR_ROLE_COLOR_PICKING,
- COLOR_ROLE_TEXTURE_PAINTING,
- COLOR_ROLE_DEFAULT_SEQUENCER,
- COLOR_ROLE_DEFAULT_BYTE,
- COLOR_ROLE_DEFAULT_FLOAT,
+ COLOR_ROLE_SCENE_LINEAR = 0,
+ COLOR_ROLE_COLOR_PICKING,
+ COLOR_ROLE_TEXTURE_PAINTING,
+ COLOR_ROLE_DEFAULT_SEQUENCER,
+ COLOR_ROLE_DEFAULT_BYTE,
+ COLOR_ROLE_DEFAULT_FLOAT,
};
#include "intern/colormanagement_inline.c"
-#endif /* __IMB_COLORMANAGEMENT_H__ */
+#endif /* __IMB_COLORMANAGEMENT_H__ */
diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h
index 03d07844ec8..27eb6a5eee5 100644
--- a/source/blender/imbuf/IMB_imbuf.h
+++ b/source/blender/imbuf/IMB_imbuf.h
@@ -95,9 +95,11 @@ void IMB_exit(void);
*
* \attention Defined in readimage.c
*/
-struct ImBuf *IMB_ibImageFromMemory(
- const unsigned char *mem, size_t size, int flags,
- char colorspace[IM_MAX_SPACE], const char *descr);
+struct ImBuf *IMB_ibImageFromMemory(const unsigned char *mem,
+ size_t size,
+ int flags,
+ char colorspace[IM_MAX_SPACE],
+ const char *descr);
/**
*
@@ -121,8 +123,10 @@ void IMB_freeImBuf(struct ImBuf *ibuf);
*
* \attention Defined in allocimbuf.c
*/
-struct ImBuf *IMB_allocImBuf(unsigned int x, unsigned int y,
- unsigned char planes, unsigned int flags);
+struct ImBuf *IMB_allocImBuf(unsigned int x,
+ unsigned int y,
+ unsigned char planes,
+ unsigned int flags);
/**
* Initialize given ImBuf.
@@ -131,16 +135,17 @@ struct ImBuf *IMB_allocImBuf(unsigned int x, unsigned int y,
*
* \attention Defined in allocimbuf.c
*/
-bool IMB_initImBuf(struct ImBuf *ibuf,
- unsigned int x, unsigned int y,
- unsigned char planes, unsigned int flags);
+bool IMB_initImBuf(
+ struct ImBuf *ibuf, unsigned int x, unsigned int y, unsigned char planes, unsigned int flags);
/**
* Create a copy of a pixel buffer and wrap it to a new ImBuf
* \attention Defined in allocimbuf.c
*/
-struct ImBuf *IMB_allocFromBuffer(const unsigned int *rect, const float *rectf,
- unsigned int w, unsigned int h);
+struct ImBuf *IMB_allocFromBuffer(const unsigned int *rect,
+ const float *rectf,
+ unsigned int w,
+ unsigned int h);
/**
*
@@ -173,54 +178,93 @@ bool addzbuffloatImBuf(struct ImBuf *ibuf);
*/
typedef enum IMB_BlendMode {
- IMB_BLEND_MIX = 0,
- IMB_BLEND_ADD = 1,
- IMB_BLEND_SUB = 2,
- IMB_BLEND_MUL = 3,
- IMB_BLEND_LIGHTEN = 4,
- IMB_BLEND_DARKEN = 5,
- IMB_BLEND_ERASE_ALPHA = 6,
- IMB_BLEND_ADD_ALPHA = 7,
- IMB_BLEND_OVERLAY = 8,
- IMB_BLEND_HARDLIGHT = 9,
- IMB_BLEND_COLORBURN = 10,
- IMB_BLEND_LINEARBURN = 11,
- IMB_BLEND_COLORDODGE = 12,
- IMB_BLEND_SCREEN = 13,
- IMB_BLEND_SOFTLIGHT = 14,
- IMB_BLEND_PINLIGHT = 15,
- IMB_BLEND_VIVIDLIGHT = 16,
- IMB_BLEND_LINEARLIGHT = 17,
- IMB_BLEND_DIFFERENCE = 18,
- IMB_BLEND_EXCLUSION = 19,
- IMB_BLEND_HUE = 20,
- IMB_BLEND_SATURATION = 21,
- IMB_BLEND_LUMINOSITY = 22,
- IMB_BLEND_COLOR = 23,
- IMB_BLEND_INTERPOLATE = 24,
-
- IMB_BLEND_COPY = 1000,
- IMB_BLEND_COPY_RGB = 1001,
- IMB_BLEND_COPY_ALPHA = 1002,
+ IMB_BLEND_MIX = 0,
+ IMB_BLEND_ADD = 1,
+ IMB_BLEND_SUB = 2,
+ IMB_BLEND_MUL = 3,
+ IMB_BLEND_LIGHTEN = 4,
+ IMB_BLEND_DARKEN = 5,
+ IMB_BLEND_ERASE_ALPHA = 6,
+ IMB_BLEND_ADD_ALPHA = 7,
+ IMB_BLEND_OVERLAY = 8,
+ IMB_BLEND_HARDLIGHT = 9,
+ IMB_BLEND_COLORBURN = 10,
+ IMB_BLEND_LINEARBURN = 11,
+ IMB_BLEND_COLORDODGE = 12,
+ IMB_BLEND_SCREEN = 13,
+ IMB_BLEND_SOFTLIGHT = 14,
+ IMB_BLEND_PINLIGHT = 15,
+ IMB_BLEND_VIVIDLIGHT = 16,
+ IMB_BLEND_LINEARLIGHT = 17,
+ IMB_BLEND_DIFFERENCE = 18,
+ IMB_BLEND_EXCLUSION = 19,
+ IMB_BLEND_HUE = 20,
+ IMB_BLEND_SATURATION = 21,
+ IMB_BLEND_LUMINOSITY = 22,
+ IMB_BLEND_COLOR = 23,
+ IMB_BLEND_INTERPOLATE = 24,
+
+ IMB_BLEND_COPY = 1000,
+ IMB_BLEND_COPY_RGB = 1001,
+ IMB_BLEND_COPY_ALPHA = 1002,
} IMB_BlendMode;
-void IMB_blend_color_byte(unsigned char dst[4], unsigned char src1[4],
- unsigned char src2[4], IMB_BlendMode mode);
-void IMB_blend_color_float(float dst[4], float src1[4], float src2[4],
- IMB_BlendMode mode);
-
-void IMB_rectclip(struct ImBuf *dbuf, struct ImBuf *sbuf, int *destx,
- int *desty, int *srcx, int *srcy, int *width, int *height);
-void IMB_rectcpy(struct ImBuf *drect, struct ImBuf *srect, int destx,
- int desty, int srcx, int srcy, int width, int height);
-void IMB_rectblend(struct ImBuf *dbuf, struct ImBuf *obuf, struct ImBuf *sbuf,
- unsigned short *dmask, unsigned short *curvemask, unsigned short *mmask, float mask_max,
- int destx, int desty, int origx, int origy, int srcx, int srcy,
- int width, int height, IMB_BlendMode mode, bool accumulate);
-void IMB_rectblend_threaded(struct ImBuf *dbuf, struct ImBuf *obuf, struct ImBuf *sbuf,
- unsigned short *dmask, unsigned short *curvemask, unsigned short *mmask, float mask_max,
- int destx, int desty, int origx, int origy, int srcx, int srcy,
- int width, int height, IMB_BlendMode mode, bool accumulate);
+void IMB_blend_color_byte(unsigned char dst[4],
+ unsigned char src1[4],
+ unsigned char src2[4],
+ IMB_BlendMode mode);
+void IMB_blend_color_float(float dst[4], float src1[4], float src2[4], IMB_BlendMode mode);
+
+void IMB_rectclip(struct ImBuf *dbuf,
+ struct ImBuf *sbuf,
+ int *destx,
+ int *desty,
+ int *srcx,
+ int *srcy,
+ int *width,
+ int *height);
+void IMB_rectcpy(struct ImBuf *drect,
+ struct ImBuf *srect,
+ int destx,
+ int desty,
+ int srcx,
+ int srcy,
+ int width,
+ int height);
+void IMB_rectblend(struct ImBuf *dbuf,
+ struct ImBuf *obuf,
+ struct ImBuf *sbuf,
+ unsigned short *dmask,
+ unsigned short *curvemask,
+ unsigned short *mmask,
+ float mask_max,
+ int destx,
+ int desty,
+ int origx,
+ int origy,
+ int srcx,
+ int srcy,
+ int width,
+ int height,
+ IMB_BlendMode mode,
+ bool accumulate);
+void IMB_rectblend_threaded(struct ImBuf *dbuf,
+ struct ImBuf *obuf,
+ struct ImBuf *sbuf,
+ unsigned short *dmask,
+ unsigned short *curvemask,
+ unsigned short *mmask,
+ float mask_max,
+ int destx,
+ int desty,
+ int origx,
+ int origy,
+ int srcx,
+ int srcy,
+ int width,
+ int height,
+ IMB_BlendMode mode,
+ bool accumulate);
/**
*
@@ -228,50 +272,54 @@ void IMB_rectblend_threaded(struct ImBuf *dbuf, struct ImBuf *obuf, struct ImBuf
*/
typedef enum IMB_Timecode_Type {
- IMB_TC_NONE = 0, /* don't use timecode files at all */
-
- IMB_TC_RECORD_RUN = 1, /* use images in the order as they are recorded
- * (currently, this is the only one implemented
- * and is a sane default) */
-
- IMB_TC_FREE_RUN = 2, /* use global timestamp written by recording
- * device (prosumer camcorders e.g. can do that) */
- IMB_TC_INTERPOLATED_REC_DATE_FREE_RUN = 4, /* interpolate a global timestamp using the
- * record date and time written by recording
- * device (*every* consumer camcorder can do
- * that :) )*/
- IMB_TC_RECORD_RUN_NO_GAPS = 8,
- IMB_TC_MAX_SLOT = 4,
+ IMB_TC_NONE = 0, /* don't use timecode files at all */
+
+ IMB_TC_RECORD_RUN = 1, /* use images in the order as they are recorded
+ * (currently, this is the only one implemented
+ * and is a sane default) */
+
+ IMB_TC_FREE_RUN = 2, /* use global timestamp written by recording
+ * device (prosumer camcorders e.g. can do that) */
+ IMB_TC_INTERPOLATED_REC_DATE_FREE_RUN = 4, /* interpolate a global timestamp using the
+ * record date and time written by recording
+ * device (*every* consumer camcorder can do
+ * that :) )*/
+ IMB_TC_RECORD_RUN_NO_GAPS = 8,
+ IMB_TC_MAX_SLOT = 4,
} IMB_Timecode_Type;
typedef enum IMB_Proxy_Size {
- IMB_PROXY_NONE = 0,
- IMB_PROXY_25 = 1,
- IMB_PROXY_50 = 2,
- IMB_PROXY_75 = 4,
- IMB_PROXY_100 = 8,
- IMB_PROXY_MAX_SLOT = 4,
+ IMB_PROXY_NONE = 0,
+ IMB_PROXY_25 = 1,
+ IMB_PROXY_50 = 2,
+ IMB_PROXY_75 = 4,
+ IMB_PROXY_100 = 8,
+ IMB_PROXY_MAX_SLOT = 4,
} IMB_Proxy_Size;
/* defaults to BL_proxy within the directory of the animation */
void IMB_anim_set_index_dir(struct anim *anim, const char *dir);
void IMB_anim_get_fname(struct anim *anim, char *file, int size);
-int IMB_anim_index_get_frame_index(struct anim *anim, IMB_Timecode_Type tc,
- int position);
+int IMB_anim_index_get_frame_index(struct anim *anim, IMB_Timecode_Type tc, int position);
IMB_Proxy_Size IMB_anim_proxy_get_existing(struct anim *anim);
struct IndexBuildContext;
/* prepare context for proxies/imecodes builder */
-struct IndexBuildContext *IMB_anim_index_rebuild_context(struct anim *anim, IMB_Timecode_Type tcs_in_use,
- IMB_Proxy_Size proxy_sizes_in_use, int quality,
- const bool overwite, struct GSet *file_list);
+struct IndexBuildContext *IMB_anim_index_rebuild_context(struct anim *anim,
+ IMB_Timecode_Type tcs_in_use,
+ IMB_Proxy_Size proxy_sizes_in_use,
+ int quality,
+ const bool overwite,
+ struct GSet *file_list);
/* will rebuild all used indices and proxies at once */
void IMB_anim_index_rebuild(struct IndexBuildContext *context,
- short *stop, short *do_update, float *progress);
+ short *stop,
+ short *do_update,
+ float *progress);
/* finish rebuilding proxises/timecodes and free temporary contexts used */
void IMB_anim_index_rebuild_finish(struct IndexBuildContext *context, short stop);
@@ -281,19 +329,20 @@ void IMB_anim_index_rebuild_finish(struct IndexBuildContext *context, short stop
*/
int IMB_anim_get_duration(struct anim *anim, IMB_Timecode_Type tc);
-
/**
* Return the fps contained in movie files (function rval is false,
* and frs_sec and frs_sec_base untouched if none available!)
*/
-bool IMB_anim_get_fps(struct anim *anim,
- short *frs_sec, float *frs_sec_base, bool no_av_base);
+bool IMB_anim_get_fps(struct anim *anim, short *frs_sec, float *frs_sec_base, bool no_av_base);
/**
*
* \attention Defined in anim_movie.c
*/
-struct anim *IMB_open_anim(const char *name, int ib_flags, int streamindex, char colorspace[IM_MAX_SPACE]);
+struct anim *IMB_open_anim(const char *name,
+ int ib_flags,
+ int streamindex,
+ char colorspace[IM_MAX_SPACE]);
void IMB_suffix_anim(struct anim *anim, const char *suffix);
void IMB_close_anim(struct anim *anim);
void IMB_close_anim_proxies(struct anim *anim);
@@ -312,10 +361,10 @@ int IMB_anim_get_preseek(struct anim *anim);
* \attention Defined in anim_movie.c
*/
-struct ImBuf *IMB_anim_absolute(
- struct anim *anim, int position,
- IMB_Timecode_Type tc /* = 1 = IMB_TC_RECORD_RUN */,
- IMB_Proxy_Size preview_size /* = 0 = IMB_PROXY_NONE */);
+struct ImBuf *IMB_anim_absolute(struct anim *anim,
+ int position,
+ IMB_Timecode_Type tc /* = 1 = IMB_TC_RECORD_RUN */,
+ IMB_Proxy_Size preview_size /* = 0 = IMB_PROXY_NONE */);
/**
*
@@ -335,9 +384,9 @@ void IMB_free_anim(struct anim *anim);
* \attention Defined in filter.c
*/
-#define FILTER_MASK_NULL 0
-#define FILTER_MASK_MARGIN 1
-#define FILTER_MASK_USED 2
+#define FILTER_MASK_NULL 0
+#define FILTER_MASK_MARGIN 1
+#define FILTER_MASK_USED 2
void IMB_filter(struct ImBuf *ibuf);
void IMB_mask_filter_extend(char *mask, int width, int height);
@@ -398,7 +447,7 @@ bool IMB_prepare_write_ImBuf(const bool isfloat, struct ImBuf *ibuf);
* \attention Defined in util.c
*/
bool IMB_ispic(const char *name);
-int IMB_ispic_type(const char *name);
+int IMB_ispic_type(const char *name);
/**
*
@@ -422,32 +471,80 @@ bool IMB_isfloat(struct ImBuf *ibuf);
void IMB_rect_from_float(struct ImBuf *ibuf);
/* Create char buffer for part of the image, color corrected if necessary,
* Changed part will be stored in buffer. This is expected to be used for texture painting updates */
-void IMB_partial_rect_from_float(struct ImBuf *ibuf, float *buffer, int x, int y, int w, int h, bool is_data);
+void IMB_partial_rect_from_float(
+ struct ImBuf *ibuf, float *buffer, int x, int y, int w, int h, bool is_data);
void IMB_float_from_rect(struct ImBuf *ibuf);
void IMB_color_to_bw(struct ImBuf *ibuf);
void IMB_saturation(struct ImBuf *ibuf, float sat);
/* converting pixel buffers */
-void IMB_buffer_byte_from_float(unsigned char *rect_to, const float *rect_from,
- int channels_from, float dither, int profile_to, int profile_from, bool predivide,
- int width, int height, int stride_to, int stride_from);
-void IMB_buffer_byte_from_float_mask(unsigned char *rect_to, const float *rect_from,
- int channels_from, float dither, bool predivide,
- int width, int height, int stride_to, int stride_from, char *mask);
-void IMB_buffer_float_from_byte(float *rect_to, const unsigned char *rect_from,
- int profile_to, int profile_from, bool predivide,
- int width, int height, int stride_to, int stride_from);
-void IMB_buffer_float_from_float(float *rect_to, const float *rect_from,
- int channels_from, int profile_to, int profile_from, bool predivide,
- int width, int height, int stride_to, int stride_from);
-void IMB_buffer_float_from_float_threaded(float *rect_to, const float *rect_from,
- int channels_from, int profile_to, int profile_from, bool predivide,
- int width, int height, int stride_to, int stride_from);
-void IMB_buffer_float_from_float_mask(float *rect_to, const float *rect_from,
- int channels_from, int width, int height, int stride_to, int stride_from, char *mask);
-void IMB_buffer_byte_from_byte(unsigned char *rect_to, const unsigned char *rect_from,
- int profile_to, int profile_from, bool predivide,
- int width, int height, int stride_to, int stride_from);
+void IMB_buffer_byte_from_float(unsigned char *rect_to,
+ const float *rect_from,
+ int channels_from,
+ float dither,
+ int profile_to,
+ int profile_from,
+ bool predivide,
+ int width,
+ int height,
+ int stride_to,
+ int stride_from);
+void IMB_buffer_byte_from_float_mask(unsigned char *rect_to,
+ const float *rect_from,
+ int channels_from,
+ float dither,
+ bool predivide,
+ int width,
+ int height,
+ int stride_to,
+ int stride_from,
+ char *mask);
+void IMB_buffer_float_from_byte(float *rect_to,
+ const unsigned char *rect_from,
+ int profile_to,
+ int profile_from,
+ bool predivide,
+ int width,
+ int height,
+ int stride_to,
+ int stride_from);
+void IMB_buffer_float_from_float(float *rect_to,
+ const float *rect_from,
+ int channels_from,
+ int profile_to,
+ int profile_from,
+ bool predivide,
+ int width,
+ int height,
+ int stride_to,
+ int stride_from);
+void IMB_buffer_float_from_float_threaded(float *rect_to,
+ const float *rect_from,
+ int channels_from,
+ int profile_to,
+ int profile_from,
+ bool predivide,
+ int width,
+ int height,
+ int stride_to,
+ int stride_from);
+void IMB_buffer_float_from_float_mask(float *rect_to,
+ const float *rect_from,
+ int channels_from,
+ int width,
+ int height,
+ int stride_to,
+ int stride_from,
+ char *mask);
+void IMB_buffer_byte_from_byte(unsigned char *rect_to,
+ const unsigned char *rect_from,
+ int profile_to,
+ int profile_from,
+ bool predivide,
+ int width,
+ int height,
+ int stride_to,
+ int stride_from);
void IMB_buffer_float_clamp(float *buf, int width, int height);
void IMB_buffer_float_unpremultiply(float *buf, int width, int height);
void IMB_buffer_float_premultiply(float *buf, int width, int height);
@@ -464,15 +561,23 @@ void IMB_convert_rgba_to_abgr(struct ImBuf *ibuf);
*
* \attention defined in imageprocess.c
*/
-void bicubic_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
-void nearest_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
-void bilinear_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
-
-void bicubic_interpolation_color(struct ImBuf *in, unsigned char col[4], float col_float[4], float u, float v);
-void nearest_interpolation_color(struct ImBuf *in, unsigned char col[4], float col_float[4], float u, float v);
-void nearest_interpolation_color_wrap(struct ImBuf *in, unsigned char col[4], float col_float[4], float u, float v);
-void bilinear_interpolation_color(struct ImBuf *in, unsigned char col[4], float col_float[4], float u, float v);
-void bilinear_interpolation_color_wrap(struct ImBuf *in, unsigned char col[4], float col_float[4], float u, float v);
+void bicubic_interpolation(
+ struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
+void nearest_interpolation(
+ struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
+void bilinear_interpolation(
+ struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
+
+void bicubic_interpolation_color(
+ struct ImBuf *in, unsigned char col[4], float col_float[4], float u, float v);
+void nearest_interpolation_color(
+ struct ImBuf *in, unsigned char col[4], float col_float[4], float u, float v);
+void nearest_interpolation_color_wrap(
+ struct ImBuf *in, unsigned char col[4], float col_float[4], float u, float v);
+void bilinear_interpolation_color(
+ struct ImBuf *in, unsigned char col[4], float col_float[4], float u, float v);
+void bilinear_interpolation_color_wrap(
+ struct ImBuf *in, unsigned char col[4], float col_float[4], float u, float v);
void IMB_alpha_under_color_float(float *rect_float, int x, int y, float backcol[3]);
void IMB_alpha_under_color_byte(unsigned char *rect, int x, int y, float backcol[3]);
@@ -481,7 +586,8 @@ void IMB_alpha_under_color_byte(unsigned char *rect, int x, int y, float backcol
*
* \attention defined in readimage.c
*/
-struct ImBuf *IMB_loadifffile(int file, const char *filepath, int flags, char colorspace[IM_MAX_SPACE], const char *descr);
+struct ImBuf *IMB_loadifffile(
+ int file, const char *filepath, int flags, char colorspace[IM_MAX_SPACE], const char *descr);
/**
*
@@ -543,20 +649,30 @@ void IMB_freezbuffloatImBuf(struct ImBuf *ibuf);
* \attention Defined in rectop.c
*/
void IMB_rectfill(struct ImBuf *drect, const float col[4]);
-void IMB_rectfill_area(struct ImBuf *ibuf, const float col[4], int x1, int y1, int x2, int y2, struct ColorManagedDisplay *display);
+void IMB_rectfill_area(struct ImBuf *ibuf,
+ const float col[4],
+ int x1,
+ int y1,
+ int x2,
+ int y2,
+ struct ColorManagedDisplay *display);
void IMB_rectfill_alpha(struct ImBuf *ibuf, const float value);
/* this should not be here, really, we needed it for operating on render data, IMB_rectfill_area calls it */
-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);
+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);
/* exported for image tools in blender, to quickly allocate 32 bits rect */
-void *imb_alloc_pixels(unsigned int x,
- unsigned int y,
- unsigned int channels,
- size_t typesize,
- const char *name);
+void *imb_alloc_pixels(
+ unsigned int x, unsigned int y, unsigned int channels, size_t typesize, const char *name);
bool imb_addrectImBuf(struct ImBuf *ibuf);
void imb_freerectImBuf(struct ImBuf *ibuf);
@@ -569,19 +685,18 @@ bool imb_addtilesImBuf(struct ImBuf *ibuf);
void imb_freetilesImBuf(struct ImBuf *ibuf);
/* threaded processors */
-void IMB_processor_apply_threaded(int buffer_lines, int handle_size, void *init_customdata,
- void (init_handle) (void *handle, int start_line, int tot_line,
- void *customdata),
- void *(do_thread) (void *));
-
-typedef void (*ScanlineThreadFunc) (void *custom_data,
- int start_scanline,
- int num_scanlines);
+void IMB_processor_apply_threaded(
+ int buffer_lines,
+ int handle_size,
+ void *init_customdata,
+ void(init_handle)(void *handle, int start_line, int tot_line, void *customdata),
+ void *(do_thread)(void *));
+
+typedef void (*ScanlineThreadFunc)(void *custom_data, int start_scanline, int num_scanlines);
void IMB_processor_apply_threaded_scanlines(int total_scanlines,
ScanlineThreadFunc do_thread,
void *custom_data);
-
/* ffmpeg */
void IMB_ffmpeg_init(void);
const char *IMB_ffmpeg_last_error(void);
@@ -590,23 +705,36 @@ const char *IMB_ffmpeg_last_error(void);
*
* \attention defined in stereoimbuf.c
*/
-void IMB_stereo3d_write_dimensions(
- const char mode, const bool is_squeezed, const size_t width, const size_t height,
- size_t *r_width, size_t *r_height);
-void IMB_stereo3d_read_dimensions(
- const char mode, const bool is_squeezed, const size_t width, const size_t height,
- size_t *r_width, size_t *r_height);
-int *IMB_stereo3d_from_rect(
- struct ImageFormatData *im_format, const size_t x, const size_t y, const size_t channels,
- int *rect_left, int *rect_right);
-float *IMB_stereo3d_from_rectf(
- struct ImageFormatData *im_format, const size_t x, const size_t y, const size_t channels,
- float *rectf_left, float *rectf_right);
-struct ImBuf *IMB_stereo3d_ImBuf(
- struct ImageFormatData *im_format,
- struct ImBuf *ibuf_left, struct ImBuf *ibuf_right);
-void IMB_ImBufFromStereo3d(
- struct Stereo3dFormat *s3d, struct ImBuf *ibuf_stereo,
- struct ImBuf **r_ibuf_left, struct ImBuf **r_ibuf_right);
+void IMB_stereo3d_write_dimensions(const char mode,
+ const bool is_squeezed,
+ const size_t width,
+ const size_t height,
+ size_t *r_width,
+ size_t *r_height);
+void IMB_stereo3d_read_dimensions(const char mode,
+ const bool is_squeezed,
+ const size_t width,
+ const size_t height,
+ size_t *r_width,
+ size_t *r_height);
+int *IMB_stereo3d_from_rect(struct ImageFormatData *im_format,
+ const size_t x,
+ const size_t y,
+ const size_t channels,
+ int *rect_left,
+ int *rect_right);
+float *IMB_stereo3d_from_rectf(struct ImageFormatData *im_format,
+ const size_t x,
+ const size_t y,
+ const size_t channels,
+ float *rectf_left,
+ float *rectf_right);
+struct ImBuf *IMB_stereo3d_ImBuf(struct ImageFormatData *im_format,
+ struct ImBuf *ibuf_left,
+ struct ImBuf *ibuf_right);
+void IMB_ImBufFromStereo3d(struct Stereo3dFormat *s3d,
+ struct ImBuf *ibuf_stereo,
+ struct ImBuf **r_ibuf_left,
+ struct ImBuf **r_ibuf_right);
#endif
diff --git a/source/blender/imbuf/IMB_imbuf_types.h b/source/blender/imbuf/IMB_imbuf_types.h
index d6e33d0d186..d6bebe197c4 100644
--- a/source/blender/imbuf/IMB_imbuf_types.h
+++ b/source/blender/imbuf/IMB_imbuf_types.h
@@ -20,7 +20,7 @@
#ifndef __IMB_IMBUF_TYPES_H__
#define __IMB_IMBUF_TYPES_H__
-#include "DNA_vec_types.h" /* for rcti */
+#include "DNA_vec_types.h" /* for rcti */
/** \file
* \ingroup imbuf
@@ -38,18 +38,18 @@
* contains an Amiga-format file).
*/
-#define IMB_MIPMAP_LEVELS 20
-#define IMB_FILENAME_SIZE 1024
+#define IMB_MIPMAP_LEVELS 20
+#define IMB_FILENAME_SIZE 1024
typedef struct DDSData {
- /** DDS fourcc info */
- unsigned int fourcc;
- /** The number of mipmaps in the dds file */
- unsigned int nummipmaps;
- /** The compressed image data */
- unsigned char *data;
- /** The size of the compressed data */
- unsigned int size;
+ /** DDS fourcc info */
+ unsigned int fourcc;
+ /** The number of mipmaps in the dds file */
+ unsigned int nummipmaps;
+ /** The compressed image data */
+ unsigned char *data;
+ /** The size of the compressed data */
+ unsigned int size;
} DDSData;
/**
@@ -60,7 +60,6 @@ typedef struct DDSData {
* Also; add new variables to the end to save pain!
*/
-
/* Warning: Keep explicit value assignments here,
* this file is included in areas where not all format defines are set
* (e.g. intern/dds only get WITH_DDS, even if TIFF, HDR etc are also defined).
@@ -68,183 +67,183 @@ typedef struct DDSData {
/** #ImBuf.ftype flag, main image types. */
enum eImbTypes {
- IMB_FTYPE_PNG = 1,
- IMB_FTYPE_TGA = 2,
- IMB_FTYPE_JPG = 3,
- IMB_FTYPE_BMP = 4,
- IMB_FTYPE_OPENEXR = 5,
- IMB_FTYPE_IMAGIC = 6,
+ IMB_FTYPE_PNG = 1,
+ IMB_FTYPE_TGA = 2,
+ IMB_FTYPE_JPG = 3,
+ IMB_FTYPE_BMP = 4,
+ IMB_FTYPE_OPENEXR = 5,
+ IMB_FTYPE_IMAGIC = 6,
#ifdef WITH_OPENIMAGEIO
- IMB_FTYPE_PSD = 7,
+ IMB_FTYPE_PSD = 7,
#endif
#ifdef WITH_OPENJPEG
- IMB_FTYPE_JP2 = 8,
+ IMB_FTYPE_JP2 = 8,
#endif
#ifdef WITH_HDR
- IMB_FTYPE_RADHDR = 9,
+ IMB_FTYPE_RADHDR = 9,
#endif
#ifdef WITH_TIFF
- IMB_FTYPE_TIF = 10,
+ IMB_FTYPE_TIF = 10,
#endif
#ifdef WITH_CINEON
- IMB_FTYPE_CINEON = 11,
- IMB_FTYPE_DPX = 12,
+ IMB_FTYPE_CINEON = 11,
+ IMB_FTYPE_DPX = 12,
#endif
#ifdef WITH_DDS
- IMB_FTYPE_DDS = 13,
+ IMB_FTYPE_DDS = 13,
#endif
};
/* ibuf->foptions flag, type specific options.
* Some formats include compression rations on some bits */
-#define OPENEXR_HALF (1 << 8 )
+#define OPENEXR_HALF (1 << 8)
/* careful changing this, it's used in DNA as well */
#define OPENEXR_COMPRESS (15)
#ifdef WITH_CINEON
-#define CINEON_LOG (1 << 8)
-#define CINEON_16BIT (1 << 7)
-#define CINEON_12BIT (1 << 6)
-#define CINEON_10BIT (1 << 5)
+# define CINEON_LOG (1 << 8)
+# define CINEON_16BIT (1 << 7)
+# define CINEON_12BIT (1 << 6)
+# define CINEON_10BIT (1 << 5)
#endif
#ifdef WITH_OPENJPEG
-#define JP2_12BIT (1 << 9)
-#define JP2_16BIT (1 << 8)
-#define JP2_YCC (1 << 7)
-#define JP2_CINE (1 << 6)
-#define JP2_CINE_48FPS (1 << 5)
-#define JP2_JP2 (1 << 4)
-#define JP2_J2K (1 << 3)
+# define JP2_12BIT (1 << 9)
+# define JP2_16BIT (1 << 8)
+# define JP2_YCC (1 << 7)
+# define JP2_CINE (1 << 6)
+# define JP2_CINE_48FPS (1 << 5)
+# define JP2_JP2 (1 << 4)
+# define JP2_J2K (1 << 3)
#endif
-#define PNG_16BIT (1 << 10)
+#define PNG_16BIT (1 << 10)
-#define RAWTGA 1
+#define RAWTGA 1
#ifdef WITH_TIFF
-#define TIF_16BIT (1 << 8)
-#define TIF_COMPRESS_NONE (1 << 7)
-#define TIF_COMPRESS_DEFLATE (1 << 6)
-#define TIF_COMPRESS_LZW (1 << 5)
-#define TIF_COMPRESS_PACKBITS (1 << 4)
+# define TIF_16BIT (1 << 8)
+# define TIF_COMPRESS_NONE (1 << 7)
+# define TIF_COMPRESS_DEFLATE (1 << 6)
+# define TIF_COMPRESS_LZW (1 << 5)
+# define TIF_COMPRESS_PACKBITS (1 << 4)
#endif
typedef struct ImbFormatOptions {
- short flag;
- /** quality serves dual purpose as quality number for jpeg or compression amount for png */
- char quality;
+ short flag;
+ /** quality serves dual purpose as quality number for jpeg or compression amount for png */
+ char quality;
} ImbFormatOptions;
typedef struct ImBuf {
- struct ImBuf *next, *prev; /**< allow lists of ImBufs, for caches or flipbooks */
-
- /* dimensions */
- /** Width and Height of our image buffer.
- * Should be 'unsigned int' since most formats use this.
- * but this is problematic with texture math in imagetexture.c
- * avoid problems and use int. - campbell */
- int x, y;
-
- /** Active amount of bits/bitplanes */
- unsigned char planes;
- /** Number of channels in `rect_float` (0 = 4 channel default) */
- int channels;
-
- /* flags */
- /** Controls which components should exist. */
- int flags;
- /** what is malloced internal, and can be freed */
- int mall;
-
- /* pixels */
-
- /** Image pixel buffer (8bit representation):
- * - color space defaults to `sRGB`.
- * - alpha defaults to 'straight'.
- */
- unsigned int *rect;
- /** Image pixel buffer (float representation):
- * - color space defaults to 'linear' (`rec709`).
- * - alpha defaults to 'premul'.
- * \note May need gamma correction to `sRGB` when generating 8bit representations.
- * \note Formats that support higher more than 8 but channels load as floats.
- */
- float *rect_float;
-
- /* resolution - pixels per meter */
- double ppm[2];
-
- /* tiled pixel storage */
- int tilex, tiley;
- int xtiles, ytiles;
- unsigned int **tiles;
-
- /* zbuffer */
- /** z buffer data, original zbuffer */
- int *zbuf;
- /** z buffer data, camera coordinates */
- float *zbuf_float;
-
- /* parameters used by conversion between byte and float */
- /** random dither value, for conversion from float -> byte rect */
- float dither;
-
- /* mipmapping */
- /** MipMap levels, a series of halved images */
- struct ImBuf *mipmap[IMB_MIPMAP_LEVELS];
- int miptot, miplevel;
-
- /* externally used data */
- /** reference index for ImBuf lists */
- int index;
- /** used to set imbuf to dirty and other stuff */
- int userflags;
- /** image metadata */
- struct IDProperty *metadata;
- /** temporary storage */
- void *userdata;
-
- /* file information */
- /** file type we are going to save as */
- enum eImbTypes ftype;
- /** file format specific flags */
- ImbFormatOptions foptions;
- /** filename associated with this image */
- char name[IMB_FILENAME_SIZE];
- /** full filename used for reading from cache */
- char cachename[IMB_FILENAME_SIZE];
-
- /* memory cache limiter */
- /** handle for cache limiter */
- struct MEM_CacheLimiterHandle_s *c_handle;
- /** reference counter for multiple users */
- int refcounter;
-
- /* some parameters to pass along for packing images */
- /** Compressed image only used with png currently */
- unsigned char *encodedbuffer;
- /** Size of data written to encodedbuffer */
- unsigned int encodedsize;
- /** Size of encodedbuffer */
- unsigned int encodedbuffersize;
-
- /* color management */
- /** color space of byte buffer */
- struct ColorSpace *rect_colorspace;
- /** color space of float buffer, used by sequencer only */
- struct ColorSpace *float_colorspace;
- /** array of per-display display buffers dirty flags */
- unsigned int *display_buffer_flags;
- /** cache used by color management */
- struct ColormanageCache *colormanage_cache;
- int colormanage_flag;
- rcti invalid_rect;
-
- /* information for compressed textures */
- struct DDSData dds_data;
+ struct ImBuf *next, *prev; /**< allow lists of ImBufs, for caches or flipbooks */
+
+ /* dimensions */
+ /** Width and Height of our image buffer.
+ * Should be 'unsigned int' since most formats use this.
+ * but this is problematic with texture math in imagetexture.c
+ * avoid problems and use int. - campbell */
+ int x, y;
+
+ /** Active amount of bits/bitplanes */
+ unsigned char planes;
+ /** Number of channels in `rect_float` (0 = 4 channel default) */
+ int channels;
+
+ /* flags */
+ /** Controls which components should exist. */
+ int flags;
+ /** what is malloced internal, and can be freed */
+ int mall;
+
+ /* pixels */
+
+ /** Image pixel buffer (8bit representation):
+ * - color space defaults to `sRGB`.
+ * - alpha defaults to 'straight'.
+ */
+ unsigned int *rect;
+ /** Image pixel buffer (float representation):
+ * - color space defaults to 'linear' (`rec709`).
+ * - alpha defaults to 'premul'.
+ * \note May need gamma correction to `sRGB` when generating 8bit representations.
+ * \note Formats that support higher more than 8 but channels load as floats.
+ */
+ float *rect_float;
+
+ /* resolution - pixels per meter */
+ double ppm[2];
+
+ /* tiled pixel storage */
+ int tilex, tiley;
+ int xtiles, ytiles;
+ unsigned int **tiles;
+
+ /* zbuffer */
+ /** z buffer data, original zbuffer */
+ int *zbuf;
+ /** z buffer data, camera coordinates */
+ float *zbuf_float;
+
+ /* parameters used by conversion between byte and float */
+ /** random dither value, for conversion from float -> byte rect */
+ float dither;
+
+ /* mipmapping */
+ /** MipMap levels, a series of halved images */
+ struct ImBuf *mipmap[IMB_MIPMAP_LEVELS];
+ int miptot, miplevel;
+
+ /* externally used data */
+ /** reference index for ImBuf lists */
+ int index;
+ /** used to set imbuf to dirty and other stuff */
+ int userflags;
+ /** image metadata */
+ struct IDProperty *metadata;
+ /** temporary storage */
+ void *userdata;
+
+ /* file information */
+ /** file type we are going to save as */
+ enum eImbTypes ftype;
+ /** file format specific flags */
+ ImbFormatOptions foptions;
+ /** filename associated with this image */
+ char name[IMB_FILENAME_SIZE];
+ /** full filename used for reading from cache */
+ char cachename[IMB_FILENAME_SIZE];
+
+ /* memory cache limiter */
+ /** handle for cache limiter */
+ struct MEM_CacheLimiterHandle_s *c_handle;
+ /** reference counter for multiple users */
+ int refcounter;
+
+ /* some parameters to pass along for packing images */
+ /** Compressed image only used with png currently */
+ unsigned char *encodedbuffer;
+ /** Size of data written to encodedbuffer */
+ unsigned int encodedsize;
+ /** Size of encodedbuffer */
+ unsigned int encodedbuffersize;
+
+ /* color management */
+ /** color space of byte buffer */
+ struct ColorSpace *rect_colorspace;
+ /** color space of float buffer, used by sequencer only */
+ struct ColorSpace *float_colorspace;
+ /** array of per-display display buffers dirty flags */
+ unsigned int *display_buffer_flags;
+ /** cache used by color management */
+ struct ColormanageCache *colormanage_cache;
+ int colormanage_flag;
+ rcti invalid_rect;
+
+ /* information for compressed textures */
+ struct DDSData dds_data;
} ImBuf;
/**
@@ -252,16 +251,16 @@ typedef struct ImBuf {
*/
enum {
- /** image needs to be saved is not the same as filename */
- IB_BITMAPDIRTY = (1 << 1),
- /** image mipmaps are invalid, need recreate */
- IB_MIPMAP_INVALID = (1 << 2),
- /** float buffer changed, needs recreation of byte rect */
- IB_RECT_INVALID = (1 << 3),
- /** either float or byte buffer changed, need to re-calculate display buffers */
- IB_DISPLAY_BUFFER_INVALID = (1 << 4),
- /** image buffer is persistent in the memory and should never be removed from the cache */
- IB_PERSISTENT = (1 << 5),
+ /** image needs to be saved is not the same as filename */
+ IB_BITMAPDIRTY = (1 << 1),
+ /** image mipmaps are invalid, need recreate */
+ IB_MIPMAP_INVALID = (1 << 2),
+ /** float buffer changed, needs recreation of byte rect */
+ IB_RECT_INVALID = (1 << 3),
+ /** either float or byte buffer changed, need to re-calculate display buffers */
+ IB_DISPLAY_BUFFER_INVALID = (1 << 4),
+ /** image buffer is persistent in the memory and should never be removed from the cache */
+ IB_PERSISTENT = (1 << 5),
};
/**
@@ -271,25 +270,25 @@ enum {
* \{ */
enum {
- IB_rect = 1 << 0,
- IB_test = 1 << 1,
- IB_zbuf = 1 << 3,
- IB_mem = 1 << 4,
- IB_rectfloat = 1 << 5,
- IB_zbuffloat = 1 << 6,
- IB_multilayer = 1 << 7,
- IB_metadata = 1 << 8,
- IB_animdeinterlace = 1 << 9,
- IB_tiles = 1 << 10,
- IB_tilecache = 1 << 11,
- /** indicates whether image on disk have premul alpha */
- IB_alphamode_premul = 1 << 12,
- /** if this flag is set, alpha mode would be guessed from file */
- IB_alphamode_detect = 1 << 13,
- /** ignore alpha on load and substitute it with 1.0f */
- IB_ignore_alpha = 1 << 14,
- IB_thumbnail = 1 << 15,
- IB_multiview = 1 << 16,
+ IB_rect = 1 << 0,
+ IB_test = 1 << 1,
+ IB_zbuf = 1 << 3,
+ IB_mem = 1 << 4,
+ IB_rectfloat = 1 << 5,
+ IB_zbuffloat = 1 << 6,
+ IB_multilayer = 1 << 7,
+ IB_metadata = 1 << 8,
+ IB_animdeinterlace = 1 << 9,
+ IB_tiles = 1 << 10,
+ IB_tilecache = 1 << 11,
+ /** indicates whether image on disk have premul alpha */
+ IB_alphamode_premul = 1 << 12,
+ /** if this flag is set, alpha mode would be guessed from file */
+ IB_alphamode_detect = 1 << 13,
+ /** ignore alpha on load and substitute it with 1.0f */
+ IB_ignore_alpha = 1 << 14,
+ IB_thumbnail = 1 << 15,
+ IB_multiview = 1 << 16,
};
/** \} */
@@ -299,35 +298,33 @@ enum {
* \brief Some predefined color space profiles that 8 bit imbufs can represent
*
* \{ */
-#define IB_PROFILE_NONE 0
-#define IB_PROFILE_LINEAR_RGB 1
-#define IB_PROFILE_SRGB 2
-#define IB_PROFILE_CUSTOM 3
+#define IB_PROFILE_NONE 0
+#define IB_PROFILE_LINEAR_RGB 1
+#define IB_PROFILE_SRGB 2
+#define IB_PROFILE_CUSTOM 3
/** \} */
/* dds */
#ifdef WITH_DDS
-#ifndef DDS_MAKEFOURCC
-#define DDS_MAKEFOURCC(ch0, ch1, ch2, ch3)\
- ((unsigned long)(unsigned char)(ch0) | \
- ((unsigned long)(unsigned char)(ch1) << 8) | \
- ((unsigned long)(unsigned char)(ch2) << 16) | \
- ((unsigned long)(unsigned char)(ch3) << 24))
-#endif /* DDS_MAKEFOURCC */
+# ifndef DDS_MAKEFOURCC
+# define DDS_MAKEFOURCC(ch0, ch1, ch2, ch3) \
+ ((unsigned long)(unsigned char)(ch0) | ((unsigned long)(unsigned char)(ch1) << 8) | \
+ ((unsigned long)(unsigned char)(ch2) << 16) | ((unsigned long)(unsigned char)(ch3) << 24))
+# endif /* DDS_MAKEFOURCC */
/*
* FOURCC codes for DX compressed-texture pixel formats
*/
-#define FOURCC_DDS (DDS_MAKEFOURCC('D','D','S',' '))
-#define FOURCC_DXT1 (DDS_MAKEFOURCC('D','X','T','1'))
-#define FOURCC_DXT2 (DDS_MAKEFOURCC('D','X','T','2'))
-#define FOURCC_DXT3 (DDS_MAKEFOURCC('D','X','T','3'))
-#define FOURCC_DXT4 (DDS_MAKEFOURCC('D','X','T','4'))
-#define FOURCC_DXT5 (DDS_MAKEFOURCC('D','X','T','5'))
+# define FOURCC_DDS (DDS_MAKEFOURCC('D', 'D', 'S', ' '))
+# define FOURCC_DXT1 (DDS_MAKEFOURCC('D', 'X', 'T', '1'))
+# define FOURCC_DXT2 (DDS_MAKEFOURCC('D', 'X', 'T', '2'))
+# define FOURCC_DXT3 (DDS_MAKEFOURCC('D', 'X', 'T', '3'))
+# define FOURCC_DXT4 (DDS_MAKEFOURCC('D', 'X', 'T', '4'))
+# define FOURCC_DXT5 (DDS_MAKEFOURCC('D', 'X', 'T', '5'))
-#endif /* DDS */
+#endif /* DDS */
extern const char *imb_ext_image[];
extern const char *imb_ext_movie[];
extern const char *imb_ext_audio[];
@@ -342,9 +339,9 @@ extern const char *imb_ext_image_filepath_only[];
* \{ */
enum {
- IMB_COLORMANAGE_IS_DATA = (1 << 0),
+ IMB_COLORMANAGE_IS_DATA = (1 << 0),
};
/** \} */
-#endif /* __IMB_IMBUF_TYPES_H__ */
+#endif /* __IMB_IMBUF_TYPES_H__ */
diff --git a/source/blender/imbuf/IMB_metadata.h b/source/blender/imbuf/IMB_metadata.h
index d4e8dc1a3b6..64a8db6c526 100644
--- a/source/blender/imbuf/IMB_metadata.h
+++ b/source/blender/imbuf/IMB_metadata.h
@@ -21,7 +21,6 @@
* \ingroup imbuf
*/
-
#ifndef __IMB_METADATA_H__
#define __IMB_METADATA_H__
@@ -53,7 +52,10 @@ void IMB_metadata_free(struct IDProperty *metadata);
* \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);
+bool IMB_metadata_get_field(struct IDProperty *metadata,
+ const char *key,
+ char *value,
+ const size_t len);
/** Set user data in the metadata.
* If the field already exists its value is overwritten, otherwise the field
diff --git a/source/blender/imbuf/IMB_moviecache.h b/source/blender/imbuf/IMB_moviecache.h
index 706c7b1a7db..25494df9c00 100644
--- a/source/blender/imbuf/IMB_moviecache.h
+++ b/source/blender/imbuf/IMB_moviecache.h
@@ -34,18 +34,23 @@
struct ImBuf;
struct MovieCache;
-typedef void (*MovieCacheGetKeyDataFP) (void *userkey, int *framenr, int *proxy, int *render_flags);
+typedef void (*MovieCacheGetKeyDataFP)(void *userkey, int *framenr, int *proxy, int *render_flags);
-typedef void *(*MovieCacheGetPriorityDataFP) (void *userkey);
-typedef int (*MovieCacheGetItemPriorityFP) (void *last_userkey, void *priority_data);
-typedef void (*MovieCachePriorityDeleterFP) (void *priority_data);
+typedef void *(*MovieCacheGetPriorityDataFP)(void *userkey);
+typedef int (*MovieCacheGetItemPriorityFP)(void *last_userkey, void *priority_data);
+typedef void (*MovieCachePriorityDeleterFP)(void *priority_data);
void IMB_moviecache_init(void);
void IMB_moviecache_destruct(void);
-struct MovieCache *IMB_moviecache_create(const char *name, int keysize, GHashHashFP hashfp, GHashCmpFP cmpfp);
-void IMB_moviecache_set_getdata_callback(struct MovieCache *cache, MovieCacheGetKeyDataFP getdatafp);
-void IMB_moviecache_set_priority_callback(struct MovieCache *cache, MovieCacheGetPriorityDataFP getprioritydatafp,
+struct MovieCache *IMB_moviecache_create(const char *name,
+ int keysize,
+ GHashHashFP hashfp,
+ GHashCmpFP cmpfp);
+void IMB_moviecache_set_getdata_callback(struct MovieCache *cache,
+ MovieCacheGetKeyDataFP getdatafp);
+void IMB_moviecache_set_priority_callback(struct MovieCache *cache,
+ MovieCacheGetPriorityDataFP getprioritydatafp,
MovieCacheGetItemPriorityFP getitempriorityfp,
MovieCachePriorityDeleterFP prioritydeleterfp);
@@ -56,10 +61,13 @@ bool IMB_moviecache_has_frame(struct MovieCache *cache, void *userkey);
void IMB_moviecache_free(struct MovieCache *cache);
void IMB_moviecache_cleanup(struct MovieCache *cache,
- bool (cleanup_check_cb) (struct ImBuf *ibuf, void *userkey, void *userdata),
+ bool(cleanup_check_cb)(struct ImBuf *ibuf,
+ void *userkey,
+ void *userdata),
void *userdata);
-void IMB_moviecache_get_cache_segments(struct MovieCache *cache, int proxy, int render_flags, int *totseg_r, int **points_r);
+void IMB_moviecache_get_cache_segments(
+ struct MovieCache *cache, int proxy, int render_flags, int *totseg_r, int **points_r);
struct MovieCacheIter;
struct MovieCacheIter *IMB_moviecacheIter_new(struct MovieCache *cache);
diff --git a/source/blender/imbuf/IMB_thumbs.h b/source/blender/imbuf/IMB_thumbs.h
index 1c64edb21da..bac408e869b 100644
--- a/source/blender/imbuf/IMB_thumbs.h
+++ b/source/blender/imbuf/IMB_thumbs.h
@@ -21,7 +21,6 @@
* \ingroup imbuf
*/
-
#ifndef __IMB_THUMBS_H__
#define __IMB_THUMBS_H__
@@ -36,18 +35,17 @@ struct ImBuf;
* Reference: http://jens.triq.net/thumbnail-spec/index.html
*/
-
typedef enum ThumbSize {
- THB_NORMAL,
- THB_LARGE,
- THB_FAIL,
+ THB_NORMAL,
+ THB_LARGE,
+ THB_FAIL,
} ThumbSize;
typedef enum ThumbSource {
- THB_SOURCE_IMAGE,
- THB_SOURCE_MOVIE,
- THB_SOURCE_BLEND,
- THB_SOURCE_FONT,
+ THB_SOURCE_IMAGE,
+ THB_SOURCE_MOVIE,
+ THB_SOURCE_BLEND,
+ THB_SOURCE_FONT,
} ThumbSource;
/* don't generate thumbs for images bigger then this (100mb) */
@@ -58,7 +56,7 @@ typedef enum ThumbSource {
/* Note this can also be used as versioning system,
* to force refreshing all thumbnails if e.g. we change some thumb generating code or so.
* Only used by fonts so far. */
-#define THUMB_DEFAULT_HASH "00000000000000000000000000000000"
+#define THUMB_DEFAULT_HASH "00000000000000000000000000000000"
/* create thumbnail for file and returns new imbuf for thumbnail */
ImBuf *IMB_thumb_create(const char *path, ThumbSize size, ThumbSource source, ImBuf *ibuf);
@@ -77,7 +75,7 @@ void IMB_thumb_makedirs(void);
/* special function for loading a thumbnail embedded into a blend file */
ImBuf *IMB_thumb_load_blend(const char *blen_path, const char *blen_group, const char *blen_id);
-void IMB_thumb_overlay_blend(unsigned int *thumb, int width, int height, float aspect);
+void IMB_thumb_overlay_blend(unsigned int *thumb, int width, int height, float aspect);
/* special function for previewing fonts */
ImBuf *IMB_thumb_load_font(const char *filename, unsigned int x, unsigned int y);
diff --git a/source/blender/imbuf/intern/IMB_anim.h b/source/blender/imbuf/intern/IMB_anim.h
index a0a8a938870..065c7e64d07 100644
--- a/source/blender/imbuf/intern/IMB_anim.h
+++ b/source/blender/imbuf/intern/IMB_anim.h
@@ -21,7 +21,6 @@
* \ingroup imbuf
*/
-
#ifndef __IMB_ANIM_H__
#define __IMB_ANIM_H__
@@ -34,9 +33,9 @@
# include <commdlg.h>
# include <vfw.h>
-# undef AVIIF_KEYFRAME // redefined in AVI_avi.h
-# undef AVIIF_LIST // redefined in AVI_avi.h
-#endif /* _WIN32 */
+# undef AVIIF_KEYFRAME // redefined in AVI_avi.h
+# undef AVIIF_LIST // redefined in AVI_avi.h
+#endif /* _WIN32 */
#include <sys/types.h>
#include <ctype.h>
@@ -74,84 +73,84 @@
#endif
/* anim.curtype, runtime only */
-#define ANIM_NONE 0
-#define ANIM_SEQUENCE (1 << 0)
-#define ANIM_MOVIE (1 << 4)
-#define ANIM_AVI (1 << 6)
-#define ANIM_FFMPEG (1 << 8)
+#define ANIM_NONE 0
+#define ANIM_SEQUENCE (1 << 0)
+#define ANIM_MOVIE (1 << 4)
+#define ANIM_AVI (1 << 6)
+#define ANIM_FFMPEG (1 << 8)
-#define MAXNUMSTREAMS 50
+#define MAXNUMSTREAMS 50
struct IDProperty;
struct _AviMovie;
struct anim_index;
struct anim {
- int ib_flags;
- int curtype;
- int curposition; /* index 0 = 1e, 1 = 2e, enz. */
- int duration;
- int frs_sec;
- double frs_sec_base;
- int x, y;
-
- /* for number */
- char name[1024];
- /* for sequence */
- char first[1024];
-
- /* movie */
- void *movie;
- void *track;
- void *params;
- int orientation;
- size_t framesize;
- int interlacing;
- int preseek;
- int streamindex;
-
- /* avi */
- struct _AviMovie *avi;
+ int ib_flags;
+ int curtype;
+ int curposition; /* index 0 = 1e, 1 = 2e, enz. */
+ int duration;
+ int frs_sec;
+ double frs_sec_base;
+ int x, y;
+
+ /* for number */
+ char name[1024];
+ /* for sequence */
+ char first[1024];
+
+ /* movie */
+ void *movie;
+ void *track;
+ void *params;
+ int orientation;
+ size_t framesize;
+ int interlacing;
+ int preseek;
+ int streamindex;
+
+ /* avi */
+ struct _AviMovie *avi;
#if defined(_WIN32)
- /* windows avi */
- int avistreams;
- int firstvideo;
- int pfileopen;
- PAVIFILE pfile;
- PAVISTREAM pavi[MAXNUMSTREAMS]; // the current streams
- PGETFRAME pgf;
+ /* windows avi */
+ int avistreams;
+ int firstvideo;
+ int pfileopen;
+ PAVIFILE pfile;
+ PAVISTREAM pavi[MAXNUMSTREAMS]; // the current streams
+ PGETFRAME pgf;
#endif
#ifdef WITH_FFMPEG
- AVFormatContext *pFormatCtx;
- AVCodecContext *pCodecCtx;
- AVCodec *pCodec;
- AVFrame *pFrame;
- int pFrameComplete;
- AVFrame *pFrameRGB;
- AVFrame *pFrameDeinterlaced;
- struct SwsContext *img_convert_ctx;
- int videoStream;
-
- struct ImBuf *last_frame;
- int64_t last_pts;
- int64_t next_pts;
- AVPacket next_packet;
+ AVFormatContext *pFormatCtx;
+ AVCodecContext *pCodecCtx;
+ AVCodec *pCodec;
+ AVFrame *pFrame;
+ int pFrameComplete;
+ AVFrame *pFrameRGB;
+ AVFrame *pFrameDeinterlaced;
+ struct SwsContext *img_convert_ctx;
+ int videoStream;
+
+ struct ImBuf *last_frame;
+ int64_t last_pts;
+ int64_t next_pts;
+ AVPacket next_packet;
#endif
- char index_dir[768];
+ char index_dir[768];
- int proxies_tried;
- int indices_tried;
+ int proxies_tried;
+ int indices_tried;
- struct anim *proxy_anim[IMB_PROXY_MAX_SLOT];
- struct anim_index *curr_idx[IMB_TC_MAX_SLOT];
+ struct anim *proxy_anim[IMB_PROXY_MAX_SLOT];
+ struct anim_index *curr_idx[IMB_TC_MAX_SLOT];
- char colorspace[64];
- char suffix[64]; /* MAX_NAME - multiview */
+ char colorspace[64];
+ char suffix[64]; /* MAX_NAME - multiview */
- struct IDProperty *metadata;
+ struct IDProperty *metadata;
};
#endif
diff --git a/source/blender/imbuf/intern/IMB_colormanagement_intern.h b/source/blender/imbuf/intern/IMB_colormanagement_intern.h
index 7ab36b69704..2566016ffdd 100644
--- a/source/blender/imbuf/intern/IMB_colormanagement_intern.h
+++ b/source/blender/imbuf/intern/IMB_colormanagement_intern.h
@@ -34,46 +34,46 @@ extern float imbuf_luma_coefficients[3];
extern float imbuf_xyz_to_rgb[3][3];
extern float imbuf_rgb_to_xyz[3][3];
-#define MAX_COLORSPACE_NAME 64
-#define MAX_COLORSPACE_DESCRIPTION 512
+#define MAX_COLORSPACE_NAME 64
+#define MAX_COLORSPACE_DESCRIPTION 512
typedef struct ColorSpace {
- struct ColorSpace *next, *prev;
- int index;
- char name[MAX_COLORSPACE_NAME];
- char description[MAX_COLORSPACE_DESCRIPTION];
+ struct ColorSpace *next, *prev;
+ int index;
+ char name[MAX_COLORSPACE_NAME];
+ char description[MAX_COLORSPACE_DESCRIPTION];
- struct OCIO_ConstProcessorRcPtr *to_scene_linear;
- struct OCIO_ConstProcessorRcPtr *from_scene_linear;
+ struct OCIO_ConstProcessorRcPtr *to_scene_linear;
+ struct OCIO_ConstProcessorRcPtr *from_scene_linear;
- bool is_invertible;
- bool is_data;
+ bool is_invertible;
+ bool is_data;
} ColorSpace;
typedef struct ColorManagedDisplay {
- struct ColorManagedDisplay *next, *prev;
- int index;
- char name[MAX_COLORSPACE_NAME];
- ListBase views; /* LinkData.data -> ColorManagedView */
+ struct ColorManagedDisplay *next, *prev;
+ int index;
+ char name[MAX_COLORSPACE_NAME];
+ ListBase views; /* LinkData.data -> ColorManagedView */
- struct OCIO_ConstProcessorRcPtr *to_scene_linear;
- struct OCIO_ConstProcessorRcPtr *from_scene_linear;
+ struct OCIO_ConstProcessorRcPtr *to_scene_linear;
+ struct OCIO_ConstProcessorRcPtr *from_scene_linear;
} ColorManagedDisplay;
typedef struct ColorManagedView {
- struct ColorManagedView *next, *prev;
- int index;
- char name[MAX_COLORSPACE_NAME];
+ struct ColorManagedView *next, *prev;
+ int index;
+ char name[MAX_COLORSPACE_NAME];
} ColorManagedView;
typedef struct ColorManagedLook {
- struct ColorManagedLook *next, *prev;
- int index;
- char name[MAX_COLORSPACE_NAME];
- char ui_name[MAX_COLORSPACE_NAME];
- char view[MAX_COLORSPACE_NAME];
- char process_space[MAX_COLORSPACE_NAME];
- bool is_noop;
+ struct ColorManagedLook *next, *prev;
+ int index;
+ char name[MAX_COLORSPACE_NAME];
+ char ui_name[MAX_COLORSPACE_NAME];
+ char view[MAX_COLORSPACE_NAME];
+ char process_space[MAX_COLORSPACE_NAME];
+ bool is_noop;
} ColorManagedLook;
/* ** Initialization / De-initialization ** */
@@ -94,15 +94,20 @@ struct ColorManagedView *colormanage_view_get_default(const ColorManagedDisplay
struct ColorManagedView *colormanage_view_add(const char *name);
struct ColorManagedView *colormanage_view_get_indexed(int index);
struct ColorManagedView *colormanage_view_get_named(const char *name);
-struct ColorManagedView *colormanage_view_get_named_for_display(
- const char *display_name, const char *name);
+struct ColorManagedView *colormanage_view_get_named_for_display(const char *display_name,
+ const char *name);
-struct ColorSpace *colormanage_colorspace_add(const char *name, const char *description, bool is_invertible, bool is_data);
+struct ColorSpace *colormanage_colorspace_add(const char *name,
+ const char *description,
+ bool is_invertible,
+ bool is_data);
struct ColorSpace *colormanage_colorspace_get_named(const char *name);
struct ColorSpace *colormanage_colorspace_get_roled(int role);
struct ColorSpace *colormanage_colorspace_get_indexed(int index);
-struct ColorManagedLook *colormanage_look_add(const char *name, const char *process_space, bool is_noop);
+struct ColorManagedLook *colormanage_look_add(const char *name,
+ const char *process_space,
+ bool is_noop);
struct ColorManagedLook *colormanage_look_get_named(const char *name);
struct ColorManagedLook *colormanage_look_get_indexed(int index);
@@ -111,4 +116,4 @@ void colorspace_set_default_role(char *colorspace, int size, int role);
void colormanage_imbuf_set_default_spaces(struct ImBuf *ibuf);
void colormanage_imbuf_make_linear(struct ImBuf *ibuf, const char *from_colorspace);
-#endif /* __IMB_COLORMANAGEMENT_INTERN_H__ */
+#endif /* __IMB_COLORMANAGEMENT_INTERN_H__ */
diff --git a/source/blender/imbuf/intern/IMB_filetype.h b/source/blender/imbuf/intern/IMB_filetype.h
index 8ce1a293d0f..5048414ac65 100644
--- a/source/blender/imbuf/intern/IMB_filetype.h
+++ b/source/blender/imbuf/intern/IMB_filetype.h
@@ -18,7 +18,6 @@
* \ingroup imbuf
*/
-
#ifndef __IMB_FILETYPE_H__
#define __IMB_FILETYPE_H__
@@ -26,23 +25,31 @@
struct ImBuf;
-#define IM_FTYPE_FLOAT 1
+#define IM_FTYPE_FLOAT 1
typedef struct ImFileType {
- void (*init)(void);
- void (*exit)(void);
-
- int (*is_a)(const unsigned char *buf);
- int (*is_a_filepath)(const char *name);
- int (*ftype)(const struct ImFileType *type, struct ImBuf *ibuf);
- struct ImBuf *(*load)(const unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE]);
- struct ImBuf *(*load_filepath)(const char *name, int flags, char colorspace[IM_MAX_SPACE]);
- int (*save)(struct ImBuf *ibuf, const char *name, int flags);
- void (*load_tile)(struct ImBuf *ibuf, const unsigned char *mem, size_t size, int tx, int ty, unsigned int *rect);
-
- int flag;
- int filetype;
- int default_save_role;
+ void (*init)(void);
+ void (*exit)(void);
+
+ int (*is_a)(const unsigned char *buf);
+ int (*is_a_filepath)(const char *name);
+ int (*ftype)(const struct ImFileType *type, struct ImBuf *ibuf);
+ struct ImBuf *(*load)(const unsigned char *mem,
+ size_t size,
+ int flags,
+ char colorspace[IM_MAX_SPACE]);
+ struct ImBuf *(*load_filepath)(const char *name, int flags, char colorspace[IM_MAX_SPACE]);
+ int (*save)(struct ImBuf *ibuf, const char *name, int flags);
+ void (*load_tile)(struct ImBuf *ibuf,
+ const unsigned char *mem,
+ size_t size,
+ int tx,
+ int ty,
+ unsigned int *rect);
+
+ int flag;
+ int filetype;
+ int default_save_role;
} ImFileType;
extern const ImFileType IMB_FILE_TYPES[];
@@ -61,56 +68,86 @@ void imb_tile_cache_tile_free(struct ImBuf *ibuf, int tx, int ty);
/* png */
int imb_is_a_png(const unsigned char *buf);
-struct ImBuf *imb_loadpng(const unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE]);
+struct ImBuf *imb_loadpng(const unsigned char *mem,
+ size_t size,
+ int flags,
+ char colorspace[IM_MAX_SPACE]);
int imb_savepng(struct ImBuf *ibuf, const char *name, int flags);
/* targa */
int imb_is_a_targa(const unsigned char *buf);
-struct ImBuf *imb_loadtarga(const unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE]);
+struct ImBuf *imb_loadtarga(const unsigned char *mem,
+ size_t size,
+ int flags,
+ char colorspace[IM_MAX_SPACE]);
int imb_savetarga(struct ImBuf *ibuf, const char *name, int flags);
/* iris */
int imb_is_a_iris(const unsigned char *mem);
-struct ImBuf *imb_loadiris(const unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE]);
+struct ImBuf *imb_loadiris(const unsigned char *mem,
+ size_t size,
+ int flags,
+ char colorspace[IM_MAX_SPACE]);
int imb_saveiris(struct ImBuf *ibuf, const char *name, int flags);
/* jp2 */
int imb_is_a_jp2(const unsigned char *buf);
-struct ImBuf *imb_load_jp2(const unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE]);
+struct ImBuf *imb_load_jp2(const unsigned char *mem,
+ size_t size,
+ int flags,
+ char colorspace[IM_MAX_SPACE]);
struct ImBuf *imb_load_jp2_filepath(const char *name, int flags, char colorspace[IM_MAX_SPACE]);
int imb_save_jp2(struct ImBuf *ibuf, const char *name, int flags);
/* jpeg */
int imb_is_a_jpeg(const unsigned char *mem);
int imb_savejpeg(struct ImBuf *ibuf, const char *name, int flags);
-struct ImBuf *imb_load_jpeg(const unsigned char *buffer, size_t size, int flags, char colorspace[IM_MAX_SPACE]);
+struct ImBuf *imb_load_jpeg(const unsigned char *buffer,
+ size_t size,
+ int flags,
+ char colorspace[IM_MAX_SPACE]);
/* bmp */
int imb_is_a_bmp(const unsigned char *buf);
-struct ImBuf *imb_bmp_decode(const unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE]);
+struct ImBuf *imb_bmp_decode(const unsigned char *mem,
+ size_t size,
+ int flags,
+ char colorspace[IM_MAX_SPACE]);
int imb_savebmp(struct ImBuf *ibuf, const char *name, int flags);
/* cineon */
int imb_is_cineon(const unsigned char *buf);
int imb_save_cineon(struct ImBuf *buf, const char *name, int flags);
-struct ImBuf *imb_load_cineon(const unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE]);
+struct ImBuf *imb_load_cineon(const unsigned char *mem,
+ size_t size,
+ int flags,
+ char colorspace[IM_MAX_SPACE]);
/* dpx */
int imb_is_dpx(const unsigned char *buf);
int imb_save_dpx(struct ImBuf *buf, const char *name, int flags);
-struct ImBuf *imb_load_dpx(const unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE]);
+struct ImBuf *imb_load_dpx(const unsigned char *mem,
+ size_t size,
+ int flags,
+ char colorspace[IM_MAX_SPACE]);
/* hdr */
int imb_is_a_hdr(const unsigned char *buf);
-struct ImBuf *imb_loadhdr(const unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE]);
+struct ImBuf *imb_loadhdr(const unsigned char *mem,
+ size_t size,
+ int flags,
+ char colorspace[IM_MAX_SPACE]);
int imb_savehdr(struct ImBuf *ibuf, const char *name, int flags);
/* tiff */
void imb_inittiff(void);
int imb_is_a_tiff(const unsigned char *buf);
-struct ImBuf *imb_loadtiff(const unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE]);
-void imb_loadtiletiff(struct ImBuf *ibuf, const unsigned char *mem, size_t size,
- int tx, int ty, unsigned int *rect);
+struct ImBuf *imb_loadtiff(const unsigned char *mem,
+ size_t size,
+ int flags,
+ char colorspace[IM_MAX_SPACE]);
+void imb_loadtiletiff(
+ struct ImBuf *ibuf, const unsigned char *mem, size_t size, int tx, int ty, unsigned int *rect);
int imb_savetiff(struct ImBuf *ibuf, const char *name, int flags);
-#endif /* __IMB_FILETYPE_H__ */
+#endif /* __IMB_FILETYPE_H__ */
diff --git a/source/blender/imbuf/intern/IMB_indexer.h b/source/blender/imbuf/intern/IMB_indexer.h
index 02ba846d148..4817518dab6 100644
--- a/source/blender/imbuf/intern/IMB_indexer.h
+++ b/source/blender/imbuf/intern/IMB_indexer.h
@@ -14,7 +14,6 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-
#ifndef __IMB_INDEXER_H__
#define __IMB_INDEXER_H__
@@ -49,74 +48,68 @@
*/
typedef struct anim_index_entry {
- int frameno;
- unsigned long long seek_pos;
- unsigned long long seek_pos_dts;
- unsigned long long pts;
+ int frameno;
+ unsigned long long seek_pos;
+ unsigned long long seek_pos_dts;
+ unsigned long long pts;
} anim_index_entry;
struct anim_index {
- char name[1024];
+ char name[1024];
- int num_entries;
- struct anim_index_entry *entries;
+ int num_entries;
+ struct anim_index_entry *entries;
};
struct anim_index_builder;
typedef struct anim_index_builder {
- FILE *fp;
- char name[FILE_MAX];
- char temp_name[FILE_MAX];
+ FILE *fp;
+ char name[FILE_MAX];
+ char temp_name[FILE_MAX];
- void *private_data;
+ void *private_data;
- void (*delete_priv_data)(struct anim_index_builder *idx);
- void (*proc_frame)(struct anim_index_builder *idx,
- unsigned char *buffer,
- int data_size,
- struct anim_index_entry *entry);
+ void (*delete_priv_data)(struct anim_index_builder *idx);
+ void (*proc_frame)(struct anim_index_builder *idx,
+ unsigned char *buffer,
+ int data_size,
+ struct anim_index_entry *entry);
} anim_index_builder;
anim_index_builder *IMB_index_builder_create(const char *name);
-void IMB_index_builder_add_entry(
- anim_index_builder *fp,
- int frameno, unsigned long long seek_pos,
- unsigned long long seek_pos_dts,
- unsigned long long pts);
-
-void IMB_index_builder_proc_frame(
- anim_index_builder *fp,
- unsigned char *buffer,
- int data_size,
- int frameno, unsigned long long seek_pos,
- unsigned long long seek_pos_dts,
- unsigned long long pts);
+void IMB_index_builder_add_entry(anim_index_builder *fp,
+ int frameno,
+ unsigned long long seek_pos,
+ unsigned long long seek_pos_dts,
+ unsigned long long pts);
+
+void IMB_index_builder_proc_frame(anim_index_builder *fp,
+ unsigned char *buffer,
+ int data_size,
+ int frameno,
+ unsigned long long seek_pos,
+ unsigned long long seek_pos_dts,
+ unsigned long long pts);
void IMB_index_builder_finish(anim_index_builder *fp, int rollback);
struct anim_index *IMB_indexer_open(const char *name);
-unsigned long long IMB_indexer_get_seek_pos(
- struct anim_index *idx, int frameno_index);
-unsigned long long IMB_indexer_get_seek_pos_dts(
- struct anim_index *idx, int frameno_index);
+unsigned long long IMB_indexer_get_seek_pos(struct anim_index *idx, int frameno_index);
+unsigned long long IMB_indexer_get_seek_pos_dts(struct anim_index *idx, int frameno_index);
int IMB_indexer_get_frame_index(struct anim_index *idx, int frameno);
-unsigned long long IMB_indexer_get_pts(struct anim_index *idx,
- int frame_index);
+unsigned long long IMB_indexer_get_pts(struct anim_index *idx, int frame_index);
int IMB_indexer_get_duration(struct anim_index *idx);
-int IMB_indexer_can_scan(struct anim_index *idx,
- int old_frame_index, int new_frame_index);
+int IMB_indexer_can_scan(struct anim_index *idx, int old_frame_index, int new_frame_index);
void IMB_indexer_close(struct anim_index *idx);
void IMB_free_indices(struct anim *anim);
-struct anim *IMB_anim_open_proxy(
- struct anim *anim, IMB_Proxy_Size preview_size);
-struct anim_index *IMB_anim_open_index(
- struct anim *anim, IMB_Timecode_Type tc);
+struct anim *IMB_anim_open_proxy(struct anim *anim, IMB_Proxy_Size preview_size);
+struct anim_index *IMB_anim_open_index(struct anim *anim, IMB_Timecode_Type tc);
int IMB_proxy_size_to_array_index(IMB_Proxy_Size pr_size);
int IMB_timecode_to_array_index(IMB_Timecode_Type tc);
diff --git a/source/blender/imbuf/intern/allocimbuf.c b/source/blender/imbuf/intern/allocimbuf.c
index ac284657c5c..2c253f7f0e6 100644
--- a/source/blender/imbuf/intern/allocimbuf.c
+++ b/source/blender/imbuf/intern/allocimbuf.c
@@ -21,7 +21,6 @@
* \ingroup imbuf
*/
-
/* It's become a bit messy... Basically, only the IMB_ prefixed files
* should remain. */
@@ -46,12 +45,12 @@ static SpinLock refcounter_spin;
void imb_refcounter_lock_init(void)
{
- BLI_spin_init(&refcounter_spin);
+ BLI_spin_init(&refcounter_spin);
}
void imb_refcounter_lock_exit(void)
{
- BLI_spin_end(&refcounter_spin);
+ BLI_spin_end(&refcounter_spin);
}
#ifdef WIN32
@@ -59,505 +58,528 @@ static SpinLock mmap_spin;
void imb_mmap_lock_init(void)
{
- BLI_spin_init(&mmap_spin);
+ BLI_spin_init(&mmap_spin);
}
void imb_mmap_lock_exit(void)
{
- BLI_spin_end(&mmap_spin);
+ BLI_spin_end(&mmap_spin);
}
void imb_mmap_lock(void)
{
- BLI_spin_lock(&mmap_spin);
+ BLI_spin_lock(&mmap_spin);
}
void imb_mmap_unlock(void)
{
- BLI_spin_unlock(&mmap_spin);
+ BLI_spin_unlock(&mmap_spin);
}
#endif
void imb_freemipmapImBuf(ImBuf *ibuf)
{
- int a;
-
- /* Do not trust ibuf->miptot, in some cases IMB_remakemipmap can leave unfreed unused levels,
- * leading to memory leaks... */
- for (a = 0; a < IMB_MIPMAP_LEVELS; a++) {
- if (ibuf->mipmap[a] != NULL) {
- IMB_freeImBuf(ibuf->mipmap[a]);
- ibuf->mipmap[a] = NULL;
- }
- }
-
- ibuf->miptot = 0;
+ int a;
+
+ /* Do not trust ibuf->miptot, in some cases IMB_remakemipmap can leave unfreed unused levels,
+ * leading to memory leaks... */
+ for (a = 0; a < IMB_MIPMAP_LEVELS; a++) {
+ if (ibuf->mipmap[a] != NULL) {
+ IMB_freeImBuf(ibuf->mipmap[a]);
+ ibuf->mipmap[a] = NULL;
+ }
+ }
+
+ ibuf->miptot = 0;
}
/* any free rect frees mipmaps to be sure, creation is in render on first request */
void imb_freerectfloatImBuf(ImBuf *ibuf)
{
- if (ibuf == NULL) return;
+ if (ibuf == NULL)
+ return;
- if (ibuf->rect_float && (ibuf->mall & IB_rectfloat)) {
- MEM_freeN(ibuf->rect_float);
- ibuf->rect_float = NULL;
- }
+ if (ibuf->rect_float && (ibuf->mall & IB_rectfloat)) {
+ MEM_freeN(ibuf->rect_float);
+ ibuf->rect_float = NULL;
+ }
- imb_freemipmapImBuf(ibuf);
+ imb_freemipmapImBuf(ibuf);
- ibuf->rect_float = NULL;
- ibuf->mall &= ~IB_rectfloat;
+ ibuf->rect_float = NULL;
+ ibuf->mall &= ~IB_rectfloat;
}
/* any free rect frees mipmaps to be sure, creation is in render on first request */
void imb_freerectImBuf(ImBuf *ibuf)
{
- if (ibuf == NULL) return;
+ if (ibuf == NULL)
+ return;
- if (ibuf->rect && (ibuf->mall & IB_rect))
- MEM_freeN(ibuf->rect);
- ibuf->rect = NULL;
+ if (ibuf->rect && (ibuf->mall & IB_rect))
+ MEM_freeN(ibuf->rect);
+ ibuf->rect = NULL;
- imb_freemipmapImBuf(ibuf);
+ imb_freemipmapImBuf(ibuf);
- ibuf->mall &= ~IB_rect;
+ ibuf->mall &= ~IB_rect;
}
void imb_freetilesImBuf(ImBuf *ibuf)
{
- int tx, ty;
-
- if (ibuf == NULL) return;
-
- if (ibuf->tiles && (ibuf->mall & IB_tiles)) {
- for (ty = 0; ty < ibuf->ytiles; ty++) {
- for (tx = 0; tx < ibuf->xtiles; tx++) {
- if (ibuf->tiles[ibuf->xtiles * ty + tx]) {
- imb_tile_cache_tile_free(ibuf, tx, ty);
- MEM_freeN(ibuf->tiles[ibuf->xtiles * ty + tx]);
- }
- }
- }
-
- MEM_freeN(ibuf->tiles);
- }
-
- ibuf->tiles = NULL;
- ibuf->mall &= ~IB_tiles;
+ int tx, ty;
+
+ if (ibuf == NULL)
+ return;
+
+ if (ibuf->tiles && (ibuf->mall & IB_tiles)) {
+ for (ty = 0; ty < ibuf->ytiles; ty++) {
+ for (tx = 0; tx < ibuf->xtiles; tx++) {
+ if (ibuf->tiles[ibuf->xtiles * ty + tx]) {
+ imb_tile_cache_tile_free(ibuf, tx, ty);
+ MEM_freeN(ibuf->tiles[ibuf->xtiles * ty + tx]);
+ }
+ }
+ }
+
+ MEM_freeN(ibuf->tiles);
+ }
+
+ ibuf->tiles = NULL;
+ ibuf->mall &= ~IB_tiles;
}
static void freeencodedbufferImBuf(ImBuf *ibuf)
{
- if (ibuf == NULL) return;
+ if (ibuf == NULL)
+ return;
- if (ibuf->encodedbuffer && (ibuf->mall & IB_mem))
- MEM_freeN(ibuf->encodedbuffer);
+ if (ibuf->encodedbuffer && (ibuf->mall & IB_mem))
+ MEM_freeN(ibuf->encodedbuffer);
- ibuf->encodedbuffer = NULL;
- ibuf->encodedbuffersize = 0;
- ibuf->encodedsize = 0;
- ibuf->mall &= ~IB_mem;
+ ibuf->encodedbuffer = NULL;
+ ibuf->encodedbuffersize = 0;
+ ibuf->encodedsize = 0;
+ ibuf->mall &= ~IB_mem;
}
void IMB_freezbufImBuf(ImBuf *ibuf)
{
- if (ibuf == NULL) return;
+ if (ibuf == NULL)
+ return;
- if (ibuf->zbuf && (ibuf->mall & IB_zbuf))
- MEM_freeN(ibuf->zbuf);
+ if (ibuf->zbuf && (ibuf->mall & IB_zbuf))
+ MEM_freeN(ibuf->zbuf);
- ibuf->zbuf = NULL;
- ibuf->mall &= ~IB_zbuf;
+ ibuf->zbuf = NULL;
+ ibuf->mall &= ~IB_zbuf;
}
void IMB_freezbuffloatImBuf(ImBuf *ibuf)
{
- if (ibuf == NULL) return;
+ if (ibuf == NULL)
+ return;
- if (ibuf->zbuf_float && (ibuf->mall & IB_zbuffloat))
- MEM_freeN(ibuf->zbuf_float);
+ if (ibuf->zbuf_float && (ibuf->mall & IB_zbuffloat))
+ MEM_freeN(ibuf->zbuf_float);
- ibuf->zbuf_float = NULL;
- ibuf->mall &= ~IB_zbuffloat;
+ ibuf->zbuf_float = NULL;
+ ibuf->mall &= ~IB_zbuffloat;
}
void IMB_freeImBuf(ImBuf *ibuf)
{
- if (ibuf) {
- bool needs_free = false;
-
- BLI_spin_lock(&refcounter_spin);
- if (ibuf->refcounter > 0) {
- ibuf->refcounter--;
- }
- else {
- needs_free = true;
- }
- BLI_spin_unlock(&refcounter_spin);
-
- if (needs_free) {
- imb_freerectImBuf(ibuf);
- imb_freerectfloatImBuf(ibuf);
- imb_freetilesImBuf(ibuf);
- IMB_freezbufImBuf(ibuf);
- IMB_freezbuffloatImBuf(ibuf);
- freeencodedbufferImBuf(ibuf);
- IMB_metadata_free(ibuf->metadata);
- colormanage_cache_free(ibuf);
-
- if (ibuf->dds_data.data != NULL) {
- free(ibuf->dds_data.data); /* dds_data.data is allocated by DirectDrawSurface::readData(), so don't use MEM_freeN! */
- }
- MEM_freeN(ibuf);
- }
- }
+ if (ibuf) {
+ bool needs_free = false;
+
+ BLI_spin_lock(&refcounter_spin);
+ if (ibuf->refcounter > 0) {
+ ibuf->refcounter--;
+ }
+ else {
+ needs_free = true;
+ }
+ BLI_spin_unlock(&refcounter_spin);
+
+ if (needs_free) {
+ imb_freerectImBuf(ibuf);
+ imb_freerectfloatImBuf(ibuf);
+ imb_freetilesImBuf(ibuf);
+ IMB_freezbufImBuf(ibuf);
+ IMB_freezbuffloatImBuf(ibuf);
+ freeencodedbufferImBuf(ibuf);
+ IMB_metadata_free(ibuf->metadata);
+ colormanage_cache_free(ibuf);
+
+ if (ibuf->dds_data.data != NULL) {
+ free(
+ ibuf->dds_data
+ .data); /* dds_data.data is allocated by DirectDrawSurface::readData(), so don't use MEM_freeN! */
+ }
+ MEM_freeN(ibuf);
+ }
+ }
}
void IMB_refImBuf(ImBuf *ibuf)
{
- BLI_spin_lock(&refcounter_spin);
- ibuf->refcounter++;
- BLI_spin_unlock(&refcounter_spin);
+ BLI_spin_lock(&refcounter_spin);
+ ibuf->refcounter++;
+ BLI_spin_unlock(&refcounter_spin);
}
ImBuf *IMB_makeSingleUser(ImBuf *ibuf)
{
- ImBuf *rval;
+ ImBuf *rval;
- if (ibuf) {
- bool is_single;
- BLI_spin_lock(&refcounter_spin);
- is_single = (ibuf->refcounter == 0);
- BLI_spin_unlock(&refcounter_spin);
- if (is_single) {
- return ibuf;
- }
- }
- else {
- return NULL;
- }
+ if (ibuf) {
+ bool is_single;
+ BLI_spin_lock(&refcounter_spin);
+ is_single = (ibuf->refcounter == 0);
+ BLI_spin_unlock(&refcounter_spin);
+ if (is_single) {
+ return ibuf;
+ }
+ }
+ else {
+ return NULL;
+ }
- rval = IMB_dupImBuf(ibuf);
+ rval = IMB_dupImBuf(ibuf);
- IMB_metadata_copy(rval, ibuf);
+ IMB_metadata_copy(rval, ibuf);
- IMB_freeImBuf(ibuf);
+ IMB_freeImBuf(ibuf);
- return rval;
+ return rval;
}
bool addzbufImBuf(ImBuf *ibuf)
{
- if (ibuf == NULL) return false;
+ if (ibuf == NULL)
+ return false;
- IMB_freezbufImBuf(ibuf);
+ IMB_freezbufImBuf(ibuf);
- if ((ibuf->zbuf = imb_alloc_pixels(ibuf->x, ibuf->y, 1, sizeof(unsigned int), __func__))) {
- ibuf->mall |= IB_zbuf;
- ibuf->flags |= IB_zbuf;
- return true;
- }
+ if ((ibuf->zbuf = imb_alloc_pixels(ibuf->x, ibuf->y, 1, sizeof(unsigned int), __func__))) {
+ ibuf->mall |= IB_zbuf;
+ ibuf->flags |= IB_zbuf;
+ return true;
+ }
- return false;
+ return false;
}
bool addzbuffloatImBuf(ImBuf *ibuf)
{
- if (ibuf == NULL) return false;
+ if (ibuf == NULL)
+ return false;
- IMB_freezbuffloatImBuf(ibuf);
+ IMB_freezbuffloatImBuf(ibuf);
- if ((ibuf->zbuf_float = imb_alloc_pixels(ibuf->x, ibuf->y, 1, sizeof(float), __func__))) {
- ibuf->mall |= IB_zbuffloat;
- ibuf->flags |= IB_zbuffloat;
- return true;
- }
+ if ((ibuf->zbuf_float = imb_alloc_pixels(ibuf->x, ibuf->y, 1, sizeof(float), __func__))) {
+ ibuf->mall |= IB_zbuffloat;
+ ibuf->flags |= IB_zbuffloat;
+ return true;
+ }
- return false;
+ return false;
}
-
bool imb_addencodedbufferImBuf(ImBuf *ibuf)
{
- if (ibuf == NULL) return false;
+ if (ibuf == NULL)
+ return false;
- freeencodedbufferImBuf(ibuf);
+ freeencodedbufferImBuf(ibuf);
- if (ibuf->encodedbuffersize == 0)
- ibuf->encodedbuffersize = 10000;
+ if (ibuf->encodedbuffersize == 0)
+ ibuf->encodedbuffersize = 10000;
- ibuf->encodedsize = 0;
+ ibuf->encodedsize = 0;
- if ((ibuf->encodedbuffer = MEM_mallocN(ibuf->encodedbuffersize, __func__))) {
- ibuf->mall |= IB_mem;
- ibuf->flags |= IB_mem;
- return true;
- }
+ if ((ibuf->encodedbuffer = MEM_mallocN(ibuf->encodedbuffersize, __func__))) {
+ ibuf->mall |= IB_mem;
+ ibuf->flags |= IB_mem;
+ return true;
+ }
- return false;
+ return false;
}
-
bool imb_enlargeencodedbufferImBuf(ImBuf *ibuf)
{
- unsigned int newsize, encodedsize;
- void *newbuffer;
+ unsigned int newsize, encodedsize;
+ void *newbuffer;
- if (ibuf == NULL) return false;
+ if (ibuf == NULL)
+ return false;
- if (ibuf->encodedbuffersize < ibuf->encodedsize) {
- printf("%s: error in parameters\n", __func__);
- return false;
- }
+ if (ibuf->encodedbuffersize < ibuf->encodedsize) {
+ printf("%s: error in parameters\n", __func__);
+ return false;
+ }
- newsize = 2 * ibuf->encodedbuffersize;
- if (newsize < 10000) newsize = 10000;
+ newsize = 2 * ibuf->encodedbuffersize;
+ if (newsize < 10000)
+ newsize = 10000;
- newbuffer = MEM_mallocN(newsize, __func__);
- if (newbuffer == NULL) return false;
+ newbuffer = MEM_mallocN(newsize, __func__);
+ if (newbuffer == NULL)
+ return false;
- if (ibuf->encodedbuffer) {
- memcpy(newbuffer, ibuf->encodedbuffer, ibuf->encodedsize);
- }
- else {
- ibuf->encodedsize = 0;
- }
+ if (ibuf->encodedbuffer) {
+ memcpy(newbuffer, ibuf->encodedbuffer, ibuf->encodedsize);
+ }
+ else {
+ ibuf->encodedsize = 0;
+ }
- encodedsize = ibuf->encodedsize;
+ encodedsize = ibuf->encodedsize;
- freeencodedbufferImBuf(ibuf);
+ freeencodedbufferImBuf(ibuf);
- ibuf->encodedbuffersize = newsize;
- ibuf->encodedsize = encodedsize;
- ibuf->encodedbuffer = newbuffer;
- ibuf->mall |= IB_mem;
- ibuf->flags |= IB_mem;
+ ibuf->encodedbuffersize = newsize;
+ ibuf->encodedsize = encodedsize;
+ ibuf->encodedbuffer = newbuffer;
+ ibuf->mall |= IB_mem;
+ ibuf->flags |= IB_mem;
- return true;
+ return true;
}
-void *imb_alloc_pixels(unsigned int x,
- unsigned int y,
- unsigned int channels,
- size_t typesize,
- const char *name)
+void *imb_alloc_pixels(
+ unsigned int x, unsigned int y, unsigned int channels, size_t typesize, const char *name)
{
- /* Protect against buffer overflow vulnerabilities from files specifying
- * a width and height that overflow and alloc too little memory. */
- if (!((uint64_t)x * (uint64_t)y < (SIZE_MAX / (channels * typesize)))) {
- return NULL;
- }
-
- size_t size = (size_t)x * (size_t)y * (size_t)channels * typesize;
- return MEM_mapallocN(size, name);
+ /* Protect against buffer overflow vulnerabilities from files specifying
+ * a width and height that overflow and alloc too little memory. */
+ if (!((uint64_t)x * (uint64_t)y < (SIZE_MAX / (channels * typesize)))) {
+ return NULL;
+ }
+
+ size_t size = (size_t)x * (size_t)y * (size_t)channels * typesize;
+ return MEM_mapallocN(size, name);
}
bool imb_addrectfloatImBuf(ImBuf *ibuf)
{
- if (ibuf == NULL) return false;
+ if (ibuf == NULL)
+ return false;
- if (ibuf->rect_float)
- imb_freerectfloatImBuf(ibuf); /* frees mipmap too, hrm */
+ if (ibuf->rect_float)
+ imb_freerectfloatImBuf(ibuf); /* frees mipmap too, hrm */
- ibuf->channels = 4;
- if ((ibuf->rect_float = imb_alloc_pixels(ibuf->x, ibuf->y, 4, sizeof(float), __func__))) {
- ibuf->mall |= IB_rectfloat;
- ibuf->flags |= IB_rectfloat;
- return true;
- }
+ ibuf->channels = 4;
+ if ((ibuf->rect_float = imb_alloc_pixels(ibuf->x, ibuf->y, 4, sizeof(float), __func__))) {
+ ibuf->mall |= IB_rectfloat;
+ ibuf->flags |= IB_rectfloat;
+ return true;
+ }
- return false;
+ return false;
}
/* question; why also add zbuf? */
bool imb_addrectImBuf(ImBuf *ibuf)
{
- if (ibuf == NULL) return false;
-
- /* don't call imb_freerectImBuf, it frees mipmaps, this call is used only too give float buffers display */
- if (ibuf->rect && (ibuf->mall & IB_rect))
- MEM_freeN(ibuf->rect);
- ibuf->rect = NULL;
-
- if ((ibuf->rect = imb_alloc_pixels(ibuf->x, ibuf->y, 4, sizeof(unsigned char), __func__))) {
- ibuf->mall |= IB_rect;
- ibuf->flags |= IB_rect;
- if (ibuf->planes > 32) {
- return (addzbufImBuf(ibuf));
- }
- else {
- return true;
- }
- }
-
- return false;
+ if (ibuf == NULL)
+ return false;
+
+ /* don't call imb_freerectImBuf, it frees mipmaps, this call is used only too give float buffers display */
+ if (ibuf->rect && (ibuf->mall & IB_rect))
+ MEM_freeN(ibuf->rect);
+ ibuf->rect = NULL;
+
+ if ((ibuf->rect = imb_alloc_pixels(ibuf->x, ibuf->y, 4, sizeof(unsigned char), __func__))) {
+ ibuf->mall |= IB_rect;
+ ibuf->flags |= IB_rect;
+ if (ibuf->planes > 32) {
+ return (addzbufImBuf(ibuf));
+ }
+ else {
+ return true;
+ }
+ }
+
+ return false;
}
-struct ImBuf *IMB_allocFromBuffer(const unsigned int *rect, const float *rectf,
- unsigned int w, unsigned int h)
+struct ImBuf *IMB_allocFromBuffer(const unsigned int *rect,
+ const float *rectf,
+ unsigned int w,
+ unsigned int h)
{
- ImBuf *ibuf = NULL;
+ ImBuf *ibuf = NULL;
- if (!(rect || rectf))
- return NULL;
+ if (!(rect || rectf))
+ return NULL;
- ibuf = IMB_allocImBuf(w, h, 32, 0);
+ ibuf = IMB_allocImBuf(w, h, 32, 0);
- if (rectf) {
- ibuf->rect_float = MEM_dupallocN(rectf);
- ibuf->flags |= IB_rectfloat;
- ibuf->mall |= IB_rectfloat;
- }
- if (rect) {
- ibuf->rect = MEM_dupallocN(rect);
- ibuf->flags |= IB_rect;
- ibuf->mall |= IB_rect;
- }
+ if (rectf) {
+ ibuf->rect_float = MEM_dupallocN(rectf);
+ ibuf->flags |= IB_rectfloat;
+ ibuf->mall |= IB_rectfloat;
+ }
+ if (rect) {
+ ibuf->rect = MEM_dupallocN(rect);
+ ibuf->flags |= IB_rect;
+ ibuf->mall |= IB_rect;
+ }
- return ibuf;
+ return ibuf;
}
bool imb_addtilesImBuf(ImBuf *ibuf)
{
- if (ibuf == NULL) return false;
+ if (ibuf == NULL)
+ return false;
- if (!ibuf->tiles)
- if ((ibuf->tiles = MEM_callocN(sizeof(unsigned int *) * ibuf->xtiles * ibuf->ytiles, "imb_tiles")))
- ibuf->mall |= IB_tiles;
+ if (!ibuf->tiles)
+ if ((ibuf->tiles = MEM_callocN(sizeof(unsigned int *) * ibuf->xtiles * ibuf->ytiles,
+ "imb_tiles")))
+ ibuf->mall |= IB_tiles;
- return (ibuf->tiles != NULL);
+ return (ibuf->tiles != NULL);
}
ImBuf *IMB_allocImBuf(unsigned int x, unsigned int y, uchar planes, unsigned int flags)
{
- ImBuf *ibuf;
+ ImBuf *ibuf;
- ibuf = MEM_mallocN(sizeof(ImBuf), "ImBuf_struct");
+ ibuf = MEM_mallocN(sizeof(ImBuf), "ImBuf_struct");
- if (ibuf) {
- if (!IMB_initImBuf(ibuf, x, y, planes, flags)) {
- IMB_freeImBuf(ibuf);
- return NULL;
- }
- }
+ if (ibuf) {
+ if (!IMB_initImBuf(ibuf, x, y, planes, flags)) {
+ IMB_freeImBuf(ibuf);
+ return NULL;
+ }
+ }
- return (ibuf);
+ return (ibuf);
}
-bool IMB_initImBuf(struct ImBuf *ibuf,
- unsigned int x, unsigned int y,
- unsigned char planes, unsigned int flags)
+bool IMB_initImBuf(
+ struct ImBuf *ibuf, unsigned int x, unsigned int y, unsigned char planes, unsigned int flags)
{
- memset(ibuf, 0, sizeof(ImBuf));
-
- ibuf->x = x;
- ibuf->y = y;
- ibuf->planes = planes;
- ibuf->ftype = IMB_FTYPE_PNG;
- ibuf->foptions.quality = 15; /* the 15 means, set compression to low ratio but not time consuming */
- ibuf->channels = 4; /* float option, is set to other values when buffers get assigned */
- ibuf->ppm[0] = ibuf->ppm[1] = IMB_DPI_DEFAULT / 0.0254f; /* IMB_DPI_DEFAULT -> pixels-per-meter */
-
- if (flags & IB_rect) {
- if (imb_addrectImBuf(ibuf) == false) {
- return false;
- }
- }
-
- if (flags & IB_rectfloat) {
- if (imb_addrectfloatImBuf(ibuf) == false) {
- return false;
- }
- }
-
- if (flags & IB_zbuf) {
- if (addzbufImBuf(ibuf) == false) {
- return false;
- }
- }
-
- if (flags & IB_zbuffloat) {
- if (addzbuffloatImBuf(ibuf) == false) {
- return false;
- }
- }
-
- /* assign default spaces */
- colormanage_imbuf_set_default_spaces(ibuf);
-
- return true;
+ memset(ibuf, 0, sizeof(ImBuf));
+
+ ibuf->x = x;
+ ibuf->y = y;
+ ibuf->planes = planes;
+ ibuf->ftype = IMB_FTYPE_PNG;
+ ibuf->foptions.quality =
+ 15; /* the 15 means, set compression to low ratio but not time consuming */
+ ibuf->channels = 4; /* float option, is set to other values when buffers get assigned */
+ ibuf->ppm[0] = ibuf->ppm[1] = IMB_DPI_DEFAULT /
+ 0.0254f; /* IMB_DPI_DEFAULT -> pixels-per-meter */
+
+ if (flags & IB_rect) {
+ if (imb_addrectImBuf(ibuf) == false) {
+ return false;
+ }
+ }
+
+ if (flags & IB_rectfloat) {
+ if (imb_addrectfloatImBuf(ibuf) == false) {
+ return false;
+ }
+ }
+
+ if (flags & IB_zbuf) {
+ if (addzbufImBuf(ibuf) == false) {
+ return false;
+ }
+ }
+
+ if (flags & IB_zbuffloat) {
+ if (addzbuffloatImBuf(ibuf) == false) {
+ return false;
+ }
+ }
+
+ /* assign default spaces */
+ colormanage_imbuf_set_default_spaces(ibuf);
+
+ return true;
}
/* does no zbuffers? */
ImBuf *IMB_dupImBuf(const ImBuf *ibuf1)
{
- ImBuf *ibuf2, tbuf;
- int flags = 0;
- int a, x, y;
-
- if (ibuf1 == NULL) return NULL;
-
- if (ibuf1->rect) flags |= IB_rect;
- if (ibuf1->rect_float) flags |= IB_rectfloat;
- if (ibuf1->zbuf) flags |= IB_zbuf;
- if (ibuf1->zbuf_float) flags |= IB_zbuffloat;
-
- x = ibuf1->x;
- y = ibuf1->y;
-
- ibuf2 = IMB_allocImBuf(x, y, ibuf1->planes, flags);
- if (ibuf2 == NULL) return NULL;
-
- if (flags & IB_rect)
- memcpy(ibuf2->rect, ibuf1->rect, ((size_t)x) * y * sizeof(int));
-
- if (flags & IB_rectfloat)
- memcpy(ibuf2->rect_float, ibuf1->rect_float, ((size_t)ibuf1->channels) * x * y * sizeof(float));
-
- if (flags & IB_zbuf)
- memcpy(ibuf2->zbuf, ibuf1->zbuf, ((size_t)x) * y * sizeof(int));
-
- if (flags & IB_zbuffloat)
- memcpy(ibuf2->zbuf_float, ibuf1->zbuf_float, ((size_t)x) * y * sizeof(float));
-
- if (ibuf1->encodedbuffer) {
- ibuf2->encodedbuffersize = ibuf1->encodedbuffersize;
- if (imb_addencodedbufferImBuf(ibuf2) == false) {
- IMB_freeImBuf(ibuf2);
- return NULL;
- }
-
- memcpy(ibuf2->encodedbuffer, ibuf1->encodedbuffer, ibuf1->encodedsize);
- }
-
- /* silly trick to copy the entire contents of ibuf1 struct over to ibuf */
- tbuf = *ibuf1;
-
- /* fix pointers */
- tbuf.rect = ibuf2->rect;
- tbuf.rect_float = ibuf2->rect_float;
- tbuf.encodedbuffer = ibuf2->encodedbuffer;
- tbuf.zbuf = ibuf2->zbuf;
- tbuf.zbuf_float = ibuf2->zbuf_float;
- for (a = 0; a < IMB_MIPMAP_LEVELS; a++)
- tbuf.mipmap[a] = NULL;
- tbuf.dds_data.data = NULL;
-
- /* set malloc flag */
- tbuf.mall = ibuf2->mall;
- tbuf.c_handle = NULL;
- tbuf.refcounter = 0;
-
- /* for now don't duplicate metadata */
- tbuf.metadata = NULL;
-
- tbuf.display_buffer_flags = NULL;
- tbuf.colormanage_cache = NULL;
-
- *ibuf2 = tbuf;
-
- return(ibuf2);
+ ImBuf *ibuf2, tbuf;
+ int flags = 0;
+ int a, x, y;
+
+ if (ibuf1 == NULL)
+ return NULL;
+
+ if (ibuf1->rect)
+ flags |= IB_rect;
+ if (ibuf1->rect_float)
+ flags |= IB_rectfloat;
+ if (ibuf1->zbuf)
+ flags |= IB_zbuf;
+ if (ibuf1->zbuf_float)
+ flags |= IB_zbuffloat;
+
+ x = ibuf1->x;
+ y = ibuf1->y;
+
+ ibuf2 = IMB_allocImBuf(x, y, ibuf1->planes, flags);
+ if (ibuf2 == NULL)
+ return NULL;
+
+ if (flags & IB_rect)
+ memcpy(ibuf2->rect, ibuf1->rect, ((size_t)x) * y * sizeof(int));
+
+ if (flags & IB_rectfloat)
+ memcpy(
+ ibuf2->rect_float, ibuf1->rect_float, ((size_t)ibuf1->channels) * x * y * sizeof(float));
+
+ if (flags & IB_zbuf)
+ memcpy(ibuf2->zbuf, ibuf1->zbuf, ((size_t)x) * y * sizeof(int));
+
+ if (flags & IB_zbuffloat)
+ memcpy(ibuf2->zbuf_float, ibuf1->zbuf_float, ((size_t)x) * y * sizeof(float));
+
+ if (ibuf1->encodedbuffer) {
+ ibuf2->encodedbuffersize = ibuf1->encodedbuffersize;
+ if (imb_addencodedbufferImBuf(ibuf2) == false) {
+ IMB_freeImBuf(ibuf2);
+ return NULL;
+ }
+
+ memcpy(ibuf2->encodedbuffer, ibuf1->encodedbuffer, ibuf1->encodedsize);
+ }
+
+ /* silly trick to copy the entire contents of ibuf1 struct over to ibuf */
+ tbuf = *ibuf1;
+
+ /* fix pointers */
+ tbuf.rect = ibuf2->rect;
+ tbuf.rect_float = ibuf2->rect_float;
+ tbuf.encodedbuffer = ibuf2->encodedbuffer;
+ tbuf.zbuf = ibuf2->zbuf;
+ tbuf.zbuf_float = ibuf2->zbuf_float;
+ for (a = 0; a < IMB_MIPMAP_LEVELS; a++)
+ tbuf.mipmap[a] = NULL;
+ tbuf.dds_data.data = NULL;
+
+ /* set malloc flag */
+ tbuf.mall = ibuf2->mall;
+ tbuf.c_handle = NULL;
+ tbuf.refcounter = 0;
+
+ /* for now don't duplicate metadata */
+ tbuf.metadata = NULL;
+
+ tbuf.display_buffer_flags = NULL;
+ tbuf.colormanage_cache = NULL;
+
+ *ibuf2 = tbuf;
+
+ return (ibuf2);
}
#if 0 /* remove? - campbell */
@@ -565,25 +587,25 @@ ImBuf *IMB_dupImBuf(const ImBuf *ibuf1)
static void imbuf_cache_destructor(void *data)
{
- ImBuf *ibuf = (ImBuf *) data;
+ ImBuf *ibuf = (ImBuf *) data;
- imb_freerectImBuf(ibuf);
- imb_freerectfloatImBuf(ibuf);
- IMB_freezbufImBuf(ibuf);
- IMB_freezbuffloatImBuf(ibuf);
- freeencodedbufferImBuf(ibuf);
+ imb_freerectImBuf(ibuf);
+ imb_freerectfloatImBuf(ibuf);
+ IMB_freezbufImBuf(ibuf);
+ IMB_freezbuffloatImBuf(ibuf);
+ freeencodedbufferImBuf(ibuf);
- ibuf->c_handle = NULL;
+ ibuf->c_handle = NULL;
}
static MEM_CacheLimiterC **get_imbuf_cache_limiter(void)
{
- static MEM_CacheLimiterC *c = NULL;
+ static MEM_CacheLimiterC *c = NULL;
- if (!c)
- c = new_MEM_CacheLimiter(imbuf_cache_destructor, NULL);
+ if (!c)
+ c = new_MEM_CacheLimiter(imbuf_cache_destructor, NULL);
- return &c;
+ return &c;
}
#endif
diff --git a/source/blender/imbuf/intern/anim_movie.c b/source/blender/imbuf/intern/anim_movie.c
index 43d91dc0d8e..13813fb23b3 100644
--- a/source/blender/imbuf/intern/anim_movie.c
+++ b/source/blender/imbuf/intern/anim_movie.c
@@ -21,24 +21,28 @@
* \ingroup imbuf
*/
-
#ifdef _WIN32
-#define INC_OLE2
-#include <windows.h>
-#include <windowsx.h>
-#include <mmsystem.h>
-#include <memory.h>
-#include <commdlg.h>
-#include <vfw.h>
-
-#undef AVIIF_KEYFRAME /* redefined in AVI_avi.h */
-#undef AVIIF_LIST /* redefined in AVI_avi.h */
-
-#define FIXCC(fcc) \
- { \
- if (fcc == 0) { fcc = mmioFOURCC('N', 'o', 'n', 'e'); } \
- if (fcc == BI_RLE8) { fcc = mmioFOURCC('R', 'l', 'e', '8'); } \
- } (void)0
+# define INC_OLE2
+# include <windows.h>
+# include <windowsx.h>
+# include <mmsystem.h>
+# include <memory.h>
+# include <commdlg.h>
+# include <vfw.h>
+
+# undef AVIIF_KEYFRAME /* redefined in AVI_avi.h */
+# undef AVIIF_LIST /* redefined in AVI_avi.h */
+
+# define FIXCC(fcc) \
+ { \
+ if (fcc == 0) { \
+ fcc = mmioFOURCC('N', 'o', 'n', 'e'); \
+ } \
+ if (fcc == BI_RLE8) { \
+ fcc = mmioFOURCC('R', 'l', 'e', '8'); \
+ } \
+ } \
+ (void)0
#endif
@@ -49,9 +53,9 @@
#include <math.h>
#include <limits.h>
#ifndef _WIN32
-#include <dirent.h>
+# include <dirent.h>
#else
-#include <io.h>
+# include <io.h>
#endif
#include "BLI_utildefines.h"
@@ -75,7 +79,7 @@
#include "IMB_metadata.h"
#ifdef WITH_FFMPEG
-# include "BKE_global.h" /* ENDIAN_ORDER */
+# include "BKE_global.h" /* ENDIAN_ORDER */
# include <libavformat/avformat.h>
# include <libavcodec/avcodec.h>
@@ -83,28 +87,27 @@
# include <libswscale/swscale.h>
# include "ffmpeg_compat.h"
-#endif //WITH_FFMPEG
+#endif //WITH_FFMPEG
int ismovie(const char *UNUSED(filepath))
{
- return 0;
+ return 0;
}
/* never called, just keep the linker happy */
static int startmovie(struct anim *UNUSED(anim))
{
- return 1;
+ return 1;
}
static ImBuf *movie_fetchibuf(struct anim *UNUSED(anim), int UNUSED(position))
{
- return NULL;
+ return NULL;
}
static void free_anim_movie(struct anim *UNUSED(anim))
{
- /* pass */
+ /* pass */
}
-
#if defined(_WIN32)
# define PATHSEPARATOR '\\'
#else
@@ -113,84 +116,88 @@ static void free_anim_movie(struct anim *UNUSED(anim))
static int an_stringdec(const char *string, char *head, char *tail, unsigned short *numlen)
{
- unsigned short len, nume, nums = 0;
- short i;
- bool found = false;
-
- len = strlen(string);
- nume = len;
-
- for (i = len - 1; i >= 0; i--) {
- if (string[i] == PATHSEPARATOR) break;
- if (isdigit(string[i])) {
- if (found) {
- nums = i;
- }
- else {
- nume = i;
- nums = i;
- found = true;
- }
- }
- else {
- if (found) break;
- }
- }
- if (found) {
- strcpy(tail, &string[nume + 1]);
- strcpy(head, string);
- head[nums] = '\0';
- *numlen = nume - nums + 1;
- return ((int)atoi(&(string[nums])));
- }
- tail[0] = '\0';
- strcpy(head, string);
- *numlen = 0;
- return true;
+ unsigned short len, nume, nums = 0;
+ short i;
+ bool found = false;
+
+ len = strlen(string);
+ nume = len;
+
+ for (i = len - 1; i >= 0; i--) {
+ if (string[i] == PATHSEPARATOR)
+ break;
+ if (isdigit(string[i])) {
+ if (found) {
+ nums = i;
+ }
+ else {
+ nume = i;
+ nums = i;
+ found = true;
+ }
+ }
+ else {
+ if (found)
+ break;
+ }
+ }
+ if (found) {
+ strcpy(tail, &string[nume + 1]);
+ strcpy(head, string);
+ head[nums] = '\0';
+ *numlen = nume - nums + 1;
+ return ((int)atoi(&(string[nums])));
+ }
+ tail[0] = '\0';
+ strcpy(head, string);
+ *numlen = 0;
+ return true;
}
-
-static void an_stringenc(char *string, const char *head, const char *tail, unsigned short numlen, int pic)
+static void an_stringenc(
+ char *string, const char *head, const char *tail, unsigned short numlen, int pic)
{
- BLI_stringenc(string, head, tail, numlen, pic);
+ BLI_stringenc(string, head, tail, numlen, pic);
}
#ifdef WITH_AVI
static void free_anim_avi(struct anim *anim)
{
-#if defined(_WIN32)
- int i;
-#endif
-
- if (anim == NULL) return;
- if (anim->avi == NULL) return;
-
- AVI_close(anim->avi);
- MEM_freeN(anim->avi);
- anim->avi = NULL;
-
-#if defined(_WIN32)
-
- if (anim->pgf) {
- AVIStreamGetFrameClose(anim->pgf);
- anim->pgf = NULL;
- }
-
- for (i = 0; i < anim->avistreams; i++) {
- AVIStreamRelease(anim->pavi[i]);
- }
- anim->avistreams = 0;
-
- if (anim->pfileopen) {
- AVIFileRelease(anim->pfile);
- anim->pfileopen = 0;
- AVIFileExit();
- }
-#endif
-
- anim->duration = 0;
+# if defined(_WIN32)
+ int i;
+# endif
+
+ if (anim == NULL)
+ return;
+ if (anim->avi == NULL)
+ return;
+
+ AVI_close(anim->avi);
+ MEM_freeN(anim->avi);
+ anim->avi = NULL;
+
+# if defined(_WIN32)
+
+ if (anim->pgf) {
+ AVIStreamGetFrameClose(anim->pgf);
+ anim->pgf = NULL;
+ }
+
+ for (i = 0; i < anim->avistreams; i++) {
+ AVIStreamRelease(anim->pavi[i]);
+ }
+ anim->avistreams = 0;
+
+ if (anim->pfileopen) {
+ AVIFileRelease(anim->pfile);
+ anim->pfileopen = 0;
+ AVIFileExit();
+ }
+# endif
+
+ anim->duration = 0;
}
-#endif /* WITH_AVI */
+#endif /* WITH_AVI */
#ifdef WITH_FFMPEG
static void free_anim_ffmpeg(struct anim *anim);
@@ -198,487 +205,496 @@ static void free_anim_ffmpeg(struct anim *anim);
void IMB_free_anim(struct anim *anim)
{
- if (anim == NULL) {
- printf("free anim, anim == NULL\n");
- return;
- }
+ if (anim == NULL) {
+ printf("free anim, anim == NULL\n");
+ return;
+ }
- free_anim_movie(anim);
+ free_anim_movie(anim);
#ifdef WITH_AVI
- free_anim_avi(anim);
+ free_anim_avi(anim);
#endif
#ifdef WITH_FFMPEG
- free_anim_ffmpeg(anim);
+ free_anim_ffmpeg(anim);
#endif
- IMB_free_indices(anim);
- IMB_metadata_free(anim->metadata);
+ IMB_free_indices(anim);
+ IMB_metadata_free(anim->metadata);
- MEM_freeN(anim);
+ MEM_freeN(anim);
}
void IMB_close_anim(struct anim *anim)
{
- if (anim == NULL) return;
+ if (anim == NULL)
+ return;
- IMB_free_anim(anim);
+ IMB_free_anim(anim);
}
void IMB_close_anim_proxies(struct anim *anim)
{
- if (anim == NULL)
- return;
+ if (anim == NULL)
+ return;
- IMB_free_indices(anim);
+ IMB_free_indices(anim);
}
struct IDProperty *IMB_anim_load_metadata(struct anim *anim)
{
- switch (anim->curtype) {
- case ANIM_FFMPEG:
- {
+ switch (anim->curtype) {
+ case ANIM_FFMPEG: {
#ifdef WITH_FFMPEG
- AVDictionaryEntry *entry = NULL;
+ AVDictionaryEntry *entry = NULL;
- BLI_assert(anim->pFormatCtx != NULL);
- av_log(anim->pFormatCtx, AV_LOG_DEBUG, "METADATA FETCH\n");
+ BLI_assert(anim->pFormatCtx != NULL);
+ av_log(anim->pFormatCtx, AV_LOG_DEBUG, "METADATA FETCH\n");
- while (true) {
- entry = av_dict_get(anim->pFormatCtx->metadata, "", entry, AV_DICT_IGNORE_SUFFIX);
- if (entry == NULL) break;
+ while (true) {
+ entry = av_dict_get(anim->pFormatCtx->metadata, "", entry, AV_DICT_IGNORE_SUFFIX);
+ if (entry == NULL)
+ break;
- /* Delay creation of the property group until there is actual metadata to put in there. */
- IMB_metadata_ensure(&anim->metadata);
- IMB_metadata_set_field(anim->metadata, entry->key, entry->value);
- }
+ /* Delay creation of the property group until there is actual metadata to put in there. */
+ IMB_metadata_ensure(&anim->metadata);
+ IMB_metadata_set_field(anim->metadata, entry->key, entry->value);
+ }
#endif
- break;
- }
- case ANIM_SEQUENCE:
- case ANIM_AVI:
- case ANIM_MOVIE:
- /* TODO */
- break;
- case ANIM_NONE:
- default:
- break;
- }
- return anim->metadata;
+ break;
+ }
+ case ANIM_SEQUENCE:
+ case ANIM_AVI:
+ case ANIM_MOVIE:
+ /* TODO */
+ break;
+ case ANIM_NONE:
+ default:
+ break;
+ }
+ return anim->metadata;
}
-struct anim *IMB_open_anim(const char *name, int ib_flags, int streamindex, char colorspace[IM_MAX_SPACE])
+struct anim *IMB_open_anim(const char *name,
+ int ib_flags,
+ int streamindex,
+ char colorspace[IM_MAX_SPACE])
{
- struct anim *anim;
-
- BLI_assert(!BLI_path_is_rel(name));
-
- anim = (struct anim *)MEM_callocN(sizeof(struct anim), "anim struct");
- if (anim != NULL) {
- if (colorspace) {
- colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE);
- BLI_strncpy(anim->colorspace, colorspace, sizeof(anim->colorspace));
- }
- else {
- colorspace_set_default_role(anim->colorspace, sizeof(anim->colorspace), COLOR_ROLE_DEFAULT_BYTE);
- }
-
- BLI_strncpy(anim->name, name, sizeof(anim->name));
- anim->ib_flags = ib_flags;
- anim->streamindex = streamindex;
- }
- return(anim);
+ struct anim *anim;
+
+ BLI_assert(!BLI_path_is_rel(name));
+
+ anim = (struct anim *)MEM_callocN(sizeof(struct anim), "anim struct");
+ if (anim != NULL) {
+ if (colorspace) {
+ colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE);
+ BLI_strncpy(anim->colorspace, colorspace, sizeof(anim->colorspace));
+ }
+ else {
+ colorspace_set_default_role(
+ anim->colorspace, sizeof(anim->colorspace), COLOR_ROLE_DEFAULT_BYTE);
+ }
+
+ BLI_strncpy(anim->name, name, sizeof(anim->name));
+ anim->ib_flags = ib_flags;
+ anim->streamindex = streamindex;
+ }
+ return (anim);
}
void IMB_suffix_anim(struct anim *anim, const char *suffix)
{
- BLI_strncpy(anim->suffix, suffix, sizeof(anim->suffix));
+ BLI_strncpy(anim->suffix, suffix, sizeof(anim->suffix));
}
#ifdef WITH_AVI
static int startavi(struct anim *anim)
{
- AviError avierror;
-#if defined(_WIN32)
- HRESULT hr;
- int i, firstvideo = -1;
- int streamcount;
- BYTE abFormat[1024];
- LONG l;
- LPBITMAPINFOHEADER lpbi;
- AVISTREAMINFO avis;
-
- streamcount = anim->streamindex;
-#endif
-
- anim->avi = MEM_callocN(sizeof(AviMovie), "animavi");
-
- if (anim->avi == NULL) {
- printf("Can't open avi: %s\n", anim->name);
- return -1;
- }
-
- avierror = AVI_open_movie(anim->name, anim->avi);
-
-#if defined(_WIN32)
- if (avierror == AVI_ERROR_COMPRESSION) {
- AVIFileInit();
- hr = AVIFileOpen(&anim->pfile, anim->name, OF_READ, 0L);
- if (hr == 0) {
- anim->pfileopen = 1;
- for (i = 0; i < MAXNUMSTREAMS; i++) {
- if (AVIFileGetStream(anim->pfile, &anim->pavi[i], 0L, i) != AVIERR_OK) {
- break;
- }
-
- AVIStreamInfo(anim->pavi[i], &avis, sizeof(avis));
- if ((avis.fccType == streamtypeVIDEO) && (firstvideo == -1)) {
- if (streamcount > 0) {
- streamcount--;
- continue;
- }
- anim->pgf = AVIStreamGetFrameOpen(anim->pavi[i], NULL);
- if (anim->pgf) {
- firstvideo = i;
-
- /* get stream length */
- anim->avi->header->TotalFrames = AVIStreamLength(anim->pavi[i]);
-
- /* get information about images inside the stream */
- l = sizeof(abFormat);
- AVIStreamReadFormat(anim->pavi[i], 0, &abFormat, &l);
- lpbi = (LPBITMAPINFOHEADER)abFormat;
- anim->avi->header->Height = lpbi->biHeight;
- anim->avi->header->Width = lpbi->biWidth;
- }
- else {
- FIXCC(avis.fccHandler);
- FIXCC(avis.fccType);
- printf("Can't find AVI decoder for type : %4.4hs/%4.4hs\n",
- (LPSTR)&avis.fccType,
- (LPSTR)&avis.fccHandler);
- }
- }
- }
-
- /* register number of opened avistreams */
- anim->avistreams = i;
-
- /*
- * Couldn't get any video streams out of this file
- */
- if ((anim->avistreams == 0) || (firstvideo == -1)) {
- avierror = AVI_ERROR_FORMAT;
- }
- else {
- avierror = AVI_ERROR_NONE;
- anim->firstvideo = firstvideo;
- }
- }
- else {
- AVIFileExit();
- }
- }
-#endif
-
- if (avierror != AVI_ERROR_NONE) {
- AVI_print_error(avierror);
- printf("Error loading avi: %s\n", anim->name);
- free_anim_avi(anim);
- return -1;
- }
-
- anim->duration = anim->avi->header->TotalFrames;
- anim->params = NULL;
-
- anim->x = anim->avi->header->Width;
- anim->y = anim->avi->header->Height;
- anim->interlacing = 0;
- anim->orientation = 0;
- anim->framesize = anim->x * anim->y * 4;
-
- anim->curposition = 0;
- anim->preseek = 0;
-
- /* printf("x:%d y:%d size:%d interl:%d dur:%d\n", anim->x, anim->y, anim->framesize, anim->interlacing, anim->duration);*/
-
- return 0;
+ AviError avierror;
+# if defined(_WIN32)
+ HRESULT hr;
+ int i, firstvideo = -1;
+ int streamcount;
+ BYTE abFormat[1024];
+ LONG l;
+ LPBITMAPINFOHEADER lpbi;
+ AVISTREAMINFO avis;
+
+ streamcount = anim->streamindex;
+# endif
+
+ anim->avi = MEM_callocN(sizeof(AviMovie), "animavi");
+
+ if (anim->avi == NULL) {
+ printf("Can't open avi: %s\n", anim->name);
+ return -1;
+ }
+
+ avierror = AVI_open_movie(anim->name, anim->avi);
+
+# if defined(_WIN32)
+ if (avierror == AVI_ERROR_COMPRESSION) {
+ AVIFileInit();
+ hr = AVIFileOpen(&anim->pfile, anim->name, OF_READ, 0L);
+ if (hr == 0) {
+ anim->pfileopen = 1;
+ for (i = 0; i < MAXNUMSTREAMS; i++) {
+ if (AVIFileGetStream(anim->pfile, &anim->pavi[i], 0L, i) != AVIERR_OK) {
+ break;
+ }
+
+ AVIStreamInfo(anim->pavi[i], &avis, sizeof(avis));
+ if ((avis.fccType == streamtypeVIDEO) && (firstvideo == -1)) {
+ if (streamcount > 0) {
+ streamcount--;
+ continue;
+ }
+ anim->pgf = AVIStreamGetFrameOpen(anim->pavi[i], NULL);
+ if (anim->pgf) {
+ firstvideo = i;
+
+ /* get stream length */
+ anim->avi->header->TotalFrames = AVIStreamLength(anim->pavi[i]);
+
+ /* get information about images inside the stream */
+ l = sizeof(abFormat);
+ AVIStreamReadFormat(anim->pavi[i], 0, &abFormat, &l);
+ lpbi = (LPBITMAPINFOHEADER)abFormat;
+ anim->avi->header->Height = lpbi->biHeight;
+ anim->avi->header->Width = lpbi->biWidth;
+ }
+ else {
+ FIXCC(avis.fccHandler);
+ FIXCC(avis.fccType);
+ printf("Can't find AVI decoder for type : %4.4hs/%4.4hs\n",
+ (LPSTR)&avis.fccType,
+ (LPSTR)&avis.fccHandler);
+ }
+ }
+ }
+
+ /* register number of opened avistreams */
+ anim->avistreams = i;
+
+ /*
+ * Couldn't get any video streams out of this file
+ */
+ if ((anim->avistreams == 0) || (firstvideo == -1)) {
+ avierror = AVI_ERROR_FORMAT;
+ }
+ else {
+ avierror = AVI_ERROR_NONE;
+ anim->firstvideo = firstvideo;
+ }
+ }
+ else {
+ AVIFileExit();
+ }
+ }
+# endif
+
+ if (avierror != AVI_ERROR_NONE) {
+ AVI_print_error(avierror);
+ printf("Error loading avi: %s\n", anim->name);
+ free_anim_avi(anim);
+ return -1;
+ }
+
+ anim->duration = anim->avi->header->TotalFrames;
+ anim->params = NULL;
+
+ anim->x = anim->avi->header->Width;
+ anim->y = anim->avi->header->Height;
+ anim->interlacing = 0;
+ anim->orientation = 0;
+ anim->framesize = anim->x * anim->y * 4;
+
+ anim->curposition = 0;
+ anim->preseek = 0;
+
+ /* printf("x:%d y:%d size:%d interl:%d dur:%d\n", anim->x, anim->y, anim->framesize, anim->interlacing, anim->duration);*/
+
+ return 0;
}
-#endif /* WITH_AVI */
+#endif /* WITH_AVI */
#ifdef WITH_AVI
static ImBuf *avi_fetchibuf(struct anim *anim, int position)
{
- ImBuf *ibuf = NULL;
- int *tmp;
- int y;
-
- if (anim == NULL) {
- return NULL;
- }
-
-#if defined(_WIN32)
- if (anim->avistreams) {
- LPBITMAPINFOHEADER lpbi;
-
- if (anim->pgf) {
- lpbi = AVIStreamGetFrame(anim->pgf, position + AVIStreamStart(anim->pavi[anim->firstvideo]));
- if (lpbi) {
- ibuf = IMB_ibImageFromMemory((const unsigned char *) lpbi, 100, IB_rect, anim->colorspace, "<avi_fetchibuf>");
-//Oh brother...
- }
- }
- }
- else
-#endif
- {
- ibuf = IMB_allocImBuf(anim->x, anim->y, 24, IB_rect);
-
- tmp = AVI_read_frame(anim->avi, AVI_FORMAT_RGB32, position,
- AVI_get_stream(anim->avi, AVIST_VIDEO, 0));
-
- if (tmp == NULL) {
- printf("Error reading frame from AVI: '%s'\n", anim->name);
- IMB_freeImBuf(ibuf);
- return NULL;
- }
-
- for (y = 0; y < anim->y; y++) {
- memcpy(&(ibuf->rect)[((anim->y - y) - 1) * anim->x], &tmp[y * anim->x],
- anim->x * 4);
- }
-
- MEM_freeN(tmp);
- }
-
- ibuf->rect_colorspace = colormanage_colorspace_get_named(anim->colorspace);
-
- return ibuf;
+ ImBuf *ibuf = NULL;
+ int *tmp;
+ int y;
+
+ if (anim == NULL) {
+ return NULL;
+ }
+
+# if defined(_WIN32)
+ if (anim->avistreams) {
+ LPBITMAPINFOHEADER lpbi;
+
+ if (anim->pgf) {
+ lpbi = AVIStreamGetFrame(anim->pgf, position + AVIStreamStart(anim->pavi[anim->firstvideo]));
+ if (lpbi) {
+ ibuf = IMB_ibImageFromMemory(
+ (const unsigned char *)lpbi, 100, IB_rect, anim->colorspace, "<avi_fetchibuf>");
+ //Oh brother...
+ }
+ }
+ }
+ else
+# endif
+ {
+ ibuf = IMB_allocImBuf(anim->x, anim->y, 24, IB_rect);
+
+ tmp = AVI_read_frame(
+ anim->avi, AVI_FORMAT_RGB32, position, AVI_get_stream(anim->avi, AVIST_VIDEO, 0));
+
+ if (tmp == NULL) {
+ printf("Error reading frame from AVI: '%s'\n", anim->name);
+ IMB_freeImBuf(ibuf);
+ return NULL;
+ }
+
+ for (y = 0; y < anim->y; y++) {
+ memcpy(&(ibuf->rect)[((anim->y - y) - 1) * anim->x], &tmp[y * anim->x], anim->x * 4);
+ }
+
+ MEM_freeN(tmp);
+ }
+
+ ibuf->rect_colorspace = colormanage_colorspace_get_named(anim->colorspace);
+
+ return ibuf;
}
-#endif /* WITH_AVI */
+#endif /* WITH_AVI */
#ifdef WITH_FFMPEG
BLI_INLINE bool need_aligned_ffmpeg_buffer(struct anim *anim)
{
- return (anim->x & 31) != 0;
+ return (anim->x & 31) != 0;
}
static int startffmpeg(struct anim *anim)
{
- int i, videoStream;
-
- AVCodec *pCodec;
- AVFormatContext *pFormatCtx = NULL;
- AVCodecContext *pCodecCtx;
- AVRational frame_rate;
- int frs_num;
- double frs_den;
- int streamcount;
-
-#ifdef FFMPEG_SWSCALE_COLOR_SPACE_SUPPORT
- /* The following for color space determination */
- int srcRange, dstRange, brightness, contrast, saturation;
- int *table;
- const int *inv_table;
-#endif
-
- if (anim == NULL) return(-1);
-
- streamcount = anim->streamindex;
-
- if (avformat_open_input(&pFormatCtx, anim->name, NULL, NULL) != 0) {
- return -1;
- }
-
- if (avformat_find_stream_info(pFormatCtx, NULL) < 0) {
- avformat_close_input(&pFormatCtx);
- return -1;
- }
-
- av_dump_format(pFormatCtx, 0, anim->name, 0);
-
-
- /* Find the video stream */
- videoStream = -1;
-
- for (i = 0; i < pFormatCtx->nb_streams; i++)
- if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
- if (streamcount > 0) {
- streamcount--;
- continue;
- }
- videoStream = i;
- break;
- }
-
- if (videoStream == -1) {
- avformat_close_input(&pFormatCtx);
- return -1;
- }
-
- pCodecCtx = pFormatCtx->streams[videoStream]->codec;
-
- /* Find the decoder for the video stream */
- pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
- if (pCodec == NULL) {
- avformat_close_input(&pFormatCtx);
- return -1;
- }
-
- pCodecCtx->workaround_bugs = 1;
-
- if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0) {
- avformat_close_input(&pFormatCtx);
- return -1;
- }
- if (pCodecCtx->pix_fmt == AV_PIX_FMT_NONE) {
- avcodec_close(anim->pCodecCtx);
- avformat_close_input(&pFormatCtx);
- return -1;
- }
-
- frame_rate = av_get_r_frame_rate_compat(pFormatCtx, pFormatCtx->streams[videoStream]);
- if (pFormatCtx->streams[videoStream]->nb_frames != 0) {
- anim->duration = pFormatCtx->streams[videoStream]->nb_frames;
- }
- else {
- anim->duration = (int)(pFormatCtx->duration *
- av_q2d(frame_rate) /
- AV_TIME_BASE + 0.5f);
- }
-
- frs_num = frame_rate.num;
- frs_den = frame_rate.den;
-
- frs_den *= AV_TIME_BASE;
-
- while (frs_num % 10 == 0 && frs_den >= 2.0 && frs_num > 10) {
- frs_num /= 10;
- frs_den /= 10;
- }
-
- anim->frs_sec = frs_num;
- anim->frs_sec_base = frs_den;
-
- anim->params = 0;
-
- anim->x = pCodecCtx->width;
- anim->y = av_get_cropped_height_from_codec(pCodecCtx);
-
- anim->pFormatCtx = pFormatCtx;
- anim->pCodecCtx = pCodecCtx;
- anim->pCodec = pCodec;
- anim->videoStream = videoStream;
-
- anim->interlacing = 0;
- anim->orientation = 0;
- anim->framesize = anim->x * anim->y * 4;
-
- anim->curposition = -1;
- anim->last_frame = 0;
- anim->last_pts = -1;
- anim->next_pts = -1;
- anim->next_packet.stream_index = -1;
-
- anim->pFrame = av_frame_alloc();
- anim->pFrameComplete = false;
- anim->pFrameDeinterlaced = av_frame_alloc();
- anim->pFrameRGB = av_frame_alloc();
-
- if (need_aligned_ffmpeg_buffer(anim)) {
- anim->pFrameRGB->format = AV_PIX_FMT_RGBA;
- anim->pFrameRGB->width = anim->x;
- anim->pFrameRGB->height = anim->y;
-
- if (av_frame_get_buffer(anim->pFrameRGB, 32) < 0) {
- fprintf(stderr, "Could not allocate frame data.\n");
- avcodec_close(anim->pCodecCtx);
- avformat_close_input(&anim->pFormatCtx);
- av_frame_free(&anim->pFrameRGB);
- av_frame_free(&anim->pFrameDeinterlaced);
- av_frame_free(&anim->pFrame);
- anim->pCodecCtx = NULL;
- return -1;
- }
- }
-
- if (avpicture_get_size(AV_PIX_FMT_RGBA, anim->x, anim->y) !=
- anim->x * anim->y * 4)
- {
- fprintf(stderr,
- "ffmpeg has changed alloc scheme ... ARGHHH!\n");
- avcodec_close(anim->pCodecCtx);
- avformat_close_input(&anim->pFormatCtx);
- av_frame_free(&anim->pFrameRGB);
- av_frame_free(&anim->pFrameDeinterlaced);
- av_frame_free(&anim->pFrame);
- anim->pCodecCtx = NULL;
- return -1;
- }
-
- if (anim->ib_flags & IB_animdeinterlace) {
- avpicture_fill((AVPicture *) anim->pFrameDeinterlaced,
- MEM_callocN(avpicture_get_size(
- anim->pCodecCtx->pix_fmt,
- anim->pCodecCtx->width,
- anim->pCodecCtx->height),
- "ffmpeg deinterlace"),
- anim->pCodecCtx->pix_fmt,
- anim->pCodecCtx->width,
- anim->pCodecCtx->height);
- }
-
- if (pCodecCtx->has_b_frames) {
- anim->preseek = 25; /* FIXME: detect gopsize ... */
- }
- else {
- anim->preseek = 0;
- }
-
- anim->img_convert_ctx = sws_getContext(
- anim->x,
- anim->y,
- anim->pCodecCtx->pix_fmt,
- anim->x,
- anim->y,
- AV_PIX_FMT_RGBA,
- SWS_FAST_BILINEAR | SWS_PRINT_INFO | SWS_FULL_CHR_H_INT,
- NULL, NULL, NULL);
-
- if (!anim->img_convert_ctx) {
- fprintf(stderr,
- "Can't transform color space??? Bailing out...\n");
- avcodec_close(anim->pCodecCtx);
- avformat_close_input(&anim->pFormatCtx);
- av_frame_free(&anim->pFrameRGB);
- av_frame_free(&anim->pFrameDeinterlaced);
- av_frame_free(&anim->pFrame);
- anim->pCodecCtx = NULL;
- return -1;
- }
-
-#ifdef FFMPEG_SWSCALE_COLOR_SPACE_SUPPORT
- /* Try do detect if input has 0-255 YCbCR range (JFIF Jpeg MotionJpeg) */
- if (!sws_getColorspaceDetails(anim->img_convert_ctx, (int **)&inv_table, &srcRange,
- &table, &dstRange, &brightness, &contrast, &saturation))
- {
- srcRange = srcRange || anim->pCodecCtx->color_range == AVCOL_RANGE_JPEG;
- inv_table = sws_getCoefficients(anim->pCodecCtx->colorspace);
-
- if (sws_setColorspaceDetails(anim->img_convert_ctx, (int *)inv_table, srcRange,
- table, dstRange, brightness, contrast, saturation))
- {
- fprintf(stderr, "Warning: Could not set libswscale colorspace details.\n");
- }
- }
- else {
- fprintf(stderr, "Warning: Could not set libswscale colorspace details.\n");
- }
-#endif
-
- return (0);
+ int i, videoStream;
+
+ AVCodec *pCodec;
+ AVFormatContext *pFormatCtx = NULL;
+ AVCodecContext *pCodecCtx;
+ AVRational frame_rate;
+ int frs_num;
+ double frs_den;
+ int streamcount;
+
+# ifdef FFMPEG_SWSCALE_COLOR_SPACE_SUPPORT
+ /* The following for color space determination */
+ int srcRange, dstRange, brightness, contrast, saturation;
+ int *table;
+ const int *inv_table;
+# endif
+
+ if (anim == NULL)
+ return (-1);
+
+ streamcount = anim->streamindex;
+
+ if (avformat_open_input(&pFormatCtx, anim->name, NULL, NULL) != 0) {
+ return -1;
+ }
+
+ if (avformat_find_stream_info(pFormatCtx, NULL) < 0) {
+ avformat_close_input(&pFormatCtx);
+ return -1;
+ }
+
+ av_dump_format(pFormatCtx, 0, anim->name, 0);
+
+ /* Find the video stream */
+ videoStream = -1;
+
+ for (i = 0; i < pFormatCtx->nb_streams; i++)
+ if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
+ if (streamcount > 0) {
+ streamcount--;
+ continue;
+ }
+ videoStream = i;
+ break;
+ }
+
+ if (videoStream == -1) {
+ avformat_close_input(&pFormatCtx);
+ return -1;
+ }
+
+ pCodecCtx = pFormatCtx->streams[videoStream]->codec;
+
+ /* Find the decoder for the video stream */
+ pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
+ if (pCodec == NULL) {
+ avformat_close_input(&pFormatCtx);
+ return -1;
+ }
+
+ pCodecCtx->workaround_bugs = 1;
+
+ if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0) {
+ avformat_close_input(&pFormatCtx);
+ return -1;
+ }
+ if (pCodecCtx->pix_fmt == AV_PIX_FMT_NONE) {
+ avcodec_close(anim->pCodecCtx);
+ avformat_close_input(&pFormatCtx);
+ return -1;
+ }
+
+ frame_rate = av_get_r_frame_rate_compat(pFormatCtx, pFormatCtx->streams[videoStream]);
+ if (pFormatCtx->streams[videoStream]->nb_frames != 0) {
+ anim->duration = pFormatCtx->streams[videoStream]->nb_frames;
+ }
+ else {
+ anim->duration = (int)(pFormatCtx->duration * av_q2d(frame_rate) / AV_TIME_BASE + 0.5f);
+ }
+
+ frs_num = frame_rate.num;
+ frs_den = frame_rate.den;
+
+ frs_den *= AV_TIME_BASE;
+
+ while (frs_num % 10 == 0 && frs_den >= 2.0 && frs_num > 10) {
+ frs_num /= 10;
+ frs_den /= 10;
+ }
+
+ anim->frs_sec = frs_num;
+ anim->frs_sec_base = frs_den;
+
+ anim->params = 0;
+
+ anim->x = pCodecCtx->width;
+ anim->y = av_get_cropped_height_from_codec(pCodecCtx);
+
+ anim->pFormatCtx = pFormatCtx;
+ anim->pCodecCtx = pCodecCtx;
+ anim->pCodec = pCodec;
+ anim->videoStream = videoStream;
+
+ anim->interlacing = 0;
+ anim->orientation = 0;
+ anim->framesize = anim->x * anim->y * 4;
+
+ anim->curposition = -1;
+ anim->last_frame = 0;
+ anim->last_pts = -1;
+ anim->next_pts = -1;
+ anim->next_packet.stream_index = -1;
+
+ anim->pFrame = av_frame_alloc();
+ anim->pFrameComplete = false;
+ anim->pFrameDeinterlaced = av_frame_alloc();
+ anim->pFrameRGB = av_frame_alloc();
+
+ if (need_aligned_ffmpeg_buffer(anim)) {
+ anim->pFrameRGB->format = AV_PIX_FMT_RGBA;
+ anim->pFrameRGB->width = anim->x;
+ anim->pFrameRGB->height = anim->y;
+
+ if (av_frame_get_buffer(anim->pFrameRGB, 32) < 0) {
+ fprintf(stderr, "Could not allocate frame data.\n");
+ avcodec_close(anim->pCodecCtx);
+ avformat_close_input(&anim->pFormatCtx);
+ av_frame_free(&anim->pFrameRGB);
+ av_frame_free(&anim->pFrameDeinterlaced);
+ av_frame_free(&anim->pFrame);
+ anim->pCodecCtx = NULL;
+ return -1;
+ }
+ }
+
+ if (avpicture_get_size(AV_PIX_FMT_RGBA, anim->x, anim->y) != anim->x * anim->y * 4) {
+ fprintf(stderr, "ffmpeg has changed alloc scheme ... ARGHHH!\n");
+ avcodec_close(anim->pCodecCtx);
+ avformat_close_input(&anim->pFormatCtx);
+ av_frame_free(&anim->pFrameRGB);
+ av_frame_free(&anim->pFrameDeinterlaced);
+ av_frame_free(&anim->pFrame);
+ anim->pCodecCtx = NULL;
+ return -1;
+ }
+
+ if (anim->ib_flags & IB_animdeinterlace) {
+ avpicture_fill((AVPicture *)anim->pFrameDeinterlaced,
+ MEM_callocN(avpicture_get_size(anim->pCodecCtx->pix_fmt,
+ anim->pCodecCtx->width,
+ anim->pCodecCtx->height),
+ "ffmpeg deinterlace"),
+ anim->pCodecCtx->pix_fmt,
+ anim->pCodecCtx->width,
+ anim->pCodecCtx->height);
+ }
+
+ if (pCodecCtx->has_b_frames) {
+ anim->preseek = 25; /* FIXME: detect gopsize ... */
+ }
+ else {
+ anim->preseek = 0;
+ }
+
+ anim->img_convert_ctx = sws_getContext(anim->x,
+ anim->y,
+ anim->pCodecCtx->pix_fmt,
+ anim->x,
+ anim->y,
+ AV_PIX_FMT_RGBA,
+ SWS_FAST_BILINEAR | SWS_PRINT_INFO | SWS_FULL_CHR_H_INT,
+ NULL,
+ NULL,
+ NULL);
+
+ if (!anim->img_convert_ctx) {
+ fprintf(stderr, "Can't transform color space??? Bailing out...\n");
+ avcodec_close(anim->pCodecCtx);
+ avformat_close_input(&anim->pFormatCtx);
+ av_frame_free(&anim->pFrameRGB);
+ av_frame_free(&anim->pFrameDeinterlaced);
+ av_frame_free(&anim->pFrame);
+ anim->pCodecCtx = NULL;
+ return -1;
+ }
+
+# ifdef FFMPEG_SWSCALE_COLOR_SPACE_SUPPORT
+ /* Try do detect if input has 0-255 YCbCR range (JFIF Jpeg MotionJpeg) */
+ if (!sws_getColorspaceDetails(anim->img_convert_ctx,
+ (int **)&inv_table,
+ &srcRange,
+ &table,
+ &dstRange,
+ &brightness,
+ &contrast,
+ &saturation)) {
+ srcRange = srcRange || anim->pCodecCtx->color_range == AVCOL_RANGE_JPEG;
+ inv_table = sws_getCoefficients(anim->pCodecCtx->colorspace);
+
+ if (sws_setColorspaceDetails(anim->img_convert_ctx,
+ (int *)inv_table,
+ srcRange,
+ table,
+ dstRange,
+ brightness,
+ contrast,
+ saturation)) {
+ fprintf(stderr, "Warning: Could not set libswscale colorspace details.\n");
+ }
+ }
+ else {
+ fprintf(stderr, "Warning: Could not set libswscale colorspace details.\n");
+ }
+# endif
+
+ return (0);
}
/* postprocess the image in anim->pFrame and do color conversion
@@ -689,535 +705,504 @@ static int startffmpeg(struct anim *anim)
static void ffmpeg_postprocess(struct anim *anim)
{
- AVFrame *input = anim->pFrame;
- ImBuf *ibuf = anim->last_frame;
- int filter_y = 0;
-
- if (!anim->pFrameComplete) {
- return;
- }
-
- /* This means the data wasnt read properly,
- * this check stops crashing */
- if (input->data[0] == 0 && input->data[1] == 0 &&
- input->data[2] == 0 && input->data[3] == 0)
- {
- fprintf(stderr, "ffmpeg_fetchibuf: "
- "data not read properly...\n");
- return;
- }
-
- av_log(anim->pFormatCtx, AV_LOG_DEBUG,
- " POSTPROC: anim->pFrame planes: %p %p %p %p\n",
- input->data[0], input->data[1], input->data[2],
- input->data[3]);
-
-
- if (anim->ib_flags & IB_animdeinterlace) {
- if (avpicture_deinterlace(
- (AVPicture *)
- anim->pFrameDeinterlaced,
- (const AVPicture *)
- anim->pFrame,
- anim->pCodecCtx->pix_fmt,
- anim->pCodecCtx->width,
- anim->pCodecCtx->height) < 0)
- {
- filter_y = true;
- }
- else {
- input = anim->pFrameDeinterlaced;
- }
- }
-
- if (!need_aligned_ffmpeg_buffer(anim)) {
- avpicture_fill((AVPicture *) anim->pFrameRGB,
- (unsigned char *) ibuf->rect,
- AV_PIX_FMT_RGBA, anim->x, anim->y);
- }
-
- if (ENDIAN_ORDER == B_ENDIAN) {
- int *dstStride = anim->pFrameRGB->linesize;
- uint8_t **dst = anim->pFrameRGB->data;
- int dstStride2[4] = { dstStride[0], 0, 0, 0 };
- uint8_t *dst2[4] = { dst[0], 0, 0, 0 };
- int x, y, h, w;
- unsigned char *bottom;
- unsigned char *top;
-
- sws_scale(anim->img_convert_ctx,
- (const uint8_t *const *)input->data,
- input->linesize,
- 0,
- anim->y,
- dst2,
- dstStride2);
-
- bottom = (unsigned char *) ibuf->rect;
- top = bottom + ibuf->x * (ibuf->y - 1) * 4;
-
- h = (ibuf->y + 1) / 2;
- w = ibuf->x;
-
- for (y = 0; y < h; y++) {
- unsigned char tmp[4];
- unsigned int *tmp_l =
- (unsigned int *) tmp;
-
- for (x = 0; x < w; x++) {
- tmp[0] = bottom[0];
- tmp[1] = bottom[1];
- tmp[2] = bottom[2];
- tmp[3] = bottom[3];
-
- bottom[0] = top[0];
- bottom[1] = top[1];
- bottom[2] = top[2];
- bottom[3] = top[3];
-
- *(unsigned int *) top = *tmp_l;
-
- bottom += 4;
- top += 4;
- }
- top -= 8 * w;
- }
- }
- else {
- int *dstStride = anim->pFrameRGB->linesize;
- uint8_t **dst = anim->pFrameRGB->data;
- int dstStride2[4] = { -dstStride[0], 0, 0, 0 };
- uint8_t *dst2[4] = { dst[0] + (anim->y - 1) * dstStride[0], 0, 0, 0 };
-
- sws_scale(anim->img_convert_ctx,
- (const uint8_t *const *)input->data,
- input->linesize,
- 0,
- anim->y,
- dst2,
- dstStride2);
- }
-
- if (need_aligned_ffmpeg_buffer(anim)) {
- uint8_t *src = anim->pFrameRGB->data[0];
- uint8_t *dst = (uint8_t *) ibuf->rect;
- for (int y = 0; y < anim->y; y++) {
- memcpy(dst, src, anim->x * 4);
- dst += anim->x * 4;
- src += anim->pFrameRGB->linesize[0];
- }
- }
-
- if (filter_y) {
- IMB_filtery(ibuf);
- }
+ AVFrame *input = anim->pFrame;
+ ImBuf *ibuf = anim->last_frame;
+ int filter_y = 0;
+
+ if (!anim->pFrameComplete) {
+ return;
+ }
+
+ /* This means the data wasnt read properly,
+ * this check stops crashing */
+ if (input->data[0] == 0 && input->data[1] == 0 && input->data[2] == 0 && input->data[3] == 0) {
+ fprintf(stderr,
+ "ffmpeg_fetchibuf: "
+ "data not read properly...\n");
+ return;
+ }
+
+ av_log(anim->pFormatCtx,
+ AV_LOG_DEBUG,
+ " POSTPROC: anim->pFrame planes: %p %p %p %p\n",
+ input->data[0],
+ input->data[1],
+ input->data[2],
+ input->data[3]);
+
+ if (anim->ib_flags & IB_animdeinterlace) {
+ if (avpicture_deinterlace((AVPicture *)anim->pFrameDeinterlaced,
+ (const AVPicture *)anim->pFrame,
+ anim->pCodecCtx->pix_fmt,
+ anim->pCodecCtx->width,
+ anim->pCodecCtx->height) < 0) {
+ filter_y = true;
+ }
+ else {
+ input = anim->pFrameDeinterlaced;
+ }
+ }
+
+ if (!need_aligned_ffmpeg_buffer(anim)) {
+ avpicture_fill((AVPicture *)anim->pFrameRGB,
+ (unsigned char *)ibuf->rect,
+ AV_PIX_FMT_RGBA,
+ anim->x,
+ anim->y);
+ }
+
+ if (ENDIAN_ORDER == B_ENDIAN) {
+ int *dstStride = anim->pFrameRGB->linesize;
+ uint8_t **dst = anim->pFrameRGB->data;
+ int dstStride2[4] = {dstStride[0], 0, 0, 0};
+ uint8_t *dst2[4] = {dst[0], 0, 0, 0};
+ int x, y, h, w;
+ unsigned char *bottom;
+ unsigned char *top;
+
+ sws_scale(anim->img_convert_ctx,
+ (const uint8_t *const *)input->data,
+ input->linesize,
+ 0,
+ anim->y,
+ dst2,
+ dstStride2);
+
+ bottom = (unsigned char *)ibuf->rect;
+ top = bottom + ibuf->x * (ibuf->y - 1) * 4;
+
+ h = (ibuf->y + 1) / 2;
+ w = ibuf->x;
+
+ for (y = 0; y < h; y++) {
+ unsigned char tmp[4];
+ unsigned int *tmp_l = (unsigned int *)tmp;
+
+ for (x = 0; x < w; x++) {
+ tmp[0] = bottom[0];
+ tmp[1] = bottom[1];
+ tmp[2] = bottom[2];
+ tmp[3] = bottom[3];
+
+ bottom[0] = top[0];
+ bottom[1] = top[1];
+ bottom[2] = top[2];
+ bottom[3] = top[3];
+
+ *(unsigned int *)top = *tmp_l;
+
+ bottom += 4;
+ top += 4;
+ }
+ top -= 8 * w;
+ }
+ }
+ else {
+ int *dstStride = anim->pFrameRGB->linesize;
+ uint8_t **dst = anim->pFrameRGB->data;
+ int dstStride2[4] = {-dstStride[0], 0, 0, 0};
+ uint8_t *dst2[4] = {dst[0] + (anim->y - 1) * dstStride[0], 0, 0, 0};
+
+ sws_scale(anim->img_convert_ctx,
+ (const uint8_t *const *)input->data,
+ input->linesize,
+ 0,
+ anim->y,
+ dst2,
+ dstStride2);
+ }
+
+ if (need_aligned_ffmpeg_buffer(anim)) {
+ uint8_t *src = anim->pFrameRGB->data[0];
+ uint8_t *dst = (uint8_t *)ibuf->rect;
+ for (int y = 0; y < anim->y; y++) {
+ memcpy(dst, src, anim->x * 4);
+ dst += anim->x * 4;
+ src += anim->pFrameRGB->linesize[0];
+ }
+ }
+
+ if (filter_y) {
+ IMB_filtery(ibuf);
+ }
}
/* decode one video frame also considering the packet read into next_packet */
static int ffmpeg_decode_video_frame(struct anim *anim)
{
- int rval = 0;
-
- av_log(anim->pFormatCtx, AV_LOG_DEBUG, " DECODE VIDEO FRAME\n");
-
- if (anim->next_packet.stream_index == anim->videoStream) {
- av_free_packet(&anim->next_packet);
- anim->next_packet.stream_index = -1;
- }
-
- while ((rval = av_read_frame(anim->pFormatCtx, &anim->next_packet)) >= 0) {
- av_log(anim->pFormatCtx,
- AV_LOG_DEBUG,
- "%sREAD: strID=%d (VID: %d) dts=%lld pts=%lld "
- "%s\n",
- (anim->next_packet.stream_index == anim->videoStream)
- ? "->" : " ",
- anim->next_packet.stream_index,
- anim->videoStream,
- (anim->next_packet.dts == AV_NOPTS_VALUE) ? -1 :
- (long long int)anim->next_packet.dts,
- (anim->next_packet.pts == AV_NOPTS_VALUE) ? -1 :
- (long long int)anim->next_packet.pts,
- (anim->next_packet.flags & AV_PKT_FLAG_KEY) ?
- " KEY" : "");
- if (anim->next_packet.stream_index == anim->videoStream) {
- anim->pFrameComplete = 0;
-
- avcodec_decode_video2(
- anim->pCodecCtx,
- anim->pFrame, &anim->pFrameComplete,
- &anim->next_packet);
-
- if (anim->pFrameComplete) {
- anim->next_pts = av_get_pts_from_frame(
- anim->pFormatCtx, anim->pFrame);
-
- av_log(anim->pFormatCtx,
- AV_LOG_DEBUG,
- " FRAME DONE: next_pts=%lld "
- "pkt_pts=%lld, guessed_pts=%lld\n",
- (anim->pFrame->pts == AV_NOPTS_VALUE) ?
- -1 : (long long int)anim->pFrame->pts,
- (anim->pFrame->pkt_pts == AV_NOPTS_VALUE) ?
- -1 : (long long int)anim->pFrame->pkt_pts,
- (long long int)anim->next_pts);
- break;
- }
- }
- av_free_packet(&anim->next_packet);
- anim->next_packet.stream_index = -1;
- }
-
- if (rval == AVERROR_EOF) {
- /* this sets size and data fields to zero,
- * which is necessary to decode the remaining data
- * in the decoder engine after EOF. It also prevents a memory
- * leak, since av_read_frame spills out a full size packet even
- * on EOF... (and: it's safe to call on NULL packets) */
-
- av_free_packet(&anim->next_packet);
-
- anim->next_packet.size = 0;
- anim->next_packet.data = 0;
-
- anim->pFrameComplete = 0;
-
- avcodec_decode_video2(
- anim->pCodecCtx,
- anim->pFrame, &anim->pFrameComplete,
- &anim->next_packet);
-
- if (anim->pFrameComplete) {
- anim->next_pts = av_get_pts_from_frame(
- anim->pFormatCtx, anim->pFrame);
-
- av_log(anim->pFormatCtx,
- AV_LOG_DEBUG,
- " FRAME DONE (after EOF): next_pts=%lld "
- "pkt_pts=%lld, guessed_pts=%lld\n",
- (anim->pFrame->pts == AV_NOPTS_VALUE) ?
- -1 : (long long int)anim->pFrame->pts,
- (anim->pFrame->pkt_pts == AV_NOPTS_VALUE) ?
- -1 : (long long int)anim->pFrame->pkt_pts,
- (long long int)anim->next_pts);
- rval = 0;
- }
- }
-
- if (rval < 0) {
- anim->next_packet.stream_index = -1;
-
- av_log(anim->pFormatCtx,
- AV_LOG_ERROR, " DECODE READ FAILED: av_read_frame() "
- "returned error: %d\n", rval);
- }
-
- return (rval >= 0);
+ int rval = 0;
+
+ av_log(anim->pFormatCtx, AV_LOG_DEBUG, " DECODE VIDEO FRAME\n");
+
+ if (anim->next_packet.stream_index == anim->videoStream) {
+ av_free_packet(&anim->next_packet);
+ anim->next_packet.stream_index = -1;
+ }
+
+ while ((rval = av_read_frame(anim->pFormatCtx, &anim->next_packet)) >= 0) {
+ av_log(anim->pFormatCtx,
+ AV_LOG_DEBUG,
+ "%sREAD: strID=%d (VID: %d) dts=%lld pts=%lld "
+ "%s\n",
+ (anim->next_packet.stream_index == anim->videoStream) ? "->" : " ",
+ anim->next_packet.stream_index,
+ anim->videoStream,
+ (anim->next_packet.dts == AV_NOPTS_VALUE) ? -1 : (long long int)anim->next_packet.dts,
+ (anim->next_packet.pts == AV_NOPTS_VALUE) ? -1 : (long long int)anim->next_packet.pts,
+ (anim->next_packet.flags & AV_PKT_FLAG_KEY) ? " KEY" : "");
+ if (anim->next_packet.stream_index == anim->videoStream) {
+ anim->pFrameComplete = 0;
+
+ avcodec_decode_video2(
+ anim->pCodecCtx, anim->pFrame, &anim->pFrameComplete, &anim->next_packet);
+
+ if (anim->pFrameComplete) {
+ anim->next_pts = av_get_pts_from_frame(anim->pFormatCtx, anim->pFrame);
+
+ av_log(anim->pFormatCtx,
+ AV_LOG_DEBUG,
+ " FRAME DONE: next_pts=%lld "
+ "pkt_pts=%lld, guessed_pts=%lld\n",
+ (anim->pFrame->pts == AV_NOPTS_VALUE) ? -1 : (long long int)anim->pFrame->pts,
+ (anim->pFrame->pkt_pts == AV_NOPTS_VALUE) ? -1 :
+ (long long int)anim->pFrame->pkt_pts,
+ (long long int)anim->next_pts);
+ break;
+ }
+ }
+ av_free_packet(&anim->next_packet);
+ anim->next_packet.stream_index = -1;
+ }
+
+ if (rval == AVERROR_EOF) {
+ /* this sets size and data fields to zero,
+ * which is necessary to decode the remaining data
+ * in the decoder engine after EOF. It also prevents a memory
+ * leak, since av_read_frame spills out a full size packet even
+ * on EOF... (and: it's safe to call on NULL packets) */
+
+ av_free_packet(&anim->next_packet);
+
+ anim->next_packet.size = 0;
+ anim->next_packet.data = 0;
+
+ anim->pFrameComplete = 0;
+
+ avcodec_decode_video2(
+ anim->pCodecCtx, anim->pFrame, &anim->pFrameComplete, &anim->next_packet);
+
+ if (anim->pFrameComplete) {
+ anim->next_pts = av_get_pts_from_frame(anim->pFormatCtx, anim->pFrame);
+
+ av_log(anim->pFormatCtx,
+ AV_LOG_DEBUG,
+ " FRAME DONE (after EOF): next_pts=%lld "
+ "pkt_pts=%lld, guessed_pts=%lld\n",
+ (anim->pFrame->pts == AV_NOPTS_VALUE) ? -1 : (long long int)anim->pFrame->pts,
+ (anim->pFrame->pkt_pts == AV_NOPTS_VALUE) ? -1 : (long long int)anim->pFrame->pkt_pts,
+ (long long int)anim->next_pts);
+ rval = 0;
+ }
+ }
+
+ if (rval < 0) {
+ anim->next_packet.stream_index = -1;
+
+ av_log(anim->pFormatCtx,
+ AV_LOG_ERROR,
+ " DECODE READ FAILED: av_read_frame() "
+ "returned error: %d\n",
+ rval);
+ }
+
+ return (rval >= 0);
}
-static void ffmpeg_decode_video_frame_scan(
- struct anim *anim, int64_t pts_to_search)
+static void ffmpeg_decode_video_frame_scan(struct anim *anim, int64_t pts_to_search)
{
- /* there seem to exist *very* silly GOP lengths out in the wild... */
- int count = 1000;
-
- av_log(anim->pFormatCtx,
- AV_LOG_DEBUG,
- "SCAN start: considering pts=%lld in search of %lld\n",
- (long long int)anim->next_pts, (long long int)pts_to_search);
-
- while (count > 0 && anim->next_pts < pts_to_search) {
- av_log(anim->pFormatCtx,
- AV_LOG_DEBUG,
- " WHILE: pts=%lld in search of %lld\n",
- (long long int)anim->next_pts, (long long int)pts_to_search);
- if (!ffmpeg_decode_video_frame(anim)) {
- break;
- }
- count--;
- }
- if (count == 0) {
- av_log(anim->pFormatCtx,
- AV_LOG_ERROR,
- "SCAN failed: completely lost in stream, "
- "bailing out at PTS=%lld, searching for PTS=%lld\n",
- (long long int)anim->next_pts, (long long int)pts_to_search);
- }
- if (anim->next_pts == pts_to_search) {
- av_log(anim->pFormatCtx,
- AV_LOG_DEBUG, "SCAN HAPPY: we found our PTS!\n");
- }
- else {
- av_log(anim->pFormatCtx,
- AV_LOG_ERROR, "SCAN UNHAPPY: PTS not matched!\n");
- }
+ /* there seem to exist *very* silly GOP lengths out in the wild... */
+ int count = 1000;
+
+ av_log(anim->pFormatCtx,
+ AV_LOG_DEBUG,
+ "SCAN start: considering pts=%lld in search of %lld\n",
+ (long long int)anim->next_pts,
+ (long long int)pts_to_search);
+
+ while (count > 0 && anim->next_pts < pts_to_search) {
+ av_log(anim->pFormatCtx,
+ AV_LOG_DEBUG,
+ " WHILE: pts=%lld in search of %lld\n",
+ (long long int)anim->next_pts,
+ (long long int)pts_to_search);
+ if (!ffmpeg_decode_video_frame(anim)) {
+ break;
+ }
+ count--;
+ }
+ if (count == 0) {
+ av_log(anim->pFormatCtx,
+ AV_LOG_ERROR,
+ "SCAN failed: completely lost in stream, "
+ "bailing out at PTS=%lld, searching for PTS=%lld\n",
+ (long long int)anim->next_pts,
+ (long long int)pts_to_search);
+ }
+ if (anim->next_pts == pts_to_search) {
+ av_log(anim->pFormatCtx, AV_LOG_DEBUG, "SCAN HAPPY: we found our PTS!\n");
+ }
+ else {
+ av_log(anim->pFormatCtx, AV_LOG_ERROR, "SCAN UNHAPPY: PTS not matched!\n");
+ }
}
static int match_format(const char *name, AVFormatContext *pFormatCtx)
{
- const char *p;
- int len, namelen;
-
- const char *names = pFormatCtx->iformat->name;
-
- if (!name || !names)
- return 0;
-
- namelen = strlen(name);
- while ((p = strchr(names, ','))) {
- len = MAX2(p - names, namelen);
- if (!BLI_strncasecmp(name, names, len))
- return 1;
- names = p + 1;
- }
- return !BLI_strcasecmp(name, names);
+ const char *p;
+ int len, namelen;
+
+ const char *names = pFormatCtx->iformat->name;
+
+ if (!name || !names)
+ return 0;
+
+ namelen = strlen(name);
+ while ((p = strchr(names, ','))) {
+ len = MAX2(p - names, namelen);
+ if (!BLI_strncasecmp(name, names, len))
+ return 1;
+ names = p + 1;
+ }
+ return !BLI_strcasecmp(name, names);
}
static int ffmpeg_seek_by_byte(AVFormatContext *pFormatCtx)
{
- static const char *byte_seek_list[] = { "mpegts", 0 };
- const char **p;
+ static const char *byte_seek_list[] = {"mpegts", 0};
+ const char **p;
- if (pFormatCtx->iformat->flags & AVFMT_TS_DISCONT) {
- return true;
- }
+ if (pFormatCtx->iformat->flags & AVFMT_TS_DISCONT) {
+ return true;
+ }
- p = byte_seek_list;
+ p = byte_seek_list;
- while (*p) {
- if (match_format(*p++, pFormatCtx)) {
- return true;
- }
- }
+ while (*p) {
+ if (match_format(*p++, pFormatCtx)) {
+ return true;
+ }
+ }
- return false;
+ return false;
}
-static ImBuf *ffmpeg_fetchibuf(struct anim *anim, int position,
- IMB_Timecode_Type tc)
+static ImBuf *ffmpeg_fetchibuf(struct anim *anim, int position, IMB_Timecode_Type tc)
{
- int64_t pts_to_search = 0;
- double frame_rate;
- double pts_time_base;
- long long st_time;
- struct anim_index *tc_index = 0;
- AVStream *v_st;
- int new_frame_index = 0; /* To quiet gcc barking... */
- int old_frame_index = 0; /* To quiet gcc barking... */
-
- if (anim == NULL) return (0);
-
- av_log(anim->pFormatCtx, AV_LOG_DEBUG, "FETCH: pos=%d\n", position);
-
- if (tc != IMB_TC_NONE) {
- tc_index = IMB_anim_open_index(anim, tc);
- }
-
- v_st = anim->pFormatCtx->streams[anim->videoStream];
-
- frame_rate = av_q2d(av_get_r_frame_rate_compat(anim->pFormatCtx, v_st));
-
- st_time = anim->pFormatCtx->start_time;
- pts_time_base = av_q2d(v_st->time_base);
-
- if (tc_index) {
- new_frame_index = IMB_indexer_get_frame_index(
- tc_index, position);
- old_frame_index = IMB_indexer_get_frame_index(
- tc_index, anim->curposition);
- pts_to_search = IMB_indexer_get_pts(
- tc_index, new_frame_index);
- }
- else {
- pts_to_search = (long long)
- floor(((double) position) /
- pts_time_base / frame_rate + 0.5);
-
- if (st_time != AV_NOPTS_VALUE) {
- pts_to_search += st_time / pts_time_base / AV_TIME_BASE;
- }
- }
-
- av_log(anim->pFormatCtx, AV_LOG_DEBUG,
- "FETCH: looking for PTS=%lld "
- "(pts_timebase=%g, frame_rate=%g, st_time=%lld)\n",
- (long long int)pts_to_search, pts_time_base, frame_rate, st_time);
-
- if (anim->last_frame &&
- anim->last_pts <= pts_to_search && anim->next_pts > pts_to_search)
- {
- av_log(anim->pFormatCtx, AV_LOG_DEBUG,
- "FETCH: frame repeat: last: %lld next: %lld\n",
- (long long int)anim->last_pts,
- (long long int)anim->next_pts);
- IMB_refImBuf(anim->last_frame);
- anim->curposition = position;
- return anim->last_frame;
- }
-
- if (position > anim->curposition + 1 &&
- anim->preseek &&
- !tc_index &&
- position - (anim->curposition + 1) < anim->preseek)
- {
- av_log(anim->pFormatCtx, AV_LOG_DEBUG,
- "FETCH: within preseek interval (no index)\n");
-
- ffmpeg_decode_video_frame_scan(anim, pts_to_search);
- }
- else if (tc_index &&
- IMB_indexer_can_scan(tc_index, old_frame_index,
- new_frame_index))
- {
- av_log(anim->pFormatCtx, AV_LOG_DEBUG,
- "FETCH: within preseek interval "
- "(index tells us)\n");
-
- ffmpeg_decode_video_frame_scan(anim, pts_to_search);
- }
- else if (position != anim->curposition + 1) {
- long long pos;
- int ret;
-
- if (tc_index) {
- unsigned long long dts;
-
- pos = IMB_indexer_get_seek_pos(
- tc_index, new_frame_index);
- dts = IMB_indexer_get_seek_pos_dts(
- tc_index, new_frame_index);
-
- av_log(anim->pFormatCtx, AV_LOG_DEBUG,
- "TC INDEX seek pos = %lld\n", pos);
- av_log(anim->pFormatCtx, AV_LOG_DEBUG,
- "TC INDEX seek dts = %llu\n", dts);
-
- if (ffmpeg_seek_by_byte(anim->pFormatCtx)) {
- av_log(anim->pFormatCtx, AV_LOG_DEBUG,
- "... using BYTE pos\n");
-
- ret = av_seek_frame(anim->pFormatCtx,
- -1,
- pos, AVSEEK_FLAG_BYTE);
- av_update_cur_dts(anim->pFormatCtx, v_st, dts);
- }
- else {
- av_log(anim->pFormatCtx, AV_LOG_DEBUG,
- "... using DTS pos\n");
- ret = av_seek_frame(anim->pFormatCtx,
- anim->videoStream,
- dts, AVSEEK_FLAG_BACKWARD);
- }
- }
- else {
- pos = (long long) (position - anim->preseek) *
- AV_TIME_BASE / frame_rate;
-
- av_log(anim->pFormatCtx, AV_LOG_DEBUG,
- "NO INDEX seek pos = %lld, st_time = %lld\n",
- pos, (st_time != AV_NOPTS_VALUE) ? st_time : 0);
-
- if (pos < 0) {
- pos = 0;
- }
-
- if (st_time != AV_NOPTS_VALUE) {
- pos += st_time;
- }
-
- av_log(anim->pFormatCtx, AV_LOG_DEBUG,
- "NO INDEX final seek pos = %lld\n", pos);
-
- ret = av_seek_frame(anim->pFormatCtx, -1,
- pos, AVSEEK_FLAG_BACKWARD);
- }
-
- if (ret < 0) {
- av_log(anim->pFormatCtx, AV_LOG_ERROR,
- "FETCH: "
- "error while seeking to DTS = %lld "
- "(frameno = %d, PTS = %lld): errcode = %d\n",
- pos, position, (long long int)pts_to_search, ret);
- }
-
- avcodec_flush_buffers(anim->pCodecCtx);
-
- anim->next_pts = -1;
-
- if (anim->next_packet.stream_index == anim->videoStream) {
- av_free_packet(&anim->next_packet);
- anim->next_packet.stream_index = -1;
- }
-
- /* memset(anim->pFrame, ...) ?? */
-
- if (ret >= 0) {
- ffmpeg_decode_video_frame_scan(anim, pts_to_search);
- }
- }
- else if (position == 0 && anim->curposition == -1) {
- /* first frame without seeking special case... */
- ffmpeg_decode_video_frame(anim);
- }
- else {
- av_log(anim->pFormatCtx, AV_LOG_DEBUG,
- "FETCH: no seek necessary, just continue...\n");
- }
-
- IMB_freeImBuf(anim->last_frame);
- anim->last_frame = IMB_allocImBuf(anim->x, anim->y, 32, IB_rect);
- anim->last_frame->rect_colorspace = colormanage_colorspace_get_named(anim->colorspace);
-
- ffmpeg_postprocess(anim);
-
- anim->last_pts = anim->next_pts;
-
- ffmpeg_decode_video_frame(anim);
-
- anim->curposition = position;
-
- IMB_refImBuf(anim->last_frame);
-
- return anim->last_frame;
+ int64_t pts_to_search = 0;
+ double frame_rate;
+ double pts_time_base;
+ long long st_time;
+ struct anim_index *tc_index = 0;
+ AVStream *v_st;
+ int new_frame_index = 0; /* To quiet gcc barking... */
+ int old_frame_index = 0; /* To quiet gcc barking... */
+
+ if (anim == NULL)
+ return (0);
+
+ av_log(anim->pFormatCtx, AV_LOG_DEBUG, "FETCH: pos=%d\n", position);
+
+ if (tc != IMB_TC_NONE) {
+ tc_index = IMB_anim_open_index(anim, tc);
+ }
+
+ v_st = anim->pFormatCtx->streams[anim->videoStream];
+
+ frame_rate = av_q2d(av_get_r_frame_rate_compat(anim->pFormatCtx, v_st));
+
+ st_time = anim->pFormatCtx->start_time;
+ pts_time_base = av_q2d(v_st->time_base);
+
+ if (tc_index) {
+ new_frame_index = IMB_indexer_get_frame_index(tc_index, position);
+ old_frame_index = IMB_indexer_get_frame_index(tc_index, anim->curposition);
+ pts_to_search = IMB_indexer_get_pts(tc_index, new_frame_index);
+ }
+ else {
+ pts_to_search = (long long)floor(((double)position) / pts_time_base / frame_rate + 0.5);
+
+ if (st_time != AV_NOPTS_VALUE) {
+ pts_to_search += st_time / pts_time_base / AV_TIME_BASE;
+ }
+ }
+
+ av_log(anim->pFormatCtx,
+ AV_LOG_DEBUG,
+ "FETCH: looking for PTS=%lld "
+ "(pts_timebase=%g, frame_rate=%g, st_time=%lld)\n",
+ (long long int)pts_to_search,
+ pts_time_base,
+ frame_rate,
+ st_time);
+
+ if (anim->last_frame && anim->last_pts <= pts_to_search && anim->next_pts > pts_to_search) {
+ av_log(anim->pFormatCtx,
+ AV_LOG_DEBUG,
+ "FETCH: frame repeat: last: %lld next: %lld\n",
+ (long long int)anim->last_pts,
+ (long long int)anim->next_pts);
+ IMB_refImBuf(anim->last_frame);
+ anim->curposition = position;
+ return anim->last_frame;
+ }
+
+ if (position > anim->curposition + 1 && anim->preseek && !tc_index &&
+ position - (anim->curposition + 1) < anim->preseek) {
+ av_log(anim->pFormatCtx, AV_LOG_DEBUG, "FETCH: within preseek interval (no index)\n");
+
+ ffmpeg_decode_video_frame_scan(anim, pts_to_search);
+ }
+ else if (tc_index && IMB_indexer_can_scan(tc_index, old_frame_index, new_frame_index)) {
+ av_log(anim->pFormatCtx,
+ AV_LOG_DEBUG,
+ "FETCH: within preseek interval "
+ "(index tells us)\n");
+
+ ffmpeg_decode_video_frame_scan(anim, pts_to_search);
+ }
+ else if (position != anim->curposition + 1) {
+ long long pos;
+ int ret;
+
+ if (tc_index) {
+ unsigned long long dts;
+
+ pos = IMB_indexer_get_seek_pos(tc_index, new_frame_index);
+ dts = IMB_indexer_get_seek_pos_dts(tc_index, new_frame_index);
+
+ av_log(anim->pFormatCtx, AV_LOG_DEBUG, "TC INDEX seek pos = %lld\n", pos);
+ av_log(anim->pFormatCtx, AV_LOG_DEBUG, "TC INDEX seek dts = %llu\n", dts);
+
+ if (ffmpeg_seek_by_byte(anim->pFormatCtx)) {
+ av_log(anim->pFormatCtx, AV_LOG_DEBUG, "... using BYTE pos\n");
+
+ ret = av_seek_frame(anim->pFormatCtx, -1, pos, AVSEEK_FLAG_BYTE);
+ av_update_cur_dts(anim->pFormatCtx, v_st, dts);
+ }
+ else {
+ av_log(anim->pFormatCtx, AV_LOG_DEBUG, "... using DTS pos\n");
+ ret = av_seek_frame(anim->pFormatCtx, anim->videoStream, dts, AVSEEK_FLAG_BACKWARD);
+ }
+ }
+ else {
+ pos = (long long)(position - anim->preseek) * AV_TIME_BASE / frame_rate;
+
+ av_log(anim->pFormatCtx,
+ AV_LOG_DEBUG,
+ "NO INDEX seek pos = %lld, st_time = %lld\n",
+ pos,
+ (st_time != AV_NOPTS_VALUE) ? st_time : 0);
+
+ if (pos < 0) {
+ pos = 0;
+ }
+
+ if (st_time != AV_NOPTS_VALUE) {
+ pos += st_time;
+ }
+
+ av_log(anim->pFormatCtx, AV_LOG_DEBUG, "NO INDEX final seek pos = %lld\n", pos);
+
+ ret = av_seek_frame(anim->pFormatCtx, -1, pos, AVSEEK_FLAG_BACKWARD);
+ }
+
+ if (ret < 0) {
+ av_log(anim->pFormatCtx,
+ AV_LOG_ERROR,
+ "FETCH: "
+ "error while seeking to DTS = %lld "
+ "(frameno = %d, PTS = %lld): errcode = %d\n",
+ pos,
+ position,
+ (long long int)pts_to_search,
+ ret);
+ }
+
+ avcodec_flush_buffers(anim->pCodecCtx);
+
+ anim->next_pts = -1;
+
+ if (anim->next_packet.stream_index == anim->videoStream) {
+ av_free_packet(&anim->next_packet);
+ anim->next_packet.stream_index = -1;
+ }
+
+ /* memset(anim->pFrame, ...) ?? */
+
+ if (ret >= 0) {
+ ffmpeg_decode_video_frame_scan(anim, pts_to_search);
+ }
+ }
+ else if (position == 0 && anim->curposition == -1) {
+ /* first frame without seeking special case... */
+ ffmpeg_decode_video_frame(anim);
+ }
+ else {
+ av_log(anim->pFormatCtx, AV_LOG_DEBUG, "FETCH: no seek necessary, just continue...\n");
+ }
+
+ IMB_freeImBuf(anim->last_frame);
+ anim->last_frame = IMB_allocImBuf(anim->x, anim->y, 32, IB_rect);
+ anim->last_frame->rect_colorspace = colormanage_colorspace_get_named(anim->colorspace);
+
+ ffmpeg_postprocess(anim);
+
+ anim->last_pts = anim->next_pts;
+
+ ffmpeg_decode_video_frame(anim);
+
+ anim->curposition = position;
+
+ IMB_refImBuf(anim->last_frame);
+
+ return anim->last_frame;
}
static void free_anim_ffmpeg(struct anim *anim)
{
- if (anim == NULL) return;
-
- if (anim->pCodecCtx) {
- avcodec_close(anim->pCodecCtx);
- avformat_close_input(&anim->pFormatCtx);
-
- /* Special case here: pFrame could share pointers with codec,
- * so in order to avoid double-free we don't use av_frame_free()
- * to free the frame.
- *
- * Could it be a bug in FFmpeg?
- */
- av_free(anim->pFrame);
-
- if (!need_aligned_ffmpeg_buffer(anim)) {
- /* If there's no need for own aligned buffer it means that FFmpeg's
- * frame shares the same buffer as temporary ImBuf. In this case we
- * should not free the buffer when freeing the FFmpeg buffer.
- */
- avpicture_fill((AVPicture *)anim->pFrameRGB,
- NULL,
- AV_PIX_FMT_RGBA,
- anim->x, anim->y);
- }
- av_frame_free(&anim->pFrameRGB);
- av_frame_free(&anim->pFrameDeinterlaced);
-
- sws_freeContext(anim->img_convert_ctx);
- IMB_freeImBuf(anim->last_frame);
- if (anim->next_packet.stream_index != -1) {
- av_free_packet(&anim->next_packet);
- }
- }
- anim->duration = 0;
+ if (anim == NULL)
+ return;
+
+ if (anim->pCodecCtx) {
+ avcodec_close(anim->pCodecCtx);
+ avformat_close_input(&anim->pFormatCtx);
+
+ /* Special case here: pFrame could share pointers with codec,
+ * so in order to avoid double-free we don't use av_frame_free()
+ * to free the frame.
+ *
+ * Could it be a bug in FFmpeg?
+ */
+ av_free(anim->pFrame);
+
+ if (!need_aligned_ffmpeg_buffer(anim)) {
+ /* If there's no need for own aligned buffer it means that FFmpeg's
+ * frame shares the same buffer as temporary ImBuf. In this case we
+ * should not free the buffer when freeing the FFmpeg buffer.
+ */
+ avpicture_fill((AVPicture *)anim->pFrameRGB, NULL, AV_PIX_FMT_RGBA, anim->x, anim->y);
+ }
+ av_frame_free(&anim->pFrameRGB);
+ av_frame_free(&anim->pFrameDeinterlaced);
+
+ sws_freeContext(anim->img_convert_ctx);
+ IMB_freeImBuf(anim->last_frame);
+ if (anim->next_packet.stream_index != -1) {
+ av_free_packet(&anim->next_packet);
+ }
+ }
+ anim->duration = 0;
}
#endif
@@ -1228,208 +1213,211 @@ static void free_anim_ffmpeg(struct anim *anim)
static ImBuf *anim_getnew(struct anim *anim)
{
- struct ImBuf *ibuf = NULL;
+ struct ImBuf *ibuf = NULL;
- if (anim == NULL) return(NULL);
+ if (anim == NULL)
+ return (NULL);
- free_anim_movie(anim);
+ free_anim_movie(anim);
#ifdef WITH_AVI
- free_anim_avi(anim);
+ free_anim_avi(anim);
#endif
#ifdef WITH_FFMPEG
- free_anim_ffmpeg(anim);
+ free_anim_ffmpeg(anim);
#endif
- if (anim->curtype != 0) return (NULL);
- anim->curtype = imb_get_anim_type(anim->name);
-
- switch (anim->curtype) {
- case ANIM_SEQUENCE:
- ibuf = IMB_loadiffname(anim->name, anim->ib_flags, anim->colorspace);
- if (ibuf) {
- BLI_strncpy(anim->first, anim->name, sizeof(anim->first));
- anim->duration = 1;
- }
- break;
- case ANIM_MOVIE:
- if (startmovie(anim)) return (NULL);
- ibuf = IMB_allocImBuf(anim->x, anim->y, 24, 0); /* fake */
- break;
+ if (anim->curtype != 0)
+ return (NULL);
+ anim->curtype = imb_get_anim_type(anim->name);
+
+ switch (anim->curtype) {
+ case ANIM_SEQUENCE:
+ ibuf = IMB_loadiffname(anim->name, anim->ib_flags, anim->colorspace);
+ if (ibuf) {
+ BLI_strncpy(anim->first, anim->name, sizeof(anim->first));
+ anim->duration = 1;
+ }
+ break;
+ case ANIM_MOVIE:
+ if (startmovie(anim))
+ return (NULL);
+ ibuf = IMB_allocImBuf(anim->x, anim->y, 24, 0); /* fake */
+ break;
#ifdef WITH_AVI
- case ANIM_AVI:
- if (startavi(anim)) {
- printf("couldn't start avi\n");
- return (NULL);
- }
- ibuf = IMB_allocImBuf(anim->x, anim->y, 24, 0);
- break;
+ case ANIM_AVI:
+ if (startavi(anim)) {
+ printf("couldn't start avi\n");
+ return (NULL);
+ }
+ ibuf = IMB_allocImBuf(anim->x, anim->y, 24, 0);
+ break;
#endif
#ifdef WITH_FFMPEG
- case ANIM_FFMPEG:
- if (startffmpeg(anim)) return (0);
- ibuf = IMB_allocImBuf(anim->x, anim->y, 24, 0);
- break;
+ case ANIM_FFMPEG:
+ if (startffmpeg(anim))
+ return (0);
+ ibuf = IMB_allocImBuf(anim->x, anim->y, 24, 0);
+ break;
#endif
- }
- return(ibuf);
+ }
+ return (ibuf);
}
struct ImBuf *IMB_anim_previewframe(struct anim *anim)
{
- struct ImBuf *ibuf = NULL;
- int position = 0;
-
- ibuf = IMB_anim_absolute(anim, 0, IMB_TC_NONE, IMB_PROXY_NONE);
- if (ibuf) {
- IMB_freeImBuf(ibuf);
- position = anim->duration / 2;
- ibuf = IMB_anim_absolute(anim, position, IMB_TC_NONE,
- IMB_PROXY_NONE);
- }
- return ibuf;
+ struct ImBuf *ibuf = NULL;
+ int position = 0;
+
+ ibuf = IMB_anim_absolute(anim, 0, IMB_TC_NONE, IMB_PROXY_NONE);
+ if (ibuf) {
+ IMB_freeImBuf(ibuf);
+ position = anim->duration / 2;
+ ibuf = IMB_anim_absolute(anim, position, IMB_TC_NONE, IMB_PROXY_NONE);
+ }
+ return ibuf;
}
-struct ImBuf *IMB_anim_absolute(struct anim *anim, int position,
+struct ImBuf *IMB_anim_absolute(struct anim *anim,
+ int position,
IMB_Timecode_Type tc,
IMB_Proxy_Size preview_size)
{
- struct ImBuf *ibuf = NULL;
- char head[256], tail[256];
- unsigned short digits;
- int pic;
- int filter_y;
- if (anim == NULL) return(NULL);
-
- filter_y = (anim->ib_flags & IB_animdeinterlace);
-
- if (preview_size == IMB_PROXY_NONE) {
- if (anim->curtype == 0) {
- ibuf = anim_getnew(anim);
- if (ibuf == NULL) {
- return(NULL);
- }
-
- IMB_freeImBuf(ibuf); /* ???? */
- ibuf = NULL;
- }
-
- if (position < 0) return(NULL);
- if (position >= anim->duration) return(NULL);
- }
- else {
- struct anim *proxy = IMB_anim_open_proxy(anim, preview_size);
-
- if (proxy) {
- position = IMB_anim_index_get_frame_index(
- anim, tc, position);
-
- return IMB_anim_absolute(
- proxy, position,
- IMB_TC_NONE, IMB_PROXY_NONE);
- }
- }
-
- switch (anim->curtype) {
- case ANIM_SEQUENCE:
- pic = an_stringdec(anim->first, head, tail, &digits);
- pic += position;
- an_stringenc(anim->name, head, tail, digits, pic);
- ibuf = IMB_loadiffname(anim->name, IB_rect, anim->colorspace);
- if (ibuf) {
- anim->curposition = position;
- }
- break;
- case ANIM_MOVIE:
- ibuf = movie_fetchibuf(anim, position);
- if (ibuf) {
- anim->curposition = position;
- IMB_convert_rgba_to_abgr(ibuf);
- }
- break;
+ struct ImBuf *ibuf = NULL;
+ char head[256], tail[256];
+ unsigned short digits;
+ int pic;
+ int filter_y;
+ if (anim == NULL)
+ return (NULL);
+
+ filter_y = (anim->ib_flags & IB_animdeinterlace);
+
+ if (preview_size == IMB_PROXY_NONE) {
+ if (anim->curtype == 0) {
+ ibuf = anim_getnew(anim);
+ if (ibuf == NULL) {
+ return (NULL);
+ }
+
+ IMB_freeImBuf(ibuf); /* ???? */
+ ibuf = NULL;
+ }
+
+ if (position < 0)
+ return (NULL);
+ if (position >= anim->duration)
+ return (NULL);
+ }
+ else {
+ struct anim *proxy = IMB_anim_open_proxy(anim, preview_size);
+
+ if (proxy) {
+ position = IMB_anim_index_get_frame_index(anim, tc, position);
+
+ return IMB_anim_absolute(proxy, position, IMB_TC_NONE, IMB_PROXY_NONE);
+ }
+ }
+
+ switch (anim->curtype) {
+ case ANIM_SEQUENCE:
+ pic = an_stringdec(anim->first, head, tail, &digits);
+ pic += position;
+ an_stringenc(anim->name, head, tail, digits, pic);
+ ibuf = IMB_loadiffname(anim->name, IB_rect, anim->colorspace);
+ if (ibuf) {
+ anim->curposition = position;
+ }
+ break;
+ case ANIM_MOVIE:
+ ibuf = movie_fetchibuf(anim, position);
+ if (ibuf) {
+ anim->curposition = position;
+ IMB_convert_rgba_to_abgr(ibuf);
+ }
+ break;
#ifdef WITH_AVI
- case ANIM_AVI:
- ibuf = avi_fetchibuf(anim, position);
- if (ibuf)
- anim->curposition = position;
- break;
+ case ANIM_AVI:
+ ibuf = avi_fetchibuf(anim, position);
+ if (ibuf)
+ anim->curposition = position;
+ break;
#endif
#ifdef WITH_FFMPEG
- case ANIM_FFMPEG:
- ibuf = ffmpeg_fetchibuf(anim, position, tc);
- if (ibuf)
- anim->curposition = position;
- filter_y = 0; /* done internally */
- break;
+ case ANIM_FFMPEG:
+ ibuf = ffmpeg_fetchibuf(anim, position, tc);
+ if (ibuf)
+ anim->curposition = position;
+ filter_y = 0; /* done internally */
+ break;
#endif
- }
-
- if (ibuf) {
- if (filter_y) IMB_filtery(ibuf);
- BLI_snprintf(ibuf->name, sizeof(ibuf->name), "%s.%04d", anim->name, anim->curposition + 1);
-
- }
- return(ibuf);
+ }
+
+ if (ibuf) {
+ if (filter_y)
+ IMB_filtery(ibuf);
+ BLI_snprintf(ibuf->name, sizeof(ibuf->name), "%s.%04d", anim->name, anim->curposition + 1);
+ }
+ return (ibuf);
}
/***/
int IMB_anim_get_duration(struct anim *anim, IMB_Timecode_Type tc)
{
- struct anim_index *idx;
- if (tc == IMB_TC_NONE) {
- return anim->duration;
- }
+ struct anim_index *idx;
+ if (tc == IMB_TC_NONE) {
+ return anim->duration;
+ }
- idx = IMB_anim_open_index(anim, tc);
- if (!idx) {
- return anim->duration;
- }
+ idx = IMB_anim_open_index(anim, tc);
+ if (!idx) {
+ return anim->duration;
+ }
- return IMB_indexer_get_duration(idx);
+ return IMB_indexer_get_duration(idx);
}
-bool IMB_anim_get_fps(struct anim *anim,
- short *frs_sec, float *frs_sec_base, bool no_av_base)
+bool IMB_anim_get_fps(struct anim *anim, short *frs_sec, float *frs_sec_base, bool no_av_base)
{
- double frs_sec_base_double;
- if (anim->frs_sec) {
- if (anim->frs_sec > SHRT_MAX) {
- /* We cannot store original rational in our short/float format,
- * we need to approximate it as best as we can... */
- *frs_sec = SHRT_MAX;
- frs_sec_base_double = anim->frs_sec_base * (double)SHRT_MAX / (double)anim->frs_sec;
- }
- else {
- *frs_sec = anim->frs_sec;
- frs_sec_base_double = anim->frs_sec_base;
- }
+ double frs_sec_base_double;
+ if (anim->frs_sec) {
+ if (anim->frs_sec > SHRT_MAX) {
+ /* We cannot store original rational in our short/float format,
+ * we need to approximate it as best as we can... */
+ *frs_sec = SHRT_MAX;
+ frs_sec_base_double = anim->frs_sec_base * (double)SHRT_MAX / (double)anim->frs_sec;
+ }
+ else {
+ *frs_sec = anim->frs_sec;
+ frs_sec_base_double = anim->frs_sec_base;
+ }
#ifdef WITH_FFMPEG
- if (no_av_base) {
- *frs_sec_base = (float)(frs_sec_base_double / AV_TIME_BASE);
- }
- else {
- *frs_sec_base = (float)frs_sec_base_double;
- }
+ if (no_av_base) {
+ *frs_sec_base = (float)(frs_sec_base_double / AV_TIME_BASE);
+ }
+ else {
+ *frs_sec_base = (float)frs_sec_base_double;
+ }
#else
- UNUSED_VARS(no_av_base);
- *frs_sec_base = (float)frs_sec_base_double;
+ UNUSED_VARS(no_av_base);
+ *frs_sec_base = (float)frs_sec_base_double;
#endif
- BLI_assert(*frs_sec > 0);
- BLI_assert(*frs_sec_base > 0.0f);
+ BLI_assert(*frs_sec > 0);
+ BLI_assert(*frs_sec_base > 0.0f);
- return true;
- }
- return false;
+ return true;
+ }
+ return false;
}
void IMB_anim_set_preseek(struct anim *anim, int preseek)
{
- anim->preseek = preseek;
+ anim->preseek = preseek;
}
int IMB_anim_get_preseek(struct anim *anim)
{
- return anim->preseek;
+ return anim->preseek;
}
diff --git a/source/blender/imbuf/intern/bmp.c b/source/blender/imbuf/intern/bmp.c
index d92e6f4ffcb..f5c12c916f0 100644
--- a/source/blender/imbuf/intern/bmp.c
+++ b/source/blender/imbuf/intern/bmp.c
@@ -39,238 +39,242 @@
*/
typedef struct BMPINFOHEADER {
- unsigned int biSize;
- unsigned int biWidth;
- unsigned int biHeight;
- unsigned short biPlanes;
- unsigned short biBitCount;
- unsigned int biCompression;
- unsigned int biSizeImage;
- unsigned int biXPelsPerMeter;
- unsigned int biYPelsPerMeter;
- unsigned int biClrUsed;
- unsigned int biClrImportant;
+ unsigned int biSize;
+ unsigned int biWidth;
+ unsigned int biHeight;
+ unsigned short biPlanes;
+ unsigned short biBitCount;
+ unsigned int biCompression;
+ unsigned int biSizeImage;
+ unsigned int biXPelsPerMeter;
+ unsigned int biYPelsPerMeter;
+ unsigned int biClrUsed;
+ unsigned int biClrImportant;
} BMPINFOHEADER;
#if 0
typedef struct BMPHEADER {
- unsigned short biType;
- unsigned int biSize;
- unsigned short biRes1;
- unsigned short biRes2;
- unsigned int biOffBits;
+ unsigned short biType;
+ unsigned int biSize;
+ unsigned short biRes1;
+ unsigned short biRes2;
+ unsigned int biOffBits;
} BMPHEADER;
#endif
#define BMP_FILEHEADER_SIZE 14
#define CHECK_HEADER_FIELD(_mem, _field) ((_mem[0] == _field[0]) && (_mem[1] == _field[1]))
-#define CHECK_HEADER_FIELD_BMP(_mem) \
- (CHECK_HEADER_FIELD(_mem, "BM") || \
- CHECK_HEADER_FIELD(_mem, "BA") || \
- CHECK_HEADER_FIELD(_mem, "CI") || \
- CHECK_HEADER_FIELD(_mem, "CP") || \
- CHECK_HEADER_FIELD(_mem, "IC") || \
- CHECK_HEADER_FIELD(_mem, "PT"))
+#define CHECK_HEADER_FIELD_BMP(_mem) \
+ (CHECK_HEADER_FIELD(_mem, "BM") || CHECK_HEADER_FIELD(_mem, "BA") || \
+ CHECK_HEADER_FIELD(_mem, "CI") || CHECK_HEADER_FIELD(_mem, "CP") || \
+ CHECK_HEADER_FIELD(_mem, "IC") || CHECK_HEADER_FIELD(_mem, "PT"))
static int checkbmp(const unsigned char *mem)
{
- int ret_val = 0;
- BMPINFOHEADER bmi;
- unsigned int u;
-
- if (mem) {
- if (CHECK_HEADER_FIELD_BMP(mem)) {
- /* skip fileheader */
- mem += BMP_FILEHEADER_SIZE;
- }
- else {
- return 0;
- }
-
- /* for systems where an int needs to be 4 bytes aligned */
- memcpy(&bmi, mem, sizeof(bmi));
-
- u = LITTLE_LONG(bmi.biSize);
- /* we only support uncompressed images for now. */
- if (u >= sizeof(BMPINFOHEADER)) {
- if (bmi.biCompression == 0) {
- u = LITTLE_SHORT(bmi.biBitCount);
- if (u > 0 && u <= 32) {
- ret_val = 1;
- }
- }
- }
- }
-
- return(ret_val);
+ int ret_val = 0;
+ BMPINFOHEADER bmi;
+ unsigned int u;
+
+ if (mem) {
+ if (CHECK_HEADER_FIELD_BMP(mem)) {
+ /* skip fileheader */
+ mem += BMP_FILEHEADER_SIZE;
+ }
+ else {
+ return 0;
+ }
+
+ /* for systems where an int needs to be 4 bytes aligned */
+ memcpy(&bmi, mem, sizeof(bmi));
+
+ u = LITTLE_LONG(bmi.biSize);
+ /* we only support uncompressed images for now. */
+ if (u >= sizeof(BMPINFOHEADER)) {
+ if (bmi.biCompression == 0) {
+ u = LITTLE_SHORT(bmi.biBitCount);
+ if (u > 0 && u <= 32) {
+ ret_val = 1;
+ }
+ }
+ }
+ }
+
+ return (ret_val);
}
int imb_is_a_bmp(const unsigned char *buf)
{
- return checkbmp(buf);
+ return checkbmp(buf);
}
-struct ImBuf *imb_bmp_decode(const unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE])
+struct ImBuf *imb_bmp_decode(const unsigned char *mem,
+ size_t size,
+ int flags,
+ char colorspace[IM_MAX_SPACE])
{
- struct ImBuf *ibuf = NULL;
- BMPINFOHEADER bmi;
- int x, y, depth, ibuf_depth, skip;
- const unsigned char *bmp;
- unsigned char *rect;
- unsigned short col;
- double xppm, yppm;
- bool top_to_bottom = false;
-
- (void)size; /* unused */
-
- if (checkbmp(mem) == 0) return(NULL);
-
- colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE);
-
- bmp = mem + LITTLE_LONG(*(int *)(mem + 10));
-
- if (CHECK_HEADER_FIELD_BMP(mem)) {
- /* skip fileheader */
- mem += BMP_FILEHEADER_SIZE;
- }
- else {
- return NULL;
- }
-
- /* for systems where an int needs to be 4 bytes aligned */
- memcpy(&bmi, mem, sizeof(bmi));
-
- skip = LITTLE_LONG(bmi.biSize);
- x = LITTLE_LONG(bmi.biWidth);
- y = LITTLE_LONG(bmi.biHeight);
- depth = LITTLE_SHORT(bmi.biBitCount);
- xppm = LITTLE_LONG(bmi.biXPelsPerMeter);
- yppm = LITTLE_LONG(bmi.biYPelsPerMeter);
-
- if (depth <= 8) {
- ibuf_depth = 24;
- }
- else {
- ibuf_depth = depth;
- }
-
- if (y < 0) {
- /* Negative height means bitmap is stored top-to-bottom... */
- y = -y;
- top_to_bottom = true;
- }
+ struct ImBuf *ibuf = NULL;
+ BMPINFOHEADER bmi;
+ int x, y, depth, ibuf_depth, skip;
+ const unsigned char *bmp;
+ unsigned char *rect;
+ unsigned short col;
+ double xppm, yppm;
+ bool top_to_bottom = false;
+
+ (void)size; /* unused */
+
+ if (checkbmp(mem) == 0)
+ return (NULL);
+
+ colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE);
+
+ bmp = mem + LITTLE_LONG(*(int *)(mem + 10));
+
+ if (CHECK_HEADER_FIELD_BMP(mem)) {
+ /* skip fileheader */
+ mem += BMP_FILEHEADER_SIZE;
+ }
+ else {
+ return NULL;
+ }
+
+ /* for systems where an int needs to be 4 bytes aligned */
+ memcpy(&bmi, mem, sizeof(bmi));
+
+ skip = LITTLE_LONG(bmi.biSize);
+ x = LITTLE_LONG(bmi.biWidth);
+ y = LITTLE_LONG(bmi.biHeight);
+ depth = LITTLE_SHORT(bmi.biBitCount);
+ xppm = LITTLE_LONG(bmi.biXPelsPerMeter);
+ yppm = LITTLE_LONG(bmi.biYPelsPerMeter);
+
+ if (depth <= 8) {
+ ibuf_depth = 24;
+ }
+ else {
+ ibuf_depth = depth;
+ }
+
+ if (y < 0) {
+ /* Negative height means bitmap is stored top-to-bottom... */
+ y = -y;
+ top_to_bottom = true;
+ }
#if 0
- printf("skip: %d, x: %d y: %d, depth: %d (%x)\n", skip, x, y, depth, bmi.biBitCount);
+ printf("skip: %d, x: %d y: %d, depth: %d (%x)\n", skip, x, y, depth, bmi.biBitCount);
#endif
- if (flags & IB_test) {
- ibuf = IMB_allocImBuf(x, y, ibuf_depth, 0);
- }
- else {
- ibuf = IMB_allocImBuf(x, y, ibuf_depth, IB_rect);
- if (!ibuf) {
- return NULL;
- }
-
- rect = (unsigned char *) ibuf->rect;
-
- if (depth <= 8) {
- const int rowsize = (depth * x + 31) / 32 * 4;
- const char (*palette)[4] = (void *)(mem + skip);
- const int startmask = ((1 << depth) - 1) << 8;
- for (size_t i = y; i > 0; i--) {
- int index;
- int bitoffs = 8;
- int bitmask = startmask;
- int nbytes = 0;
- const char *pcol;
- if (top_to_bottom) {
- rect = (unsigned char *) &ibuf->rect[(i - 1) * x];
- }
- for (size_t j = x; j > 0; j--) {
- bitoffs -= depth;
- bitmask >>= depth;
- index = (bmp[0] & bitmask) >> bitoffs;
- pcol = palette[index];
- /* intentionally BGR -> RGB */
- rect[0] = pcol[2];
- rect[1] = pcol[1];
- rect[2] = pcol[0];
-
- rect[3] = 255;
- rect += 4;
- if (bitoffs == 0) {
- /* Advance to the next byte */
- bitoffs = 8;
- bitmask = startmask;
- nbytes += 1;
- bmp += 1;
- }
- }
- /* Advance to the next row */
- bmp += (rowsize - nbytes);
- }
- }
- else if (depth == 16) {
- for (size_t i = y; i > 0; i--) {
- if (top_to_bottom) {
- rect = (unsigned char *) &ibuf->rect[(i - 1) * x];
- }
- for (size_t j = x; j > 0; j--) {
- col = bmp[0] + (bmp[1] << 8);
- rect[0] = ((col >> 10) & 0x1f) << 3;
- rect[1] = ((col >> 5) & 0x1f) << 3;
- rect[2] = ((col >> 0) & 0x1f) << 3;
-
- rect[3] = 255;
- rect += 4; bmp += 2;
- }
- }
- }
- else if (depth == 24) {
- const int x_pad = x % 4;
- for (size_t i = y; i > 0; i--) {
- if (top_to_bottom) {
- rect = (unsigned char *) &ibuf->rect[(i - 1) * x];
- }
- for (size_t j = x; j > 0; j--) {
- rect[0] = bmp[2];
- rect[1] = bmp[1];
- rect[2] = bmp[0];
-
- rect[3] = 255;
- rect += 4; bmp += 3;
- }
- /* for 24-bit images, rows are padded to multiples of 4 */
- bmp += x_pad;
- }
- }
- else if (depth == 32) {
- for (size_t i = y; i > 0; i--) {
- if (top_to_bottom) {
- rect = (unsigned char *) &ibuf->rect[(i - 1) * x];
- }
- for (size_t j = x; j > 0; j--) {
- rect[0] = bmp[2];
- rect[1] = bmp[1];
- rect[2] = bmp[0];
- rect[3] = bmp[3];
- rect += 4; bmp += 4;
- }
- }
- }
- }
-
- if (ibuf) {
- ibuf->ppm[0] = xppm;
- ibuf->ppm[1] = yppm;
- ibuf->ftype = IMB_FTYPE_BMP;
- }
-
- return(ibuf);
+ if (flags & IB_test) {
+ ibuf = IMB_allocImBuf(x, y, ibuf_depth, 0);
+ }
+ else {
+ ibuf = IMB_allocImBuf(x, y, ibuf_depth, IB_rect);
+ if (!ibuf) {
+ return NULL;
+ }
+
+ rect = (unsigned char *)ibuf->rect;
+
+ if (depth <= 8) {
+ const int rowsize = (depth * x + 31) / 32 * 4;
+ const char(*palette)[4] = (void *)(mem + skip);
+ const int startmask = ((1 << depth) - 1) << 8;
+ for (size_t i = y; i > 0; i--) {
+ int index;
+ int bitoffs = 8;
+ int bitmask = startmask;
+ int nbytes = 0;
+ const char *pcol;
+ if (top_to_bottom) {
+ rect = (unsigned char *)&ibuf->rect[(i - 1) * x];
+ }
+ for (size_t j = x; j > 0; j--) {
+ bitoffs -= depth;
+ bitmask >>= depth;
+ index = (bmp[0] & bitmask) >> bitoffs;
+ pcol = palette[index];
+ /* intentionally BGR -> RGB */
+ rect[0] = pcol[2];
+ rect[1] = pcol[1];
+ rect[2] = pcol[0];
+
+ rect[3] = 255;
+ rect += 4;
+ if (bitoffs == 0) {
+ /* Advance to the next byte */
+ bitoffs = 8;
+ bitmask = startmask;
+ nbytes += 1;
+ bmp += 1;
+ }
+ }
+ /* Advance to the next row */
+ bmp += (rowsize - nbytes);
+ }
+ }
+ else if (depth == 16) {
+ for (size_t i = y; i > 0; i--) {
+ if (top_to_bottom) {
+ rect = (unsigned char *)&ibuf->rect[(i - 1) * x];
+ }
+ for (size_t j = x; j > 0; j--) {
+ col = bmp[0] + (bmp[1] << 8);
+ rect[0] = ((col >> 10) & 0x1f) << 3;
+ rect[1] = ((col >> 5) & 0x1f) << 3;
+ rect[2] = ((col >> 0) & 0x1f) << 3;
+
+ rect[3] = 255;
+ rect += 4;
+ bmp += 2;
+ }
+ }
+ }
+ else if (depth == 24) {
+ const int x_pad = x % 4;
+ for (size_t i = y; i > 0; i--) {
+ if (top_to_bottom) {
+ rect = (unsigned char *)&ibuf->rect[(i - 1) * x];
+ }
+ for (size_t j = x; j > 0; j--) {
+ rect[0] = bmp[2];
+ rect[1] = bmp[1];
+ rect[2] = bmp[0];
+
+ rect[3] = 255;
+ rect += 4;
+ bmp += 3;
+ }
+ /* for 24-bit images, rows are padded to multiples of 4 */
+ bmp += x_pad;
+ }
+ }
+ else if (depth == 32) {
+ for (size_t i = y; i > 0; i--) {
+ if (top_to_bottom) {
+ rect = (unsigned char *)&ibuf->rect[(i - 1) * x];
+ }
+ for (size_t j = x; j > 0; j--) {
+ rect[0] = bmp[2];
+ rect[1] = bmp[1];
+ rect[2] = bmp[0];
+ rect[3] = bmp[3];
+ rect += 4;
+ bmp += 4;
+ }
+ }
+ }
+ }
+
+ if (ibuf) {
+ ibuf->ppm[0] = xppm;
+ ibuf->ppm[1] = yppm;
+ ibuf->ftype = IMB_FTYPE_BMP;
+ }
+
+ return (ibuf);
}
#undef CHECK_HEADER_FIELD_BMP
@@ -279,69 +283,74 @@ struct ImBuf *imb_bmp_decode(const unsigned char *mem, size_t size, int flags, c
/* Couple of helper functions for writing our data */
static int putIntLSB(unsigned int ui, FILE *ofile)
{
- putc((ui >> 0) & 0xFF, ofile);
- putc((ui >> 8) & 0xFF, ofile);
- putc((ui >> 16) & 0xFF, ofile);
- return putc((ui >> 24) & 0xFF, ofile);
+ putc((ui >> 0) & 0xFF, ofile);
+ putc((ui >> 8) & 0xFF, ofile);
+ putc((ui >> 16) & 0xFF, ofile);
+ return putc((ui >> 24) & 0xFF, ofile);
}
static int putShortLSB(unsigned short us, FILE *ofile)
{
- putc((us >> 0) & 0xFF, ofile);
- return putc((us >> 8) & 0xFF, ofile);
+ putc((us >> 0) & 0xFF, ofile);
+ return putc((us >> 8) & 0xFF, ofile);
}
/* Found write info at http://users.ece.gatech.edu/~slabaugh/personal/c/bitmapUnix.c */
int imb_savebmp(struct ImBuf *ibuf, const char *name, int flags)
{
- BMPINFOHEADER infoheader;
- size_t bytesize, extrabytes, ptr;
- uchar *data;
- FILE *ofile;
-
- (void)flags; /* unused */
-
- extrabytes = (4 - ibuf->x * 3 % 4) % 4;
- bytesize = (ibuf->x * 3 + extrabytes) * ibuf->y;
-
- data = (uchar *) ibuf->rect;
- ofile = BLI_fopen(name, "wb");
- if (!ofile) return 0;
-
- putShortLSB(19778, ofile); /* "BM" */
- putIntLSB(bytesize + BMP_FILEHEADER_SIZE + sizeof(infoheader), ofile); /* Total file size */
- putShortLSB(0, ofile); /* Res1 */
- putShortLSB(0, ofile); /* Res2 */
- putIntLSB(BMP_FILEHEADER_SIZE + sizeof(infoheader), ofile);
-
- putIntLSB(sizeof(infoheader), ofile);
- putIntLSB(ibuf->x, ofile);
- putIntLSB(ibuf->y, ofile);
- putShortLSB(1, ofile);
- putShortLSB(24, ofile);
- putIntLSB(0, ofile);
- putIntLSB(bytesize, ofile);
- putIntLSB((int)(ibuf->ppm[0] + 0.5), ofile);
- putIntLSB((int)(ibuf->ppm[1] + 0.5), ofile);
- putIntLSB(0, ofile);
- putIntLSB(0, ofile);
-
- /* Need to write out padded image data in bgr format */
- for (size_t y = 0; y < ibuf->y; y++) {
- for (size_t x = 0; x < ibuf->x; x++) {
- ptr = (x + y * ibuf->x) * 4;
- if (putc(data[ptr + 2], ofile) == EOF) return 0;
- if (putc(data[ptr + 1], ofile) == EOF) return 0;
- if (putc(data[ptr], ofile) == EOF) return 0;
- }
- /* add padding here */
- for (size_t t = 0; t < extrabytes; t++) {
- if (putc(0, ofile) == EOF) return 0;
- }
- }
- if (ofile) {
- fflush(ofile);
- fclose(ofile);
- }
- return 1;
+ BMPINFOHEADER infoheader;
+ size_t bytesize, extrabytes, ptr;
+ uchar *data;
+ FILE *ofile;
+
+ (void)flags; /* unused */
+
+ extrabytes = (4 - ibuf->x * 3 % 4) % 4;
+ bytesize = (ibuf->x * 3 + extrabytes) * ibuf->y;
+
+ data = (uchar *)ibuf->rect;
+ ofile = BLI_fopen(name, "wb");
+ if (!ofile)
+ return 0;
+
+ putShortLSB(19778, ofile); /* "BM" */
+ putIntLSB(bytesize + BMP_FILEHEADER_SIZE + sizeof(infoheader), ofile); /* Total file size */
+ putShortLSB(0, ofile); /* Res1 */
+ putShortLSB(0, ofile); /* Res2 */
+ putIntLSB(BMP_FILEHEADER_SIZE + sizeof(infoheader), ofile);
+
+ putIntLSB(sizeof(infoheader), ofile);
+ putIntLSB(ibuf->x, ofile);
+ putIntLSB(ibuf->y, ofile);
+ putShortLSB(1, ofile);
+ putShortLSB(24, ofile);
+ putIntLSB(0, ofile);
+ putIntLSB(bytesize, ofile);
+ putIntLSB((int)(ibuf->ppm[0] + 0.5), ofile);
+ putIntLSB((int)(ibuf->ppm[1] + 0.5), ofile);
+ putIntLSB(0, ofile);
+ putIntLSB(0, ofile);
+
+ /* Need to write out padded image data in bgr format */
+ for (size_t y = 0; y < ibuf->y; y++) {
+ for (size_t x = 0; x < ibuf->x; x++) {
+ ptr = (x + y * ibuf->x) * 4;
+ if (putc(data[ptr + 2], ofile) == EOF)
+ return 0;
+ if (putc(data[ptr + 1], ofile) == EOF)
+ return 0;
+ if (putc(data[ptr], ofile) == EOF)
+ return 0;
+ }
+ /* add padding here */
+ for (size_t t = 0; t < extrabytes; t++) {
+ if (putc(0, ofile) == EOF)
+ return 0;
+ }
+ }
+ if (ofile) {
+ fflush(ofile);
+ fclose(ofile);
+ }
+ return 1;
}
diff --git a/source/blender/imbuf/intern/cache.c b/source/blender/imbuf/intern/cache.c
index 92e9d21bb65..e6244364ba8 100644
--- a/source/blender/imbuf/intern/cache.c
+++ b/source/blender/imbuf/intern/cache.c
@@ -41,46 +41,46 @@
* back to the global cache every pixel, but not to big to keep too many tiles
* locked and using memory. */
-#define IB_THREAD_CACHE_SIZE 100
+#define IB_THREAD_CACHE_SIZE 100
typedef struct ImGlobalTile {
- struct ImGlobalTile *next, *prev;
+ struct ImGlobalTile *next, *prev;
- ImBuf *ibuf;
- int tx, ty;
- int refcount;
- volatile int loading;
+ ImBuf *ibuf;
+ int tx, ty;
+ int refcount;
+ volatile int loading;
} ImGlobalTile;
typedef struct ImThreadTile {
- struct ImThreadTile *next, *prev;
+ struct ImThreadTile *next, *prev;
- ImBuf *ibuf;
- int tx, ty;
+ ImBuf *ibuf;
+ int tx, ty;
- ImGlobalTile *global;
+ ImGlobalTile *global;
} ImThreadTile;
typedef struct ImThreadTileCache {
- ListBase tiles;
- ListBase unused;
- GHash *tilehash;
+ ListBase tiles;
+ ListBase unused;
+ GHash *tilehash;
} ImThreadTileCache;
typedef struct ImGlobalTileCache {
- ListBase tiles;
- ListBase unused;
- GHash *tilehash;
+ ListBase tiles;
+ ListBase unused;
+ GHash *tilehash;
- MemArena *memarena;
- uintptr_t totmem, maxmem;
+ MemArena *memarena;
+ uintptr_t totmem, maxmem;
- ImThreadTileCache thread_cache[BLENDER_MAX_THREADS + 1];
- int totthread;
+ ImThreadTileCache thread_cache[BLENDER_MAX_THREADS + 1];
+ int totthread;
- ThreadMutex mutex;
+ ThreadMutex mutex;
- int initialized;
+ int initialized;
} ImGlobalTileCache;
static ImGlobalTileCache GLOBAL_CACHE;
@@ -89,360 +89,365 @@ static ImGlobalTileCache GLOBAL_CACHE;
static unsigned int imb_global_tile_hash(const void *gtile_p)
{
- const ImGlobalTile *gtile = gtile_p;
+ const ImGlobalTile *gtile = gtile_p;
- return ((unsigned int)(intptr_t)gtile->ibuf) * 769 + gtile->tx * 53 + gtile->ty * 97;
+ return ((unsigned int)(intptr_t)gtile->ibuf) * 769 + gtile->tx * 53 + gtile->ty * 97;
}
static bool imb_global_tile_cmp(const void *a_p, const void *b_p)
{
- const ImGlobalTile *a = a_p;
- const ImGlobalTile *b = b_p;
+ const ImGlobalTile *a = a_p;
+ const ImGlobalTile *b = b_p;
- return ((a->ibuf != b->ibuf) ||
- (a->tx != b->tx) ||
- (a->ty != b->ty));
+ return ((a->ibuf != b->ibuf) || (a->tx != b->tx) || (a->ty != b->ty));
}
static unsigned int imb_thread_tile_hash(const void *ttile_p)
{
- const ImThreadTile *ttile = ttile_p;
+ const ImThreadTile *ttile = ttile_p;
- return ((unsigned int)(intptr_t)ttile->ibuf) * 769 + ttile->tx * 53 + ttile->ty * 97;
+ return ((unsigned int)(intptr_t)ttile->ibuf) * 769 + ttile->tx * 53 + ttile->ty * 97;
}
static bool imb_thread_tile_cmp(const void *a_p, const void *b_p)
{
- const ImThreadTile *a = a_p;
- const ImThreadTile *b = b_p;
+ const ImThreadTile *a = a_p;
+ const ImThreadTile *b = b_p;
- return ((a->ibuf != b->ibuf) ||
- (a->tx != b->tx) ||
- (a->ty != b->ty));
+ return ((a->ibuf != b->ibuf) || (a->tx != b->tx) || (a->ty != b->ty));
}
/******************************** Load/Unload ********************************/
static void imb_global_cache_tile_load(ImGlobalTile *gtile)
{
- ImBuf *ibuf = gtile->ibuf;
- int toffs = ibuf->xtiles * gtile->ty + gtile->tx;
- unsigned int *rect;
+ ImBuf *ibuf = gtile->ibuf;
+ int toffs = ibuf->xtiles * gtile->ty + gtile->tx;
+ unsigned int *rect;
- rect = MEM_callocN(sizeof(unsigned int) * ibuf->tilex * ibuf->tiley, "imb_tile");
- imb_loadtile(ibuf, gtile->tx, gtile->ty, rect);
- ibuf->tiles[toffs] = rect;
+ rect = MEM_callocN(sizeof(unsigned int) * ibuf->tilex * ibuf->tiley, "imb_tile");
+ imb_loadtile(ibuf, gtile->tx, gtile->ty, rect);
+ ibuf->tiles[toffs] = rect;
}
static void imb_global_cache_tile_unload(ImGlobalTile *gtile)
{
- ImBuf *ibuf = gtile->ibuf;
- int toffs = ibuf->xtiles * gtile->ty + gtile->tx;
+ ImBuf *ibuf = gtile->ibuf;
+ int toffs = ibuf->xtiles * gtile->ty + gtile->tx;
- MEM_freeN(ibuf->tiles[toffs]);
- ibuf->tiles[toffs] = NULL;
+ MEM_freeN(ibuf->tiles[toffs]);
+ ibuf->tiles[toffs] = NULL;
- GLOBAL_CACHE.totmem -= sizeof(unsigned int) * ibuf->tilex * ibuf->tiley;
+ GLOBAL_CACHE.totmem -= sizeof(unsigned int) * ibuf->tilex * ibuf->tiley;
}
/* external free */
void imb_tile_cache_tile_free(ImBuf *ibuf, int tx, int ty)
{
- ImGlobalTile *gtile, lookuptile;
+ ImGlobalTile *gtile, lookuptile;
- BLI_mutex_lock(&GLOBAL_CACHE.mutex);
+ BLI_mutex_lock(&GLOBAL_CACHE.mutex);
- lookuptile.ibuf = ibuf;
- lookuptile.tx = tx;
- lookuptile.ty = ty;
- gtile = BLI_ghash_lookup(GLOBAL_CACHE.tilehash, &lookuptile);
+ lookuptile.ibuf = ibuf;
+ lookuptile.tx = tx;
+ lookuptile.ty = ty;
+ gtile = BLI_ghash_lookup(GLOBAL_CACHE.tilehash, &lookuptile);
- if (gtile) {
- /* in case another thread is loading this */
- while (gtile->loading)
- ;
+ if (gtile) {
+ /* in case another thread is loading this */
+ while (gtile->loading)
+ ;
- BLI_ghash_remove(GLOBAL_CACHE.tilehash, gtile, NULL, NULL);
- BLI_remlink(&GLOBAL_CACHE.tiles, gtile);
- BLI_addtail(&GLOBAL_CACHE.unused, gtile);
- }
+ BLI_ghash_remove(GLOBAL_CACHE.tilehash, gtile, NULL, NULL);
+ BLI_remlink(&GLOBAL_CACHE.tiles, gtile);
+ BLI_addtail(&GLOBAL_CACHE.unused, gtile);
+ }
- BLI_mutex_unlock(&GLOBAL_CACHE.mutex);
+ BLI_mutex_unlock(&GLOBAL_CACHE.mutex);
}
/******************************* Init/Exit ***********************************/
static void imb_thread_cache_init(ImThreadTileCache *cache)
{
- ImThreadTile *ttile;
- int a;
+ ImThreadTile *ttile;
+ int a;
- memset(cache, 0, sizeof(ImThreadTileCache));
+ memset(cache, 0, sizeof(ImThreadTileCache));
- cache->tilehash = BLI_ghash_new(imb_thread_tile_hash, imb_thread_tile_cmp, "imb_thread_cache_init gh");
+ cache->tilehash = BLI_ghash_new(
+ imb_thread_tile_hash, imb_thread_tile_cmp, "imb_thread_cache_init gh");
- /* pre-allocate all thread local tiles in unused list */
- for (a = 0; a < IB_THREAD_CACHE_SIZE; a++) {
- ttile = BLI_memarena_alloc(GLOBAL_CACHE.memarena, sizeof(ImThreadTile));
- BLI_addtail(&cache->unused, ttile);
- }
+ /* pre-allocate all thread local tiles in unused list */
+ for (a = 0; a < IB_THREAD_CACHE_SIZE; a++) {
+ ttile = BLI_memarena_alloc(GLOBAL_CACHE.memarena, sizeof(ImThreadTile));
+ BLI_addtail(&cache->unused, ttile);
+ }
}
static void imb_thread_cache_exit(ImThreadTileCache *cache)
{
- BLI_ghash_free(cache->tilehash, NULL, NULL);
+ BLI_ghash_free(cache->tilehash, NULL, NULL);
}
void imb_tile_cache_init(void)
{
- memset(&GLOBAL_CACHE, 0, sizeof(ImGlobalTileCache));
+ memset(&GLOBAL_CACHE, 0, sizeof(ImGlobalTileCache));
- BLI_mutex_init(&GLOBAL_CACHE.mutex);
+ BLI_mutex_init(&GLOBAL_CACHE.mutex);
- /* initialize for one thread, for places that access textures
- * outside of rendering (displace modifier, painting, ..) */
- IMB_tile_cache_params(0, 0);
+ /* initialize for one thread, for places that access textures
+ * outside of rendering (displace modifier, painting, ..) */
+ IMB_tile_cache_params(0, 0);
- GLOBAL_CACHE.initialized = 1;
+ GLOBAL_CACHE.initialized = 1;
}
void imb_tile_cache_exit(void)
{
- ImGlobalTile *gtile;
- int a;
+ ImGlobalTile *gtile;
+ int a;
- if (GLOBAL_CACHE.initialized) {
- for (gtile = GLOBAL_CACHE.tiles.first; gtile; gtile = gtile->next)
- imb_global_cache_tile_unload(gtile);
+ if (GLOBAL_CACHE.initialized) {
+ for (gtile = GLOBAL_CACHE.tiles.first; gtile; gtile = gtile->next)
+ imb_global_cache_tile_unload(gtile);
- for (a = 0; a < GLOBAL_CACHE.totthread; a++)
- imb_thread_cache_exit(&GLOBAL_CACHE.thread_cache[a]);
+ for (a = 0; a < GLOBAL_CACHE.totthread; a++)
+ imb_thread_cache_exit(&GLOBAL_CACHE.thread_cache[a]);
- if (GLOBAL_CACHE.memarena)
- BLI_memarena_free(GLOBAL_CACHE.memarena);
+ if (GLOBAL_CACHE.memarena)
+ BLI_memarena_free(GLOBAL_CACHE.memarena);
- if (GLOBAL_CACHE.tilehash)
- BLI_ghash_free(GLOBAL_CACHE.tilehash, NULL, NULL);
+ if (GLOBAL_CACHE.tilehash)
+ BLI_ghash_free(GLOBAL_CACHE.tilehash, NULL, NULL);
- BLI_mutex_end(&GLOBAL_CACHE.mutex);
+ BLI_mutex_end(&GLOBAL_CACHE.mutex);
- memset(&GLOBAL_CACHE, 0, sizeof(ImGlobalTileCache));
- }
+ memset(&GLOBAL_CACHE, 0, sizeof(ImGlobalTileCache));
+ }
}
/* presumed to be called when no threads are running */
void IMB_tile_cache_params(int totthread, int maxmem)
{
- int a;
+ int a;
- /* always one cache for non-threaded access */
- totthread++;
+ /* always one cache for non-threaded access */
+ totthread++;
- /* lazy initialize cache */
- if (GLOBAL_CACHE.totthread == totthread && GLOBAL_CACHE.maxmem == maxmem)
- return;
+ /* lazy initialize cache */
+ if (GLOBAL_CACHE.totthread == totthread && GLOBAL_CACHE.maxmem == maxmem)
+ return;
- imb_tile_cache_exit();
+ imb_tile_cache_exit();
- memset(&GLOBAL_CACHE, 0, sizeof(ImGlobalTileCache));
+ memset(&GLOBAL_CACHE, 0, sizeof(ImGlobalTileCache));
- GLOBAL_CACHE.tilehash = BLI_ghash_new(imb_global_tile_hash, imb_global_tile_cmp, "tile_cache_params gh");
+ GLOBAL_CACHE.tilehash = BLI_ghash_new(
+ imb_global_tile_hash, imb_global_tile_cmp, "tile_cache_params gh");
- GLOBAL_CACHE.memarena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "ImTileCache arena");
- BLI_memarena_use_calloc(GLOBAL_CACHE.memarena);
+ GLOBAL_CACHE.memarena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "ImTileCache arena");
+ BLI_memarena_use_calloc(GLOBAL_CACHE.memarena);
- GLOBAL_CACHE.maxmem = maxmem * 1024 * 1024;
+ GLOBAL_CACHE.maxmem = maxmem * 1024 * 1024;
- GLOBAL_CACHE.totthread = totthread;
- for (a = 0; a < totthread; a++)
- imb_thread_cache_init(&GLOBAL_CACHE.thread_cache[a]);
+ GLOBAL_CACHE.totthread = totthread;
+ for (a = 0; a < totthread; a++)
+ imb_thread_cache_init(&GLOBAL_CACHE.thread_cache[a]);
- BLI_mutex_init(&GLOBAL_CACHE.mutex);
+ BLI_mutex_init(&GLOBAL_CACHE.mutex);
}
/***************************** Global Cache **********************************/
-static ImGlobalTile *imb_global_cache_get_tile(ImBuf *ibuf, int tx, int ty, ImGlobalTile *replacetile)
+static ImGlobalTile *imb_global_cache_get_tile(ImBuf *ibuf,
+ int tx,
+ int ty,
+ ImGlobalTile *replacetile)
{
- ImGlobalTile *gtile, lookuptile;
-
- BLI_mutex_lock(&GLOBAL_CACHE.mutex);
-
- if (replacetile)
- replacetile->refcount--;
-
- /* find tile in global cache */
- lookuptile.ibuf = ibuf;
- lookuptile.tx = tx;
- lookuptile.ty = ty;
- gtile = BLI_ghash_lookup(GLOBAL_CACHE.tilehash, &lookuptile);
-
- if (gtile) {
- /* found tile. however it may be in the process of being loaded
- * by another thread, in that case we do stupid busy loop waiting
- * for the other thread to load the tile */
- gtile->refcount++;
-
- BLI_mutex_unlock(&GLOBAL_CACHE.mutex);
-
- while (gtile->loading)
- ;
- }
- else {
- /* not found, let's load it from disk */
-
- /* first check if we hit the memory limit */
- if (GLOBAL_CACHE.maxmem && GLOBAL_CACHE.totmem > GLOBAL_CACHE.maxmem) {
- /* find an existing tile to unload */
- for (gtile = GLOBAL_CACHE.tiles.last; gtile; gtile = gtile->prev)
- if (gtile->refcount == 0 && gtile->loading == 0)
- break;
- }
-
- if (gtile) {
- /* found a tile to unload */
- imb_global_cache_tile_unload(gtile);
- BLI_ghash_remove(GLOBAL_CACHE.tilehash, gtile, NULL, NULL);
- BLI_remlink(&GLOBAL_CACHE.tiles, gtile);
- }
- else {
- /* allocate a new tile or reuse unused */
- if (GLOBAL_CACHE.unused.first) {
- gtile = GLOBAL_CACHE.unused.first;
- BLI_remlink(&GLOBAL_CACHE.unused, gtile);
- }
- else
- gtile = BLI_memarena_alloc(GLOBAL_CACHE.memarena, sizeof(ImGlobalTile));
- }
-
- /* setup new tile */
- gtile->ibuf = ibuf;
- gtile->tx = tx;
- gtile->ty = ty;
- gtile->refcount = 1;
- gtile->loading = 1;
-
- BLI_ghash_insert(GLOBAL_CACHE.tilehash, gtile, gtile);
- BLI_addhead(&GLOBAL_CACHE.tiles, gtile);
-
- /* mark as being loaded and unlock to allow other threads to load too */
- GLOBAL_CACHE.totmem += sizeof(unsigned int) * ibuf->tilex * ibuf->tiley;
-
- BLI_mutex_unlock(&GLOBAL_CACHE.mutex);
-
- /* load from disk */
- imb_global_cache_tile_load(gtile);
-
- /* mark as done loading */
- gtile->loading = 0;
- }
-
- return gtile;
+ ImGlobalTile *gtile, lookuptile;
+
+ BLI_mutex_lock(&GLOBAL_CACHE.mutex);
+
+ if (replacetile)
+ replacetile->refcount--;
+
+ /* find tile in global cache */
+ lookuptile.ibuf = ibuf;
+ lookuptile.tx = tx;
+ lookuptile.ty = ty;
+ gtile = BLI_ghash_lookup(GLOBAL_CACHE.tilehash, &lookuptile);
+
+ if (gtile) {
+ /* found tile. however it may be in the process of being loaded
+ * by another thread, in that case we do stupid busy loop waiting
+ * for the other thread to load the tile */
+ gtile->refcount++;
+
+ BLI_mutex_unlock(&GLOBAL_CACHE.mutex);
+
+ while (gtile->loading)
+ ;
+ }
+ else {
+ /* not found, let's load it from disk */
+
+ /* first check if we hit the memory limit */
+ if (GLOBAL_CACHE.maxmem && GLOBAL_CACHE.totmem > GLOBAL_CACHE.maxmem) {
+ /* find an existing tile to unload */
+ for (gtile = GLOBAL_CACHE.tiles.last; gtile; gtile = gtile->prev)
+ if (gtile->refcount == 0 && gtile->loading == 0)
+ break;
+ }
+
+ if (gtile) {
+ /* found a tile to unload */
+ imb_global_cache_tile_unload(gtile);
+ BLI_ghash_remove(GLOBAL_CACHE.tilehash, gtile, NULL, NULL);
+ BLI_remlink(&GLOBAL_CACHE.tiles, gtile);
+ }
+ else {
+ /* allocate a new tile or reuse unused */
+ if (GLOBAL_CACHE.unused.first) {
+ gtile = GLOBAL_CACHE.unused.first;
+ BLI_remlink(&GLOBAL_CACHE.unused, gtile);
+ }
+ else
+ gtile = BLI_memarena_alloc(GLOBAL_CACHE.memarena, sizeof(ImGlobalTile));
+ }
+
+ /* setup new tile */
+ gtile->ibuf = ibuf;
+ gtile->tx = tx;
+ gtile->ty = ty;
+ gtile->refcount = 1;
+ gtile->loading = 1;
+
+ BLI_ghash_insert(GLOBAL_CACHE.tilehash, gtile, gtile);
+ BLI_addhead(&GLOBAL_CACHE.tiles, gtile);
+
+ /* mark as being loaded and unlock to allow other threads to load too */
+ GLOBAL_CACHE.totmem += sizeof(unsigned int) * ibuf->tilex * ibuf->tiley;
+
+ BLI_mutex_unlock(&GLOBAL_CACHE.mutex);
+
+ /* load from disk */
+ imb_global_cache_tile_load(gtile);
+
+ /* mark as done loading */
+ gtile->loading = 0;
+ }
+
+ return gtile;
}
/***************************** Per-Thread Cache ******************************/
-static unsigned int *imb_thread_cache_get_tile(ImThreadTileCache *cache, ImBuf *ibuf, int tx, int ty)
+static unsigned int *imb_thread_cache_get_tile(ImThreadTileCache *cache,
+ ImBuf *ibuf,
+ int tx,
+ int ty)
{
- ImThreadTile *ttile, lookuptile;
- ImGlobalTile *gtile, *replacetile;
- int toffs = ibuf->xtiles * ty + tx;
-
- /* test if it is already in our thread local cache */
- if ((ttile = cache->tiles.first)) {
- /* check last used tile before going to hash */
- if (ttile->ibuf == ibuf && ttile->tx == tx && ttile->ty == ty)
- return ibuf->tiles[toffs];
-
- /* find tile in hash */
- lookuptile.ibuf = ibuf;
- lookuptile.tx = tx;
- lookuptile.ty = ty;
-
- if ((ttile = BLI_ghash_lookup(cache->tilehash, &lookuptile))) {
- BLI_remlink(&cache->tiles, ttile);
- BLI_addhead(&cache->tiles, ttile);
-
- return ibuf->tiles[toffs];
- }
- }
-
- /* not found, have to do slow lookup in global cache */
- if (BLI_listbase_is_empty(&cache->unused)) {
- ttile = cache->tiles.last;
- replacetile = ttile->global;
- BLI_remlink(&cache->tiles, ttile);
- BLI_ghash_remove(cache->tilehash, ttile, NULL, NULL);
- }
- else {
- ttile = cache->unused.first;
- replacetile = NULL;
- BLI_remlink(&cache->unused, ttile);
- }
-
- BLI_addhead(&cache->tiles, ttile);
- BLI_ghash_insert(cache->tilehash, ttile, ttile);
-
- gtile = imb_global_cache_get_tile(ibuf, tx, ty, replacetile);
-
- ttile->ibuf = gtile->ibuf;
- ttile->tx = gtile->tx;
- ttile->ty = gtile->ty;
- ttile->global = gtile;
-
- return ibuf->tiles[toffs];
+ ImThreadTile *ttile, lookuptile;
+ ImGlobalTile *gtile, *replacetile;
+ int toffs = ibuf->xtiles * ty + tx;
+
+ /* test if it is already in our thread local cache */
+ if ((ttile = cache->tiles.first)) {
+ /* check last used tile before going to hash */
+ if (ttile->ibuf == ibuf && ttile->tx == tx && ttile->ty == ty)
+ return ibuf->tiles[toffs];
+
+ /* find tile in hash */
+ lookuptile.ibuf = ibuf;
+ lookuptile.tx = tx;
+ lookuptile.ty = ty;
+
+ if ((ttile = BLI_ghash_lookup(cache->tilehash, &lookuptile))) {
+ BLI_remlink(&cache->tiles, ttile);
+ BLI_addhead(&cache->tiles, ttile);
+
+ return ibuf->tiles[toffs];
+ }
+ }
+
+ /* not found, have to do slow lookup in global cache */
+ if (BLI_listbase_is_empty(&cache->unused)) {
+ ttile = cache->tiles.last;
+ replacetile = ttile->global;
+ BLI_remlink(&cache->tiles, ttile);
+ BLI_ghash_remove(cache->tilehash, ttile, NULL, NULL);
+ }
+ else {
+ ttile = cache->unused.first;
+ replacetile = NULL;
+ BLI_remlink(&cache->unused, ttile);
+ }
+
+ BLI_addhead(&cache->tiles, ttile);
+ BLI_ghash_insert(cache->tilehash, ttile, ttile);
+
+ gtile = imb_global_cache_get_tile(ibuf, tx, ty, replacetile);
+
+ ttile->ibuf = gtile->ibuf;
+ ttile->tx = gtile->tx;
+ ttile->ty = gtile->ty;
+ ttile->global = gtile;
+
+ return ibuf->tiles[toffs];
}
unsigned int *IMB_gettile(ImBuf *ibuf, int tx, int ty, int thread)
{
- return imb_thread_cache_get_tile(&GLOBAL_CACHE.thread_cache[thread + 1], ibuf, tx, ty);
+ return imb_thread_cache_get_tile(&GLOBAL_CACHE.thread_cache[thread + 1], ibuf, tx, ty);
}
void IMB_tiles_to_rect(ImBuf *ibuf)
{
- ImBuf *mipbuf;
- ImGlobalTile *gtile;
- unsigned int *to, *from;
- int a, tx, ty, y, w, h;
-
- for (a = 0; a < ibuf->miptot; a++) {
- mipbuf = IMB_getmipmap(ibuf, a);
-
- /* don't call imb_addrectImBuf, it frees all mipmaps */
- if (!mipbuf->rect) {
- if ((mipbuf->rect = MEM_mapallocN(ibuf->x * ibuf->y * sizeof(unsigned int), "imb_addrectImBuf"))) {
- mipbuf->mall |= IB_rect;
- mipbuf->flags |= IB_rect;
- }
- else
- break;
- }
-
- for (ty = 0; ty < mipbuf->ytiles; ty++) {
- for (tx = 0; tx < mipbuf->xtiles; tx++) {
- /* acquire tile through cache, this assumes cache is initialized,
- * which it is always now but it's a weak assumption ... */
- gtile = imb_global_cache_get_tile(mipbuf, tx, ty, NULL);
-
- /* setup pointers */
- from = mipbuf->tiles[mipbuf->xtiles * ty + tx];
- to = mipbuf->rect + mipbuf->x * ty * mipbuf->tiley + tx * mipbuf->tilex;
-
- /* exception in tile width/height for tiles at end of image */
- w = (tx == mipbuf->xtiles - 1) ? mipbuf->x - tx * mipbuf->tilex : mipbuf->tilex;
- h = (ty == mipbuf->ytiles - 1) ? mipbuf->y - ty * mipbuf->tiley : mipbuf->tiley;
-
- for (y = 0; y < h; y++) {
- memcpy(to, from, sizeof(unsigned int) * w);
- from += mipbuf->tilex;
- to += mipbuf->x;
- }
-
- /* decrease refcount for tile again */
- BLI_mutex_lock(&GLOBAL_CACHE.mutex);
- gtile->refcount--;
- BLI_mutex_unlock(&GLOBAL_CACHE.mutex);
- }
- }
- }
+ ImBuf *mipbuf;
+ ImGlobalTile *gtile;
+ unsigned int *to, *from;
+ int a, tx, ty, y, w, h;
+
+ for (a = 0; a < ibuf->miptot; a++) {
+ mipbuf = IMB_getmipmap(ibuf, a);
+
+ /* don't call imb_addrectImBuf, it frees all mipmaps */
+ if (!mipbuf->rect) {
+ if ((mipbuf->rect = MEM_mapallocN(ibuf->x * ibuf->y * sizeof(unsigned int),
+ "imb_addrectImBuf"))) {
+ mipbuf->mall |= IB_rect;
+ mipbuf->flags |= IB_rect;
+ }
+ else
+ break;
+ }
+
+ for (ty = 0; ty < mipbuf->ytiles; ty++) {
+ for (tx = 0; tx < mipbuf->xtiles; tx++) {
+ /* acquire tile through cache, this assumes cache is initialized,
+ * which it is always now but it's a weak assumption ... */
+ gtile = imb_global_cache_get_tile(mipbuf, tx, ty, NULL);
+
+ /* setup pointers */
+ from = mipbuf->tiles[mipbuf->xtiles * ty + tx];
+ to = mipbuf->rect + mipbuf->x * ty * mipbuf->tiley + tx * mipbuf->tilex;
+
+ /* exception in tile width/height for tiles at end of image */
+ w = (tx == mipbuf->xtiles - 1) ? mipbuf->x - tx * mipbuf->tilex : mipbuf->tilex;
+ h = (ty == mipbuf->ytiles - 1) ? mipbuf->y - ty * mipbuf->tiley : mipbuf->tiley;
+
+ for (y = 0; y < h; y++) {
+ memcpy(to, from, sizeof(unsigned int) * w);
+ from += mipbuf->tilex;
+ to += mipbuf->x;
+ }
+
+ /* decrease refcount for tile again */
+ BLI_mutex_lock(&GLOBAL_CACHE.mutex);
+ gtile->refcount--;
+ BLI_mutex_unlock(&GLOBAL_CACHE.mutex);
+ }
+ }
+ }
}
diff --git a/source/blender/imbuf/intern/cineon/CMakeLists.txt b/source/blender/imbuf/intern/cineon/CMakeLists.txt
index 2f6ca2793e3..d740b080c35 100644
--- a/source/blender/imbuf/intern/cineon/CMakeLists.txt
+++ b/source/blender/imbuf/intern/cineon/CMakeLists.txt
@@ -19,13 +19,13 @@
# ***** END GPL LICENSE BLOCK *****
set(INC
- .
- ..
- ../..
- ../../../blenkernel
- ../../../blenlib
- ../../../makesdna
- ../../../../../intern/guardedalloc
+ .
+ ..
+ ../..
+ ../../../blenkernel
+ ../../../blenlib
+ ../../../makesdna
+ ../../../../../intern/guardedalloc
)
set(INC_SYS
@@ -33,23 +33,23 @@ set(INC_SYS
)
set(SRC
- cineonlib.h
- dpxlib.h
- logImageCore.h
- logmemfile.h
-
- cineon_dpx.c
- cineonlib.c
- dpxlib.c
- logImageCore.c
- logmemfile.c
+ cineonlib.h
+ dpxlib.h
+ logImageCore.h
+ logmemfile.h
+
+ cineon_dpx.c
+ cineonlib.c
+ dpxlib.c
+ logImageCore.c
+ logmemfile.c
)
set(LIB
)
if(WITH_IMAGE_CINEON)
- add_definitions(-DWITH_CINEON)
+ add_definitions(-DWITH_CINEON)
endif()
blender_add_lib(bf_imbuf_cineon "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/source/blender/imbuf/intern/cineon/cineon_dpx.c b/source/blender/imbuf/intern/cineon/cineon_dpx.c
index 2db7668c0ca..8f3829ee91e 100644
--- a/source/blender/imbuf/intern/cineon/cineon_dpx.c
+++ b/source/blender/imbuf/intern/cineon/cineon_dpx.c
@@ -20,7 +20,6 @@
* \ingroup imbcineon
*/
-
#include <stdio.h>
#include <string.h>
#include <math.h>
@@ -37,164 +36,183 @@
#include "MEM_guardedalloc.h"
-static struct ImBuf *imb_load_dpx_cineon(
- const unsigned char *mem, size_t size, int use_cineon, int flags,
- char colorspace[IM_MAX_SPACE])
+static struct ImBuf *imb_load_dpx_cineon(const unsigned char *mem,
+ size_t size,
+ int use_cineon,
+ int flags,
+ char colorspace[IM_MAX_SPACE])
{
- ImBuf *ibuf;
- LogImageFile *image;
- int width, height, depth;
+ ImBuf *ibuf;
+ LogImageFile *image;
+ int width, height, depth;
- colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_FLOAT);
+ colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_FLOAT);
- logImageSetVerbose((G.debug & G_DEBUG) ? 1 : 0);
+ logImageSetVerbose((G.debug & G_DEBUG) ? 1 : 0);
- image = logImageOpenFromMemory(mem, size);
+ image = logImageOpenFromMemory(mem, size);
- if (image == NULL) {
- printf("DPX/Cineon: error opening image.\n");
- return NULL;
- }
+ if (image == NULL) {
+ printf("DPX/Cineon: error opening image.\n");
+ return NULL;
+ }
- logImageGetSize(image, &width, &height, &depth);
+ logImageGetSize(image, &width, &height, &depth);
- ibuf = IMB_allocImBuf(width, height, 32, IB_rectfloat | flags);
- if (ibuf == NULL) {
- logImageClose(image);
- return NULL;
- }
+ 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);
- }
+ 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 ? IMB_FTYPE_CINEON : IMB_FTYPE_DPX;
+ logImageClose(image);
+ ibuf->ftype = use_cineon ? IMB_FTYPE_CINEON : IMB_FTYPE_DPX;
- if (flags & IB_alphamode_detect)
- ibuf->flags |= IB_alphamode_premul;
+ if (flags & IB_alphamode_detect)
+ ibuf->flags |= IB_alphamode_premul;
- return ibuf;
+ return ibuf;
}
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.debug & 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->foptions.flag & CINEON_10BIT)
- bitspersample = 10;
- else if (ibuf->foptions.flag & CINEON_12BIT)
- bitspersample = 12;
- else if (ibuf->foptions.flag & CINEON_16BIT)
- bitspersample = 16;
- else
- bitspersample = 8;
-
- logImage = logImageCreate(filename, use_cineon, ibuf->x, ibuf->y, bitspersample, (depth == 4),
- (ibuf->foptions.flag & 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;
+ 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.debug & 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->foptions.flag & CINEON_10BIT)
+ bitspersample = 10;
+ else if (ibuf->foptions.flag & CINEON_12BIT)
+ bitspersample = 12;
+ else if (ibuf->foptions.flag & CINEON_16BIT)
+ bitspersample = 16;
+ else
+ bitspersample = 8;
+
+ logImage = logImageCreate(filename,
+ use_cineon,
+ ibuf->x,
+ ibuf->y,
+ bitspersample,
+ (depth == 4),
+ (ibuf->foptions.flag & 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;
}
int imb_save_cineon(struct ImBuf *buf, const char *myfile, int flags)
{
- return imb_save_dpx_cineon(buf, myfile, 1, flags);
+ return imb_save_dpx_cineon(buf, myfile, 1, flags);
}
int imb_is_cineon(const unsigned char *buf)
{
- return logImageIsCineon(buf);
+ return logImageIsCineon(buf);
}
-ImBuf *imb_load_cineon(const unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE])
+ImBuf *imb_load_cineon(const unsigned char *mem,
+ size_t size,
+ int flags,
+ char colorspace[IM_MAX_SPACE])
{
- if (imb_is_cineon(mem))
- return imb_load_dpx_cineon(mem, size, 1, flags, colorspace);
- return NULL;
+ if (imb_is_cineon(mem))
+ return imb_load_dpx_cineon(mem, size, 1, flags, colorspace);
+ return NULL;
}
int imb_save_dpx(struct ImBuf *buf, const char *myfile, int flags)
{
- return imb_save_dpx_cineon(buf, myfile, 0, flags);
+ return imb_save_dpx_cineon(buf, myfile, 0, flags);
}
int imb_is_dpx(const unsigned char *buf)
{
- return logImageIsDpx(buf);
+ return logImageIsDpx(buf);
}
-ImBuf *imb_load_dpx(const unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE])
+ImBuf *imb_load_dpx(const unsigned char *mem,
+ size_t size,
+ int flags,
+ char colorspace[IM_MAX_SPACE])
{
- if (imb_is_dpx(mem))
- return imb_load_dpx_cineon(mem, size, 0, flags, colorspace);
- return NULL;
+ if (imb_is_dpx(mem))
+ return imb_load_dpx_cineon(mem, size, 0, flags, colorspace);
+ return NULL;
}
diff --git a/source/blender/imbuf/intern/cineon/cineonlib.c b/source/blender/imbuf/intern/cineon/cineonlib.c
index 14389a566fd..79f419e747c 100644
--- a/source/blender/imbuf/intern/cineon/cineonlib.c
+++ b/source/blender/imbuf/intern/cineon/cineonlib.c
@@ -22,7 +22,6 @@
* Cineon image file format library routines.
*/
-
#include "cineonlib.h"
#include "logmemfile.h"
@@ -46,342 +45,373 @@ static int verbose = 0;
void cineonSetVerbose(int verbosity)
{
- verbose = verbosity;
+ verbose = verbosity;
}
-static void fillCineonMainHeader(LogImageFile *cineon, CineonMainHeader *header,
- const char *filename, const char *creator)
+static void fillCineonMainHeader(LogImageFile *cineon,
+ CineonMainHeader *header,
+ const char *filename,
+ const char *creator)
{
- time_t fileClock;
- struct tm *fileTime;
- int i;
-
- memset(header, 0, sizeof(CineonMainHeader));
-
- /* --- File header --- */
- header->fileHeader.magic_num = swap_uint(CINEON_FILE_MAGIC, cineon->isMSB);
- header->fileHeader.offset = swap_uint(cineon->element[0].dataOffset, cineon->isMSB);
- header->fileHeader.gen_hdr_size = swap_uint(sizeof(CineonFileHeader) + sizeof(CineonImageHeader) +
- sizeof(CineonOriginationHeader), cineon->isMSB);
- header->fileHeader.ind_hdr_size = 0;
- header->fileHeader.user_data_size = 0;
- header->fileHeader.file_size = swap_uint(cineon->element[0].dataOffset + cineon->height * getRowLength(cineon->width, cineon->element[0]), cineon->isMSB);
- strcpy(header->fileHeader.version, "v4.5");
- strncpy(header->fileHeader.file_name, filename, 99);
- header->fileHeader.file_name[99] = 0;
- fileClock = time(NULL);
- fileTime = localtime(&fileClock);
- strftime(header->fileHeader.creation_date, 12, "%Y:%m:%d", fileTime);
- strftime(header->fileHeader.creation_time, 12, "%H:%M:%S%Z", fileTime);
- header->fileHeader.creation_time[11] = 0;
-
- /* --- Image header --- */
- header->imageHeader.orientation = 0;
- header->imageHeader.elements_per_image = cineon->depth;
-
- for (i = 0; i < 3; i++) {
- header->imageHeader.element[i].descriptor1 = 0;
- header->imageHeader.element[i].descriptor2 = i;
- header->imageHeader.element[i].bits_per_sample = cineon->element[0].bitsPerSample;
- header->imageHeader.element[i].pixels_per_line = swap_uint(cineon->width, cineon->isMSB);
- header->imageHeader.element[i].lines_per_image = swap_uint(cineon->height, cineon->isMSB);
- header->imageHeader.element[i].ref_low_data = swap_uint(cineon->element[0].refLowData, cineon->isMSB);
- header->imageHeader.element[i].ref_low_quantity = swap_float(cineon->element[0].refLowQuantity, cineon->isMSB);
- header->imageHeader.element[i].ref_high_data = swap_uint(cineon->element[0].refHighData, cineon->isMSB);
- header->imageHeader.element[i].ref_high_quantity = swap_float(cineon->element[0].refHighQuantity, cineon->isMSB);
- }
-
- header->imageHeader.white_point_x = swap_float(0.0f, cineon->isMSB);
- header->imageHeader.white_point_y = swap_float(0.0f, cineon->isMSB);
- header->imageHeader.red_primary_x = swap_float(0.0f, cineon->isMSB);
- header->imageHeader.red_primary_y = swap_float(0.0f, cineon->isMSB);
- header->imageHeader.green_primary_x = swap_float(0.0f, cineon->isMSB);
- header->imageHeader.green_primary_y = swap_float(0.0f, cineon->isMSB);
- header->imageHeader.blue_primary_x = swap_float(0.0f, cineon->isMSB);
- header->imageHeader.blue_primary_y = swap_float(0.0f, cineon->isMSB);
- strncpy(header->imageHeader.label, creator, 199);
- header->imageHeader.label[199] = 0;
- header->imageHeader.interleave = 0;
- header->imageHeader.data_sign = 0;
- header->imageHeader.sense = 0;
- header->imageHeader.line_padding = swap_uint(0, cineon->isMSB);
- header->imageHeader.element_padding = swap_uint(0, cineon->isMSB);
-
- switch (cineon->element[0].packing) {
- case 0:
- header->imageHeader.packing = 0;
- break;
-
- case 1:
- header->imageHeader.packing = 5;
- break;
-
- case 2:
- header->imageHeader.packing = 6;
- break;
- }
-
- /* --- Origination header --- */
- /* we leave it blank */
-
- /* --- Film header --- */
- /* we leave it blank */
+ time_t fileClock;
+ struct tm *fileTime;
+ int i;
+
+ memset(header, 0, sizeof(CineonMainHeader));
+
+ /* --- File header --- */
+ header->fileHeader.magic_num = swap_uint(CINEON_FILE_MAGIC, cineon->isMSB);
+ header->fileHeader.offset = swap_uint(cineon->element[0].dataOffset, cineon->isMSB);
+ header->fileHeader.gen_hdr_size = swap_uint(
+ sizeof(CineonFileHeader) + sizeof(CineonImageHeader) + sizeof(CineonOriginationHeader),
+ cineon->isMSB);
+ header->fileHeader.ind_hdr_size = 0;
+ header->fileHeader.user_data_size = 0;
+ header->fileHeader.file_size = swap_uint(cineon->element[0].dataOffset +
+ cineon->height *
+ getRowLength(cineon->width, cineon->element[0]),
+ cineon->isMSB);
+ strcpy(header->fileHeader.version, "v4.5");
+ strncpy(header->fileHeader.file_name, filename, 99);
+ header->fileHeader.file_name[99] = 0;
+ fileClock = time(NULL);
+ fileTime = localtime(&fileClock);
+ strftime(header->fileHeader.creation_date, 12, "%Y:%m:%d", fileTime);
+ strftime(header->fileHeader.creation_time, 12, "%H:%M:%S%Z", fileTime);
+ header->fileHeader.creation_time[11] = 0;
+
+ /* --- Image header --- */
+ header->imageHeader.orientation = 0;
+ header->imageHeader.elements_per_image = cineon->depth;
+
+ for (i = 0; i < 3; i++) {
+ header->imageHeader.element[i].descriptor1 = 0;
+ header->imageHeader.element[i].descriptor2 = i;
+ header->imageHeader.element[i].bits_per_sample = cineon->element[0].bitsPerSample;
+ header->imageHeader.element[i].pixels_per_line = swap_uint(cineon->width, cineon->isMSB);
+ header->imageHeader.element[i].lines_per_image = swap_uint(cineon->height, cineon->isMSB);
+ header->imageHeader.element[i].ref_low_data = swap_uint(cineon->element[0].refLowData,
+ cineon->isMSB);
+ header->imageHeader.element[i].ref_low_quantity = swap_float(cineon->element[0].refLowQuantity,
+ cineon->isMSB);
+ header->imageHeader.element[i].ref_high_data = swap_uint(cineon->element[0].refHighData,
+ cineon->isMSB);
+ header->imageHeader.element[i].ref_high_quantity = swap_float(
+ cineon->element[0].refHighQuantity, cineon->isMSB);
+ }
+
+ header->imageHeader.white_point_x = swap_float(0.0f, cineon->isMSB);
+ header->imageHeader.white_point_y = swap_float(0.0f, cineon->isMSB);
+ header->imageHeader.red_primary_x = swap_float(0.0f, cineon->isMSB);
+ header->imageHeader.red_primary_y = swap_float(0.0f, cineon->isMSB);
+ header->imageHeader.green_primary_x = swap_float(0.0f, cineon->isMSB);
+ header->imageHeader.green_primary_y = swap_float(0.0f, cineon->isMSB);
+ header->imageHeader.blue_primary_x = swap_float(0.0f, cineon->isMSB);
+ header->imageHeader.blue_primary_y = swap_float(0.0f, cineon->isMSB);
+ strncpy(header->imageHeader.label, creator, 199);
+ header->imageHeader.label[199] = 0;
+ header->imageHeader.interleave = 0;
+ header->imageHeader.data_sign = 0;
+ header->imageHeader.sense = 0;
+ header->imageHeader.line_padding = swap_uint(0, cineon->isMSB);
+ header->imageHeader.element_padding = swap_uint(0, cineon->isMSB);
+
+ switch (cineon->element[0].packing) {
+ case 0:
+ header->imageHeader.packing = 0;
+ break;
+
+ case 1:
+ header->imageHeader.packing = 5;
+ break;
+
+ case 2:
+ header->imageHeader.packing = 6;
+ break;
+ }
+
+ /* --- Origination header --- */
+ /* we leave it blank */
+
+ /* --- Film header --- */
+ /* we leave it blank */
}
LogImageFile *cineonOpen(const unsigned char *byteStuff, int fromMemory, size_t bufferSize)
{
- CineonMainHeader header;
- LogImageFile *cineon = (LogImageFile *)MEM_mallocN(sizeof(LogImageFile), __func__);
- const char *filename = (const char *)byteStuff;
- int i;
- unsigned int dataOffset;
-
- if (cineon == NULL) {
- if (verbose) printf("Cineon: Failed to malloc cineon file structure.\n");
- return NULL;
- }
-
- /* zero the header */
- memset(&header, 0, sizeof(CineonMainHeader));
-
- /* for close routine */
- cineon->file = NULL;
-
- if (fromMemory == 0) {
- /* byteStuff is then the filename */
- cineon->file = BLI_fopen(filename, "rb");
- if (cineon->file == NULL) {
- if (verbose) printf("Cineon: Failed to open file \"%s\".\n", filename);
- logImageClose(cineon);
- return NULL;
- }
- /* not used in this case */
- cineon->memBuffer = NULL;
- cineon->memCursor = NULL;
- cineon->memBufferSize = 0;
- }
- else {
- cineon->memBuffer = (unsigned char *)byteStuff;
- cineon->memCursor = (unsigned char *)byteStuff;
- cineon->memBufferSize = bufferSize;
- }
-
- if (logimage_fread(&header, sizeof(header), 1, cineon) == 0) {
- if (verbose) printf("Cineon: Not enough data for header in \"%s\".\n", byteStuff);
- logImageClose(cineon);
- return NULL;
- }
-
- /* endianness determination */
- if (header.fileHeader.magic_num == swap_uint(CINEON_FILE_MAGIC, 1)) {
- cineon->isMSB = 1;
- if (verbose) printf("Cineon: File is MSB.\n");
- }
- else if (header.fileHeader.magic_num == CINEON_FILE_MAGIC) {
- cineon->isMSB = 0;
- if (verbose) printf("Cineon: File is LSB.\n");
- }
- else {
- if (verbose) {
- printf("Cineon: Bad magic number %lu in \"%s\".\n",
- (unsigned long)header.fileHeader.magic_num, byteStuff);
- }
- logImageClose(cineon);
- return NULL;
- }
-
- cineon->width = swap_uint(header.imageHeader.element[0].pixels_per_line, cineon->isMSB);
- cineon->height = swap_uint(header.imageHeader.element[0].lines_per_image, cineon->isMSB);
-
- if (cineon->width == 0 || cineon->height == 0) {
- if (verbose) printf("Cineon: Wrong image dimension: %dx%d\n", cineon->width, cineon->height);
- logImageClose(cineon);
- return NULL;
- }
-
- cineon->depth = header.imageHeader.elements_per_image;
- cineon->srcFormat = format_Cineon;
-
- if (header.imageHeader.interleave == 0)
- cineon->numElements = 1;
- else if (header.imageHeader.interleave == 2)
- cineon->numElements = header.imageHeader.elements_per_image;
- else {
- if (verbose) printf("Cineon: Data interleave not supported: %d\n", header.imageHeader.interleave);
- logImageClose(cineon);
- return NULL;
- }
-
- if (cineon->depth == 1) {
- /* Grayscale image */
- cineon->element[0].descriptor = descriptor_Luminance;
- cineon->element[0].transfer = transfer_Linear;
- cineon->element[0].depth = 1;
- }
- else if (cineon->depth == 3) {
- /* RGB image */
- if (cineon->numElements == 1) {
- cineon->element[0].descriptor = descriptor_RGB;
- cineon->element[0].transfer = transfer_PrintingDensity;
- cineon->element[0].depth = 3;
- }
- else if (cineon->numElements == 3) {
- cineon->element[0].descriptor = descriptor_Red;
- cineon->element[0].transfer = transfer_PrintingDensity;
- cineon->element[0].depth = 1;
- cineon->element[1].descriptor = descriptor_Green;
- cineon->element[1].transfer = transfer_PrintingDensity;
- cineon->element[1].depth = 1;
- cineon->element[2].descriptor = descriptor_Blue;
- cineon->element[2].transfer = transfer_PrintingDensity;
- cineon->element[2].depth = 1;
- }
- }
- else {
- if (verbose) printf("Cineon: Cineon image depth unsupported: %d\n", cineon->depth);
- logImageClose(cineon);
- return NULL;
- }
-
- dataOffset = swap_uint(header.fileHeader.offset, cineon->isMSB);
-
- for (i = 0; i < cineon->numElements; i++) {
- cineon->element[i].bitsPerSample = header.imageHeader.element[i].bits_per_sample;
- cineon->element[i].maxValue = powf(2, cineon->element[i].bitsPerSample) - 1.0f;
- cineon->element[i].refLowData = swap_uint(header.imageHeader.element[i].ref_low_data, cineon->isMSB);
- cineon->element[i].refLowQuantity = swap_float(header.imageHeader.element[i].ref_low_quantity, cineon->isMSB);
- cineon->element[i].refHighData = swap_uint(header.imageHeader.element[i].ref_high_data, cineon->isMSB);
- cineon->element[i].refHighQuantity = swap_float(header.imageHeader.element[i].ref_high_quantity, cineon->isMSB);
-
- switch (header.imageHeader.packing) {
- case 0:
- cineon->element[i].packing = 0;
- break;
-
- case 5:
- cineon->element[i].packing = 1;
- break;
-
- case 6:
- cineon->element[i].packing = 2;
- break;
-
- default:
- /* Not supported */
- if (verbose) printf("Cineon: packing unsupported: %d\n", header.imageHeader.packing);
- logImageClose(cineon);
- return NULL;
- }
-
- if (cineon->element[i].refLowData == CINEON_UNDEFINED_U32)
- cineon->element[i].refLowData = 0;
-
- if (cineon->element[i].refHighData == CINEON_UNDEFINED_U32)
- cineon->element[i].refHighData = (unsigned int)cineon->element[i].maxValue;
-
- if (cineon->element[i].refLowQuantity == CINEON_UNDEFINED_R32 || isnan(cineon->element[i].refLowQuantity))
- cineon->element[i].refLowQuantity = 0.0f;
-
- if (cineon->element[i].refHighQuantity == CINEON_UNDEFINED_R32 || isnan(cineon->element[i].refHighQuantity)) {
- if (cineon->element[i].transfer == transfer_PrintingDensity)
- cineon->element[i].refHighQuantity = 2.048f;
- else
- cineon->element[i].refHighQuantity = cineon->element[i].maxValue;
- }
-
- cineon->element[i].dataOffset = dataOffset;
- dataOffset += cineon->height * getRowLength(cineon->width, cineon->element[i]);
- }
-
- cineon->referenceBlack = 95.0f / 1023.0f * cineon->element[0].maxValue;
- cineon->referenceWhite = 685.0f / 1023.0f * cineon->element[0].maxValue;
- cineon->gamma = 1.7f;
-
- if (verbose) {
- printf("size %d x %d x %d elements\n", cineon->width, cineon->height, cineon->numElements);
- for (i = 0; i < cineon->numElements; i++) {
- printf(" Element %d:\n", i);
- printf(" Bits per sample: %d\n", cineon->element[i].bitsPerSample);
- printf(" Depth: %d\n", cineon->element[i].depth);
- printf(" Transfer characteristics: %d\n", cineon->element[i].transfer);
- printf(" Packing: %d\n", cineon->element[i].packing);
- printf(" Descriptor: %d\n", cineon->element[i].descriptor);
- printf(" Data offset: %d\n", cineon->element[i].dataOffset);
- printf(" Reference low data: %u\n", cineon->element[i].refLowData);
- printf(" Reference low quantity: %f\n", cineon->element[i].refLowQuantity);
- printf(" Reference high data: %u\n", cineon->element[i].refHighData);
- printf(" Reference high quantity: %f\n", cineon->element[i].refHighQuantity);
- printf("\n");
- }
-
- printf("Gamma: %f\n", cineon->gamma);
- printf("Reference black: %f\n", cineon->referenceBlack);
- printf("Reference white: %f\n", cineon->referenceWhite);
- printf("Orientation: %d\n", header.imageHeader.orientation);
- printf("----------------------------\n");
- }
- return cineon;
+ CineonMainHeader header;
+ LogImageFile *cineon = (LogImageFile *)MEM_mallocN(sizeof(LogImageFile), __func__);
+ const char *filename = (const char *)byteStuff;
+ int i;
+ unsigned int dataOffset;
+
+ if (cineon == NULL) {
+ if (verbose)
+ printf("Cineon: Failed to malloc cineon file structure.\n");
+ return NULL;
+ }
+
+ /* zero the header */
+ memset(&header, 0, sizeof(CineonMainHeader));
+
+ /* for close routine */
+ cineon->file = NULL;
+
+ if (fromMemory == 0) {
+ /* byteStuff is then the filename */
+ cineon->file = BLI_fopen(filename, "rb");
+ if (cineon->file == NULL) {
+ if (verbose)
+ printf("Cineon: Failed to open file \"%s\".\n", filename);
+ logImageClose(cineon);
+ return NULL;
+ }
+ /* not used in this case */
+ cineon->memBuffer = NULL;
+ cineon->memCursor = NULL;
+ cineon->memBufferSize = 0;
+ }
+ else {
+ cineon->memBuffer = (unsigned char *)byteStuff;
+ cineon->memCursor = (unsigned char *)byteStuff;
+ cineon->memBufferSize = bufferSize;
+ }
+
+ if (logimage_fread(&header, sizeof(header), 1, cineon) == 0) {
+ if (verbose)
+ printf("Cineon: Not enough data for header in \"%s\".\n", byteStuff);
+ logImageClose(cineon);
+ return NULL;
+ }
+
+ /* endianness determination */
+ if (header.fileHeader.magic_num == swap_uint(CINEON_FILE_MAGIC, 1)) {
+ cineon->isMSB = 1;
+ if (verbose)
+ printf("Cineon: File is MSB.\n");
+ }
+ else if (header.fileHeader.magic_num == CINEON_FILE_MAGIC) {
+ cineon->isMSB = 0;
+ if (verbose)
+ printf("Cineon: File is LSB.\n");
+ }
+ else {
+ if (verbose) {
+ printf("Cineon: Bad magic number %lu in \"%s\".\n",
+ (unsigned long)header.fileHeader.magic_num,
+ byteStuff);
+ }
+ logImageClose(cineon);
+ return NULL;
+ }
+
+ cineon->width = swap_uint(header.imageHeader.element[0].pixels_per_line, cineon->isMSB);
+ cineon->height = swap_uint(header.imageHeader.element[0].lines_per_image, cineon->isMSB);
+
+ if (cineon->width == 0 || cineon->height == 0) {
+ if (verbose)
+ printf("Cineon: Wrong image dimension: %dx%d\n", cineon->width, cineon->height);
+ logImageClose(cineon);
+ return NULL;
+ }
+
+ cineon->depth = header.imageHeader.elements_per_image;
+ cineon->srcFormat = format_Cineon;
+
+ if (header.imageHeader.interleave == 0)
+ cineon->numElements = 1;
+ else if (header.imageHeader.interleave == 2)
+ cineon->numElements = header.imageHeader.elements_per_image;
+ else {
+ if (verbose)
+ printf("Cineon: Data interleave not supported: %d\n", header.imageHeader.interleave);
+ logImageClose(cineon);
+ return NULL;
+ }
+
+ if (cineon->depth == 1) {
+ /* Grayscale image */
+ cineon->element[0].descriptor = descriptor_Luminance;
+ cineon->element[0].transfer = transfer_Linear;
+ cineon->element[0].depth = 1;
+ }
+ else if (cineon->depth == 3) {
+ /* RGB image */
+ if (cineon->numElements == 1) {
+ cineon->element[0].descriptor = descriptor_RGB;
+ cineon->element[0].transfer = transfer_PrintingDensity;
+ cineon->element[0].depth = 3;
+ }
+ else if (cineon->numElements == 3) {
+ cineon->element[0].descriptor = descriptor_Red;
+ cineon->element[0].transfer = transfer_PrintingDensity;
+ cineon->element[0].depth = 1;
+ cineon->element[1].descriptor = descriptor_Green;
+ cineon->element[1].transfer = transfer_PrintingDensity;
+ cineon->element[1].depth = 1;
+ cineon->element[2].descriptor = descriptor_Blue;
+ cineon->element[2].transfer = transfer_PrintingDensity;
+ cineon->element[2].depth = 1;
+ }
+ }
+ else {
+ if (verbose)
+ printf("Cineon: Cineon image depth unsupported: %d\n", cineon->depth);
+ logImageClose(cineon);
+ return NULL;
+ }
+
+ dataOffset = swap_uint(header.fileHeader.offset, cineon->isMSB);
+
+ for (i = 0; i < cineon->numElements; i++) {
+ cineon->element[i].bitsPerSample = header.imageHeader.element[i].bits_per_sample;
+ cineon->element[i].maxValue = powf(2, cineon->element[i].bitsPerSample) - 1.0f;
+ cineon->element[i].refLowData = swap_uint(header.imageHeader.element[i].ref_low_data,
+ cineon->isMSB);
+ cineon->element[i].refLowQuantity = swap_float(header.imageHeader.element[i].ref_low_quantity,
+ cineon->isMSB);
+ cineon->element[i].refHighData = swap_uint(header.imageHeader.element[i].ref_high_data,
+ cineon->isMSB);
+ cineon->element[i].refHighQuantity = swap_float(
+ header.imageHeader.element[i].ref_high_quantity, cineon->isMSB);
+
+ switch (header.imageHeader.packing) {
+ case 0:
+ cineon->element[i].packing = 0;
+ break;
+
+ case 5:
+ cineon->element[i].packing = 1;
+ break;
+
+ case 6:
+ cineon->element[i].packing = 2;
+ break;
+
+ default:
+ /* Not supported */
+ if (verbose)
+ printf("Cineon: packing unsupported: %d\n", header.imageHeader.packing);
+ logImageClose(cineon);
+ return NULL;
+ }
+
+ if (cineon->element[i].refLowData == CINEON_UNDEFINED_U32)
+ cineon->element[i].refLowData = 0;
+
+ if (cineon->element[i].refHighData == CINEON_UNDEFINED_U32)
+ cineon->element[i].refHighData = (unsigned int)cineon->element[i].maxValue;
+
+ if (cineon->element[i].refLowQuantity == CINEON_UNDEFINED_R32 ||
+ isnan(cineon->element[i].refLowQuantity))
+ cineon->element[i].refLowQuantity = 0.0f;
+
+ if (cineon->element[i].refHighQuantity == CINEON_UNDEFINED_R32 ||
+ isnan(cineon->element[i].refHighQuantity)) {
+ if (cineon->element[i].transfer == transfer_PrintingDensity)
+ cineon->element[i].refHighQuantity = 2.048f;
+ else
+ cineon->element[i].refHighQuantity = cineon->element[i].maxValue;
+ }
+
+ cineon->element[i].dataOffset = dataOffset;
+ dataOffset += cineon->height * getRowLength(cineon->width, cineon->element[i]);
+ }
+
+ cineon->referenceBlack = 95.0f / 1023.0f * cineon->element[0].maxValue;
+ cineon->referenceWhite = 685.0f / 1023.0f * cineon->element[0].maxValue;
+ cineon->gamma = 1.7f;
+
+ if (verbose) {
+ printf("size %d x %d x %d elements\n", cineon->width, cineon->height, cineon->numElements);
+ for (i = 0; i < cineon->numElements; i++) {
+ printf(" Element %d:\n", i);
+ printf(" Bits per sample: %d\n", cineon->element[i].bitsPerSample);
+ printf(" Depth: %d\n", cineon->element[i].depth);
+ printf(" Transfer characteristics: %d\n", cineon->element[i].transfer);
+ printf(" Packing: %d\n", cineon->element[i].packing);
+ printf(" Descriptor: %d\n", cineon->element[i].descriptor);
+ printf(" Data offset: %d\n", cineon->element[i].dataOffset);
+ printf(" Reference low data: %u\n", cineon->element[i].refLowData);
+ printf(" Reference low quantity: %f\n", cineon->element[i].refLowQuantity);
+ printf(" Reference high data: %u\n", cineon->element[i].refHighData);
+ printf(" Reference high quantity: %f\n", cineon->element[i].refHighQuantity);
+ printf("\n");
+ }
+
+ printf("Gamma: %f\n", cineon->gamma);
+ printf("Reference black: %f\n", cineon->referenceBlack);
+ printf("Reference white: %f\n", cineon->referenceWhite);
+ printf("Orientation: %d\n", header.imageHeader.orientation);
+ printf("----------------------------\n");
+ }
+ return cineon;
}
-LogImageFile *cineonCreate(const char *filename, int width, int height, int bitsPerSample, const char *creator)
+LogImageFile *cineonCreate(
+ const char *filename, int width, int height, int bitsPerSample, const char *creator)
{
- CineonMainHeader header;
- const char *shortFilename = NULL;
- /* unsigned char pad[6044]; */
-
- LogImageFile *cineon = (LogImageFile *)MEM_mallocN(sizeof(LogImageFile), __func__);
- if (cineon == NULL) {
- if (verbose) printf("cineon: Failed to malloc cineon file structure.\n");
- return NULL;
- }
-
- /* Only 10 bits Cineon are supported */
- if (bitsPerSample != 10) {
- if (verbose) printf("cineon: Only 10 bits Cineon are supported.\n");
- logImageClose(cineon);
- return NULL;
- }
-
- cineon->width = width;
- cineon->height = height;
- cineon->element[0].bitsPerSample = 10;
- cineon->element[0].dataOffset = sizeof(CineonMainHeader);
- cineon->element[0].maxValue = 1023;
- cineon->isMSB = 1;
- cineon->numElements = 1;
- cineon->element[0].packing = 1;
- cineon->depth = 3;
- cineon->element[0].depth = 3;
- cineon->element[0].descriptor = descriptor_RGB;
- cineon->element[0].transfer = transfer_PrintingDensity;
- cineon->element[0].refHighQuantity = 2.048f;
- cineon->element[0].refLowQuantity = 0;
- cineon->element[0].refLowData = 0;
- cineon->element[0].refHighData = cineon->element[0].maxValue;
- cineon->referenceWhite = 685.0f;
- cineon->referenceBlack = 95.0f;
- cineon->gamma = 1.7f;
-
- shortFilename = strrchr(filename, '/');
- if (shortFilename == NULL)
- shortFilename = filename;
- else
- shortFilename++;
-
- cineon->file = BLI_fopen(filename, "wb");
- if (cineon->file == NULL) {
- if (verbose) printf("cineon: Couldn't open file %s\n", filename);
- logImageClose(cineon);
- return NULL;
- }
-
- fillCineonMainHeader(cineon, &header, shortFilename, creator);
-
- if (fwrite(&header, sizeof(header), 1, cineon->file) == 0) {
- if (verbose) printf("cineon: Couldn't write image header\n");
- logImageClose(cineon);
- return NULL;
- }
-
- return cineon;
+ CineonMainHeader header;
+ const char *shortFilename = NULL;
+ /* unsigned char pad[6044]; */
+
+ LogImageFile *cineon = (LogImageFile *)MEM_mallocN(sizeof(LogImageFile), __func__);
+ if (cineon == NULL) {
+ if (verbose)
+ printf("cineon: Failed to malloc cineon file structure.\n");
+ return NULL;
+ }
+
+ /* Only 10 bits Cineon are supported */
+ if (bitsPerSample != 10) {
+ if (verbose)
+ printf("cineon: Only 10 bits Cineon are supported.\n");
+ logImageClose(cineon);
+ return NULL;
+ }
+
+ cineon->width = width;
+ cineon->height = height;
+ cineon->element[0].bitsPerSample = 10;
+ cineon->element[0].dataOffset = sizeof(CineonMainHeader);
+ cineon->element[0].maxValue = 1023;
+ cineon->isMSB = 1;
+ cineon->numElements = 1;
+ cineon->element[0].packing = 1;
+ cineon->depth = 3;
+ cineon->element[0].depth = 3;
+ cineon->element[0].descriptor = descriptor_RGB;
+ cineon->element[0].transfer = transfer_PrintingDensity;
+ cineon->element[0].refHighQuantity = 2.048f;
+ cineon->element[0].refLowQuantity = 0;
+ cineon->element[0].refLowData = 0;
+ cineon->element[0].refHighData = cineon->element[0].maxValue;
+ cineon->referenceWhite = 685.0f;
+ cineon->referenceBlack = 95.0f;
+ cineon->gamma = 1.7f;
+
+ shortFilename = strrchr(filename, '/');
+ if (shortFilename == NULL)
+ shortFilename = filename;
+ else
+ shortFilename++;
+
+ cineon->file = BLI_fopen(filename, "wb");
+ if (cineon->file == NULL) {
+ if (verbose)
+ printf("cineon: Couldn't open file %s\n", filename);
+ logImageClose(cineon);
+ return NULL;
+ }
+
+ fillCineonMainHeader(cineon, &header, shortFilename, creator);
+
+ if (fwrite(&header, sizeof(header), 1, cineon->file) == 0) {
+ if (verbose)
+ printf("cineon: Couldn't write image header\n");
+ logImageClose(cineon);
+ return NULL;
+ }
+
+ return cineon;
}
diff --git a/source/blender/imbuf/intern/cineon/cineonlib.h b/source/blender/imbuf/intern/cineon/cineonlib.h
index fddef8e658f..461407fcf25 100644
--- a/source/blender/imbuf/intern/cineon/cineonlib.h
+++ b/source/blender/imbuf/intern/cineon/cineonlib.h
@@ -23,7 +23,6 @@
* Also handles DPX files (almost)
*/
-
#ifndef __CINEONLIB_H__
#define __CINEONLIB_H__
@@ -33,107 +32,108 @@ extern "C" {
#include "logImageCore.h"
-#define CINEON_FILE_MAGIC 0x802A5FD7
-#define CINEON_UNDEFINED_U8 0xFF
-#define CINEON_UNDEFINED_U16 0xFFFF
-#define CINEON_UNDEFINED_U32 0xFFFFFFFF
-#define CINEON_UNDEFINED_R32 0x7F800000
-#define CINEON_UNDEFINED_CHAR 0
+#define CINEON_FILE_MAGIC 0x802A5FD7
+#define CINEON_UNDEFINED_U8 0xFF
+#define CINEON_UNDEFINED_U16 0xFFFF
+#define CINEON_UNDEFINED_U32 0xFFFFFFFF
+#define CINEON_UNDEFINED_R32 0x7F800000
+#define CINEON_UNDEFINED_CHAR 0
typedef struct {
- unsigned int magic_num;
- unsigned int offset;
- unsigned int gen_hdr_size;
- unsigned int ind_hdr_size;
- unsigned int user_data_size;
- unsigned int file_size;
- char version[8];
- char file_name[100];
- char creation_date[12];
- char creation_time[12];
- char reserved[36];
+ unsigned int magic_num;
+ unsigned int offset;
+ unsigned int gen_hdr_size;
+ unsigned int ind_hdr_size;
+ unsigned int user_data_size;
+ unsigned int file_size;
+ char version[8];
+ char file_name[100];
+ char creation_date[12];
+ char creation_time[12];
+ char reserved[36];
} CineonFileHeader;
typedef struct {
- unsigned char descriptor1;
- unsigned char descriptor2;
- unsigned char bits_per_sample;
- unsigned char filler;
- unsigned int pixels_per_line;
- unsigned int lines_per_image;
- unsigned int ref_low_data;
- float ref_low_quantity;
- unsigned int ref_high_data;
- float ref_high_quantity;
+ unsigned char descriptor1;
+ unsigned char descriptor2;
+ unsigned char bits_per_sample;
+ unsigned char filler;
+ unsigned int pixels_per_line;
+ unsigned int lines_per_image;
+ unsigned int ref_low_data;
+ float ref_low_quantity;
+ unsigned int ref_high_data;
+ float ref_high_quantity;
} CineonElementHeader;
typedef struct {
- unsigned char orientation;
- unsigned char elements_per_image;
- unsigned short filler;
- CineonElementHeader element[8];
- float white_point_x;
- float white_point_y;
- float red_primary_x;
- float red_primary_y;
- float green_primary_x;
- float green_primary_y;
- float blue_primary_x;
- float blue_primary_y;
- char label[200];
- char reserved[28];
- unsigned char interleave;
- unsigned char packing;
- unsigned char data_sign;
- unsigned char sense;
- unsigned int line_padding;
- unsigned int element_padding;
- char reserved2[20];
+ unsigned char orientation;
+ unsigned char elements_per_image;
+ unsigned short filler;
+ CineonElementHeader element[8];
+ float white_point_x;
+ float white_point_y;
+ float red_primary_x;
+ float red_primary_y;
+ float green_primary_x;
+ float green_primary_y;
+ float blue_primary_x;
+ float blue_primary_y;
+ char label[200];
+ char reserved[28];
+ unsigned char interleave;
+ unsigned char packing;
+ unsigned char data_sign;
+ unsigned char sense;
+ unsigned int line_padding;
+ unsigned int element_padding;
+ char reserved2[20];
} CineonImageHeader;
typedef struct {
- int x_offset;
- int y_offset;
- char file_name[100];
- char creation_date[12];
- char creation_time[12];
- char input_device[64];
- char model_number[32];
- char input_serial_number[32];
- float x_input_samples_per_mm;
- float y_input_samples_per_mm;
- float input_device_gamma;
- char reserved[40];
+ int x_offset;
+ int y_offset;
+ char file_name[100];
+ char creation_date[12];
+ char creation_time[12];
+ char input_device[64];
+ char model_number[32];
+ char input_serial_number[32];
+ float x_input_samples_per_mm;
+ float y_input_samples_per_mm;
+ float input_device_gamma;
+ char reserved[40];
} CineonOriginationHeader;
typedef struct {
- unsigned char film_code;
- unsigned char film_type;
- unsigned char edge_code_perforation_offset;
- unsigned char filler;
- unsigned int prefix;
- unsigned int count;
- char format[32];
- unsigned int frame_position;
- float frame_rate;
- char attribute[32];
- char slate[200];
- char reserved[740];
+ unsigned char film_code;
+ unsigned char film_type;
+ unsigned char edge_code_perforation_offset;
+ unsigned char filler;
+ unsigned int prefix;
+ unsigned int count;
+ char format[32];
+ unsigned int frame_position;
+ float frame_rate;
+ char attribute[32];
+ char slate[200];
+ char reserved[740];
} CineonFilmHeader;
typedef struct {
- CineonFileHeader fileHeader;
- CineonImageHeader imageHeader;
- CineonOriginationHeader originationHeader;
- CineonFilmHeader filmHeader;
+ CineonFileHeader fileHeader;
+ CineonImageHeader imageHeader;
+ CineonOriginationHeader originationHeader;
+ CineonFilmHeader filmHeader;
} CineonMainHeader;
void cineonSetVerbose(int);
LogImageFile *cineonOpen(const unsigned char *byteStuff, int fromMemory, size_t bufferSize);
-LogImageFile *cineonCreate(const char *filename, int width, int height, int bitsPerSample, const char *creator);
+LogImageFile *cineonCreate(
+ const char *filename, int width, int height, int bitsPerSample, const char *creator);
#ifdef __cplusplus
}
#endif
-#endif /* __CINEONLIB_H__ */
+#endif /* __CINEONLIB_H__ */
diff --git a/source/blender/imbuf/intern/cineon/dpxlib.c b/source/blender/imbuf/intern/cineon/dpxlib.c
index 7ffe259186d..8c0cd88f256 100644
--- a/source/blender/imbuf/intern/cineon/dpxlib.c
+++ b/source/blender/imbuf/intern/cineon/dpxlib.c
@@ -22,7 +22,6 @@
* Dpx image file format library routines.
*/
-
#include "dpxlib.h"
#include "logmemfile.h"
@@ -46,452 +45,490 @@ static int verbose = 0;
void dpxSetVerbose(int verbosity)
{
- verbose = verbosity;
+ verbose = verbosity;
}
-
/*
* Headers
*/
-static void fillDpxMainHeader(LogImageFile *dpx, DpxMainHeader *header, const char *filename, const char *creator)
+static void fillDpxMainHeader(LogImageFile *dpx,
+ DpxMainHeader *header,
+ const char *filename,
+ const char *creator)
{
- time_t fileClock;
- struct tm *fileTime;
-
- memset(header, 0, sizeof(DpxMainHeader));
-
- /* --- File header --- */
- header->fileHeader.magic_num = swap_uint(DPX_FILE_MAGIC, dpx->isMSB);
- header->fileHeader.offset = swap_uint(dpx->element[0].dataOffset, dpx->isMSB);
- strcpy(header->fileHeader.version, "V2.0");
- header->fileHeader.file_size = swap_uint(dpx->element[0].dataOffset + dpx->height * getRowLength(dpx->width, dpx->element[0]), dpx->isMSB);
- header->fileHeader.ditto_key = 0;
- header->fileHeader.gen_hdr_size = swap_uint(sizeof(DpxFileHeader) + sizeof(DpxImageHeader) + sizeof(DpxOrientationHeader), dpx->isMSB);
- header->fileHeader.ind_hdr_size = swap_uint(sizeof(DpxFilmHeader) + sizeof(DpxTelevisionHeader), dpx->isMSB);
- header->fileHeader.user_data_size = DPX_UNDEFINED_U32;
- strncpy(header->fileHeader.file_name, filename, 99);
- header->fileHeader.file_name[99] = 0;
- fileClock = time(NULL);
- fileTime = localtime(&fileClock);
- strftime(header->fileHeader.creation_date, 24, "%Y:%m:%d:%H:%M:%S%Z", fileTime);
- header->fileHeader.creation_date[23] = 0;
- strncpy(header->fileHeader.creator, creator, 99);
- header->fileHeader.creator[99] = 0;
- header->fileHeader.project[0] = 0;
- header->fileHeader.copyright[0] = 0;
- header->fileHeader.key = 0xFFFFFFFF;
-
- /* --- Image header --- */
- header->imageHeader.orientation = 0;
- header->imageHeader.elements_per_image = swap_ushort(1, dpx->isMSB);
- header->imageHeader.pixels_per_line = swap_uint(dpx->width, dpx->isMSB);
- header->imageHeader.lines_per_element = swap_uint(dpx->height, dpx->isMSB);
-
- /* Fills element */
- header->imageHeader.element[0].data_sign = 0;
- header->imageHeader.element[0].ref_low_data = swap_uint(dpx->element[0].refLowData, dpx->isMSB);
- header->imageHeader.element[0].ref_low_quantity = swap_float(dpx->element[0].refLowQuantity, dpx->isMSB);
- header->imageHeader.element[0].ref_high_data = swap_uint(dpx->element[0].refHighData, dpx->isMSB);
- header->imageHeader.element[0].ref_high_quantity = swap_float(dpx->element[0].refHighQuantity, dpx->isMSB);
- header->imageHeader.element[0].descriptor = dpx->element[0].descriptor;
- header->imageHeader.element[0].transfer = dpx->element[0].transfer;
- header->imageHeader.element[0].colorimetric = 0;
- header->imageHeader.element[0].bits_per_sample = dpx->element[0].bitsPerSample;
- header->imageHeader.element[0].packing = swap_ushort(dpx->element[0].packing, dpx->isMSB);
- header->imageHeader.element[0].encoding = 0;
- header->imageHeader.element[0].data_offset = swap_uint(dpx->element[0].dataOffset, dpx->isMSB);
- header->imageHeader.element[0].line_padding = 0;
- header->imageHeader.element[0].element_padding = 0;
- header->imageHeader.element[0].description[0] = 0;
-
- /* --- Orientation header --- */
- /* we leave it blank */
-
- /* --- Television header --- */
- header->televisionHeader.time_code = DPX_UNDEFINED_U32;
- header->televisionHeader.user_bits = DPX_UNDEFINED_U32;
- header->televisionHeader.interlace = DPX_UNDEFINED_U8;
- header->televisionHeader.field_number = DPX_UNDEFINED_U8;
- header->televisionHeader.video_signal = DPX_UNDEFINED_U8;
- header->televisionHeader.padding = DPX_UNDEFINED_U8;
- header->televisionHeader.horizontal_sample_rate = DPX_UNDEFINED_R32;
- header->televisionHeader.vertical_sample_rate = DPX_UNDEFINED_R32;
- header->televisionHeader.frame_rate = DPX_UNDEFINED_R32;
- header->televisionHeader.time_offset = DPX_UNDEFINED_R32;
- header->televisionHeader.gamma = swap_float(dpx->gamma, dpx->isMSB);
- header->televisionHeader.black_level = swap_float(dpx->referenceBlack, dpx->isMSB);
- header->televisionHeader.black_gain = DPX_UNDEFINED_R32;
- header->televisionHeader.breakpoint = DPX_UNDEFINED_R32;
- header->televisionHeader.white_level = swap_float(dpx->referenceWhite, dpx->isMSB);
- header->televisionHeader.integration_times = DPX_UNDEFINED_R32;
+ time_t fileClock;
+ struct tm *fileTime;
+
+ memset(header, 0, sizeof(DpxMainHeader));
+
+ /* --- File header --- */
+ header->fileHeader.magic_num = swap_uint(DPX_FILE_MAGIC, dpx->isMSB);
+ header->fileHeader.offset = swap_uint(dpx->element[0].dataOffset, dpx->isMSB);
+ strcpy(header->fileHeader.version, "V2.0");
+ header->fileHeader.file_size = swap_uint(
+ dpx->element[0].dataOffset + dpx->height * getRowLength(dpx->width, dpx->element[0]),
+ dpx->isMSB);
+ header->fileHeader.ditto_key = 0;
+ header->fileHeader.gen_hdr_size = swap_uint(
+ sizeof(DpxFileHeader) + sizeof(DpxImageHeader) + sizeof(DpxOrientationHeader), dpx->isMSB);
+ header->fileHeader.ind_hdr_size = swap_uint(sizeof(DpxFilmHeader) + sizeof(DpxTelevisionHeader),
+ dpx->isMSB);
+ header->fileHeader.user_data_size = DPX_UNDEFINED_U32;
+ strncpy(header->fileHeader.file_name, filename, 99);
+ header->fileHeader.file_name[99] = 0;
+ fileClock = time(NULL);
+ fileTime = localtime(&fileClock);
+ strftime(header->fileHeader.creation_date, 24, "%Y:%m:%d:%H:%M:%S%Z", fileTime);
+ header->fileHeader.creation_date[23] = 0;
+ strncpy(header->fileHeader.creator, creator, 99);
+ header->fileHeader.creator[99] = 0;
+ header->fileHeader.project[0] = 0;
+ header->fileHeader.copyright[0] = 0;
+ header->fileHeader.key = 0xFFFFFFFF;
+
+ /* --- Image header --- */
+ header->imageHeader.orientation = 0;
+ header->imageHeader.elements_per_image = swap_ushort(1, dpx->isMSB);
+ header->imageHeader.pixels_per_line = swap_uint(dpx->width, dpx->isMSB);
+ header->imageHeader.lines_per_element = swap_uint(dpx->height, dpx->isMSB);
+
+ /* Fills element */
+ header->imageHeader.element[0].data_sign = 0;
+ header->imageHeader.element[0].ref_low_data = swap_uint(dpx->element[0].refLowData, dpx->isMSB);
+ header->imageHeader.element[0].ref_low_quantity = swap_float(dpx->element[0].refLowQuantity,
+ dpx->isMSB);
+ header->imageHeader.element[0].ref_high_data = swap_uint(dpx->element[0].refHighData,
+ dpx->isMSB);
+ header->imageHeader.element[0].ref_high_quantity = swap_float(dpx->element[0].refHighQuantity,
+ dpx->isMSB);
+ header->imageHeader.element[0].descriptor = dpx->element[0].descriptor;
+ header->imageHeader.element[0].transfer = dpx->element[0].transfer;
+ header->imageHeader.element[0].colorimetric = 0;
+ header->imageHeader.element[0].bits_per_sample = dpx->element[0].bitsPerSample;
+ header->imageHeader.element[0].packing = swap_ushort(dpx->element[0].packing, dpx->isMSB);
+ header->imageHeader.element[0].encoding = 0;
+ header->imageHeader.element[0].data_offset = swap_uint(dpx->element[0].dataOffset, dpx->isMSB);
+ header->imageHeader.element[0].line_padding = 0;
+ header->imageHeader.element[0].element_padding = 0;
+ header->imageHeader.element[0].description[0] = 0;
+
+ /* --- Orientation header --- */
+ /* we leave it blank */
+
+ /* --- Television header --- */
+ header->televisionHeader.time_code = DPX_UNDEFINED_U32;
+ header->televisionHeader.user_bits = DPX_UNDEFINED_U32;
+ header->televisionHeader.interlace = DPX_UNDEFINED_U8;
+ header->televisionHeader.field_number = DPX_UNDEFINED_U8;
+ header->televisionHeader.video_signal = DPX_UNDEFINED_U8;
+ header->televisionHeader.padding = DPX_UNDEFINED_U8;
+ header->televisionHeader.horizontal_sample_rate = DPX_UNDEFINED_R32;
+ header->televisionHeader.vertical_sample_rate = DPX_UNDEFINED_R32;
+ header->televisionHeader.frame_rate = DPX_UNDEFINED_R32;
+ header->televisionHeader.time_offset = DPX_UNDEFINED_R32;
+ header->televisionHeader.gamma = swap_float(dpx->gamma, dpx->isMSB);
+ header->televisionHeader.black_level = swap_float(dpx->referenceBlack, dpx->isMSB);
+ header->televisionHeader.black_gain = DPX_UNDEFINED_R32;
+ header->televisionHeader.breakpoint = DPX_UNDEFINED_R32;
+ header->televisionHeader.white_level = swap_float(dpx->referenceWhite, dpx->isMSB);
+ header->televisionHeader.integration_times = DPX_UNDEFINED_R32;
}
LogImageFile *dpxOpen(const unsigned char *byteStuff, int fromMemory, size_t bufferSize)
{
- DpxMainHeader header;
- LogImageFile *dpx = (LogImageFile *)MEM_mallocN(sizeof(LogImageFile), __func__);
- const char *filename = (const char *)byteStuff;
- int i;
-
- if (dpx == NULL) {
- if (verbose) printf("DPX: Failed to malloc dpx file structure.\n");
- return NULL;
- }
-
- /* zero the header */
- memset(&header, 0, sizeof(DpxMainHeader));
-
- /* for close routine */
- dpx->file = NULL;
-
- if (fromMemory == 0) {
- /* byteStuff is then the filename */
- dpx->file = BLI_fopen(filename, "rb");
- if (dpx->file == NULL) {
- if (verbose) printf("DPX: Failed to open file \"%s\".\n", filename);
- logImageClose(dpx);
- return NULL;
- }
- /* not used in this case */
- dpx->memBuffer = NULL;
- dpx->memCursor = NULL;
- dpx->memBufferSize = 0;
- }
- else {
- dpx->memBuffer = (unsigned char *)byteStuff;
- dpx->memCursor = (unsigned char *)byteStuff;
- dpx->memBufferSize = bufferSize;
- }
-
- if (logimage_fread(&header, sizeof(header), 1, dpx) == 0) {
- if (verbose) printf("DPX: Not enough data for header in \"%s\".\n", byteStuff);
- logImageClose(dpx);
- return NULL;
- }
-
- /* endianness determination */
- if (header.fileHeader.magic_num == swap_uint(DPX_FILE_MAGIC, 1)) {
- dpx->isMSB = 1;
- if (verbose) printf("DPX: File is MSB.\n");
- }
- else if (header.fileHeader.magic_num == DPX_FILE_MAGIC) {
- dpx->isMSB = 0;
- if (verbose) printf("DPX: File is LSB.\n");
- }
- else {
- if (verbose) {
- printf("DPX: Bad magic number %u in \"%s\".\n",
- header.fileHeader.magic_num, byteStuff);
- }
- logImageClose(dpx);
- return NULL;
- }
-
- dpx->srcFormat = format_DPX;
- dpx->numElements = swap_ushort(header.imageHeader.elements_per_image, dpx->isMSB);
- size_t max_elements = sizeof(header.imageHeader.element) / sizeof(header.imageHeader.element[0]);
- if (dpx->numElements == 0 || dpx->numElements >= max_elements) {
- if (verbose) printf("DPX: Wrong number of elements: %d\n", dpx->numElements);
- logImageClose(dpx);
- return NULL;
- }
-
- dpx->width = swap_uint(header.imageHeader.pixels_per_line, dpx->isMSB);
- dpx->height = swap_uint(header.imageHeader.lines_per_element, dpx->isMSB);
-
- if (dpx->width == 0 || dpx->height == 0) {
- if (verbose) printf("DPX: Wrong image dimension: %dx%d\n", dpx->width, dpx->height);
- logImageClose(dpx);
- return NULL;
- }
-
- dpx->depth = 0;
-
- for (i = 0; i < dpx->numElements; i++) {
- dpx->element[i].descriptor = header.imageHeader.element[i].descriptor;
-
- switch (dpx->element[i].descriptor) {
- case descriptor_Red:
- case descriptor_Green:
- case descriptor_Blue:
- case descriptor_Alpha:
- case descriptor_Luminance:
- case descriptor_Chrominance:
- dpx->depth++;
- dpx->element[i].depth = 1;
- break;
-
- case descriptor_CbYCrY:
- dpx->depth += 2;
- dpx->element[i].depth = 2;
- break;
-
- case descriptor_RGB:
- case descriptor_CbYCr:
- case descriptor_CbYACrYA:
- dpx->depth += 3;
- dpx->element[i].depth = 3;
- break;
-
- case descriptor_RGBA:
- case descriptor_ABGR:
- case descriptor_CbYCrA:
- dpx->depth += 4;
- dpx->element[i].depth = 4;
- break;
-
- case descriptor_Depth:
- case descriptor_Composite:
- /* unsupported */
- break;
- }
-
- if (dpx->depth == 0 || dpx->depth > 4) {
- if (verbose) printf("DPX: Unsupported image depth: %d\n", dpx->depth);
- logImageClose(dpx);
- return NULL;
- }
-
- dpx->element[i].bitsPerSample = header.imageHeader.element[i].bits_per_sample;
- if (dpx->element[i].bitsPerSample != 1 && dpx->element[i].bitsPerSample != 8 &&
- dpx->element[i].bitsPerSample != 10 && dpx->element[i].bitsPerSample != 12 &&
- dpx->element[i].bitsPerSample != 16)
- {
- if (verbose) printf("DPX: Unsupported bitsPerSample for elements %d: %d\n", i, dpx->element[i].bitsPerSample);
- logImageClose(dpx);
- return NULL;
- }
-
- dpx->element[i].maxValue = powf(2, dpx->element[i].bitsPerSample) - 1.0f;
-
- dpx->element[i].packing = swap_ushort(header.imageHeader.element[i].packing, dpx->isMSB);
- if (dpx->element[i].packing > 2) {
- if (verbose) printf("DPX: Unsupported packing for element %d: %d\n", i, dpx->element[i].packing);
- logImageClose(dpx);
- return NULL;
- }
-
- /* Sometimes, the offset is not set correctly in the header */
- dpx->element[i].dataOffset = swap_uint(header.imageHeader.element[i].data_offset, dpx->isMSB);
- if (dpx->element[i].dataOffset == 0 && dpx->numElements == 1)
- dpx->element[i].dataOffset = swap_uint(header.fileHeader.offset, dpx->isMSB);
-
- if (dpx->element[i].dataOffset == 0) {
- if (verbose) printf("DPX: Image header is corrupted.\n");
- logImageClose(dpx);
- return NULL;
- }
-
- dpx->element[i].transfer = header.imageHeader.element[i].transfer;
-
- /* if undefined, assign default */
- dpx->element[i].refLowData = swap_uint(header.imageHeader.element[i].ref_low_data, dpx->isMSB);
- dpx->element[i].refLowQuantity = swap_float(header.imageHeader.element[i].ref_low_quantity, dpx->isMSB);
- dpx->element[i].refHighData = swap_uint(header.imageHeader.element[i].ref_high_data, dpx->isMSB);
- dpx->element[i].refHighQuantity = swap_float(header.imageHeader.element[i].ref_high_quantity, dpx->isMSB);
-
- switch (dpx->element[i].descriptor) {
- case descriptor_Red:
- case descriptor_Green:
- case descriptor_Blue:
- case descriptor_Alpha:
- case descriptor_RGB:
- case descriptor_RGBA:
- case descriptor_ABGR:
- if (dpx->element[i].refLowData == DPX_UNDEFINED_U32)
- dpx->element[i].refLowData = 0;
-
- if (dpx->element[i].refHighData == DPX_UNDEFINED_U32)
- dpx->element[i].refHighData = (unsigned int)dpx->element[i].maxValue;
-
- if (dpx->element[i].refLowQuantity == DPX_UNDEFINED_R32 || isnan(dpx->element[i].refLowQuantity))
- dpx->element[i].refLowQuantity = 0.0f;
-
- if (dpx->element[i].refHighQuantity == DPX_UNDEFINED_R32 || isnan(dpx->element[i].refHighQuantity)) {
- if (dpx->element[i].transfer == transfer_PrintingDensity || dpx->element[i].transfer == transfer_Logarithmic)
- dpx->element[i].refHighQuantity = 2.048f;
- else
- dpx->element[i].refHighQuantity = dpx->element[i].maxValue;
- }
-
- break;
-
- case descriptor_Luminance:
- case descriptor_Chrominance:
- case descriptor_CbYCrY:
- case descriptor_CbYCr:
- case descriptor_CbYACrYA:
- case descriptor_CbYCrA:
- if (dpx->element[i].refLowData == DPX_UNDEFINED_U32)
- dpx->element[i].refLowData = 16.0f / 255.0f * dpx->element[i].maxValue;
-
- if (dpx->element[i].refHighData == DPX_UNDEFINED_U32)
- dpx->element[i].refHighData = 235.0f / 255.0f * dpx->element[i].maxValue;
-
- if (dpx->element[i].refLowQuantity == DPX_UNDEFINED_R32 || isnan(dpx->element[i].refLowQuantity))
- dpx->element[i].refLowQuantity = 0.0f;
-
- if (dpx->element[i].refHighQuantity == DPX_UNDEFINED_R32 || isnan(dpx->element[i].refHighQuantity))
- dpx->element[i].refHighQuantity = 0.7f;
-
- break;
-
- default:
- break;
- }
- }
-
- dpx->referenceBlack = swap_float(header.televisionHeader.black_level, dpx->isMSB);
- dpx->referenceWhite = swap_float(header.televisionHeader.white_level, dpx->isMSB);
- dpx->gamma = swap_float(header.televisionHeader.gamma, dpx->isMSB);
-
- if ((dpx->referenceBlack == DPX_UNDEFINED_R32 || isnan(dpx->referenceBlack)) ||
- (dpx->referenceWhite == DPX_UNDEFINED_R32 || dpx->referenceWhite <= dpx->referenceBlack || isnan(dpx->referenceWhite)) ||
- (dpx->gamma == DPX_UNDEFINED_R32 || dpx->gamma <= 0 || isnan(dpx->gamma)))
- {
- dpx->referenceBlack = 95.0f / 1023.0f * dpx->element[0].maxValue;
- dpx->referenceWhite = 685.0f / 1023.0f * dpx->element[0].maxValue;
- dpx->gamma = 1.7f;
- }
-
- if (verbose) {
- printf("size %d x %d x %d elements\n", dpx->width, dpx->height, dpx->numElements);
- for (i = 0; i < dpx->numElements; i++) {
- printf(" Element %d:\n", i);
- printf(" Bits per sample: %d\n", dpx->element[i].bitsPerSample);
- printf(" Depth: %d\n", dpx->element[i].depth);
- printf(" Transfer characteristics: %d\n", dpx->element[i].transfer);
- printf(" Packing: %d\n", dpx->element[i].packing);
- printf(" Descriptor: %d\n", dpx->element[i].descriptor);
- printf(" Data offset: %d\n", dpx->element[i].dataOffset);
- printf(" Reference low data: %u\n", dpx->element[i].refLowData);
- printf(" Reference low quantity: %f\n", dpx->element[i].refLowQuantity);
- printf(" Reference high data: %u\n", dpx->element[i].refHighData);
- printf(" Reference high quantity: %f\n", dpx->element[i].refHighQuantity);
- printf("\n");
- }
-
- printf("Gamma: %f\n", dpx->gamma);
- printf("Reference black: %f\n", dpx->referenceBlack);
- printf("Reference white: %f\n", dpx->referenceWhite);
- printf("Orientation: %d\n", header.imageHeader.orientation);
- printf("----------------------------\n");
- }
- return dpx;
+ DpxMainHeader header;
+ LogImageFile *dpx = (LogImageFile *)MEM_mallocN(sizeof(LogImageFile), __func__);
+ const char *filename = (const char *)byteStuff;
+ int i;
+
+ if (dpx == NULL) {
+ if (verbose)
+ printf("DPX: Failed to malloc dpx file structure.\n");
+ return NULL;
+ }
+
+ /* zero the header */
+ memset(&header, 0, sizeof(DpxMainHeader));
+
+ /* for close routine */
+ dpx->file = NULL;
+
+ if (fromMemory == 0) {
+ /* byteStuff is then the filename */
+ dpx->file = BLI_fopen(filename, "rb");
+ if (dpx->file == NULL) {
+ if (verbose)
+ printf("DPX: Failed to open file \"%s\".\n", filename);
+ logImageClose(dpx);
+ return NULL;
+ }
+ /* not used in this case */
+ dpx->memBuffer = NULL;
+ dpx->memCursor = NULL;
+ dpx->memBufferSize = 0;
+ }
+ else {
+ dpx->memBuffer = (unsigned char *)byteStuff;
+ dpx->memCursor = (unsigned char *)byteStuff;
+ dpx->memBufferSize = bufferSize;
+ }
+
+ if (logimage_fread(&header, sizeof(header), 1, dpx) == 0) {
+ if (verbose)
+ printf("DPX: Not enough data for header in \"%s\".\n", byteStuff);
+ logImageClose(dpx);
+ return NULL;
+ }
+
+ /* endianness determination */
+ if (header.fileHeader.magic_num == swap_uint(DPX_FILE_MAGIC, 1)) {
+ dpx->isMSB = 1;
+ if (verbose)
+ printf("DPX: File is MSB.\n");
+ }
+ else if (header.fileHeader.magic_num == DPX_FILE_MAGIC) {
+ dpx->isMSB = 0;
+ if (verbose)
+ printf("DPX: File is LSB.\n");
+ }
+ else {
+ if (verbose) {
+ printf("DPX: Bad magic number %u in \"%s\".\n", header.fileHeader.magic_num, byteStuff);
+ }
+ logImageClose(dpx);
+ return NULL;
+ }
+
+ dpx->srcFormat = format_DPX;
+ dpx->numElements = swap_ushort(header.imageHeader.elements_per_image, dpx->isMSB);
+ size_t max_elements = sizeof(header.imageHeader.element) / sizeof(header.imageHeader.element[0]);
+ if (dpx->numElements == 0 || dpx->numElements >= max_elements) {
+ if (verbose)
+ printf("DPX: Wrong number of elements: %d\n", dpx->numElements);
+ logImageClose(dpx);
+ return NULL;
+ }
+
+ dpx->width = swap_uint(header.imageHeader.pixels_per_line, dpx->isMSB);
+ dpx->height = swap_uint(header.imageHeader.lines_per_element, dpx->isMSB);
+
+ if (dpx->width == 0 || dpx->height == 0) {
+ if (verbose)
+ printf("DPX: Wrong image dimension: %dx%d\n", dpx->width, dpx->height);
+ logImageClose(dpx);
+ return NULL;
+ }
+
+ dpx->depth = 0;
+
+ for (i = 0; i < dpx->numElements; i++) {
+ dpx->element[i].descriptor = header.imageHeader.element[i].descriptor;
+
+ switch (dpx->element[i].descriptor) {
+ case descriptor_Red:
+ case descriptor_Green:
+ case descriptor_Blue:
+ case descriptor_Alpha:
+ case descriptor_Luminance:
+ case descriptor_Chrominance:
+ dpx->depth++;
+ dpx->element[i].depth = 1;
+ break;
+
+ case descriptor_CbYCrY:
+ dpx->depth += 2;
+ dpx->element[i].depth = 2;
+ break;
+
+ case descriptor_RGB:
+ case descriptor_CbYCr:
+ case descriptor_CbYACrYA:
+ dpx->depth += 3;
+ dpx->element[i].depth = 3;
+ break;
+
+ case descriptor_RGBA:
+ case descriptor_ABGR:
+ case descriptor_CbYCrA:
+ dpx->depth += 4;
+ dpx->element[i].depth = 4;
+ break;
+
+ case descriptor_Depth:
+ case descriptor_Composite:
+ /* unsupported */
+ break;
+ }
+
+ if (dpx->depth == 0 || dpx->depth > 4) {
+ if (verbose)
+ printf("DPX: Unsupported image depth: %d\n", dpx->depth);
+ logImageClose(dpx);
+ return NULL;
+ }
+
+ dpx->element[i].bitsPerSample = header.imageHeader.element[i].bits_per_sample;
+ if (dpx->element[i].bitsPerSample != 1 && dpx->element[i].bitsPerSample != 8 &&
+ dpx->element[i].bitsPerSample != 10 && dpx->element[i].bitsPerSample != 12 &&
+ dpx->element[i].bitsPerSample != 16) {
+ if (verbose)
+ printf("DPX: Unsupported bitsPerSample for elements %d: %d\n",
+ i,
+ dpx->element[i].bitsPerSample);
+ logImageClose(dpx);
+ return NULL;
+ }
+
+ dpx->element[i].maxValue = powf(2, dpx->element[i].bitsPerSample) - 1.0f;
+
+ dpx->element[i].packing = swap_ushort(header.imageHeader.element[i].packing, dpx->isMSB);
+ if (dpx->element[i].packing > 2) {
+ if (verbose)
+ printf("DPX: Unsupported packing for element %d: %d\n", i, dpx->element[i].packing);
+ logImageClose(dpx);
+ return NULL;
+ }
+
+ /* Sometimes, the offset is not set correctly in the header */
+ dpx->element[i].dataOffset = swap_uint(header.imageHeader.element[i].data_offset, dpx->isMSB);
+ if (dpx->element[i].dataOffset == 0 && dpx->numElements == 1)
+ dpx->element[i].dataOffset = swap_uint(header.fileHeader.offset, dpx->isMSB);
+
+ if (dpx->element[i].dataOffset == 0) {
+ if (verbose)
+ printf("DPX: Image header is corrupted.\n");
+ logImageClose(dpx);
+ return NULL;
+ }
+
+ dpx->element[i].transfer = header.imageHeader.element[i].transfer;
+
+ /* if undefined, assign default */
+ dpx->element[i].refLowData = swap_uint(header.imageHeader.element[i].ref_low_data, dpx->isMSB);
+ dpx->element[i].refLowQuantity = swap_float(header.imageHeader.element[i].ref_low_quantity,
+ dpx->isMSB);
+ dpx->element[i].refHighData = swap_uint(header.imageHeader.element[i].ref_high_data,
+ dpx->isMSB);
+ dpx->element[i].refHighQuantity = swap_float(header.imageHeader.element[i].ref_high_quantity,
+ dpx->isMSB);
+
+ switch (dpx->element[i].descriptor) {
+ case descriptor_Red:
+ case descriptor_Green:
+ case descriptor_Blue:
+ case descriptor_Alpha:
+ case descriptor_RGB:
+ case descriptor_RGBA:
+ case descriptor_ABGR:
+ if (dpx->element[i].refLowData == DPX_UNDEFINED_U32)
+ dpx->element[i].refLowData = 0;
+
+ if (dpx->element[i].refHighData == DPX_UNDEFINED_U32)
+ dpx->element[i].refHighData = (unsigned int)dpx->element[i].maxValue;
+
+ if (dpx->element[i].refLowQuantity == DPX_UNDEFINED_R32 ||
+ isnan(dpx->element[i].refLowQuantity))
+ dpx->element[i].refLowQuantity = 0.0f;
+
+ if (dpx->element[i].refHighQuantity == DPX_UNDEFINED_R32 ||
+ isnan(dpx->element[i].refHighQuantity)) {
+ if (dpx->element[i].transfer == transfer_PrintingDensity ||
+ dpx->element[i].transfer == transfer_Logarithmic)
+ dpx->element[i].refHighQuantity = 2.048f;
+ else
+ dpx->element[i].refHighQuantity = dpx->element[i].maxValue;
+ }
+
+ break;
+
+ case descriptor_Luminance:
+ case descriptor_Chrominance:
+ case descriptor_CbYCrY:
+ case descriptor_CbYCr:
+ case descriptor_CbYACrYA:
+ case descriptor_CbYCrA:
+ if (dpx->element[i].refLowData == DPX_UNDEFINED_U32)
+ dpx->element[i].refLowData = 16.0f / 255.0f * dpx->element[i].maxValue;
+
+ if (dpx->element[i].refHighData == DPX_UNDEFINED_U32)
+ dpx->element[i].refHighData = 235.0f / 255.0f * dpx->element[i].maxValue;
+
+ if (dpx->element[i].refLowQuantity == DPX_UNDEFINED_R32 ||
+ isnan(dpx->element[i].refLowQuantity))
+ dpx->element[i].refLowQuantity = 0.0f;
+
+ if (dpx->element[i].refHighQuantity == DPX_UNDEFINED_R32 ||
+ isnan(dpx->element[i].refHighQuantity))
+ dpx->element[i].refHighQuantity = 0.7f;
+
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ dpx->referenceBlack = swap_float(header.televisionHeader.black_level, dpx->isMSB);
+ dpx->referenceWhite = swap_float(header.televisionHeader.white_level, dpx->isMSB);
+ dpx->gamma = swap_float(header.televisionHeader.gamma, dpx->isMSB);
+
+ if ((dpx->referenceBlack == DPX_UNDEFINED_R32 || isnan(dpx->referenceBlack)) ||
+ (dpx->referenceWhite == DPX_UNDEFINED_R32 || dpx->referenceWhite <= dpx->referenceBlack ||
+ isnan(dpx->referenceWhite)) ||
+ (dpx->gamma == DPX_UNDEFINED_R32 || dpx->gamma <= 0 || isnan(dpx->gamma))) {
+ dpx->referenceBlack = 95.0f / 1023.0f * dpx->element[0].maxValue;
+ dpx->referenceWhite = 685.0f / 1023.0f * dpx->element[0].maxValue;
+ dpx->gamma = 1.7f;
+ }
+
+ if (verbose) {
+ printf("size %d x %d x %d elements\n", dpx->width, dpx->height, dpx->numElements);
+ for (i = 0; i < dpx->numElements; i++) {
+ printf(" Element %d:\n", i);
+ printf(" Bits per sample: %d\n", dpx->element[i].bitsPerSample);
+ printf(" Depth: %d\n", dpx->element[i].depth);
+ printf(" Transfer characteristics: %d\n", dpx->element[i].transfer);
+ printf(" Packing: %d\n", dpx->element[i].packing);
+ printf(" Descriptor: %d\n", dpx->element[i].descriptor);
+ printf(" Data offset: %d\n", dpx->element[i].dataOffset);
+ printf(" Reference low data: %u\n", dpx->element[i].refLowData);
+ printf(" Reference low quantity: %f\n", dpx->element[i].refLowQuantity);
+ printf(" Reference high data: %u\n", dpx->element[i].refHighData);
+ printf(" Reference high quantity: %f\n", dpx->element[i].refHighQuantity);
+ printf("\n");
+ }
+
+ printf("Gamma: %f\n", dpx->gamma);
+ printf("Reference black: %f\n", dpx->referenceBlack);
+ printf("Reference white: %f\n", dpx->referenceWhite);
+ printf("Orientation: %d\n", header.imageHeader.orientation);
+ printf("----------------------------\n");
+ }
+ return dpx;
}
-LogImageFile *dpxCreate(const char *filename, int width, int height, int bitsPerSample, int hasAlpha,
- int isLogarithmic, int referenceWhite, int referenceBlack, float gamma,
+LogImageFile *dpxCreate(const char *filename,
+ int width,
+ int height,
+ int bitsPerSample,
+ int hasAlpha,
+ int isLogarithmic,
+ int referenceWhite,
+ int referenceBlack,
+ float gamma,
const char *creator)
{
- DpxMainHeader header;
- const char *shortFilename = NULL;
- unsigned char pad[6044];
-
- LogImageFile *dpx = (LogImageFile *)MEM_mallocN(sizeof(LogImageFile), __func__);
- if (dpx == NULL) {
- if (verbose) printf("DPX: Failed to malloc dpx file structure.\n");
- return NULL;
- }
-
- dpx->width = width;
- dpx->height = height;
- dpx->element[0].bitsPerSample = bitsPerSample;
- dpx->element[0].dataOffset = 8092;
- dpx->element[0].maxValue = powf(2, dpx->element[0].bitsPerSample) - 1.0f;
- dpx->isMSB = 1;
- dpx->numElements = 1;
-
- switch (bitsPerSample) {
- case 8:
- case 16:
- dpx->element[0].packing = 0;
- break;
-
- case 10:
- case 12:
- /* Packed Type A padding is the most common 10/12 bits format */
- dpx->element[0].packing = 1;
- break;
-
- default:
- if (verbose) printf("DPX: bitsPerSample not supported: %d\n", bitsPerSample);
- logImageClose(dpx);
- return NULL;
- }
-
- if (hasAlpha == 0) {
- dpx->depth = 3;
- dpx->element[0].depth = 3;
- dpx->element[0].descriptor = descriptor_RGB;
- }
- else {
- dpx->depth = 4;
- dpx->element[0].depth = 4;
- dpx->element[0].descriptor = descriptor_RGBA;
- }
-
- if (isLogarithmic == 0) {
- dpx->element[0].transfer = transfer_Linear;
- dpx->element[0].refHighQuantity = dpx->element[0].maxValue;
- }
- else {
- dpx->element[0].transfer = transfer_PrintingDensity;
- dpx->element[0].refHighQuantity = 2.048f;
-
- }
-
- dpx->element[0].refLowQuantity = 0;
- dpx->element[0].refLowData = 0;
- dpx->element[0].refHighData = dpx->element[0].maxValue;
-
- if (referenceWhite > 0)
- dpx->referenceWhite = referenceWhite;
- else
- dpx->referenceWhite = 685.0f / 1023.0f * dpx->element[0].maxValue;
-
- if (referenceBlack > 0)
- dpx->referenceBlack = referenceBlack;
- else
- dpx->referenceBlack = 95.0f / 1023.0f * dpx->element[0].maxValue;
-
- if (gamma > 0.0f)
- dpx->gamma = gamma;
- else
- dpx->gamma = 1.7f;
-
-
- shortFilename = strrchr(filename, '/');
- if (shortFilename == NULL)
- shortFilename = filename;
- else
- shortFilename++;
-
- dpx->file = BLI_fopen(filename, "wb");
-
- if (dpx->file == NULL) {
- if (verbose) printf("DPX: Couldn't open file %s\n", filename);
- logImageClose(dpx);
- return NULL;
- }
-
- fillDpxMainHeader(dpx, &header, shortFilename, creator);
-
- if (fwrite(&header, sizeof(header), 1, dpx->file) == 0) {
- if (verbose) printf("DPX: Couldn't write image header\n");
- logImageClose(dpx);
- return NULL;
- }
-
- /* Header should be rounded to next 8k block
- * 6044 = 8092 - sizeof(DpxMainHeader) */
- memset(&pad, 0, 6044);
- if (fwrite(&pad, 6044, 1, dpx->file) == 0) {
- if (verbose) printf("DPX: Couldn't write image header\n");
- logImageClose(dpx);
- return NULL;
- }
-
- return dpx;
+ DpxMainHeader header;
+ const char *shortFilename = NULL;
+ unsigned char pad[6044];
+
+ LogImageFile *dpx = (LogImageFile *)MEM_mallocN(sizeof(LogImageFile), __func__);
+ if (dpx == NULL) {
+ if (verbose)
+ printf("DPX: Failed to malloc dpx file structure.\n");
+ return NULL;
+ }
+
+ dpx->width = width;
+ dpx->height = height;
+ dpx->element[0].bitsPerSample = bitsPerSample;
+ dpx->element[0].dataOffset = 8092;
+ dpx->element[0].maxValue = powf(2, dpx->element[0].bitsPerSample) - 1.0f;
+ dpx->isMSB = 1;
+ dpx->numElements = 1;
+
+ switch (bitsPerSample) {
+ case 8:
+ case 16:
+ dpx->element[0].packing = 0;
+ break;
+
+ case 10:
+ case 12:
+ /* Packed Type A padding is the most common 10/12 bits format */
+ dpx->element[0].packing = 1;
+ break;
+
+ default:
+ if (verbose)
+ printf("DPX: bitsPerSample not supported: %d\n", bitsPerSample);
+ logImageClose(dpx);
+ return NULL;
+ }
+
+ if (hasAlpha == 0) {
+ dpx->depth = 3;
+ dpx->element[0].depth = 3;
+ dpx->element[0].descriptor = descriptor_RGB;
+ }
+ else {
+ dpx->depth = 4;
+ dpx->element[0].depth = 4;
+ dpx->element[0].descriptor = descriptor_RGBA;
+ }
+
+ if (isLogarithmic == 0) {
+ dpx->element[0].transfer = transfer_Linear;
+ dpx->element[0].refHighQuantity = dpx->element[0].maxValue;
+ }
+ else {
+ dpx->element[0].transfer = transfer_PrintingDensity;
+ dpx->element[0].refHighQuantity = 2.048f;
+ }
+
+ dpx->element[0].refLowQuantity = 0;
+ dpx->element[0].refLowData = 0;
+ dpx->element[0].refHighData = dpx->element[0].maxValue;
+
+ if (referenceWhite > 0)
+ dpx->referenceWhite = referenceWhite;
+ else
+ dpx->referenceWhite = 685.0f / 1023.0f * dpx->element[0].maxValue;
+
+ if (referenceBlack > 0)
+ dpx->referenceBlack = referenceBlack;
+ else
+ dpx->referenceBlack = 95.0f / 1023.0f * dpx->element[0].maxValue;
+
+ if (gamma > 0.0f)
+ dpx->gamma = gamma;
+ else
+ dpx->gamma = 1.7f;
+
+ shortFilename = strrchr(filename, '/');
+ if (shortFilename == NULL)
+ shortFilename = filename;
+ else
+ shortFilename++;
+
+ dpx->file = BLI_fopen(filename, "wb");
+
+ if (dpx->file == NULL) {
+ if (verbose)
+ printf("DPX: Couldn't open file %s\n", filename);
+ logImageClose(dpx);
+ return NULL;
+ }
+
+ fillDpxMainHeader(dpx, &header, shortFilename, creator);
+
+ if (fwrite(&header, sizeof(header), 1, dpx->file) == 0) {
+ if (verbose)
+ printf("DPX: Couldn't write image header\n");
+ logImageClose(dpx);
+ return NULL;
+ }
+
+ /* Header should be rounded to next 8k block
+ * 6044 = 8092 - sizeof(DpxMainHeader) */
+ memset(&pad, 0, 6044);
+ if (fwrite(&pad, 6044, 1, dpx->file) == 0) {
+ if (verbose)
+ printf("DPX: Couldn't write image header\n");
+ logImageClose(dpx);
+ return NULL;
+ }
+
+ return dpx;
}
diff --git a/source/blender/imbuf/intern/cineon/dpxlib.h b/source/blender/imbuf/intern/cineon/dpxlib.h
index fe9f34901b8..bf07b8e329d 100644
--- a/source/blender/imbuf/intern/cineon/dpxlib.h
+++ b/source/blender/imbuf/intern/cineon/dpxlib.h
@@ -22,7 +22,6 @@
* DPX image file format library definitions.
*/
-
#ifndef __DPXLIB_H__
#define __DPXLIB_H__
@@ -32,126 +31,134 @@ extern "C" {
#include "logImageCore.h"
-#define DPX_FILE_MAGIC 0x53445058
-#define DPX_UNDEFINED_U8 0xFF
-#define DPX_UNDEFINED_U16 0xFFFF
-#define DPX_UNDEFINED_U32 0xFFFFFFFF
-#define DPX_UNDEFINED_R32 0xFFFFFFFF
-#define DPX_UNDEFINED_CHAR 0
+#define DPX_FILE_MAGIC 0x53445058
+#define DPX_UNDEFINED_U8 0xFF
+#define DPX_UNDEFINED_U16 0xFFFF
+#define DPX_UNDEFINED_U32 0xFFFFFFFF
+#define DPX_UNDEFINED_R32 0xFFFFFFFF
+#define DPX_UNDEFINED_CHAR 0
typedef struct {
- unsigned int magic_num;
- unsigned int offset;
- char version[8];
- unsigned int file_size;
- unsigned int ditto_key;
- unsigned int gen_hdr_size;
- unsigned int ind_hdr_size;
- unsigned int user_data_size;
- char file_name[100];
- char creation_date[24];
- char creator[100];
- char project[200];
- char copyright[200];
- unsigned int key;
- char reserved[104];
+ unsigned int magic_num;
+ unsigned int offset;
+ char version[8];
+ unsigned int file_size;
+ unsigned int ditto_key;
+ unsigned int gen_hdr_size;
+ unsigned int ind_hdr_size;
+ unsigned int user_data_size;
+ char file_name[100];
+ char creation_date[24];
+ char creator[100];
+ char project[200];
+ char copyright[200];
+ unsigned int key;
+ char reserved[104];
} DpxFileHeader;
typedef struct {
- unsigned int data_sign;
- unsigned int ref_low_data;
- float ref_low_quantity;
- unsigned int ref_high_data;
- float ref_high_quantity;
- unsigned char descriptor;
- unsigned char transfer;
- unsigned char colorimetric;
- unsigned char bits_per_sample;
- unsigned short packing;
- unsigned short encoding;
- unsigned int data_offset;
- unsigned int line_padding;
- unsigned int element_padding;
- char description[32];
+ unsigned int data_sign;
+ unsigned int ref_low_data;
+ float ref_low_quantity;
+ unsigned int ref_high_data;
+ float ref_high_quantity;
+ unsigned char descriptor;
+ unsigned char transfer;
+ unsigned char colorimetric;
+ unsigned char bits_per_sample;
+ unsigned short packing;
+ unsigned short encoding;
+ unsigned int data_offset;
+ unsigned int line_padding;
+ unsigned int element_padding;
+ char description[32];
} DpxElementHeader;
typedef struct {
- unsigned short orientation;
- unsigned short elements_per_image;
- unsigned int pixels_per_line;
- unsigned int lines_per_element;
- DpxElementHeader element[8];
- char reserved[52];
+ unsigned short orientation;
+ unsigned short elements_per_image;
+ unsigned int pixels_per_line;
+ unsigned int lines_per_element;
+ DpxElementHeader element[8];
+ char reserved[52];
} DpxImageHeader;
typedef struct {
- unsigned int x_offset;
- unsigned int y_offset;
- float x_center;
- float y_center;
- unsigned int x_original_size;
- unsigned int y_original_size;
- char file_name[100];
- char creation_time[24];
- char input_device[32];
- char input_serial_number[32];
- unsigned short border_validity[4];
- unsigned int pixel_aspect_ratio[2];
- char reserved[28];
+ unsigned int x_offset;
+ unsigned int y_offset;
+ float x_center;
+ float y_center;
+ unsigned int x_original_size;
+ unsigned int y_original_size;
+ char file_name[100];
+ char creation_time[24];
+ char input_device[32];
+ char input_serial_number[32];
+ unsigned short border_validity[4];
+ unsigned int pixel_aspect_ratio[2];
+ char reserved[28];
} DpxOrientationHeader;
typedef struct {
- char film_manufacturer_id[2];
- char film_type[2];
- char edge_code_perforation_offset[2];
- char edge_code_prefix[6];
- char edge_code_count[4];
- char film_format[32];
- unsigned int frame_position;
- unsigned int sequence_length;
- unsigned int held_count;
- float frame_rate;
- float shutter_angle;
- char frame_identification[32];
- char slate_info[100];
- char reserved[56];
+ char film_manufacturer_id[2];
+ char film_type[2];
+ char edge_code_perforation_offset[2];
+ char edge_code_prefix[6];
+ char edge_code_count[4];
+ char film_format[32];
+ unsigned int frame_position;
+ unsigned int sequence_length;
+ unsigned int held_count;
+ float frame_rate;
+ float shutter_angle;
+ char frame_identification[32];
+ char slate_info[100];
+ char reserved[56];
} DpxFilmHeader;
typedef struct {
- unsigned int time_code;
- unsigned int user_bits;
- unsigned char interlace;
- unsigned char field_number;
- unsigned char video_signal;
- unsigned char padding;
- float horizontal_sample_rate;
- float vertical_sample_rate;
- float frame_rate;
- float time_offset;
- float gamma;
- float black_level;
- float black_gain;
- float breakpoint;
- float white_level;
- float integration_times;
- unsigned char reserved[76];
+ unsigned int time_code;
+ unsigned int user_bits;
+ unsigned char interlace;
+ unsigned char field_number;
+ unsigned char video_signal;
+ unsigned char padding;
+ float horizontal_sample_rate;
+ float vertical_sample_rate;
+ float frame_rate;
+ float time_offset;
+ float gamma;
+ float black_level;
+ float black_gain;
+ float breakpoint;
+ float white_level;
+ float integration_times;
+ unsigned char reserved[76];
} DpxTelevisionHeader;
-
typedef struct {
- DpxFileHeader fileHeader;
- DpxImageHeader imageHeader;
- DpxOrientationHeader orientationHeader;
- DpxFilmHeader filmHeader;
- DpxTelevisionHeader televisionHeader;
+ DpxFileHeader fileHeader;
+ DpxImageHeader imageHeader;
+ DpxOrientationHeader orientationHeader;
+ DpxFilmHeader filmHeader;
+ DpxTelevisionHeader televisionHeader;
} DpxMainHeader;
void dpxSetVerbose(int verbosity);
LogImageFile *dpxOpen(const unsigned char *byteStuff, int fromMemory, size_t bufferSize);
-LogImageFile *dpxCreate(const char *filename, int width, int height, int bitsPerSample, int hasAlpha, int isLogarithmic, int referenceWhite, int referenceBlack, float gamma, const char *creator);
+LogImageFile *dpxCreate(const char *filename,
+ int width,
+ int height,
+ int bitsPerSample,
+ int hasAlpha,
+ int isLogarithmic,
+ int referenceWhite,
+ int referenceBlack,
+ float gamma,
+ const char *creator);
#ifdef __cplusplus
}
#endif
-#endif /* __DPXLIB_H__ */
+#endif /* __DPXLIB_H__ */
diff --git a/source/blender/imbuf/intern/cineon/logImageCore.c b/source/blender/imbuf/intern/cineon/logImageCore.c
index 3dcf1814f27..2169665cf78 100644
--- a/source/blender/imbuf/intern/cineon/logImageCore.c
+++ b/source/blender/imbuf/intern/cineon/logImageCore.c
@@ -22,7 +22,6 @@
* Cineon image file format library routines.
*/
-
#include "logmemfile.h"
#include "logImageCore.h"
#include "dpxlib.h"
@@ -51,13 +50,24 @@ static int logImageElementGetData(LogImageFile *dpx, LogImageElement logElement,
static int logImageElementGetData1(LogImageFile *dpx, LogImageElement logElement, float *data);
static int logImageElementGetData8(LogImageFile *dpx, LogImageElement logElement, float *data);
static int logImageElementGetData10(LogImageFile *dpx, LogImageElement logElement, float *data);
-static int logImageElementGetData10Packed(LogImageFile *dpx, LogImageElement logElement, float *data);
+static int logImageElementGetData10Packed(LogImageFile *dpx,
+ LogImageElement logElement,
+ float *data);
static int logImageElementGetData12(LogImageFile *dpx, LogImageElement logElement, float *data);
-static int logImageElementGetData12Packed(LogImageFile *dpx, LogImageElement logElement, float *data);
+static int logImageElementGetData12Packed(LogImageFile *dpx,
+ LogImageElement logElement,
+ float *data);
static int logImageElementGetData16(LogImageFile *dpx, LogImageElement logElement, float *data);
-static int convertLogElementToRGBA(float *src, float *dst, LogImageFile *logImage, LogImageElement logElement, int dstIsLinearRGB);
-static int convertRGBAToLogElement(float *src, float *dst, LogImageFile *logImage, LogImageElement logElement, int srcIsLinearRGB);
-
+static int convertLogElementToRGBA(float *src,
+ float *dst,
+ LogImageFile *logImage,
+ LogImageElement logElement,
+ int dstIsLinearRGB);
+static int convertRGBAToLogElement(float *src,
+ float *dst,
+ LogImageFile *logImage,
+ LogImageElement logElement,
+ int srcIsLinearRGB);
/*
* For debug purpose
@@ -67,1409 +77,1569 @@ static int verbose = 0;
void logImageSetVerbose(int verbosity)
{
- verbose = verbosity;
- cineonSetVerbose(verbosity);
- dpxSetVerbose(verbosity);
+ verbose = verbosity;
+ cineonSetVerbose(verbosity);
+ dpxSetVerbose(verbosity);
}
-
/*
* IO stuff
*/
int logImageIsDpx(const void *buffer)
{
- unsigned int magicNum = *(unsigned int *)buffer;
- return (magicNum == DPX_FILE_MAGIC || magicNum == swap_uint(DPX_FILE_MAGIC, 1));
+ unsigned int magicNum = *(unsigned int *)buffer;
+ return (magicNum == DPX_FILE_MAGIC || magicNum == swap_uint(DPX_FILE_MAGIC, 1));
}
int logImageIsCineon(const void *buffer)
{
- unsigned int magicNum = *(unsigned int *)buffer;
- return (magicNum == CINEON_FILE_MAGIC || magicNum == swap_uint(CINEON_FILE_MAGIC, 1));
+ unsigned int magicNum = *(unsigned int *)buffer;
+ return (magicNum == CINEON_FILE_MAGIC || magicNum == swap_uint(CINEON_FILE_MAGIC, 1));
}
LogImageFile *logImageOpenFromFile(const char *filename, int cineon)
{
- unsigned int magicNum;
- FILE *f = BLI_fopen(filename, "rb");
+ unsigned int magicNum;
+ FILE *f = BLI_fopen(filename, "rb");
- (void)cineon;
+ (void)cineon;
- if (f == NULL)
- return NULL;
+ if (f == NULL)
+ return NULL;
- if (fread(&magicNum, sizeof(unsigned int), 1, f) != 1) {
- fclose(f);
- return NULL;
- }
+ if (fread(&magicNum, sizeof(unsigned int), 1, f) != 1) {
+ fclose(f);
+ return NULL;
+ }
- fclose(f);
+ fclose(f);
- if (logImageIsDpx(&magicNum))
- return dpxOpen((const unsigned char *)filename, 0, 0);
- else if (logImageIsCineon(&magicNum))
- return cineonOpen((const unsigned char *)filename, 0, 0);
+ if (logImageIsDpx(&magicNum))
+ return dpxOpen((const unsigned char *)filename, 0, 0);
+ else if (logImageIsCineon(&magicNum))
+ return cineonOpen((const unsigned char *)filename, 0, 0);
- return NULL;
+ return NULL;
}
LogImageFile *logImageOpenFromMemory(const unsigned char *buffer, unsigned int size)
{
- if (logImageIsDpx(buffer))
- return dpxOpen(buffer, 1, size);
- else if (logImageIsCineon(buffer))
- return cineonOpen(buffer, 1, size);
+ if (logImageIsDpx(buffer))
+ return dpxOpen(buffer, 1, size);
+ else if (logImageIsCineon(buffer))
+ return cineonOpen(buffer, 1, size);
- return NULL;
+ return NULL;
}
-LogImageFile *logImageCreate(const char *filename, int cineon, int width, int height, int bitsPerSample,
- int isLogarithmic, int hasAlpha, int referenceWhite, int referenceBlack,
- float gamma, const char *creator)
+LogImageFile *logImageCreate(const char *filename,
+ int cineon,
+ int width,
+ int height,
+ int bitsPerSample,
+ int isLogarithmic,
+ int hasAlpha,
+ int referenceWhite,
+ int referenceBlack,
+ float gamma,
+ const char *creator)
{
- /* referenceWhite, referenceBlack and gamma values are only supported for DPX file */
- if (cineon)
- return cineonCreate(filename, width, height, bitsPerSample, creator);
- else
- return dpxCreate(filename, width, height, bitsPerSample, isLogarithmic, hasAlpha,
- referenceWhite, referenceBlack, gamma, creator);
-
- return NULL;
+ /* referenceWhite, referenceBlack and gamma values are only supported for DPX file */
+ if (cineon)
+ return cineonCreate(filename, width, height, bitsPerSample, creator);
+ else
+ return dpxCreate(filename,
+ width,
+ height,
+ bitsPerSample,
+ isLogarithmic,
+ hasAlpha,
+ referenceWhite,
+ referenceBlack,
+ gamma,
+ creator);
+
+ return NULL;
}
void logImageClose(LogImageFile *logImage)
{
- if (logImage != NULL) {
- if (logImage->file) {
- fclose(logImage->file);
- logImage->file = NULL;
- }
- MEM_freeN(logImage);
- }
+ if (logImage != NULL) {
+ if (logImage->file) {
+ fclose(logImage->file);
+ logImage->file = NULL;
+ }
+ MEM_freeN(logImage);
+ }
}
void logImageGetSize(LogImageFile *logImage, int *width, int *height, int *depth)
{
- *width = logImage->width;
- *height = logImage->height;
- *depth = logImage->depth;
+ *width = logImage->width;
+ *height = logImage->height;
+ *depth = logImage->depth;
}
-
/*
* Helper
*/
size_t getRowLength(size_t width, LogImageElement logElement)
{
- /* return the row length in bytes according to width and packing method */
- switch (logElement.bitsPerSample) {
- case 1:
- return ((width * logElement.depth - 1) / 32 + 1) * 4;
-
- case 8:
- return ((width * logElement.depth - 1) / 4 + 1) * 4;
-
- case 10:
- if (logElement.packing == 0)
- return ((width * logElement.depth * 10 - 1) / 32 + 1) * 4;
- else if (logElement.packing == 1 || logElement.packing == 2)
- return ((width * logElement.depth - 1) / 3 + 1) * 4;
- break;
- case 12:
- if (logElement.packing == 0)
- return ((width * logElement.depth * 12 - 1) / 32 + 1) * 4;
- else if (logElement.packing == 1 || logElement.packing == 2)
- return width * logElement.depth * 2;
- break;
- case 16:
- return width * logElement.depth * 2;
-
- }
- return 0;
+ /* return the row length in bytes according to width and packing method */
+ switch (logElement.bitsPerSample) {
+ case 1:
+ return ((width * logElement.depth - 1) / 32 + 1) * 4;
+
+ case 8:
+ return ((width * logElement.depth - 1) / 4 + 1) * 4;
+
+ case 10:
+ if (logElement.packing == 0)
+ return ((width * logElement.depth * 10 - 1) / 32 + 1) * 4;
+ else if (logElement.packing == 1 || logElement.packing == 2)
+ return ((width * logElement.depth - 1) / 3 + 1) * 4;
+ break;
+ case 12:
+ if (logElement.packing == 0)
+ return ((width * logElement.depth * 12 - 1) / 32 + 1) * 4;
+ else if (logElement.packing == 1 || logElement.packing == 2)
+ return width * logElement.depth * 2;
+ break;
+ case 16:
+ return width * logElement.depth * 2;
+ }
+ return 0;
}
-
/*
* Data writing
*/
int logImageSetDataRGBA(LogImageFile *logImage, float *data, int dataIsLinearRGB)
{
- float *elementData;
- int returnValue;
-
- elementData = (float *)imb_alloc_pixels(logImage->width, logImage->height, logImage->depth, sizeof(float), __func__);
- if (elementData == NULL)
- return 1;
-
- if (convertRGBAToLogElement(data, elementData, logImage, logImage->element[0], dataIsLinearRGB) != 0) {
- MEM_freeN(elementData);
- return 1;
- }
-
- switch (logImage->element[0].bitsPerSample) {
- case 8:
- returnValue = logImageSetData8(logImage, logImage->element[0], elementData);
- break;
-
- case 10:
- returnValue = logImageSetData10(logImage, logImage->element[0], elementData);
- break;
-
- case 12:
- returnValue = logImageSetData12(logImage, logImage->element[0], elementData);
- break;
-
- case 16:
- returnValue = logImageSetData16(logImage, logImage->element[0], elementData);
- break;
-
- default:
- returnValue = 1;
- break;
- }
-
- MEM_freeN(elementData);
- return returnValue;
+ float *elementData;
+ int returnValue;
+
+ elementData = (float *)imb_alloc_pixels(
+ logImage->width, logImage->height, logImage->depth, sizeof(float), __func__);
+ if (elementData == NULL)
+ return 1;
+
+ if (convertRGBAToLogElement(
+ data, elementData, logImage, logImage->element[0], dataIsLinearRGB) != 0) {
+ MEM_freeN(elementData);
+ return 1;
+ }
+
+ switch (logImage->element[0].bitsPerSample) {
+ case 8:
+ returnValue = logImageSetData8(logImage, logImage->element[0], elementData);
+ break;
+
+ case 10:
+ returnValue = logImageSetData10(logImage, logImage->element[0], elementData);
+ break;
+
+ case 12:
+ returnValue = logImageSetData12(logImage, logImage->element[0], elementData);
+ break;
+
+ case 16:
+ returnValue = logImageSetData16(logImage, logImage->element[0], elementData);
+ break;
+
+ default:
+ returnValue = 1;
+ break;
+ }
+
+ MEM_freeN(elementData);
+ return returnValue;
}
static int logImageSetData8(LogImageFile *logImage, LogImageElement logElement, float *data)
{
- size_t rowLength = getRowLength(logImage->width, logElement);
- unsigned char *row;
-
- row = (unsigned char *)MEM_mallocN(rowLength, __func__);
- if (row == NULL) {
- if (verbose) printf("DPX/Cineon: Cannot allocate row.\n");
- return 1;
- }
- memset(row, 0, rowLength);
-
- for (size_t y = 0; y < logImage->height; y++) {
- for (size_t x = 0; x < logImage->width * logImage->depth; x++)
- row[x] = (unsigned char)float_uint(data[y * logImage->width * logImage->depth + x], 255);
-
- if (logimage_fwrite(row, rowLength, 1, logImage) == 0) {
- if (verbose) printf("DPX/Cineon: Error while writing file.\n");
- MEM_freeN(row);
- return 1;
- }
- }
- MEM_freeN(row);
- return 0;
+ size_t rowLength = getRowLength(logImage->width, logElement);
+ unsigned char *row;
+
+ row = (unsigned char *)MEM_mallocN(rowLength, __func__);
+ if (row == NULL) {
+ if (verbose)
+ printf("DPX/Cineon: Cannot allocate row.\n");
+ return 1;
+ }
+ memset(row, 0, rowLength);
+
+ for (size_t y = 0; y < logImage->height; y++) {
+ for (size_t x = 0; x < logImage->width * logImage->depth; x++)
+ row[x] = (unsigned char)float_uint(data[y * logImage->width * logImage->depth + x], 255);
+
+ if (logimage_fwrite(row, rowLength, 1, logImage) == 0) {
+ if (verbose)
+ printf("DPX/Cineon: Error while writing file.\n");
+ MEM_freeN(row);
+ return 1;
+ }
+ }
+ MEM_freeN(row);
+ return 0;
}
static int logImageSetData10(LogImageFile *logImage, LogImageElement logElement, float *data)
{
- size_t rowLength = getRowLength(logImage->width, logElement);
- unsigned int pixel, index;
- unsigned int *row;
-
- row = (unsigned int *)MEM_mallocN(rowLength, __func__);
- if (row == NULL) {
- if (verbose) printf("DPX/Cineon: Cannot allocate row.\n");
- return 1;
- }
-
- for (size_t y = 0; y < logImage->height; y++) {
- int offset = 22;
- index = 0;
- pixel = 0;
-
- for (size_t x = 0; x < logImage->width * logImage->depth; x++) {
- pixel |= (unsigned int)float_uint(data[y * logImage->width * logImage->depth + x], 1023) << offset;
- offset -= 10;
- if (offset < 0) {
- row[index] = swap_uint(pixel, logImage->isMSB);
- index++;
- pixel = 0;
- offset = 22;
- }
- }
- if (pixel != 0)
- row[index] = swap_uint(pixel, logImage->isMSB);
-
- if (logimage_fwrite(row, rowLength, 1, logImage) == 0) {
- if (verbose) {
- printf("DPX/Cineon: Error while writing file.\n");
- }
- MEM_freeN(row);
- return 1;
- }
- }
- MEM_freeN(row);
- return 0;
+ size_t rowLength = getRowLength(logImage->width, logElement);
+ unsigned int pixel, index;
+ unsigned int *row;
+
+ row = (unsigned int *)MEM_mallocN(rowLength, __func__);
+ if (row == NULL) {
+ if (verbose)
+ printf("DPX/Cineon: Cannot allocate row.\n");
+ return 1;
+ }
+
+ for (size_t y = 0; y < logImage->height; y++) {
+ int offset = 22;
+ index = 0;
+ pixel = 0;
+
+ for (size_t x = 0; x < logImage->width * logImage->depth; x++) {
+ pixel |= (unsigned int)float_uint(data[y * logImage->width * logImage->depth + x], 1023)
+ << offset;
+ offset -= 10;
+ if (offset < 0) {
+ row[index] = swap_uint(pixel, logImage->isMSB);
+ index++;
+ pixel = 0;
+ offset = 22;
+ }
+ }
+ if (pixel != 0)
+ row[index] = swap_uint(pixel, logImage->isMSB);
+
+ if (logimage_fwrite(row, rowLength, 1, logImage) == 0) {
+ if (verbose) {
+ printf("DPX/Cineon: Error while writing file.\n");
+ }
+ MEM_freeN(row);
+ return 1;
+ }
+ }
+ MEM_freeN(row);
+ return 0;
}
static int logImageSetData12(LogImageFile *logImage, LogImageElement logElement, float *data)
{
- size_t rowLength = getRowLength(logImage->width, logElement);
- unsigned short *row;
-
- row = (unsigned short *)MEM_mallocN(rowLength, __func__);
- if (row == NULL) {
- if (verbose) printf("DPX/Cineon: Cannot allocate row.\n");
- return 1;
- }
-
- for (size_t y = 0; y < logImage->height; y++) {
- for (size_t x = 0; x < logImage->width * logImage->depth; x++)
- row[x] = swap_ushort(((unsigned short)float_uint(data[y * logImage->width * logImage->depth + x], 4095)) << 4, logImage->isMSB);
-
- if (logimage_fwrite(row, rowLength, 1, logImage) == 0) {
- if (verbose) printf("DPX/Cineon: Error while writing file.\n");
- MEM_freeN(row);
- return 1;
- }
- }
- MEM_freeN(row);
- return 0;
+ size_t rowLength = getRowLength(logImage->width, logElement);
+ unsigned short *row;
+
+ row = (unsigned short *)MEM_mallocN(rowLength, __func__);
+ if (row == NULL) {
+ if (verbose)
+ printf("DPX/Cineon: Cannot allocate row.\n");
+ return 1;
+ }
+
+ for (size_t y = 0; y < logImage->height; y++) {
+ for (size_t x = 0; x < logImage->width * logImage->depth; x++)
+ row[x] = swap_ushort(
+ ((unsigned short)float_uint(data[y * logImage->width * logImage->depth + x], 4095)) << 4,
+ logImage->isMSB);
+
+ if (logimage_fwrite(row, rowLength, 1, logImage) == 0) {
+ if (verbose)
+ printf("DPX/Cineon: Error while writing file.\n");
+ MEM_freeN(row);
+ return 1;
+ }
+ }
+ MEM_freeN(row);
+ return 0;
}
static int logImageSetData16(LogImageFile *logImage, LogImageElement logElement, float *data)
{
- size_t rowLength = getRowLength(logImage->width, logElement);
- unsigned short *row;
-
- row = (unsigned short *)MEM_mallocN(rowLength, __func__);
- if (row == NULL) {
- if (verbose) printf("DPX/Cineon: Cannot allocate row.\n");
- return 1;
- }
-
- for (size_t y = 0; y < logImage->height; y++) {
- for (size_t x = 0; x < logImage->width * logImage->depth; x++)
- row[x] = swap_ushort((unsigned short)float_uint(data[y * logImage->width * logImage->depth + x], 65535), logImage->isMSB);
-
- if (logimage_fwrite(row, rowLength, 1, logImage) == 0) {
- if (verbose) printf("DPX/Cineon: Error while writing file.\n");
- MEM_freeN(row);
- return 1;
- }
- }
- MEM_freeN(row);
- return 0;
+ size_t rowLength = getRowLength(logImage->width, logElement);
+ unsigned short *row;
+
+ row = (unsigned short *)MEM_mallocN(rowLength, __func__);
+ if (row == NULL) {
+ if (verbose)
+ printf("DPX/Cineon: Cannot allocate row.\n");
+ return 1;
+ }
+
+ for (size_t y = 0; y < logImage->height; y++) {
+ for (size_t x = 0; x < logImage->width * logImage->depth; x++)
+ row[x] = swap_ushort(
+ (unsigned short)float_uint(data[y * logImage->width * logImage->depth + x], 65535),
+ logImage->isMSB);
+
+ if (logimage_fwrite(row, rowLength, 1, logImage) == 0) {
+ if (verbose)
+ printf("DPX/Cineon: Error while writing file.\n");
+ MEM_freeN(row);
+ return 1;
+ }
+ }
+ MEM_freeN(row);
+ return 0;
}
-
/*
* Data reading
*/
int logImageGetDataRGBA(LogImageFile *logImage, float *data, int dataIsLinearRGB)
{
- /* Fills data with 32 bits float RGBA values */
- int i, j, returnValue, sortedElementData[8], hasAlpha;
- float *elementData[8];
- float *elementData_ptr[8];
- float *mergedData;
- unsigned int sampleIndex;
- LogImageElement mergedElement;
-
- /* Determine the depth of the picture and if there's a separate alpha element.
- * If the element is supported, load it into an unsigned ints array. */
- memset(&elementData, 0, 8 * sizeof(float *));
- hasAlpha = 0;
-
- for (i = 0; i < logImage->numElements; i++) {
- /* descriptor_Depth and descriptor_Composite are not supported */
- if (logImage->element[i].descriptor != descriptor_Depth && logImage->element[i].descriptor != descriptor_Composite) {
- /* Allocate memory */
- elementData[i] = imb_alloc_pixels(logImage->width, logImage->height, logImage->element[i].depth, sizeof(float), __func__);
- if (elementData[i] == NULL) {
- if (verbose) printf("DPX/Cineon: Cannot allocate memory for elementData[%d]\n.", i);
- for (j = 0; j < i; j++)
- if (elementData[j] != NULL)
- MEM_freeN(elementData[j]);
- return 1;
- }
- elementData_ptr[i] = elementData[i];
-
- /* Load data */
- if (logImageElementGetData(logImage, logImage->element[i], elementData[i]) != 0) {
- if (verbose) printf("DPX/Cineon: Cannot read elementData[%d]\n.", i);
- for (j = 0; j < i; j++)
- if (elementData[j] != NULL)
- MEM_freeN(elementData[j]);
- return 1;
- }
- }
-
- if (logImage->element[i].descriptor == descriptor_Alpha)
- hasAlpha = 1;
- }
-
- /* only one element, easy case, no need to do anything */
- if (logImage->numElements == 1) {
- returnValue = convertLogElementToRGBA(elementData[0], data, logImage, logImage->element[0], dataIsLinearRGB);
- MEM_freeN(elementData[0]);
- }
- else {
- /* The goal here is to merge every elements into only one
- * to recreate a classic 16 bits RGB, RGBA or YCbCr element.
- * Unsupported elements are skipped (depth, composite) */
-
- memcpy(&mergedElement, &logImage->element[0], sizeof(LogImageElement));
- mergedElement.descriptor = -1;
- mergedElement.depth = logImage->depth;
- memset(&sortedElementData, -1, 8 * sizeof(int));
-
- /* Try to know how to assemble the elements */
- for (i = 0; i < logImage->numElements; i++) {
- switch (logImage->element[i].descriptor) {
- case descriptor_Red:
- case descriptor_RGB:
- if (hasAlpha == 0)
- mergedElement.descriptor = descriptor_RGB;
- else
- mergedElement.descriptor = descriptor_RGBA;
-
- sortedElementData[0] = i;
- break;
-
- case descriptor_Green:
- if (hasAlpha == 0)
- mergedElement.descriptor = descriptor_RGB;
- else
- mergedElement.descriptor = descriptor_RGBA;
-
- sortedElementData[1] = i;
- break;
-
- case descriptor_Blue:
- if (hasAlpha == 0)
- mergedElement.descriptor = descriptor_RGB;
- else
- mergedElement.descriptor = descriptor_RGBA;
-
- sortedElementData[2] = i;
- break;
-
- case descriptor_Alpha:
- /* Alpha component is always the last one */
- sortedElementData[mergedElement.depth - 1] = i;
- break;
-
- case descriptor_Luminance:
- if (mergedElement.descriptor == -1)
- if (hasAlpha == 0)
- mergedElement.descriptor = descriptor_Luminance;
- else
- mergedElement.descriptor = descriptor_YA;
- else if (mergedElement.descriptor == descriptor_Chrominance) {
- if (mergedElement.depth == 2)
- mergedElement.descriptor = descriptor_CbYCrY;
- else if (mergedElement.depth == 3)
- if (hasAlpha == 0)
- mergedElement.descriptor = descriptor_CbYCr;
- else
- mergedElement.descriptor = descriptor_CbYACrYA;
- else if (mergedElement.depth == 4)
- mergedElement.descriptor = descriptor_CbYCrA;
- }
-
- /* Y component always in 1 except if it's alone or with alpha */
- if (mergedElement.depth == 1 || (mergedElement.depth == 2 && hasAlpha == 1))
- sortedElementData[0] = i;
- else
- sortedElementData[1] = i;
- break;
-
- case descriptor_Chrominance:
- if (mergedElement.descriptor == -1)
- mergedElement.descriptor = descriptor_Chrominance;
- else if (mergedElement.descriptor == descriptor_Luminance) {
- if (mergedElement.depth == 2)
- mergedElement.descriptor = descriptor_CbYCrY;
- else if (mergedElement.depth == 3)
- if (hasAlpha == 0)
- mergedElement.descriptor = descriptor_CbYCr;
- else
- mergedElement.descriptor = descriptor_CbYACrYA;
- else if (mergedElement.depth == 4)
- mergedElement.descriptor = descriptor_CbYCrA;
- }
-
- /* Cb and Cr always in 0 or 2 */
- if (sortedElementData[0] == -1)
- sortedElementData[0] = i;
- else
- sortedElementData[2] = i;
- break;
-
- case descriptor_CbYCr:
- if (hasAlpha == 0)
- mergedElement.descriptor = descriptor_CbYCr;
- else
- mergedElement.descriptor = descriptor_CbYCrA;
-
- sortedElementData[0] = i;
- break;
-
- case descriptor_RGBA:
- case descriptor_ABGR:
- case descriptor_CbYACrYA:
- case descriptor_CbYCrY:
- case descriptor_CbYCrA:
- /* I don't think these ones can be seen in a planar image */
- mergedElement.descriptor = logImage->element[i].descriptor;
- sortedElementData[0] = i;
- break;
-
- case descriptor_Depth:
- case descriptor_Composite:
- /* Not supported */
- break;
- }
- }
-
- mergedData = (float *)imb_alloc_pixels(logImage->width, logImage->height, mergedElement.depth, sizeof(float), __func__);
- if (mergedData == NULL) {
- if (verbose) printf("DPX/Cineon: Cannot allocate mergedData.\n");
- for (i = 0; i < logImage->numElements; i++)
- if (elementData[i] != NULL)
- MEM_freeN(elementData[i]);
- return 1;
- }
-
- sampleIndex = 0;
- while (sampleIndex < logImage->width * logImage->height * mergedElement.depth) {
- for (i = 0; i < logImage->numElements; i++)
- for (j = 0; j < logImage->element[sortedElementData[i]].depth; j++)
- mergedData[sampleIndex++] = *(elementData_ptr[sortedElementData[i]]++);
- }
-
- /* Done with elements data, clean-up */
- for (i = 0; i < logImage->numElements; i++)
- if (elementData[i] != NULL)
- MEM_freeN(elementData[i]);
-
- returnValue = convertLogElementToRGBA(mergedData, data, logImage, mergedElement, dataIsLinearRGB);
- MEM_freeN(mergedData);
- }
- return returnValue;
+ /* Fills data with 32 bits float RGBA values */
+ int i, j, returnValue, sortedElementData[8], hasAlpha;
+ float *elementData[8];
+ float *elementData_ptr[8];
+ float *mergedData;
+ unsigned int sampleIndex;
+ LogImageElement mergedElement;
+
+ /* Determine the depth of the picture and if there's a separate alpha element.
+ * If the element is supported, load it into an unsigned ints array. */
+ memset(&elementData, 0, 8 * sizeof(float *));
+ hasAlpha = 0;
+
+ for (i = 0; i < logImage->numElements; i++) {
+ /* descriptor_Depth and descriptor_Composite are not supported */
+ if (logImage->element[i].descriptor != descriptor_Depth &&
+ logImage->element[i].descriptor != descriptor_Composite) {
+ /* Allocate memory */
+ elementData[i] = imb_alloc_pixels(
+ logImage->width, logImage->height, logImage->element[i].depth, sizeof(float), __func__);
+ if (elementData[i] == NULL) {
+ if (verbose)
+ printf("DPX/Cineon: Cannot allocate memory for elementData[%d]\n.", i);
+ for (j = 0; j < i; j++)
+ if (elementData[j] != NULL)
+ MEM_freeN(elementData[j]);
+ return 1;
+ }
+ elementData_ptr[i] = elementData[i];
+
+ /* Load data */
+ if (logImageElementGetData(logImage, logImage->element[i], elementData[i]) != 0) {
+ if (verbose)
+ printf("DPX/Cineon: Cannot read elementData[%d]\n.", i);
+ for (j = 0; j < i; j++)
+ if (elementData[j] != NULL)
+ MEM_freeN(elementData[j]);
+ return 1;
+ }
+ }
+
+ if (logImage->element[i].descriptor == descriptor_Alpha)
+ hasAlpha = 1;
+ }
+
+ /* only one element, easy case, no need to do anything */
+ if (logImage->numElements == 1) {
+ returnValue = convertLogElementToRGBA(
+ elementData[0], data, logImage, logImage->element[0], dataIsLinearRGB);
+ MEM_freeN(elementData[0]);
+ }
+ else {
+ /* The goal here is to merge every elements into only one
+ * to recreate a classic 16 bits RGB, RGBA or YCbCr element.
+ * Unsupported elements are skipped (depth, composite) */
+
+ memcpy(&mergedElement, &logImage->element[0], sizeof(LogImageElement));
+ mergedElement.descriptor = -1;
+ mergedElement.depth = logImage->depth;
+ memset(&sortedElementData, -1, 8 * sizeof(int));
+
+ /* Try to know how to assemble the elements */
+ for (i = 0; i < logImage->numElements; i++) {
+ switch (logImage->element[i].descriptor) {
+ case descriptor_Red:
+ case descriptor_RGB:
+ if (hasAlpha == 0)
+ mergedElement.descriptor = descriptor_RGB;
+ else
+ mergedElement.descriptor = descriptor_RGBA;
+
+ sortedElementData[0] = i;
+ break;
+
+ case descriptor_Green:
+ if (hasAlpha == 0)
+ mergedElement.descriptor = descriptor_RGB;
+ else
+ mergedElement.descriptor = descriptor_RGBA;
+
+ sortedElementData[1] = i;
+ break;
+
+ case descriptor_Blue:
+ if (hasAlpha == 0)
+ mergedElement.descriptor = descriptor_RGB;
+ else
+ mergedElement.descriptor = descriptor_RGBA;
+
+ sortedElementData[2] = i;
+ break;
+
+ case descriptor_Alpha:
+ /* Alpha component is always the last one */
+ sortedElementData[mergedElement.depth - 1] = i;
+ break;
+
+ case descriptor_Luminance:
+ if (mergedElement.descriptor == -1)
+ if (hasAlpha == 0)
+ mergedElement.descriptor = descriptor_Luminance;
+ else
+ mergedElement.descriptor = descriptor_YA;
+ else if (mergedElement.descriptor == descriptor_Chrominance) {
+ if (mergedElement.depth == 2)
+ mergedElement.descriptor = descriptor_CbYCrY;
+ else if (mergedElement.depth == 3)
+ if (hasAlpha == 0)
+ mergedElement.descriptor = descriptor_CbYCr;
+ else
+ mergedElement.descriptor = descriptor_CbYACrYA;
+ else if (mergedElement.depth == 4)
+ mergedElement.descriptor = descriptor_CbYCrA;
+ }
+
+ /* Y component always in 1 except if it's alone or with alpha */
+ if (mergedElement.depth == 1 || (mergedElement.depth == 2 && hasAlpha == 1))
+ sortedElementData[0] = i;
+ else
+ sortedElementData[1] = i;
+ break;
+
+ case descriptor_Chrominance:
+ if (mergedElement.descriptor == -1)
+ mergedElement.descriptor = descriptor_Chrominance;
+ else if (mergedElement.descriptor == descriptor_Luminance) {
+ if (mergedElement.depth == 2)
+ mergedElement.descriptor = descriptor_CbYCrY;
+ else if (mergedElement.depth == 3)
+ if (hasAlpha == 0)
+ mergedElement.descriptor = descriptor_CbYCr;
+ else
+ mergedElement.descriptor = descriptor_CbYACrYA;
+ else if (mergedElement.depth == 4)
+ mergedElement.descriptor = descriptor_CbYCrA;
+ }
+
+ /* Cb and Cr always in 0 or 2 */
+ if (sortedElementData[0] == -1)
+ sortedElementData[0] = i;
+ else
+ sortedElementData[2] = i;
+ break;
+
+ case descriptor_CbYCr:
+ if (hasAlpha == 0)
+ mergedElement.descriptor = descriptor_CbYCr;
+ else
+ mergedElement.descriptor = descriptor_CbYCrA;
+
+ sortedElementData[0] = i;
+ break;
+
+ case descriptor_RGBA:
+ case descriptor_ABGR:
+ case descriptor_CbYACrYA:
+ case descriptor_CbYCrY:
+ case descriptor_CbYCrA:
+ /* I don't think these ones can be seen in a planar image */
+ mergedElement.descriptor = logImage->element[i].descriptor;
+ sortedElementData[0] = i;
+ break;
+
+ case descriptor_Depth:
+ case descriptor_Composite:
+ /* Not supported */
+ break;
+ }
+ }
+
+ mergedData = (float *)imb_alloc_pixels(
+ logImage->width, logImage->height, mergedElement.depth, sizeof(float), __func__);
+ if (mergedData == NULL) {
+ if (verbose)
+ printf("DPX/Cineon: Cannot allocate mergedData.\n");
+ for (i = 0; i < logImage->numElements; i++)
+ if (elementData[i] != NULL)
+ MEM_freeN(elementData[i]);
+ return 1;
+ }
+
+ sampleIndex = 0;
+ while (sampleIndex < logImage->width * logImage->height * mergedElement.depth) {
+ for (i = 0; i < logImage->numElements; i++)
+ for (j = 0; j < logImage->element[sortedElementData[i]].depth; j++)
+ mergedData[sampleIndex++] = *(elementData_ptr[sortedElementData[i]]++);
+ }
+
+ /* Done with elements data, clean-up */
+ for (i = 0; i < logImage->numElements; i++)
+ if (elementData[i] != NULL)
+ MEM_freeN(elementData[i]);
+
+ returnValue = convertLogElementToRGBA(
+ mergedData, data, logImage, mergedElement, dataIsLinearRGB);
+ MEM_freeN(mergedData);
+ }
+ return returnValue;
}
static int logImageElementGetData(LogImageFile *logImage, LogImageElement logElement, float *data)
{
- switch (logElement.bitsPerSample) {
- case 1:
- return logImageElementGetData1(logImage, logElement, data);
-
- case 8:
- return logImageElementGetData8(logImage, logElement, data);
-
- case 10:
- if (logElement.packing == 0)
- return logImageElementGetData10Packed(logImage, logElement, data);
- else if (logElement.packing == 1 || logElement.packing == 2)
- return logImageElementGetData10(logImage, logElement, data);
- break;
-
- case 12:
- if (logElement.packing == 0)
- return logImageElementGetData12Packed(logImage, logElement, data);
- else if (logElement.packing == 1 || logElement.packing == 2)
- return logImageElementGetData12(logImage, logElement, data);
- break;
-
- case 16:
- return logImageElementGetData16(logImage, logElement, data);
- }
- /* format not supported */
- return 1;
+ switch (logElement.bitsPerSample) {
+ case 1:
+ return logImageElementGetData1(logImage, logElement, data);
+
+ case 8:
+ return logImageElementGetData8(logImage, logElement, data);
+
+ case 10:
+ if (logElement.packing == 0)
+ return logImageElementGetData10Packed(logImage, logElement, data);
+ else if (logElement.packing == 1 || logElement.packing == 2)
+ return logImageElementGetData10(logImage, logElement, data);
+ break;
+
+ case 12:
+ if (logElement.packing == 0)
+ return logImageElementGetData12Packed(logImage, logElement, data);
+ else if (logElement.packing == 1 || logElement.packing == 2)
+ return logImageElementGetData12(logImage, logElement, data);
+ break;
+
+ case 16:
+ return logImageElementGetData16(logImage, logElement, data);
+ }
+ /* format not supported */
+ return 1;
}
static int logImageElementGetData1(LogImageFile *logImage, LogImageElement logElement, float *data)
{
- unsigned int pixel;
-
- /* seek at the right place */
- if (logimage_fseek(logImage, logElement.dataOffset, SEEK_SET) != 0) {
- if (verbose) printf("DPX/Cineon: Couldn't seek at %d\n", logElement.dataOffset);
- return 1;
- }
-
- /* read 1 bit data padded to 32 bits */
- for (size_t y = 0; y < logImage->height; y++) {
- for (size_t x = 0; x < logImage->width * logElement.depth; x += 32) {
- if (logimage_read_uint(&pixel, logImage) != 0) {
- if (verbose) printf("DPX/Cineon: EOF reached\n");
- return 1;
- }
- pixel = swap_uint(pixel, logImage->isMSB);
- for (int offset = 0; offset < 32 && x + offset < logImage->width; offset++)
- data[y * logImage->width * logElement.depth + x + offset] = (float)((pixel >> offset) & 0x01);
- }
- }
- return 0;
+ unsigned int pixel;
+
+ /* seek at the right place */
+ if (logimage_fseek(logImage, logElement.dataOffset, SEEK_SET) != 0) {
+ if (verbose)
+ printf("DPX/Cineon: Couldn't seek at %d\n", logElement.dataOffset);
+ return 1;
+ }
+
+ /* read 1 bit data padded to 32 bits */
+ for (size_t y = 0; y < logImage->height; y++) {
+ for (size_t x = 0; x < logImage->width * logElement.depth; x += 32) {
+ if (logimage_read_uint(&pixel, logImage) != 0) {
+ if (verbose)
+ printf("DPX/Cineon: EOF reached\n");
+ return 1;
+ }
+ pixel = swap_uint(pixel, logImage->isMSB);
+ for (int offset = 0; offset < 32 && x + offset < logImage->width; offset++)
+ data[y * logImage->width * logElement.depth + x + offset] = (float)((pixel >> offset) &
+ 0x01);
+ }
+ }
+ return 0;
}
static int logImageElementGetData8(LogImageFile *logImage, LogImageElement logElement, float *data)
{
- size_t rowLength = getRowLength(logImage->width, logElement);
- unsigned char pixel;
-
- /* extract required pixels */
- for (size_t y = 0; y < logImage->height; y++) {
- /* 8 bits are 32-bits padded so we need to seek at each row */
- if (logimage_fseek(logImage, logElement.dataOffset + y * rowLength, SEEK_SET) != 0) {
- if (verbose) printf("DPX/Cineon: Couldn't seek at %d\n", (int)(logElement.dataOffset + y * rowLength));
- return 1;
- }
-
- for (size_t x = 0; x < logImage->width * logElement.depth; x++) {
- if (logimage_read_uchar(&pixel, logImage) != 0) {
- if (verbose) printf("DPX/Cineon: EOF reached\n");
- return 1;
- }
- data[y * logImage->width * logElement.depth + x] = (float)pixel / 255.0f;
- }
- }
- return 0;
+ size_t rowLength = getRowLength(logImage->width, logElement);
+ unsigned char pixel;
+
+ /* extract required pixels */
+ for (size_t y = 0; y < logImage->height; y++) {
+ /* 8 bits are 32-bits padded so we need to seek at each row */
+ if (logimage_fseek(logImage, logElement.dataOffset + y * rowLength, SEEK_SET) != 0) {
+ if (verbose)
+ printf("DPX/Cineon: Couldn't seek at %d\n", (int)(logElement.dataOffset + y * rowLength));
+ return 1;
+ }
+
+ for (size_t x = 0; x < logImage->width * logElement.depth; x++) {
+ if (logimage_read_uchar(&pixel, logImage) != 0) {
+ if (verbose)
+ printf("DPX/Cineon: EOF reached\n");
+ return 1;
+ }
+ data[y * logImage->width * logElement.depth + x] = (float)pixel / 255.0f;
+ }
+ }
+ return 0;
}
-static int logImageElementGetData10(LogImageFile *logImage, LogImageElement logElement, float *data)
+static int logImageElementGetData10(LogImageFile *logImage,
+ LogImageElement logElement,
+ float *data)
{
- unsigned int pixel;
-
- /* seek to data */
- if (logimage_fseek(logImage, logElement.dataOffset, SEEK_SET) != 0) {
- if (verbose) printf("DPX/Cineon: Couldn't seek at %d\n", logElement.dataOffset);
- return 1;
- }
-
- if (logImage->depth == 1 && logImage->srcFormat == format_DPX) {
- for (size_t y = 0; y < logImage->height; y++) {
- int offset = 32;
- for (size_t x = 0; x < logImage->width * logElement.depth; x++) {
- /* we need to read the next long */
- if (offset >= 30) {
- if (logElement.packing == 1)
- offset = 2;
- else if (logElement.packing == 2)
- offset = 0;
-
- if (logimage_read_uint(&pixel, logImage) != 0) {
- if (verbose) printf("DPX/Cineon: EOF reached\n");
- return 1;
- }
- pixel = swap_uint(pixel, logImage->isMSB);
- }
- data[y * logImage->width * logElement.depth + x] = (float)((pixel >> offset) & 0x3ff) / 1023.0f;
- offset += 10;
- }
- }
- }
- else {
- for (size_t y = 0; y < logImage->height; y++) {
- int offset = -1;
- for (size_t x = 0; x < logImage->width * logElement.depth; x++) {
- /* we need to read the next long */
- if (offset < 0) {
- if (logElement.packing == 1)
- offset = 22;
- else if (logElement.packing == 2)
- offset = 20;
-
- if (logimage_read_uint(&pixel, logImage) != 0) {
- if (verbose) printf("DPX/Cineon: EOF reached\n");
- return 1;
- }
- pixel = swap_uint(pixel, logImage->isMSB);
- }
- data[y * logImage->width * logElement.depth + x] = (float)((pixel >> offset) & 0x3ff) / 1023.0f;
- offset -= 10;
- }
- }
- }
-
- return 0;
+ unsigned int pixel;
+
+ /* seek to data */
+ if (logimage_fseek(logImage, logElement.dataOffset, SEEK_SET) != 0) {
+ if (verbose)
+ printf("DPX/Cineon: Couldn't seek at %d\n", logElement.dataOffset);
+ return 1;
+ }
+
+ if (logImage->depth == 1 && logImage->srcFormat == format_DPX) {
+ for (size_t y = 0; y < logImage->height; y++) {
+ int offset = 32;
+ for (size_t x = 0; x < logImage->width * logElement.depth; x++) {
+ /* we need to read the next long */
+ if (offset >= 30) {
+ if (logElement.packing == 1)
+ offset = 2;
+ else if (logElement.packing == 2)
+ offset = 0;
+
+ if (logimage_read_uint(&pixel, logImage) != 0) {
+ if (verbose)
+ printf("DPX/Cineon: EOF reached\n");
+ return 1;
+ }
+ pixel = swap_uint(pixel, logImage->isMSB);
+ }
+ data[y * logImage->width * logElement.depth + x] = (float)((pixel >> offset) & 0x3ff) /
+ 1023.0f;
+ offset += 10;
+ }
+ }
+ }
+ else {
+ for (size_t y = 0; y < logImage->height; y++) {
+ int offset = -1;
+ for (size_t x = 0; x < logImage->width * logElement.depth; x++) {
+ /* we need to read the next long */
+ if (offset < 0) {
+ if (logElement.packing == 1)
+ offset = 22;
+ else if (logElement.packing == 2)
+ offset = 20;
+
+ if (logimage_read_uint(&pixel, logImage) != 0) {
+ if (verbose)
+ printf("DPX/Cineon: EOF reached\n");
+ return 1;
+ }
+ pixel = swap_uint(pixel, logImage->isMSB);
+ }
+ data[y * logImage->width * logElement.depth + x] = (float)((pixel >> offset) & 0x3ff) /
+ 1023.0f;
+ offset -= 10;
+ }
+ }
+ }
+
+ return 0;
}
-static int logImageElementGetData10Packed(LogImageFile *logImage, LogImageElement logElement, float *data)
+static int logImageElementGetData10Packed(LogImageFile *logImage,
+ LogImageElement logElement,
+ float *data)
{
- size_t rowLength = getRowLength(logImage->width, logElement);
- unsigned int pixel, oldPixel;
-
- /* converting bytes to pixels */
- for (size_t y = 0; y < logImage->height; y++) {
- /* seek to data */
- if (logimage_fseek(logImage, y * rowLength + logElement.dataOffset, SEEK_SET) != 0) {
- if (verbose) printf("DPX/Cineon: Couldn't seek at %u\n", (unsigned int)(y * rowLength + logElement.dataOffset));
- return 1;
- }
-
- oldPixel = 0;
- int offset = 0;
- int offset2 = 0;
-
- for (size_t x = 0; x < logImage->width * logElement.depth; x++) {
- if (offset2 != 0) {
- offset = 10 - offset2;
- offset2 = 0;
- oldPixel = 0;
- }
- else if (offset == 32) {
- offset = 0;
- }
- else if (offset + 10 > 32) {
- /* next pixel is on two different longs */
- oldPixel = (pixel >> offset);
- offset2 = 32 - offset;
- offset = 0;
- }
-
- if (offset == 0) {
- /* we need to read the next long */
- if (logimage_read_uint(&pixel, logImage) != 0) {
- if (verbose) printf("DPX/Cineon: EOF reached\n");
- return 1;
- }
- pixel = swap_uint(pixel, logImage->isMSB);
- }
- data[y * logImage->width * logElement.depth + x] = (float)((((pixel << offset2) >> offset) & 0x3ff) | oldPixel) / 1023.0f;
- offset += 10;
- }
- }
- return 0;
+ size_t rowLength = getRowLength(logImage->width, logElement);
+ unsigned int pixel, oldPixel;
+
+ /* converting bytes to pixels */
+ for (size_t y = 0; y < logImage->height; y++) {
+ /* seek to data */
+ if (logimage_fseek(logImage, y * rowLength + logElement.dataOffset, SEEK_SET) != 0) {
+ if (verbose)
+ printf("DPX/Cineon: Couldn't seek at %u\n",
+ (unsigned int)(y * rowLength + logElement.dataOffset));
+ return 1;
+ }
+
+ oldPixel = 0;
+ int offset = 0;
+ int offset2 = 0;
+
+ for (size_t x = 0; x < logImage->width * logElement.depth; x++) {
+ if (offset2 != 0) {
+ offset = 10 - offset2;
+ offset2 = 0;
+ oldPixel = 0;
+ }
+ else if (offset == 32) {
+ offset = 0;
+ }
+ else if (offset + 10 > 32) {
+ /* next pixel is on two different longs */
+ oldPixel = (pixel >> offset);
+ offset2 = 32 - offset;
+ offset = 0;
+ }
+
+ if (offset == 0) {
+ /* we need to read the next long */
+ if (logimage_read_uint(&pixel, logImage) != 0) {
+ if (verbose)
+ printf("DPX/Cineon: EOF reached\n");
+ return 1;
+ }
+ pixel = swap_uint(pixel, logImage->isMSB);
+ }
+ data[y * logImage->width * logElement.depth + x] =
+ (float)((((pixel << offset2) >> offset) & 0x3ff) | oldPixel) / 1023.0f;
+ offset += 10;
+ }
+ }
+ return 0;
}
-static int logImageElementGetData12(LogImageFile *logImage, LogImageElement logElement, float *data)
+static int logImageElementGetData12(LogImageFile *logImage,
+ LogImageElement logElement,
+ float *data)
{
- unsigned int sampleIndex;
- unsigned int numSamples = logImage->width * logImage->height * logElement.depth;
- unsigned short pixel;
-
- /* seek to data */
- if (logimage_fseek(logImage, logElement.dataOffset, SEEK_SET) != 0) {
- if (verbose) printf("DPX/Cineon: Couldn't seek at %d\n", logElement.dataOffset);
- return 1;
- }
-
- /* convert bytes to pixels */
- sampleIndex = 0;
-
- for (sampleIndex = 0; sampleIndex < numSamples; sampleIndex++) {
- if (logimage_read_ushort(&pixel, logImage) != 0) {
- if (verbose) printf("DPX/Cineon: EOF reached\n");
- return 1;
- }
- pixel = swap_ushort(pixel, logImage->isMSB);
-
- if (logElement.packing == 1) /* padded to the right */
- data[sampleIndex] = (float)(pixel >> 4) / 4095.0f;
- else if (logElement.packing == 2) /* padded to the left */
- data[sampleIndex] = (float)pixel / 4095.0f;
- }
- return 0;
+ unsigned int sampleIndex;
+ unsigned int numSamples = logImage->width * logImage->height * logElement.depth;
+ unsigned short pixel;
+
+ /* seek to data */
+ if (logimage_fseek(logImage, logElement.dataOffset, SEEK_SET) != 0) {
+ if (verbose)
+ printf("DPX/Cineon: Couldn't seek at %d\n", logElement.dataOffset);
+ return 1;
+ }
+
+ /* convert bytes to pixels */
+ sampleIndex = 0;
+
+ for (sampleIndex = 0; sampleIndex < numSamples; sampleIndex++) {
+ if (logimage_read_ushort(&pixel, logImage) != 0) {
+ if (verbose)
+ printf("DPX/Cineon: EOF reached\n");
+ return 1;
+ }
+ pixel = swap_ushort(pixel, logImage->isMSB);
+
+ if (logElement.packing == 1) /* padded to the right */
+ data[sampleIndex] = (float)(pixel >> 4) / 4095.0f;
+ else if (logElement.packing == 2) /* padded to the left */
+ data[sampleIndex] = (float)pixel / 4095.0f;
+ }
+ return 0;
}
-static int logImageElementGetData12Packed(LogImageFile *logImage, LogImageElement logElement, float *data)
+static int logImageElementGetData12Packed(LogImageFile *logImage,
+ LogImageElement logElement,
+ float *data)
{
- size_t rowLength = getRowLength(logImage->width, logElement);
- unsigned int pixel, oldPixel;
-
- /* converting bytes to pixels */
- for (size_t y = 0; y < logImage->height; y++) {
- /* seek to data */
- if (logimage_fseek(logImage, y * rowLength + logElement.dataOffset, SEEK_SET) != 0) {
- if (verbose) printf("DPX/Cineon: Couldn't seek at %u\n", (unsigned int)(y * rowLength + logElement.dataOffset));
- return 1;
- }
-
- oldPixel = 0;
- int offset = 0;
- int offset2 = 0;
-
- for (size_t x = 0; x < logImage->width * logElement.depth; x++) {
- if (offset2 != 0) {
- offset = 12 - offset2;
- offset2 = 0;
- oldPixel = 0;
- }
- else if (offset == 32) {
- offset = 0;
- }
- else if (offset + 12 > 32) {
- /* next pixel is on two different longs */
- oldPixel = (pixel >> offset);
- offset2 = 32 - offset;
- offset = 0;
- }
-
- if (offset == 0) {
- /* we need to read the next long */
- if (logimage_read_uint(&pixel, logImage) != 0) {
- if (verbose) printf("DPX/Cineon: EOF reached\n");
- return 1;
- }
- pixel = swap_uint(pixel, logImage->isMSB);
- }
- data[y * logImage->width * logElement.depth + x] = (float)((((pixel << offset2) >> offset) & 0xfff) | oldPixel) / 4095.0f;
- offset += 12;
- }
- }
- return 0;
+ size_t rowLength = getRowLength(logImage->width, logElement);
+ unsigned int pixel, oldPixel;
+
+ /* converting bytes to pixels */
+ for (size_t y = 0; y < logImage->height; y++) {
+ /* seek to data */
+ if (logimage_fseek(logImage, y * rowLength + logElement.dataOffset, SEEK_SET) != 0) {
+ if (verbose)
+ printf("DPX/Cineon: Couldn't seek at %u\n",
+ (unsigned int)(y * rowLength + logElement.dataOffset));
+ return 1;
+ }
+
+ oldPixel = 0;
+ int offset = 0;
+ int offset2 = 0;
+
+ for (size_t x = 0; x < logImage->width * logElement.depth; x++) {
+ if (offset2 != 0) {
+ offset = 12 - offset2;
+ offset2 = 0;
+ oldPixel = 0;
+ }
+ else if (offset == 32) {
+ offset = 0;
+ }
+ else if (offset + 12 > 32) {
+ /* next pixel is on two different longs */
+ oldPixel = (pixel >> offset);
+ offset2 = 32 - offset;
+ offset = 0;
+ }
+
+ if (offset == 0) {
+ /* we need to read the next long */
+ if (logimage_read_uint(&pixel, logImage) != 0) {
+ if (verbose)
+ printf("DPX/Cineon: EOF reached\n");
+ return 1;
+ }
+ pixel = swap_uint(pixel, logImage->isMSB);
+ }
+ data[y * logImage->width * logElement.depth + x] =
+ (float)((((pixel << offset2) >> offset) & 0xfff) | oldPixel) / 4095.0f;
+ offset += 12;
+ }
+ }
+ return 0;
}
-static int logImageElementGetData16(LogImageFile *logImage, LogImageElement logElement, float *data)
+static int logImageElementGetData16(LogImageFile *logImage,
+ LogImageElement logElement,
+ float *data)
{
- unsigned int numSamples = logImage->width * logImage->height * logElement.depth;
- unsigned int sampleIndex;
- unsigned short pixel;
-
- /* seek to data */
- if (logimage_fseek(logImage, logElement.dataOffset, SEEK_SET) != 0) {
- if (verbose) printf("DPX/Cineon: Couldn't seek at %d\n", logElement.dataOffset);
- return 1;
- }
-
- for (sampleIndex = 0; sampleIndex < numSamples; sampleIndex++) {
- if (logimage_read_ushort(&pixel, logImage) != 0) {
- if (verbose) printf("DPX/Cineon: EOF reached\n");
- return 1;
- }
- pixel = swap_ushort(pixel, logImage->isMSB);
- data[sampleIndex] = (float)pixel / 65535.0f;
- }
-
- return 0;
+ unsigned int numSamples = logImage->width * logImage->height * logElement.depth;
+ unsigned int sampleIndex;
+ unsigned short pixel;
+
+ /* seek to data */
+ if (logimage_fseek(logImage, logElement.dataOffset, SEEK_SET) != 0) {
+ if (verbose)
+ printf("DPX/Cineon: Couldn't seek at %d\n", logElement.dataOffset);
+ return 1;
+ }
+
+ for (sampleIndex = 0; sampleIndex < numSamples; sampleIndex++) {
+ if (logimage_read_ushort(&pixel, logImage) != 0) {
+ if (verbose)
+ printf("DPX/Cineon: EOF reached\n");
+ return 1;
+ }
+ pixel = swap_ushort(pixel, logImage->isMSB);
+ data[sampleIndex] = (float)pixel / 65535.0f;
+ }
+
+ return 0;
}
-
/*
* Color conversion
*/
static int getYUVtoRGBMatrix(float *matrix, LogImageElement logElement)
{
- float scaleY, scaleCbCr;
- float refHighData = (float)logElement.refHighData / logElement.maxValue;
- float refLowData = (float)logElement.refLowData / logElement.maxValue;
-
- scaleY = 1.0f / (refHighData - refLowData);
- scaleCbCr = scaleY * ((940.0f - 64.0f) / (960.0f - 64.0f));
-
- switch (logElement.transfer) {
- case 2: /* linear */
- matrix[0] = 1.0f * scaleY;
- matrix[1] = 1.0f * scaleCbCr;
- matrix[2] = 1.0f * scaleCbCr;
- matrix[3] = 1.0f * scaleY;
- matrix[4] = 1.0f * scaleCbCr;
- matrix[5] = 1.0f * scaleCbCr;
- matrix[6] = 1.0f * scaleY;
- matrix[7] = 1.0f * scaleCbCr;
- matrix[8] = 1.0f * scaleCbCr;
- return 0;
-
- case 5: /* SMPTE 240M */
- matrix[0] = 1.0000f * scaleY;
- matrix[1] = 0.0000f * scaleCbCr;
- matrix[2] = 1.5756f * scaleCbCr;
- matrix[3] = 1.0000f * scaleY;
- matrix[4] = -0.2253f * scaleCbCr;
- matrix[5] = -0.5000f * scaleCbCr;
- matrix[6] = 1.0000f * scaleY;
- matrix[7] = 1.8270f * scaleCbCr;
- matrix[8] = 0.0000f * scaleCbCr;
- return 0;
-
- case 6: /* CCIR 709-1 */
- matrix[0] = 1.000000f * scaleY;
- matrix[1] = 0.000000f * scaleCbCr;
- matrix[2] = 1.574800f * scaleCbCr;
- matrix[3] = 1.000000f * scaleY;
- matrix[4] = -0.187324f * scaleCbCr;
- matrix[5] = -0.468124f * scaleCbCr;
- matrix[6] = 1.000000f * scaleY;
- matrix[7] = 1.855600f * scaleCbCr;
- matrix[8] = 0.000000f * scaleCbCr;
- return 0;
-
- case 7: /* CCIR 601 */
- case 8: /* I'm not sure 7 and 8 should share the same matrix */
- matrix[0] = 1.000000f * scaleY;
- matrix[1] = 0.000000f * scaleCbCr;
- matrix[2] = 1.402000f * scaleCbCr;
- matrix[3] = 1.000000f * scaleY;
- matrix[4] = -0.344136f * scaleCbCr;
- matrix[5] = -0.714136f * scaleCbCr;
- matrix[6] = 1.000000f * scaleY;
- matrix[7] = 1.772000f * scaleCbCr;
- matrix[8] = 0.000000f * scaleCbCr;
- return 0;
-
- default:
- return 1;
- }
+ float scaleY, scaleCbCr;
+ float refHighData = (float)logElement.refHighData / logElement.maxValue;
+ float refLowData = (float)logElement.refLowData / logElement.maxValue;
+
+ scaleY = 1.0f / (refHighData - refLowData);
+ scaleCbCr = scaleY * ((940.0f - 64.0f) / (960.0f - 64.0f));
+
+ switch (logElement.transfer) {
+ case 2: /* linear */
+ matrix[0] = 1.0f * scaleY;
+ matrix[1] = 1.0f * scaleCbCr;
+ matrix[2] = 1.0f * scaleCbCr;
+ matrix[3] = 1.0f * scaleY;
+ matrix[4] = 1.0f * scaleCbCr;
+ matrix[5] = 1.0f * scaleCbCr;
+ matrix[6] = 1.0f * scaleY;
+ matrix[7] = 1.0f * scaleCbCr;
+ matrix[8] = 1.0f * scaleCbCr;
+ return 0;
+
+ case 5: /* SMPTE 240M */
+ matrix[0] = 1.0000f * scaleY;
+ matrix[1] = 0.0000f * scaleCbCr;
+ matrix[2] = 1.5756f * scaleCbCr;
+ matrix[3] = 1.0000f * scaleY;
+ matrix[4] = -0.2253f * scaleCbCr;
+ matrix[5] = -0.5000f * scaleCbCr;
+ matrix[6] = 1.0000f * scaleY;
+ matrix[7] = 1.8270f * scaleCbCr;
+ matrix[8] = 0.0000f * scaleCbCr;
+ return 0;
+
+ case 6: /* CCIR 709-1 */
+ matrix[0] = 1.000000f * scaleY;
+ matrix[1] = 0.000000f * scaleCbCr;
+ matrix[2] = 1.574800f * scaleCbCr;
+ matrix[3] = 1.000000f * scaleY;
+ matrix[4] = -0.187324f * scaleCbCr;
+ matrix[5] = -0.468124f * scaleCbCr;
+ matrix[6] = 1.000000f * scaleY;
+ matrix[7] = 1.855600f * scaleCbCr;
+ matrix[8] = 0.000000f * scaleCbCr;
+ return 0;
+
+ case 7: /* CCIR 601 */
+ case 8: /* I'm not sure 7 and 8 should share the same matrix */
+ matrix[0] = 1.000000f * scaleY;
+ matrix[1] = 0.000000f * scaleCbCr;
+ matrix[2] = 1.402000f * scaleCbCr;
+ matrix[3] = 1.000000f * scaleY;
+ matrix[4] = -0.344136f * scaleCbCr;
+ matrix[5] = -0.714136f * scaleCbCr;
+ matrix[6] = 1.000000f * scaleY;
+ matrix[7] = 1.772000f * scaleCbCr;
+ matrix[8] = 0.000000f * scaleCbCr;
+ return 0;
+
+ default:
+ return 1;
+ }
}
static float *getLinToLogLut(LogImageFile *logImage, LogImageElement logElement)
{
- float *lut;
- float gain, negativeFilmGamma, offset, step;
- unsigned int lutsize = (unsigned int)(logElement.maxValue + 1);
- unsigned int i;
-
- lut = MEM_mallocN(sizeof(float) * lutsize, "getLinToLogLut");
-
- negativeFilmGamma = 0.6;
- step = logElement.refHighQuantity / logElement.maxValue;
- gain = logElement.maxValue / (1.0f - powf(10, (logImage->referenceBlack - logImage->referenceWhite) * step / negativeFilmGamma * logImage->gamma / 1.7f));
- offset = gain - logElement.maxValue;
-
- for (i = 0; i < lutsize; i++)
- lut[i] = (logImage->referenceWhite + log10f(powf((i + offset) / gain, 1.7f / logImage->gamma)) / (step / negativeFilmGamma)) / logElement.maxValue;
-
- return lut;
+ float *lut;
+ float gain, negativeFilmGamma, offset, step;
+ unsigned int lutsize = (unsigned int)(logElement.maxValue + 1);
+ unsigned int i;
+
+ lut = MEM_mallocN(sizeof(float) * lutsize, "getLinToLogLut");
+
+ negativeFilmGamma = 0.6;
+ step = logElement.refHighQuantity / logElement.maxValue;
+ gain = logElement.maxValue /
+ (1.0f - powf(10,
+ (logImage->referenceBlack - logImage->referenceWhite) * step /
+ negativeFilmGamma * logImage->gamma / 1.7f));
+ offset = gain - logElement.maxValue;
+
+ for (i = 0; i < lutsize; i++)
+ lut[i] = (logImage->referenceWhite +
+ log10f(powf((i + offset) / gain, 1.7f / logImage->gamma)) /
+ (step / negativeFilmGamma)) /
+ logElement.maxValue;
+
+ return lut;
}
static float *getLogToLinLut(LogImageFile *logImage, LogImageElement logElement)
{
- float *lut;
- float breakPoint, gain, kneeGain, kneeOffset, negativeFilmGamma, offset, step, softClip;
- /* float filmGamma; unused */
- unsigned int lutsize = (unsigned int)(logElement.maxValue + 1);
- unsigned int i;
-
- lut = MEM_mallocN(sizeof(float) * lutsize, "getLogToLinLut");
-
- /* Building the Log -> Lin LUT */
- step = logElement.refHighQuantity / logElement.maxValue;
- negativeFilmGamma = 0.6;
-
- /* these are default values */
- /* filmGamma = 2.2f; unused */
- softClip = 0;
-
- breakPoint = logImage->referenceWhite - softClip;
- gain = logElement.maxValue / (1.0f - powf(10, (logImage->referenceBlack - logImage->referenceWhite) * step / negativeFilmGamma * logImage->gamma / 1.7f));
- offset = gain - logElement.maxValue;
- kneeOffset = powf(10, (breakPoint - logImage->referenceWhite) * step / negativeFilmGamma * logImage->gamma / 1.7f) * gain - offset;
- kneeGain = (logElement.maxValue - kneeOffset) / powf(5 * softClip, softClip / 100);
-
- for (i = 0; i < lutsize; i++) {
- if (i < logImage->referenceBlack)
- lut[i] = 0.0f;
- else if (i > breakPoint)
- lut[i] = (powf(i - breakPoint, softClip / 100) * kneeGain + kneeOffset) / logElement.maxValue;
- else
- lut[i] = (powf(10, ((float)i - logImage->referenceWhite) * step / negativeFilmGamma * logImage->gamma / 1.7f) * gain - offset) / logElement.maxValue;
- }
-
- return lut;
+ float *lut;
+ float breakPoint, gain, kneeGain, kneeOffset, negativeFilmGamma, offset, step, softClip;
+ /* float filmGamma; unused */
+ unsigned int lutsize = (unsigned int)(logElement.maxValue + 1);
+ unsigned int i;
+
+ lut = MEM_mallocN(sizeof(float) * lutsize, "getLogToLinLut");
+
+ /* Building the Log -> Lin LUT */
+ step = logElement.refHighQuantity / logElement.maxValue;
+ negativeFilmGamma = 0.6;
+
+ /* these are default values */
+ /* filmGamma = 2.2f; unused */
+ softClip = 0;
+
+ breakPoint = logImage->referenceWhite - softClip;
+ gain = logElement.maxValue /
+ (1.0f - powf(10,
+ (logImage->referenceBlack - logImage->referenceWhite) * step /
+ negativeFilmGamma * logImage->gamma / 1.7f));
+ offset = gain - logElement.maxValue;
+ kneeOffset = powf(10,
+ (breakPoint - logImage->referenceWhite) * step / negativeFilmGamma *
+ logImage->gamma / 1.7f) *
+ gain -
+ offset;
+ kneeGain = (logElement.maxValue - kneeOffset) / powf(5 * softClip, softClip / 100);
+
+ for (i = 0; i < lutsize; i++) {
+ if (i < logImage->referenceBlack)
+ lut[i] = 0.0f;
+ else if (i > breakPoint)
+ lut[i] = (powf(i - breakPoint, softClip / 100) * kneeGain + kneeOffset) /
+ logElement.maxValue;
+ else
+ lut[i] = (powf(10,
+ ((float)i - logImage->referenceWhite) * step / negativeFilmGamma *
+ logImage->gamma / 1.7f) *
+ gain -
+ offset) /
+ logElement.maxValue;
+ }
+
+ return lut;
}
static float *getLinToSrgbLut(LogImageElement logElement)
{
- float col, *lut;
- unsigned int lutsize = (unsigned int)(logElement.maxValue + 1);
- unsigned int i;
+ float col, *lut;
+ unsigned int lutsize = (unsigned int)(logElement.maxValue + 1);
+ unsigned int i;
- lut = MEM_mallocN(sizeof(float) * lutsize, "getLogToLinLut");
+ lut = MEM_mallocN(sizeof(float) * lutsize, "getLogToLinLut");
- for (i = 0; i < lutsize; i++) {
- col = (float)i / logElement.maxValue;
- if (col < 0.0031308f)
- lut[i] = (col < 0.0f) ? 0.0f : col * 12.92f;
- else
- lut[i] = 1.055f * powf(col, 1.0f / 2.4f) - 0.055f;
- }
+ for (i = 0; i < lutsize; i++) {
+ col = (float)i / logElement.maxValue;
+ if (col < 0.0031308f)
+ lut[i] = (col < 0.0f) ? 0.0f : col * 12.92f;
+ else
+ lut[i] = 1.055f * powf(col, 1.0f / 2.4f) - 0.055f;
+ }
- return lut;
+ return lut;
}
static float *getSrgbToLinLut(LogImageElement logElement)
{
- float col, *lut;
- unsigned int lutsize = (unsigned int)(logElement.maxValue + 1);
- unsigned int i;
+ float col, *lut;
+ unsigned int lutsize = (unsigned int)(logElement.maxValue + 1);
+ unsigned int i;
- lut = MEM_mallocN(sizeof(float) * lutsize, "getLogToLinLut");
+ lut = MEM_mallocN(sizeof(float) * lutsize, "getLogToLinLut");
- for (i = 0; i < lutsize; i++) {
- col = (float)i / logElement.maxValue;
- if (col < 0.04045f)
- lut[i] = (col < 0.0f) ? 0.0f : col * (1.0f / 12.92f);
- else
- lut[i] = powf((col + 0.055f) * (1.0f / 1.055f), 2.4f);
- }
+ for (i = 0; i < lutsize; i++) {
+ col = (float)i / logElement.maxValue;
+ if (col < 0.04045f)
+ lut[i] = (col < 0.0f) ? 0.0f : col * (1.0f / 12.92f);
+ else
+ lut[i] = powf((col + 0.055f) * (1.0f / 1.055f), 2.4f);
+ }
- return lut;
+ return lut;
}
-static int convertRGBA_RGB(float *src, float *dst, LogImageFile *logImage,
- LogImageElement logElement, int elementIsSource)
+static int convertRGBA_RGB(float *src,
+ float *dst,
+ LogImageFile *logImage,
+ LogImageElement logElement,
+ int elementIsSource)
{
- unsigned int i;
- float *src_ptr = src;
- float *dst_ptr = dst;
-
- switch (logElement.transfer) {
- case transfer_Unspecified:
- case transfer_UserDefined:
- case transfer_Linear:
- case transfer_Logarithmic: {
- for (i = 0; i < logImage->width * logImage->height; i++) {
- *(dst_ptr++) = *(src_ptr++);
- *(dst_ptr++) = *(src_ptr++);
- *(dst_ptr++) = *(src_ptr++);
- src_ptr++;
- }
-
- return 0;
- }
-
- case transfer_PrintingDensity: {
- float *lut;
-
- if (elementIsSource == 1)
- lut = getLogToLinLut(logImage, logElement);
- else
- lut = getLinToLogLut(logImage, logElement);
-
- for (i = 0; i < logImage->width * logImage->height; i++) {
- *(dst_ptr++) = lut[float_uint(*(src_ptr++), logElement.maxValue)];
- *(dst_ptr++) = lut[float_uint(*(src_ptr++), logElement.maxValue)];
- *(dst_ptr++) = lut[float_uint(*(src_ptr++), logElement.maxValue)];
- src_ptr++;
- }
-
- MEM_freeN(lut);
-
- return 0;
- }
-
- default:
- if (verbose) printf("DPX/Cineon: Unknown transfer %d.\n", logElement.transfer);
- return 1;
- }
+ unsigned int i;
+ float *src_ptr = src;
+ float *dst_ptr = dst;
+
+ switch (logElement.transfer) {
+ case transfer_Unspecified:
+ case transfer_UserDefined:
+ case transfer_Linear:
+ case transfer_Logarithmic: {
+ for (i = 0; i < logImage->width * logImage->height; i++) {
+ *(dst_ptr++) = *(src_ptr++);
+ *(dst_ptr++) = *(src_ptr++);
+ *(dst_ptr++) = *(src_ptr++);
+ src_ptr++;
+ }
+
+ return 0;
+ }
+
+ case transfer_PrintingDensity: {
+ float *lut;
+
+ if (elementIsSource == 1)
+ lut = getLogToLinLut(logImage, logElement);
+ else
+ lut = getLinToLogLut(logImage, logElement);
+
+ for (i = 0; i < logImage->width * logImage->height; i++) {
+ *(dst_ptr++) = lut[float_uint(*(src_ptr++), logElement.maxValue)];
+ *(dst_ptr++) = lut[float_uint(*(src_ptr++), logElement.maxValue)];
+ *(dst_ptr++) = lut[float_uint(*(src_ptr++), logElement.maxValue)];
+ src_ptr++;
+ }
+
+ MEM_freeN(lut);
+
+ return 0;
+ }
+
+ default:
+ if (verbose)
+ printf("DPX/Cineon: Unknown transfer %d.\n", logElement.transfer);
+ return 1;
+ }
}
-static int convertRGB_RGBA(float *src, float *dst, LogImageFile *logImage,
- LogImageElement logElement, int elementIsSource)
+static int convertRGB_RGBA(float *src,
+ float *dst,
+ LogImageFile *logImage,
+ LogImageElement logElement,
+ int elementIsSource)
{
- unsigned int i;
- float *src_ptr = src;
- float *dst_ptr = dst;
-
- switch (logElement.transfer) {
- case transfer_Unspecified:
- case transfer_UserDefined:
- case transfer_Linear:
- case transfer_Logarithmic: {
- for (i = 0; i < logImage->width * logImage->height; i++) {
- *(dst_ptr++) = *(src_ptr++);
- *(dst_ptr++) = *(src_ptr++);
- *(dst_ptr++) = *(src_ptr++);
- *(dst_ptr++) = 1.0f;
- }
-
- return 0;
- }
-
- case transfer_PrintingDensity: {
- float *lut;
-
- if (elementIsSource == 1)
- lut = getLogToLinLut(logImage, logElement);
- else
- lut = getLinToLogLut(logImage, logElement);
-
- for (i = 0; i < logImage->width * logImage->height; i++) {
- *(dst_ptr++) = lut[float_uint(*(src_ptr++), logElement.maxValue)];
- *(dst_ptr++) = lut[float_uint(*(src_ptr++), logElement.maxValue)];
- *(dst_ptr++) = lut[float_uint(*(src_ptr++), logElement.maxValue)];
- *(dst_ptr++) = 1.0f;
- }
-
- MEM_freeN(lut);
-
- return 0;
- }
-
- default:
- if (verbose) printf("DPX/Cineon: Unknown transfer %d.\n", logElement.transfer);
- return 1;
- }
+ unsigned int i;
+ float *src_ptr = src;
+ float *dst_ptr = dst;
+
+ switch (logElement.transfer) {
+ case transfer_Unspecified:
+ case transfer_UserDefined:
+ case transfer_Linear:
+ case transfer_Logarithmic: {
+ for (i = 0; i < logImage->width * logImage->height; i++) {
+ *(dst_ptr++) = *(src_ptr++);
+ *(dst_ptr++) = *(src_ptr++);
+ *(dst_ptr++) = *(src_ptr++);
+ *(dst_ptr++) = 1.0f;
+ }
+
+ return 0;
+ }
+
+ case transfer_PrintingDensity: {
+ float *lut;
+
+ if (elementIsSource == 1)
+ lut = getLogToLinLut(logImage, logElement);
+ else
+ lut = getLinToLogLut(logImage, logElement);
+
+ for (i = 0; i < logImage->width * logImage->height; i++) {
+ *(dst_ptr++) = lut[float_uint(*(src_ptr++), logElement.maxValue)];
+ *(dst_ptr++) = lut[float_uint(*(src_ptr++), logElement.maxValue)];
+ *(dst_ptr++) = lut[float_uint(*(src_ptr++), logElement.maxValue)];
+ *(dst_ptr++) = 1.0f;
+ }
+
+ MEM_freeN(lut);
+
+ return 0;
+ }
+
+ default:
+ if (verbose)
+ printf("DPX/Cineon: Unknown transfer %d.\n", logElement.transfer);
+ return 1;
+ }
}
-static int convertRGBA_RGBA(float *src, float *dst, LogImageFile *logImage,
- LogImageElement logElement, int elementIsSource)
+static int convertRGBA_RGBA(float *src,
+ float *dst,
+ LogImageFile *logImage,
+ LogImageElement logElement,
+ int elementIsSource)
{
- unsigned int i;
- float *src_ptr = src;
- float *dst_ptr = dst;
-
- switch (logElement.transfer) {
- case transfer_UserDefined:
- case transfer_Linear:
- case transfer_Logarithmic: {
- memcpy(dst, src, 4 * (size_t)logImage->width * (size_t)logImage->height * sizeof(float));
- return 0;
- }
-
- case transfer_PrintingDensity: {
- float *lut;
-
- if (elementIsSource == 1)
- lut = getLogToLinLut(logImage, logElement);
- else
- lut = getLinToLogLut(logImage, logElement);
-
- for (i = 0; i < logImage->width * logImage->height; i++) {
- *(dst_ptr++) = lut[float_uint(*(src_ptr++), logElement.maxValue)];
- *(dst_ptr++) = lut[float_uint(*(src_ptr++), logElement.maxValue)];
- *(dst_ptr++) = lut[float_uint(*(src_ptr++), logElement.maxValue)];
- *(dst_ptr++) = *(src_ptr++);
- }
-
- MEM_freeN(lut);
-
- return 0;
- }
-
- default:
- return 1;
- }
+ unsigned int i;
+ float *src_ptr = src;
+ float *dst_ptr = dst;
+
+ switch (logElement.transfer) {
+ case transfer_UserDefined:
+ case transfer_Linear:
+ case transfer_Logarithmic: {
+ memcpy(dst, src, 4 * (size_t)logImage->width * (size_t)logImage->height * sizeof(float));
+ return 0;
+ }
+
+ case transfer_PrintingDensity: {
+ float *lut;
+
+ if (elementIsSource == 1)
+ lut = getLogToLinLut(logImage, logElement);
+ else
+ lut = getLinToLogLut(logImage, logElement);
+
+ for (i = 0; i < logImage->width * logImage->height; i++) {
+ *(dst_ptr++) = lut[float_uint(*(src_ptr++), logElement.maxValue)];
+ *(dst_ptr++) = lut[float_uint(*(src_ptr++), logElement.maxValue)];
+ *(dst_ptr++) = lut[float_uint(*(src_ptr++), logElement.maxValue)];
+ *(dst_ptr++) = *(src_ptr++);
+ }
+
+ MEM_freeN(lut);
+
+ return 0;
+ }
+
+ default:
+ return 1;
+ }
}
-static int convertABGR_RGBA(float *src, float *dst, LogImageFile *logImage,
- LogImageElement logElement, int elementIsSource)
+static int convertABGR_RGBA(float *src,
+ float *dst,
+ LogImageFile *logImage,
+ LogImageElement logElement,
+ int elementIsSource)
{
- unsigned int i;
- float *src_ptr = src;
- float *dst_ptr = dst;
-
- switch (logElement.transfer) {
- case transfer_UserDefined:
- case transfer_Linear:
- case transfer_Logarithmic: {
- for (i = 0; i < logImage->width * logImage->height; i++) {
- src_ptr += 4;
- *(dst_ptr++) = *(src_ptr--);
- *(dst_ptr++) = *(src_ptr--);
- *(dst_ptr++) = *(src_ptr--);
- *(dst_ptr++) = *(src_ptr--);
- src_ptr += 4;
- }
- return 0;
- }
-
- case transfer_PrintingDensity: {
- float *lut;
-
- if (elementIsSource == 1)
- lut = getLogToLinLut(logImage, logElement);
- else
- lut = getLinToLogLut(logImage, logElement);
-
- for (i = 0; i < logImage->width * logImage->height; i++) {
- src_ptr += 4;
- *(dst_ptr++) = lut[float_uint(*(src_ptr--), logElement.maxValue)];
- *(dst_ptr++) = lut[float_uint(*(src_ptr--), logElement.maxValue)];
- *(dst_ptr++) = lut[float_uint(*(src_ptr--), logElement.maxValue)];
- *(dst_ptr++) = *(src_ptr--);
- src_ptr += 4;
- }
-
- MEM_freeN(lut);
-
- return 0;
- }
-
- default:
- return 1;
- }
+ unsigned int i;
+ float *src_ptr = src;
+ float *dst_ptr = dst;
+
+ switch (logElement.transfer) {
+ case transfer_UserDefined:
+ case transfer_Linear:
+ case transfer_Logarithmic: {
+ for (i = 0; i < logImage->width * logImage->height; i++) {
+ src_ptr += 4;
+ *(dst_ptr++) = *(src_ptr--);
+ *(dst_ptr++) = *(src_ptr--);
+ *(dst_ptr++) = *(src_ptr--);
+ *(dst_ptr++) = *(src_ptr--);
+ src_ptr += 4;
+ }
+ return 0;
+ }
+
+ case transfer_PrintingDensity: {
+ float *lut;
+
+ if (elementIsSource == 1)
+ lut = getLogToLinLut(logImage, logElement);
+ else
+ lut = getLinToLogLut(logImage, logElement);
+
+ for (i = 0; i < logImage->width * logImage->height; i++) {
+ src_ptr += 4;
+ *(dst_ptr++) = lut[float_uint(*(src_ptr--), logElement.maxValue)];
+ *(dst_ptr++) = lut[float_uint(*(src_ptr--), logElement.maxValue)];
+ *(dst_ptr++) = lut[float_uint(*(src_ptr--), logElement.maxValue)];
+ *(dst_ptr++) = *(src_ptr--);
+ src_ptr += 4;
+ }
+
+ MEM_freeN(lut);
+
+ return 0;
+ }
+
+ default:
+ return 1;
+ }
}
-static int convertCbYCr_RGBA(float *src, float *dst, LogImageFile *logImage, LogImageElement logElement)
+static int convertCbYCr_RGBA(float *src,
+ float *dst,
+ LogImageFile *logImage,
+ LogImageElement logElement)
{
- unsigned int i;
- float conversionMatrix[9], refLowData, y, cb, cr;
- float *src_ptr = src;
- float *dst_ptr = dst;
-
- if (getYUVtoRGBMatrix((float *)&conversionMatrix, logElement) != 0)
- return 1;
-
- refLowData = (float)logElement.refLowData / logElement.maxValue;
-
- for (i = 0; i < logImage->width * logImage->height; i++) {
- cb = *(src_ptr++) - 0.5f;
- y = *(src_ptr++) - refLowData;
- cr = *(src_ptr++) - 0.5f;
-
- *(dst_ptr++) = clamp_float(y * conversionMatrix[0] + cb * conversionMatrix[1] + cr * conversionMatrix[2], 0.0f, 1.0f);
- *(dst_ptr++) = clamp_float(y * conversionMatrix[3] + cb * conversionMatrix[4] + cr * conversionMatrix[5], 0.0f, 1.0f);
- *(dst_ptr++) = clamp_float(y * conversionMatrix[6] + cb * conversionMatrix[7] + cr * conversionMatrix[8], 0.0f, 1.0f);
- *(dst_ptr++) = 1.0f;
- }
- return 0;
+ unsigned int i;
+ float conversionMatrix[9], refLowData, y, cb, cr;
+ float *src_ptr = src;
+ float *dst_ptr = dst;
+
+ if (getYUVtoRGBMatrix((float *)&conversionMatrix, logElement) != 0)
+ return 1;
+
+ refLowData = (float)logElement.refLowData / logElement.maxValue;
+
+ for (i = 0; i < logImage->width * logImage->height; i++) {
+ cb = *(src_ptr++) - 0.5f;
+ y = *(src_ptr++) - refLowData;
+ cr = *(src_ptr++) - 0.5f;
+
+ *(dst_ptr++) = clamp_float(
+ y * conversionMatrix[0] + cb * conversionMatrix[1] + cr * conversionMatrix[2], 0.0f, 1.0f);
+ *(dst_ptr++) = clamp_float(
+ y * conversionMatrix[3] + cb * conversionMatrix[4] + cr * conversionMatrix[5], 0.0f, 1.0f);
+ *(dst_ptr++) = clamp_float(
+ y * conversionMatrix[6] + cb * conversionMatrix[7] + cr * conversionMatrix[8], 0.0f, 1.0f);
+ *(dst_ptr++) = 1.0f;
+ }
+ return 0;
}
-static int convertCbYCrA_RGBA(float *src, float *dst, LogImageFile *logImage, LogImageElement logElement)
+static int convertCbYCrA_RGBA(float *src,
+ float *dst,
+ LogImageFile *logImage,
+ LogImageElement logElement)
{
- unsigned int i;
- float conversionMatrix[9], refLowData, y, cb, cr, a;
- float *src_ptr = src;
- float *dst_ptr = dst;
-
- if (getYUVtoRGBMatrix((float *)&conversionMatrix, logElement) != 0)
- return 1;
-
- refLowData = (float)logElement.refLowData / logElement.maxValue;
-
- for (i = 0; i < logImage->width * logImage->height; i++) {
- cb = *(src_ptr++) - 0.5f;
- y = *(src_ptr++) - refLowData;
- cr = *(src_ptr++) - 0.5f;
- a = *(src_ptr++);
-
- *(dst_ptr++) = clamp_float(y * conversionMatrix[0] + cb * conversionMatrix[1] + cr * conversionMatrix[2], 0.0f, 1.0f);
- *(dst_ptr++) = clamp_float(y * conversionMatrix[3] + cb * conversionMatrix[4] + cr * conversionMatrix[5], 0.0f, 1.0f);
- *(dst_ptr++) = clamp_float(y * conversionMatrix[6] + cb * conversionMatrix[7] + cr * conversionMatrix[8], 0.0f, 1.0f);
- *(dst_ptr++) = a;
- }
- return 0;
+ unsigned int i;
+ float conversionMatrix[9], refLowData, y, cb, cr, a;
+ float *src_ptr = src;
+ float *dst_ptr = dst;
+
+ if (getYUVtoRGBMatrix((float *)&conversionMatrix, logElement) != 0)
+ return 1;
+
+ refLowData = (float)logElement.refLowData / logElement.maxValue;
+
+ for (i = 0; i < logImage->width * logImage->height; i++) {
+ cb = *(src_ptr++) - 0.5f;
+ y = *(src_ptr++) - refLowData;
+ cr = *(src_ptr++) - 0.5f;
+ a = *(src_ptr++);
+
+ *(dst_ptr++) = clamp_float(
+ y * conversionMatrix[0] + cb * conversionMatrix[1] + cr * conversionMatrix[2], 0.0f, 1.0f);
+ *(dst_ptr++) = clamp_float(
+ y * conversionMatrix[3] + cb * conversionMatrix[4] + cr * conversionMatrix[5], 0.0f, 1.0f);
+ *(dst_ptr++) = clamp_float(
+ y * conversionMatrix[6] + cb * conversionMatrix[7] + cr * conversionMatrix[8], 0.0f, 1.0f);
+ *(dst_ptr++) = a;
+ }
+ return 0;
}
-static int convertCbYCrY_RGBA(float *src, float *dst, LogImageFile *logImage, LogImageElement logElement)
+static int convertCbYCrY_RGBA(float *src,
+ float *dst,
+ LogImageFile *logImage,
+ LogImageElement logElement)
{
- unsigned int i;
- float conversionMatrix[9], refLowData, y1, y2, cb, cr;
- float *src_ptr = src;
- float *dst_ptr = dst;
-
- if (getYUVtoRGBMatrix((float *)&conversionMatrix, logElement) != 0)
- return 1;
-
- refLowData = (float)logElement.refLowData / logElement.maxValue;
-
- for (i = 0; i < logImage->width * logImage->height / 2; i++) {
- cb = *(src_ptr++) - 0.5f;
- y1 = *(src_ptr++) - refLowData;
- cr = *(src_ptr++) - 0.5f;
- y2 = *(src_ptr++) - refLowData;
-
- *(dst_ptr++) = clamp_float(y1 * conversionMatrix[0] + cb * conversionMatrix[1] + cr * conversionMatrix[2], 0.0f, 1.0f);
- *(dst_ptr++) = clamp_float(y1 * conversionMatrix[3] + cb * conversionMatrix[4] + cr * conversionMatrix[5], 0.0f, 1.0f);
- *(dst_ptr++) = clamp_float(y1 * conversionMatrix[6] + cb * conversionMatrix[7] + cr * conversionMatrix[8], 0.0f, 1.0f);
- *(dst_ptr++) = 1.0f;
- *(dst_ptr++) = clamp_float(y2 * conversionMatrix[0] + cb * conversionMatrix[1] + cr * conversionMatrix[2], 0.0f, 1.0f);
- *(dst_ptr++) = clamp_float(y2 * conversionMatrix[3] + cb * conversionMatrix[4] + cr * conversionMatrix[5], 0.0f, 1.0f);
- *(dst_ptr++) = clamp_float(y2 * conversionMatrix[6] + cb * conversionMatrix[7] + cr * conversionMatrix[8], 0.0f, 1.0f);
- *(dst_ptr++) = 1.0f;
- }
- return 0;
+ unsigned int i;
+ float conversionMatrix[9], refLowData, y1, y2, cb, cr;
+ float *src_ptr = src;
+ float *dst_ptr = dst;
+
+ if (getYUVtoRGBMatrix((float *)&conversionMatrix, logElement) != 0)
+ return 1;
+
+ refLowData = (float)logElement.refLowData / logElement.maxValue;
+
+ for (i = 0; i < logImage->width * logImage->height / 2; i++) {
+ cb = *(src_ptr++) - 0.5f;
+ y1 = *(src_ptr++) - refLowData;
+ cr = *(src_ptr++) - 0.5f;
+ y2 = *(src_ptr++) - refLowData;
+
+ *(dst_ptr++) = clamp_float(y1 * conversionMatrix[0] + cb * conversionMatrix[1] +
+ cr * conversionMatrix[2],
+ 0.0f,
+ 1.0f);
+ *(dst_ptr++) = clamp_float(y1 * conversionMatrix[3] + cb * conversionMatrix[4] +
+ cr * conversionMatrix[5],
+ 0.0f,
+ 1.0f);
+ *(dst_ptr++) = clamp_float(y1 * conversionMatrix[6] + cb * conversionMatrix[7] +
+ cr * conversionMatrix[8],
+ 0.0f,
+ 1.0f);
+ *(dst_ptr++) = 1.0f;
+ *(dst_ptr++) = clamp_float(y2 * conversionMatrix[0] + cb * conversionMatrix[1] +
+ cr * conversionMatrix[2],
+ 0.0f,
+ 1.0f);
+ *(dst_ptr++) = clamp_float(y2 * conversionMatrix[3] + cb * conversionMatrix[4] +
+ cr * conversionMatrix[5],
+ 0.0f,
+ 1.0f);
+ *(dst_ptr++) = clamp_float(y2 * conversionMatrix[6] + cb * conversionMatrix[7] +
+ cr * conversionMatrix[8],
+ 0.0f,
+ 1.0f);
+ *(dst_ptr++) = 1.0f;
+ }
+ return 0;
}
-static int convertCbYACrYA_RGBA(float *src, float *dst, LogImageFile *logImage, LogImageElement logElement)
+static int convertCbYACrYA_RGBA(float *src,
+ float *dst,
+ LogImageFile *logImage,
+ LogImageElement logElement)
{
- unsigned int i;
- float conversionMatrix[9], refLowData, y1, y2, cb, cr, a1, a2;
- float *src_ptr = src;
- float *dst_ptr = dst;
-
- if (getYUVtoRGBMatrix((float *)&conversionMatrix, logElement) != 0)
- return 1;
-
- refLowData = (float)logElement.refLowData / logElement.maxValue;
-
- for (i = 0; i < logImage->width * logImage->height / 2; i++) {
- cb = *(src_ptr++) - 0.5f;
- y1 = *(src_ptr++) - refLowData;
- a1 = *(src_ptr++);
- cr = *(src_ptr++) - 0.5f;
- y2 = *(src_ptr++) - refLowData;
- a2 = *(src_ptr++);
-
- *(dst_ptr++) = clamp_float(y1 * conversionMatrix[0] + cb * conversionMatrix[1] + cr * conversionMatrix[2], 0.0f, 1.0f);
- *(dst_ptr++) = clamp_float(y1 * conversionMatrix[3] + cb * conversionMatrix[4] + cr * conversionMatrix[5], 0.0f, 1.0f);
- *(dst_ptr++) = clamp_float(y1 * conversionMatrix[6] + cb * conversionMatrix[7] + cr * conversionMatrix[8], 0.0f, 1.0f);
- *(dst_ptr++) = a1;
- *(dst_ptr++) = clamp_float(y2 * conversionMatrix[0] + cb * conversionMatrix[1] + cr * conversionMatrix[2], 0.0f, 1.0f);
- *(dst_ptr++) = clamp_float(y2 * conversionMatrix[3] + cb * conversionMatrix[4] + cr * conversionMatrix[5], 0.0f, 1.0f);
- *(dst_ptr++) = clamp_float(y2 * conversionMatrix[6] + cb * conversionMatrix[7] + cr * conversionMatrix[8], 0.0f, 1.0f);
- *(dst_ptr++) = a2;
- }
- return 0;
+ unsigned int i;
+ float conversionMatrix[9], refLowData, y1, y2, cb, cr, a1, a2;
+ float *src_ptr = src;
+ float *dst_ptr = dst;
+
+ if (getYUVtoRGBMatrix((float *)&conversionMatrix, logElement) != 0)
+ return 1;
+
+ refLowData = (float)logElement.refLowData / logElement.maxValue;
+
+ for (i = 0; i < logImage->width * logImage->height / 2; i++) {
+ cb = *(src_ptr++) - 0.5f;
+ y1 = *(src_ptr++) - refLowData;
+ a1 = *(src_ptr++);
+ cr = *(src_ptr++) - 0.5f;
+ y2 = *(src_ptr++) - refLowData;
+ a2 = *(src_ptr++);
+
+ *(dst_ptr++) = clamp_float(y1 * conversionMatrix[0] + cb * conversionMatrix[1] +
+ cr * conversionMatrix[2],
+ 0.0f,
+ 1.0f);
+ *(dst_ptr++) = clamp_float(y1 * conversionMatrix[3] + cb * conversionMatrix[4] +
+ cr * conversionMatrix[5],
+ 0.0f,
+ 1.0f);
+ *(dst_ptr++) = clamp_float(y1 * conversionMatrix[6] + cb * conversionMatrix[7] +
+ cr * conversionMatrix[8],
+ 0.0f,
+ 1.0f);
+ *(dst_ptr++) = a1;
+ *(dst_ptr++) = clamp_float(y2 * conversionMatrix[0] + cb * conversionMatrix[1] +
+ cr * conversionMatrix[2],
+ 0.0f,
+ 1.0f);
+ *(dst_ptr++) = clamp_float(y2 * conversionMatrix[3] + cb * conversionMatrix[4] +
+ cr * conversionMatrix[5],
+ 0.0f,
+ 1.0f);
+ *(dst_ptr++) = clamp_float(y2 * conversionMatrix[6] + cb * conversionMatrix[7] +
+ cr * conversionMatrix[8],
+ 0.0f,
+ 1.0f);
+ *(dst_ptr++) = a2;
+ }
+ return 0;
}
-static int convertLuminance_RGBA(float *src, float *dst, LogImageFile *logImage, LogImageElement logElement)
+static int convertLuminance_RGBA(float *src,
+ float *dst,
+ LogImageFile *logImage,
+ LogImageElement logElement)
{
- unsigned int i;
- float conversionMatrix[9], value, refLowData;
- float *src_ptr = src;
- float *dst_ptr = dst;
-
- if (getYUVtoRGBMatrix((float *)&conversionMatrix, logElement) != 0)
- return 1;
-
- refLowData = (float)logElement.refLowData / logElement.maxValue;
-
- for (i = 0; i < logImage->width * logImage->height; i++) {
- value = clamp_float((*(src_ptr++) - refLowData) * conversionMatrix[0], 0.0f, 1.0f);
- *(dst_ptr++) = value;
- *(dst_ptr++) = value;
- *(dst_ptr++) = value;
- *(dst_ptr++) = 1.0f;
- }
- return 0;
+ unsigned int i;
+ float conversionMatrix[9], value, refLowData;
+ float *src_ptr = src;
+ float *dst_ptr = dst;
+
+ if (getYUVtoRGBMatrix((float *)&conversionMatrix, logElement) != 0)
+ return 1;
+
+ refLowData = (float)logElement.refLowData / logElement.maxValue;
+
+ for (i = 0; i < logImage->width * logImage->height; i++) {
+ value = clamp_float((*(src_ptr++) - refLowData) * conversionMatrix[0], 0.0f, 1.0f);
+ *(dst_ptr++) = value;
+ *(dst_ptr++) = value;
+ *(dst_ptr++) = value;
+ *(dst_ptr++) = 1.0f;
+ }
+ return 0;
}
-static int convertYA_RGBA(float *src, float *dst, LogImageFile *logImage, LogImageElement logElement)
+static int convertYA_RGBA(float *src,
+ float *dst,
+ LogImageFile *logImage,
+ LogImageElement logElement)
{
- unsigned int i;
- float conversionMatrix[9], value, refLowData;
- float *src_ptr = src;
- float *dst_ptr = dst;
-
- if (getYUVtoRGBMatrix((float *)&conversionMatrix, logElement) != 0)
- return 1;
-
- refLowData = (float)logElement.refLowData / logElement.maxValue;
-
- for (i = 0; i < logImage->width * logImage->height; i++) {
- value = clamp_float((*(src_ptr++) - refLowData) * conversionMatrix[0], 0.0f, 1.0f);
- *(dst_ptr++) = value;
- *(dst_ptr++) = value;
- *(dst_ptr++) = value;
- *(dst_ptr++) = *(src_ptr++);
- }
- return 0;
+ unsigned int i;
+ float conversionMatrix[9], value, refLowData;
+ float *src_ptr = src;
+ float *dst_ptr = dst;
+
+ if (getYUVtoRGBMatrix((float *)&conversionMatrix, logElement) != 0)
+ return 1;
+
+ refLowData = (float)logElement.refLowData / logElement.maxValue;
+
+ for (i = 0; i < logImage->width * logImage->height; i++) {
+ value = clamp_float((*(src_ptr++) - refLowData) * conversionMatrix[0], 0.0f, 1.0f);
+ *(dst_ptr++) = value;
+ *(dst_ptr++) = value;
+ *(dst_ptr++) = value;
+ *(dst_ptr++) = *(src_ptr++);
+ }
+ return 0;
}
-static int convertLogElementToRGBA(float *src, float *dst, LogImageFile *logImage,
- LogImageElement logElement, int dstIsLinearRGB)
+static int convertLogElementToRGBA(
+ float *src, float *dst, LogImageFile *logImage, LogImageElement logElement, int dstIsLinearRGB)
{
- int rvalue;
- unsigned int i;
- float *src_ptr;
- float *dst_ptr;
-
- /* Convert data in src to linear RGBA in dst */
- switch (logElement.descriptor) {
- case descriptor_RGB:
- rvalue = convertRGB_RGBA(src, dst, logImage, logElement, 1);
- break;
-
- case descriptor_RGBA:
- rvalue = convertRGBA_RGBA(src, dst, logImage, logElement, 1);
- break;
-
- case descriptor_ABGR:
- rvalue = convertABGR_RGBA(src, dst, logImage, logElement, 1);
- break;
-
- case descriptor_Luminance:
- rvalue = convertLuminance_RGBA(src, dst, logImage, logElement);
- break;
-
- case descriptor_CbYCr:
- rvalue = convertCbYCr_RGBA(src, dst, logImage, logElement);
- break;
-
- case descriptor_CbYCrY:
- rvalue = convertCbYCrY_RGBA(src, dst, logImage, logElement);
- break;
-
- case descriptor_CbYACrYA:
- rvalue = convertCbYACrYA_RGBA(src, dst, logImage, logElement);
- break;
-
- case descriptor_CbYCrA:
- rvalue = convertCbYCrA_RGBA(src, dst, logImage, logElement);
- break;
-
- case descriptor_YA: /* this descriptor is for internal use only */
- rvalue = convertYA_RGBA(src, dst, logImage, logElement);
- break;
-
- default:
- return 1;
- }
-
- if (rvalue == 1)
- return 1;
- else if (dstIsLinearRGB) {
- /* convert data from sRGB to Linear RGB via lut */
- float *lut = getSrgbToLinLut(logElement);
- src_ptr = dst; // no error here
- dst_ptr = dst;
- for (i = 0; i < logImage->width * logImage->height; i++) {
- *(dst_ptr++) = lut[float_uint(*(src_ptr++), logElement.maxValue)];
- *(dst_ptr++) = lut[float_uint(*(src_ptr++), logElement.maxValue)];
- *(dst_ptr++) = lut[float_uint(*(src_ptr++), logElement.maxValue)];
- dst_ptr++; src_ptr++;
- }
- MEM_freeN(lut);
- }
- return 0;
+ int rvalue;
+ unsigned int i;
+ float *src_ptr;
+ float *dst_ptr;
+
+ /* Convert data in src to linear RGBA in dst */
+ switch (logElement.descriptor) {
+ case descriptor_RGB:
+ rvalue = convertRGB_RGBA(src, dst, logImage, logElement, 1);
+ break;
+
+ case descriptor_RGBA:
+ rvalue = convertRGBA_RGBA(src, dst, logImage, logElement, 1);
+ break;
+
+ case descriptor_ABGR:
+ rvalue = convertABGR_RGBA(src, dst, logImage, logElement, 1);
+ break;
+
+ case descriptor_Luminance:
+ rvalue = convertLuminance_RGBA(src, dst, logImage, logElement);
+ break;
+
+ case descriptor_CbYCr:
+ rvalue = convertCbYCr_RGBA(src, dst, logImage, logElement);
+ break;
+
+ case descriptor_CbYCrY:
+ rvalue = convertCbYCrY_RGBA(src, dst, logImage, logElement);
+ break;
+
+ case descriptor_CbYACrYA:
+ rvalue = convertCbYACrYA_RGBA(src, dst, logImage, logElement);
+ break;
+
+ case descriptor_CbYCrA:
+ rvalue = convertCbYCrA_RGBA(src, dst, logImage, logElement);
+ break;
+
+ case descriptor_YA: /* this descriptor is for internal use only */
+ rvalue = convertYA_RGBA(src, dst, logImage, logElement);
+ break;
+
+ default:
+ return 1;
+ }
+
+ if (rvalue == 1)
+ return 1;
+ else if (dstIsLinearRGB) {
+ /* convert data from sRGB to Linear RGB via lut */
+ float *lut = getSrgbToLinLut(logElement);
+ src_ptr = dst; // no error here
+ dst_ptr = dst;
+ for (i = 0; i < logImage->width * logImage->height; i++) {
+ *(dst_ptr++) = lut[float_uint(*(src_ptr++), logElement.maxValue)];
+ *(dst_ptr++) = lut[float_uint(*(src_ptr++), logElement.maxValue)];
+ *(dst_ptr++) = lut[float_uint(*(src_ptr++), logElement.maxValue)];
+ dst_ptr++;
+ src_ptr++;
+ }
+ MEM_freeN(lut);
+ }
+ return 0;
}
-static int convertRGBAToLogElement(float *src, float *dst, LogImageFile *logImage,
- LogImageElement logElement, int srcIsLinearRGB)
+static int convertRGBAToLogElement(
+ float *src, float *dst, LogImageFile *logImage, LogImageElement logElement, int srcIsLinearRGB)
{
- unsigned int i;
- int rvalue;
- float *srgbSrc;
- float *srgbSrc_ptr;
- float *src_ptr = src;
- float *lut;
-
- if (srcIsLinearRGB != 0) {
- /* we need to convert src to sRGB */
- srgbSrc = (float *)imb_alloc_pixels(logImage->width, logImage->height, 4, sizeof(float), __func__);
- if (srgbSrc == NULL)
- return 1;
-
- memcpy(srgbSrc, src, 4 * (size_t)logImage->width * (size_t)logImage->height * sizeof(float));
- srgbSrc_ptr = srgbSrc;
-
- /* convert data from Linear RGB to sRGB via lut */
- lut = getLinToSrgbLut(logElement);
- for (i = 0; i < logImage->width * logImage->height; i++) {
- *(srgbSrc_ptr++) = lut[float_uint(*(src_ptr++), logElement.maxValue)];
- *(srgbSrc_ptr++) = lut[float_uint(*(src_ptr++), logElement.maxValue)];
- *(srgbSrc_ptr++) = lut[float_uint(*(src_ptr++), logElement.maxValue)];
- srgbSrc_ptr++; src_ptr++;
- }
- MEM_freeN(lut);
- }
- else
- srgbSrc = src;
-
- /* Convert linear RGBA data in src to format described by logElement in dst */
- switch (logElement.descriptor) {
- case descriptor_RGB:
- rvalue = convertRGBA_RGB(srgbSrc, dst, logImage, logElement, 0);
- break;
-
- case descriptor_RGBA:
- rvalue = convertRGBA_RGBA(srgbSrc, dst, logImage, logElement, 0);
- break;
-
- /* these ones are not supported for the moment */
- case descriptor_ABGR:
- case descriptor_Luminance:
- case descriptor_CbYCr:
- case descriptor_CbYCrY:
- case descriptor_CbYACrYA:
- case descriptor_CbYCrA:
- case descriptor_YA: /* this descriptor is for internal use only */
- default:
- rvalue = 1;
- break;
- }
-
- if (srcIsLinearRGB != 0) {
- MEM_freeN(srgbSrc);
- }
-
- return rvalue;
+ unsigned int i;
+ int rvalue;
+ float *srgbSrc;
+ float *srgbSrc_ptr;
+ float *src_ptr = src;
+ float *lut;
+
+ if (srcIsLinearRGB != 0) {
+ /* we need to convert src to sRGB */
+ srgbSrc = (float *)imb_alloc_pixels(
+ logImage->width, logImage->height, 4, sizeof(float), __func__);
+ if (srgbSrc == NULL)
+ return 1;
+
+ memcpy(srgbSrc, src, 4 * (size_t)logImage->width * (size_t)logImage->height * sizeof(float));
+ srgbSrc_ptr = srgbSrc;
+
+ /* convert data from Linear RGB to sRGB via lut */
+ lut = getLinToSrgbLut(logElement);
+ for (i = 0; i < logImage->width * logImage->height; i++) {
+ *(srgbSrc_ptr++) = lut[float_uint(*(src_ptr++), logElement.maxValue)];
+ *(srgbSrc_ptr++) = lut[float_uint(*(src_ptr++), logElement.maxValue)];
+ *(srgbSrc_ptr++) = lut[float_uint(*(src_ptr++), logElement.maxValue)];
+ srgbSrc_ptr++;
+ src_ptr++;
+ }
+ MEM_freeN(lut);
+ }
+ else
+ srgbSrc = src;
+
+ /* Convert linear RGBA data in src to format described by logElement in dst */
+ switch (logElement.descriptor) {
+ case descriptor_RGB:
+ rvalue = convertRGBA_RGB(srgbSrc, dst, logImage, logElement, 0);
+ break;
+
+ case descriptor_RGBA:
+ rvalue = convertRGBA_RGBA(srgbSrc, dst, logImage, logElement, 0);
+ break;
+
+ /* these ones are not supported for the moment */
+ case descriptor_ABGR:
+ case descriptor_Luminance:
+ case descriptor_CbYCr:
+ case descriptor_CbYCrY:
+ case descriptor_CbYACrYA:
+ case descriptor_CbYCrA:
+ case descriptor_YA: /* this descriptor is for internal use only */
+ default:
+ rvalue = 1;
+ break;
+ }
+
+ if (srcIsLinearRGB != 0) {
+ MEM_freeN(srgbSrc);
+ }
+
+ return rvalue;
}
diff --git a/source/blender/imbuf/intern/cineon/logImageCore.h b/source/blender/imbuf/intern/cineon/logImageCore.h
index 07fe6e22d40..e01c2e0f117 100644
--- a/source/blender/imbuf/intern/cineon/logImageCore.h
+++ b/source/blender/imbuf/intern/cineon/logImageCore.h
@@ -45,51 +45,50 @@ extern "C" {
/* There are some differences between DPX and Cineon so we need to know from what type of file the datas come from */
enum format {
- format_DPX,
- format_Cineon,
+ format_DPX,
+ format_Cineon,
};
typedef struct LogImageElement {
- int depth;
- int bitsPerSample;
- int dataOffset;
- int packing;
- int transfer;
- int descriptor;
- unsigned int refLowData;
- unsigned int refHighData;
- float refLowQuantity;
- float refHighQuantity;
- float maxValue; /* = 2^bitsPerSample - 1 (used internally, doesn't come from the file header) */
+ int depth;
+ int bitsPerSample;
+ int dataOffset;
+ int packing;
+ int transfer;
+ int descriptor;
+ unsigned int refLowData;
+ unsigned int refHighData;
+ float refLowQuantity;
+ float refHighQuantity;
+ float maxValue; /* = 2^bitsPerSample - 1 (used internally, doesn't come from the file header) */
} LogImageElement;
typedef struct LogImageFile {
- /* specified in header */
- int width;
- int height;
- int numElements;
- int depth;
- LogImageElement element[8];
-
- /* used for log <-> lin conversion */
- float referenceBlack;
- float referenceWhite;
- float gamma;
-
- /* io stuff */
- FILE *file;
- unsigned char *memBuffer;
- uintptr_t memBufferSize;
- unsigned char *memCursor;
-
- /* is the file LSB or MSB ? */
- int isMSB;
-
- /* DPX or Cineon ? */
- int srcFormat;
+ /* specified in header */
+ int width;
+ int height;
+ int numElements;
+ int depth;
+ LogImageElement element[8];
+
+ /* used for log <-> lin conversion */
+ float referenceBlack;
+ float referenceWhite;
+ float gamma;
+
+ /* io stuff */
+ FILE *file;
+ unsigned char *memBuffer;
+ uintptr_t memBufferSize;
+ unsigned char *memCursor;
+
+ /* is the file LSB or MSB ? */
+ int isMSB;
+
+ /* DPX or Cineon ? */
+ int srcFormat;
} LogImageFile;
-
/* The SMPTE defines this code:
* 0 - User-defined
* 1 - Printing density
@@ -110,19 +109,19 @@ typedef struct LogImageFile {
*/
enum transfer {
- transfer_UserDefined,
- transfer_PrintingDensity,
- transfer_Linear,
- transfer_Logarithmic,
- transfer_Unspecified,
- transfer_Smpte240M,
- transfer_Ccir7091,
- transfer_Ccir6012BG,
- transfer_Ccir6012M,
- transfer_NTSC,
- transfer_PAL,
- transfer_ZLinear,
- transfer_Homogeneous,
+ transfer_UserDefined,
+ transfer_PrintingDensity,
+ transfer_Linear,
+ transfer_Logarithmic,
+ transfer_Unspecified,
+ transfer_Smpte240M,
+ transfer_Ccir7091,
+ transfer_Ccir6012BG,
+ transfer_Ccir6012M,
+ transfer_NTSC,
+ transfer_PAL,
+ transfer_ZLinear,
+ transfer_Homogeneous,
};
/* The SMPTE defines this code:
@@ -152,31 +151,31 @@ enum transfer {
*/
enum descriptor {
- descriptor_UserDefined,
- descriptor_Red,
- descriptor_Green,
- descriptor_Blue,
- descriptor_Alpha,
- descriptor_Luminance = 6, /* don't ask me why there's no 5 */
- descriptor_Chrominance,
- descriptor_Depth,
- descriptor_Composite,
- descriptor_RGB = 50,
- descriptor_RGBA,
- descriptor_ABGR,
- descriptor_CbYCrY = 100,
- descriptor_CbYACrYA,
- descriptor_CbYCr,
- descriptor_CbYCrA,
- descriptor_UserDefined2Elt = 150,
- descriptor_UserDefined3Elt,
- descriptor_UserDefined4Elt,
- descriptor_UserDefined5Elt,
- descriptor_UserDefined6Elt,
- descriptor_UserDefined7Elt,
- descriptor_UserDefined8Elt,
- /* following descriptors are for internal use only */
- descriptor_YA,
+ descriptor_UserDefined,
+ descriptor_Red,
+ descriptor_Green,
+ descriptor_Blue,
+ descriptor_Alpha,
+ descriptor_Luminance = 6, /* don't ask me why there's no 5 */
+ descriptor_Chrominance,
+ descriptor_Depth,
+ descriptor_Composite,
+ descriptor_RGB = 50,
+ descriptor_RGBA,
+ descriptor_ABGR,
+ descriptor_CbYCrY = 100,
+ descriptor_CbYACrYA,
+ descriptor_CbYCr,
+ descriptor_CbYCrA,
+ descriptor_UserDefined2Elt = 150,
+ descriptor_UserDefined3Elt,
+ descriptor_UserDefined4Elt,
+ descriptor_UserDefined5Elt,
+ descriptor_UserDefined6Elt,
+ descriptor_UserDefined7Elt,
+ descriptor_UserDefined8Elt,
+ /* following descriptors are for internal use only */
+ descriptor_YA,
};
/* int functions return 0 for OK */
@@ -187,9 +186,17 @@ int logImageIsCineon(const void *buffer);
LogImageFile *logImageOpenFromMemory(const unsigned char *buffer, unsigned int size);
LogImageFile *logImageOpenFromFile(const char *filename, int cineon);
void logImageGetSize(LogImageFile *logImage, int *width, int *height, int *depth);
-LogImageFile *logImageCreate(const char *filename, int cineon, int width, int height, int bitsPerSample,
- int isLogarithmic, int hasAlpha, int referenceWhite, int referenceBlack,
- float gamma, const char *creator);
+LogImageFile *logImageCreate(const char *filename,
+ int cineon,
+ int width,
+ int height,
+ int bitsPerSample,
+ int isLogarithmic,
+ int hasAlpha,
+ int referenceWhite,
+ int referenceBlack,
+ float gamma,
+ const char *creator);
void logImageClose(LogImageFile *logImage);
/* Data handling */
@@ -205,74 +212,73 @@ int logImageGetDataRGBA(LogImageFile *logImage, float *data, int dataIsLinearRGB
BLI_INLINE unsigned short swap_ushort(unsigned short x, int swap)
{
- if (swap != 0)
- return (x >> 8) | (x << 8);
- else
- return x;
+ if (swap != 0)
+ return (x >> 8) | (x << 8);
+ else
+ return x;
}
BLI_INLINE unsigned int swap_uint(unsigned int x, int swap)
{
- if (swap != 0)
- return (x >> 24) | ((x << 8) & 0x00FF0000) | ((x >> 8) & 0x0000FF00) | (x << 24);
- else
- return x;
+ if (swap != 0)
+ return (x >> 24) | ((x << 8) & 0x00FF0000) | ((x >> 8) & 0x0000FF00) | (x << 24);
+ else
+ return x;
}
BLI_INLINE float swap_float(float x, int swap)
{
- if (swap != 0) {
- union {
- float f;
- unsigned char b[4];
- } dat1, dat2;
-
- dat1.f = x;
- dat2.b[0] = dat1.b[3];
- dat2.b[1] = dat1.b[2];
- dat2.b[2] = dat1.b[1];
- dat2.b[3] = dat1.b[0];
- return dat2.f;
- }
- else
- return x;
+ if (swap != 0) {
+ union {
+ float f;
+ unsigned char b[4];
+ } dat1, dat2;
+
+ dat1.f = x;
+ dat2.b[0] = dat1.b[3];
+ dat2.b[1] = dat1.b[2];
+ dat2.b[2] = dat1.b[1];
+ dat2.b[3] = dat1.b[0];
+ return dat2.f;
+ }
+ else
+ return x;
}
/* Other */
BLI_INLINE unsigned int clamp_uint(unsigned int x, unsigned int low, unsigned int high)
{
- if (x > high)
- return high;
- else if (x < low)
- return low;
- else
- return x;
+ if (x > high)
+ return high;
+ else if (x < low)
+ return low;
+ else
+ return x;
}
BLI_INLINE float clamp_float(float x, float low, float high)
{
- if (x > high)
- return high;
- else if (x < low)
- return low;
- else
- return x;
+ if (x > high)
+ return high;
+ else if (x < low)
+ return low;
+ else
+ return x;
}
BLI_INLINE unsigned int float_uint(float value, unsigned int max)
{
- if (value < 0.0f)
- return 0;
- else if (value > (1.0f - 0.5f / (float)max))
- return max;
- else
- return (unsigned int)(((float)max * value) + 0.5f);
+ if (value < 0.0f)
+ return 0;
+ else if (value > (1.0f - 0.5f / (float)max))
+ return max;
+ else
+ return (unsigned int)(((float)max * value) + 0.5f);
}
-
#ifdef __cplusplus
}
#endif
-#endif /* __LOGIMAGECORE_H__ */
+#endif /* __LOGIMAGECORE_H__ */
diff --git a/source/blender/imbuf/intern/cineon/logmemfile.c b/source/blender/imbuf/intern/cineon/logmemfile.c
index e67ef74951b..d7ab2855ea3 100644
--- a/source/blender/imbuf/intern/cineon/logmemfile.c
+++ b/source/blender/imbuf/intern/cineon/logmemfile.c
@@ -22,7 +22,6 @@
* Cineon image file format library routines.
*/
-
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -32,92 +31,92 @@
int logimage_fseek(LogImageFile *logFile, intptr_t offset, int origin)
{
- if (logFile->file)
- fseek(logFile->file, offset, origin);
- else { /* we're seeking in memory */
- if (origin == SEEK_SET) {
- if (offset > logFile->memBufferSize)
- return 1;
- logFile->memCursor = logFile->memBuffer + offset;
- }
- else if (origin == SEEK_END) {
- if (offset > logFile->memBufferSize)
- return 1;
- logFile->memCursor = (logFile->memBuffer + logFile->memBufferSize) - offset;
- }
- else if (origin == SEEK_CUR) {
- uintptr_t pos = (uintptr_t)logFile->memCursor - (uintptr_t)logFile->memBuffer;
- if (pos + offset > logFile->memBufferSize)
- return 1;
-
- logFile->memCursor += offset;
- }
- }
- return 0;
+ if (logFile->file)
+ fseek(logFile->file, offset, origin);
+ else { /* we're seeking in memory */
+ if (origin == SEEK_SET) {
+ if (offset > logFile->memBufferSize)
+ return 1;
+ logFile->memCursor = logFile->memBuffer + offset;
+ }
+ else if (origin == SEEK_END) {
+ if (offset > logFile->memBufferSize)
+ return 1;
+ logFile->memCursor = (logFile->memBuffer + logFile->memBufferSize) - offset;
+ }
+ else if (origin == SEEK_CUR) {
+ uintptr_t pos = (uintptr_t)logFile->memCursor - (uintptr_t)logFile->memBuffer;
+ if (pos + offset > logFile->memBufferSize)
+ return 1;
+
+ logFile->memCursor += offset;
+ }
+ }
+ return 0;
}
int logimage_fwrite(void *buffer, size_t size, unsigned int count, LogImageFile *logFile)
{
- if (logFile->file)
- return fwrite(buffer, size, count, logFile->file);
- else { /* we're writing to memory */
- /* do nothing as this isn't supported yet */
- return count;
- }
+ if (logFile->file)
+ return fwrite(buffer, size, count, logFile->file);
+ else { /* we're writing to memory */
+ /* do nothing as this isn't supported yet */
+ return count;
+ }
}
int logimage_fread(void *buffer, size_t size, unsigned int count, LogImageFile *logFile)
{
- if (logFile->file) {
- return fread(buffer, size, count, logFile->file);
- }
- else { /* we're reading from memory */
- unsigned char *buf = (unsigned char *)buffer;
- uintptr_t pos = (uintptr_t)logFile->memCursor - (uintptr_t)logFile->memBuffer;
- size_t total_size = size * count;
- if (pos + total_size > logFile->memBufferSize) {
- /* how many elements can we read without overflow ? */
- count = (logFile->memBufferSize - pos) / size;
- /* recompute the size */
- total_size = size * count;
- }
-
- if (total_size != 0)
- memcpy(buf, logFile->memCursor, total_size);
-
- return count;
- }
+ if (logFile->file) {
+ return fread(buffer, size, count, logFile->file);
+ }
+ else { /* we're reading from memory */
+ unsigned char *buf = (unsigned char *)buffer;
+ uintptr_t pos = (uintptr_t)logFile->memCursor - (uintptr_t)logFile->memBuffer;
+ size_t total_size = size * count;
+ if (pos + total_size > logFile->memBufferSize) {
+ /* how many elements can we read without overflow ? */
+ count = (logFile->memBufferSize - pos) / size;
+ /* recompute the size */
+ total_size = size * count;
+ }
+
+ if (total_size != 0)
+ memcpy(buf, logFile->memCursor, total_size);
+
+ return count;
+ }
}
int logimage_read_uchar(unsigned char *x, LogImageFile *logFile)
{
- uintptr_t pos = (uintptr_t)logFile->memCursor - (uintptr_t)logFile->memBuffer;
- if (pos + sizeof(unsigned char) > logFile->memBufferSize)
- return 1;
+ uintptr_t pos = (uintptr_t)logFile->memCursor - (uintptr_t)logFile->memBuffer;
+ if (pos + sizeof(unsigned char) > logFile->memBufferSize)
+ return 1;
- *x = *(unsigned char *)logFile->memCursor;
- logFile->memCursor += sizeof(unsigned char);
- return 0;
+ *x = *(unsigned char *)logFile->memCursor;
+ logFile->memCursor += sizeof(unsigned char);
+ return 0;
}
int logimage_read_ushort(unsigned short *x, LogImageFile *logFile)
{
- uintptr_t pos = (uintptr_t)logFile->memCursor - (uintptr_t)logFile->memBuffer;
- if (pos + sizeof(unsigned short) > logFile->memBufferSize)
- return 1;
+ uintptr_t pos = (uintptr_t)logFile->memCursor - (uintptr_t)logFile->memBuffer;
+ if (pos + sizeof(unsigned short) > logFile->memBufferSize)
+ return 1;
- *x = *(unsigned short *)logFile->memCursor;
- logFile->memCursor += sizeof(unsigned short);
- return 0;
+ *x = *(unsigned short *)logFile->memCursor;
+ logFile->memCursor += sizeof(unsigned short);
+ return 0;
}
int logimage_read_uint(unsigned int *x, LogImageFile *logFile)
{
- uintptr_t pos = (uintptr_t)logFile->memCursor - (uintptr_t)logFile->memBuffer;
- if (pos + sizeof(unsigned int) > logFile->memBufferSize)
- return 1;
+ uintptr_t pos = (uintptr_t)logFile->memCursor - (uintptr_t)logFile->memBuffer;
+ if (pos + sizeof(unsigned int) > logFile->memBufferSize)
+ return 1;
- *x = *(unsigned int *)logFile->memCursor;
- logFile->memCursor += sizeof(unsigned int);
- return 0;
+ *x = *(unsigned int *)logFile->memCursor;
+ logFile->memCursor += sizeof(unsigned int);
+ return 0;
}
diff --git a/source/blender/imbuf/intern/cineon/logmemfile.h b/source/blender/imbuf/intern/cineon/logmemfile.h
index 9b6def2a617..d0ca03193e5 100644
--- a/source/blender/imbuf/intern/cineon/logmemfile.h
+++ b/source/blender/imbuf/intern/cineon/logmemfile.h
@@ -22,7 +22,6 @@
* Cineon image file format library routines.
*/
-
#ifndef __LOGMEMFILE_H__
#define __LOGMEMFILE_H__
@@ -37,4 +36,4 @@ int logimage_read_uchar(unsigned char *x, LogImageFile *logFile);
int logimage_read_ushort(unsigned short *x, LogImageFile *logFile);
int logimage_read_uint(unsigned int *x, LogImageFile *logFile);
-#endif /* __LOGMEMFILE_H__ */
+#endif /* __LOGMEMFILE_H__ */
diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c
index 597421d80c6..ac35cc10920 100644
--- a/source/blender/imbuf/intern/colormanagement.c
+++ b/source/blender/imbuf/intern/colormanagement.c
@@ -97,37 +97,37 @@ static float imbuf_linear_srgb_to_xyz[3][3] = {{0.0f}};
static pthread_mutex_t processor_lock = BLI_MUTEX_INITIALIZER;
typedef struct ColormanageProcessor {
- OCIO_ConstProcessorRcPtr *processor;
- CurveMapping *curve_mapping;
- bool is_data_result;
+ OCIO_ConstProcessorRcPtr *processor;
+ CurveMapping *curve_mapping;
+ bool is_data_result;
} ColormanageProcessor;
static struct global_glsl_state {
- /* Actual processor used for GLSL baked LUTs. */
- OCIO_ConstProcessorRcPtr *processor;
-
- /* Settings of processor for comparison. */
- char look[MAX_COLORSPACE_NAME];
- char view[MAX_COLORSPACE_NAME];
- char display[MAX_COLORSPACE_NAME];
- char input[MAX_COLORSPACE_NAME];
- float exposure, gamma;
-
- CurveMapping *curve_mapping, *orig_curve_mapping;
- bool use_curve_mapping;
- int curve_mapping_timestamp;
- OCIO_CurveMappingSettings curve_mapping_settings;
-
- /* Container for GLSL state needed for OCIO module. */
- struct OCIO_GLSLDrawState *ocio_glsl_state;
- struct OCIO_GLSLDrawState *transform_ocio_glsl_state;
+ /* Actual processor used for GLSL baked LUTs. */
+ OCIO_ConstProcessorRcPtr *processor;
+
+ /* Settings of processor for comparison. */
+ char look[MAX_COLORSPACE_NAME];
+ char view[MAX_COLORSPACE_NAME];
+ char display[MAX_COLORSPACE_NAME];
+ char input[MAX_COLORSPACE_NAME];
+ float exposure, gamma;
+
+ CurveMapping *curve_mapping, *orig_curve_mapping;
+ bool use_curve_mapping;
+ int curve_mapping_timestamp;
+ OCIO_CurveMappingSettings curve_mapping_settings;
+
+ /* Container for GLSL state needed for OCIO module. */
+ struct OCIO_GLSLDrawState *ocio_glsl_state;
+ struct OCIO_GLSLDrawState *transform_ocio_glsl_state;
} global_glsl_state = {NULL};
static struct global_color_picking_state {
- /* Cached processor for color picking conversion. */
- OCIO_ConstProcessorRcPtr *processor_to;
- OCIO_ConstProcessorRcPtr *processor_from;
- bool failed;
+ /* Cached processor for color picking conversion. */
+ OCIO_ConstProcessorRcPtr *processor_to;
+ OCIO_ConstProcessorRcPtr *processor_from;
+ bool failed;
} global_color_picking_state = {NULL};
/*********************** Color managed cache *************************/
@@ -197,1644 +197,1778 @@ static struct global_color_picking_state {
* to color management cache system and keeps calls small and nice.
*/
typedef struct ColormanageCacheViewSettings {
- int flag;
- int look;
- int view;
- float exposure;
- float gamma;
- float dither;
- CurveMapping *curve_mapping;
+ int flag;
+ int look;
+ int view;
+ float exposure;
+ float gamma;
+ float dither;
+ CurveMapping *curve_mapping;
} ColormanageCacheViewSettings;
typedef struct ColormanageCacheDisplaySettings {
- int display;
+ int display;
} ColormanageCacheDisplaySettings;
typedef struct ColormanageCacheKey {
- int view; /* view transformation used for display buffer */
- int display; /* display device name */
+ int view; /* view transformation used for display buffer */
+ int display; /* display device name */
} ColormanageCacheKey;
typedef struct ColormanageCacheData {
- int flag; /* view flags of cached buffer */
- int look; /* Additional artistics transform */
- float exposure; /* exposure value cached buffer is calculated with */
- float gamma; /* gamma value cached buffer is calculated with */
- float dither; /* dither value cached buffer is calculated with */
- CurveMapping *curve_mapping; /* curve mapping used for cached buffer */
- int curve_mapping_timestamp; /* time stamp of curve mapping used for cached buffer */
+ int flag; /* view flags of cached buffer */
+ int look; /* Additional artistics transform */
+ float exposure; /* exposure value cached buffer is calculated with */
+ float gamma; /* gamma value cached buffer is calculated with */
+ float dither; /* dither value cached buffer is calculated with */
+ CurveMapping *curve_mapping; /* curve mapping used for cached buffer */
+ int curve_mapping_timestamp; /* time stamp of curve mapping used for cached buffer */
} ColormanageCacheData;
typedef struct ColormanageCache {
- struct MovieCache *moviecache;
+ struct MovieCache *moviecache;
- ColormanageCacheData *data;
+ ColormanageCacheData *data;
} ColormanageCache;
static struct MovieCache *colormanage_moviecache_get(const ImBuf *ibuf)
{
- if (!ibuf->colormanage_cache)
- return NULL;
+ if (!ibuf->colormanage_cache)
+ return NULL;
- return ibuf->colormanage_cache->moviecache;
+ return ibuf->colormanage_cache->moviecache;
}
static ColormanageCacheData *colormanage_cachedata_get(const ImBuf *ibuf)
{
- if (!ibuf->colormanage_cache)
- return NULL;
+ if (!ibuf->colormanage_cache)
+ return NULL;
- return ibuf->colormanage_cache->data;
+ return ibuf->colormanage_cache->data;
}
static unsigned int colormanage_hashhash(const void *key_v)
{
- const ColormanageCacheKey *key = key_v;
+ const ColormanageCacheKey *key = key_v;
- unsigned int rval = (key->display << 16) | (key->view % 0xffff);
+ unsigned int rval = (key->display << 16) | (key->view % 0xffff);
- return rval;
+ return rval;
}
static bool colormanage_hashcmp(const void *av, const void *bv)
{
- const ColormanageCacheKey *a = av;
- const ColormanageCacheKey *b = bv;
+ const ColormanageCacheKey *a = av;
+ const ColormanageCacheKey *b = bv;
- return ((a->view != b->view) ||
- (a->display != b->display));
+ return ((a->view != b->view) || (a->display != b->display));
}
static struct MovieCache *colormanage_moviecache_ensure(ImBuf *ibuf)
{
- if (!ibuf->colormanage_cache)
- ibuf->colormanage_cache = MEM_callocN(sizeof(ColormanageCache), "imbuf colormanage cache");
+ if (!ibuf->colormanage_cache)
+ ibuf->colormanage_cache = MEM_callocN(sizeof(ColormanageCache), "imbuf colormanage cache");
- if (!ibuf->colormanage_cache->moviecache) {
- struct MovieCache *moviecache;
+ if (!ibuf->colormanage_cache->moviecache) {
+ struct MovieCache *moviecache;
- moviecache = IMB_moviecache_create("colormanage cache", sizeof(ColormanageCacheKey),
- colormanage_hashhash, colormanage_hashcmp);
+ moviecache = IMB_moviecache_create("colormanage cache",
+ sizeof(ColormanageCacheKey),
+ colormanage_hashhash,
+ colormanage_hashcmp);
- ibuf->colormanage_cache->moviecache = moviecache;
- }
+ ibuf->colormanage_cache->moviecache = moviecache;
+ }
- return ibuf->colormanage_cache->moviecache;
+ return ibuf->colormanage_cache->moviecache;
}
static void colormanage_cachedata_set(ImBuf *ibuf, ColormanageCacheData *data)
{
- if (!ibuf->colormanage_cache)
- ibuf->colormanage_cache = MEM_callocN(sizeof(ColormanageCache), "imbuf colormanage cache");
+ if (!ibuf->colormanage_cache)
+ ibuf->colormanage_cache = MEM_callocN(sizeof(ColormanageCache), "imbuf colormanage cache");
- ibuf->colormanage_cache->data = data;
+ ibuf->colormanage_cache->data = data;
}
static void colormanage_view_settings_to_cache(ImBuf *ibuf,
ColormanageCacheViewSettings *cache_view_settings,
const ColorManagedViewSettings *view_settings)
{
- int look = IMB_colormanagement_look_get_named_index(view_settings->look);
- int view = IMB_colormanagement_view_get_named_index(view_settings->view_transform);
+ int look = IMB_colormanagement_look_get_named_index(view_settings->look);
+ int view = IMB_colormanagement_view_get_named_index(view_settings->view_transform);
- cache_view_settings->look = look;
- cache_view_settings->view = view;
- cache_view_settings->exposure = view_settings->exposure;
- cache_view_settings->gamma = view_settings->gamma;
- cache_view_settings->dither = ibuf->dither;
- cache_view_settings->flag = view_settings->flag;
- cache_view_settings->curve_mapping = view_settings->curve_mapping;
+ cache_view_settings->look = look;
+ cache_view_settings->view = view;
+ cache_view_settings->exposure = view_settings->exposure;
+ cache_view_settings->gamma = view_settings->gamma;
+ cache_view_settings->dither = ibuf->dither;
+ cache_view_settings->flag = view_settings->flag;
+ cache_view_settings->curve_mapping = view_settings->curve_mapping;
}
-static void colormanage_display_settings_to_cache(ColormanageCacheDisplaySettings *cache_display_settings,
- const ColorManagedDisplaySettings *display_settings)
+static void colormanage_display_settings_to_cache(
+ ColormanageCacheDisplaySettings *cache_display_settings,
+ const ColorManagedDisplaySettings *display_settings)
{
- int display = IMB_colormanagement_display_get_named_index(display_settings->display_device);
+ int display = IMB_colormanagement_display_get_named_index(display_settings->display_device);
- cache_display_settings->display = display;
+ cache_display_settings->display = display;
}
static void colormanage_settings_to_key(ColormanageCacheKey *key,
const ColormanageCacheViewSettings *view_settings,
const ColormanageCacheDisplaySettings *display_settings)
{
- key->view = view_settings->view;
- key->display = display_settings->display;
+ key->view = view_settings->view;
+ key->display = display_settings->display;
}
-static ImBuf *colormanage_cache_get_ibuf(ImBuf *ibuf, ColormanageCacheKey *key, void **cache_handle)
+static ImBuf *colormanage_cache_get_ibuf(ImBuf *ibuf,
+ ColormanageCacheKey *key,
+ void **cache_handle)
{
- ImBuf *cache_ibuf;
- struct MovieCache *moviecache = colormanage_moviecache_get(ibuf);
+ ImBuf *cache_ibuf;
+ struct MovieCache *moviecache = colormanage_moviecache_get(ibuf);
- if (!moviecache) {
- /* if there's no moviecache it means no color management was applied on given image buffer before */
+ if (!moviecache) {
+ /* if there's no moviecache it means no color management was applied on given image buffer before */
- return NULL;
- }
+ return NULL;
+ }
- *cache_handle = NULL;
+ *cache_handle = NULL;
- cache_ibuf = IMB_moviecache_get(moviecache, key);
+ cache_ibuf = IMB_moviecache_get(moviecache, key);
- *cache_handle = cache_ibuf;
+ *cache_handle = cache_ibuf;
- return cache_ibuf;
+ return cache_ibuf;
}
-static unsigned char *colormanage_cache_get(ImBuf *ibuf, const ColormanageCacheViewSettings *view_settings,
- const ColormanageCacheDisplaySettings *display_settings,
- void **cache_handle)
+static unsigned char *colormanage_cache_get(
+ ImBuf *ibuf,
+ const ColormanageCacheViewSettings *view_settings,
+ const ColormanageCacheDisplaySettings *display_settings,
+ void **cache_handle)
{
- ColormanageCacheKey key;
- ImBuf *cache_ibuf;
- int view_flag = 1 << (view_settings->view - 1);
- CurveMapping *curve_mapping = view_settings->curve_mapping;
- int curve_mapping_timestamp = curve_mapping ? curve_mapping->changed_timestamp : 0;
+ ColormanageCacheKey key;
+ ImBuf *cache_ibuf;
+ int view_flag = 1 << (view_settings->view - 1);
+ CurveMapping *curve_mapping = view_settings->curve_mapping;
+ int curve_mapping_timestamp = curve_mapping ? curve_mapping->changed_timestamp : 0;
- colormanage_settings_to_key(&key, view_settings, display_settings);
+ colormanage_settings_to_key(&key, view_settings, display_settings);
- /* check whether image was marked as dirty for requested transform */
- if ((ibuf->display_buffer_flags[display_settings->display - 1] & view_flag) == 0) {
- return NULL;
- }
+ /* check whether image was marked as dirty for requested transform */
+ if ((ibuf->display_buffer_flags[display_settings->display - 1] & view_flag) == 0) {
+ return NULL;
+ }
- cache_ibuf = colormanage_cache_get_ibuf(ibuf, &key, cache_handle);
+ cache_ibuf = colormanage_cache_get_ibuf(ibuf, &key, cache_handle);
- if (cache_ibuf) {
- ColormanageCacheData *cache_data;
+ if (cache_ibuf) {
+ ColormanageCacheData *cache_data;
- BLI_assert(cache_ibuf->x == ibuf->x &&
- cache_ibuf->y == ibuf->y);
+ BLI_assert(cache_ibuf->x == ibuf->x && cache_ibuf->y == ibuf->y);
- /* only buffers with different color space conversions are being stored
- * in cache separately. buffer which were used only different exposure/gamma
- * are re-suing the same cached buffer
- *
- * check here which exposure/gamma/curve was used for cached buffer and if they're
- * different from requested buffer should be re-generated
- */
- cache_data = colormanage_cachedata_get(cache_ibuf);
+ /* only buffers with different color space conversions are being stored
+ * in cache separately. buffer which were used only different exposure/gamma
+ * are re-suing the same cached buffer
+ *
+ * check here which exposure/gamma/curve was used for cached buffer and if they're
+ * different from requested buffer should be re-generated
+ */
+ cache_data = colormanage_cachedata_get(cache_ibuf);
- if (cache_data->look != view_settings->look ||
- cache_data->exposure != view_settings->exposure ||
- cache_data->gamma != view_settings->gamma ||
- cache_data->dither != view_settings->dither ||
- cache_data->flag != view_settings->flag ||
- cache_data->curve_mapping != curve_mapping ||
- cache_data->curve_mapping_timestamp != curve_mapping_timestamp)
- {
- *cache_handle = NULL;
+ if (cache_data->look != view_settings->look ||
+ cache_data->exposure != view_settings->exposure ||
+ cache_data->gamma != view_settings->gamma || cache_data->dither != view_settings->dither ||
+ cache_data->flag != view_settings->flag || cache_data->curve_mapping != curve_mapping ||
+ cache_data->curve_mapping_timestamp != curve_mapping_timestamp) {
+ *cache_handle = NULL;
- IMB_freeImBuf(cache_ibuf);
+ IMB_freeImBuf(cache_ibuf);
- return NULL;
- }
+ return NULL;
+ }
- return (unsigned char *) cache_ibuf->rect;
- }
+ return (unsigned char *)cache_ibuf->rect;
+ }
- return NULL;
+ return NULL;
}
-static void colormanage_cache_put(ImBuf *ibuf, const ColormanageCacheViewSettings *view_settings,
+static void colormanage_cache_put(ImBuf *ibuf,
+ const ColormanageCacheViewSettings *view_settings,
const ColormanageCacheDisplaySettings *display_settings,
- unsigned char *display_buffer, void **cache_handle)
+ unsigned char *display_buffer,
+ void **cache_handle)
{
- ColormanageCacheKey key;
- ImBuf *cache_ibuf;
- ColormanageCacheData *cache_data;
- int view_flag = 1 << (view_settings->view - 1);
- struct MovieCache *moviecache = colormanage_moviecache_ensure(ibuf);
- CurveMapping *curve_mapping = view_settings->curve_mapping;
- int curve_mapping_timestamp = curve_mapping ? curve_mapping->changed_timestamp : 0;
+ ColormanageCacheKey key;
+ ImBuf *cache_ibuf;
+ ColormanageCacheData *cache_data;
+ int view_flag = 1 << (view_settings->view - 1);
+ struct MovieCache *moviecache = colormanage_moviecache_ensure(ibuf);
+ CurveMapping *curve_mapping = view_settings->curve_mapping;
+ int curve_mapping_timestamp = curve_mapping ? curve_mapping->changed_timestamp : 0;
- colormanage_settings_to_key(&key, view_settings, display_settings);
+ colormanage_settings_to_key(&key, view_settings, display_settings);
- /* mark display buffer as valid */
- ibuf->display_buffer_flags[display_settings->display - 1] |= view_flag;
+ /* mark display buffer as valid */
+ ibuf->display_buffer_flags[display_settings->display - 1] |= view_flag;
- /* buffer itself */
- cache_ibuf = IMB_allocImBuf(ibuf->x, ibuf->y, ibuf->planes, 0);
- cache_ibuf->rect = (unsigned int *) display_buffer;
+ /* buffer itself */
+ cache_ibuf = IMB_allocImBuf(ibuf->x, ibuf->y, ibuf->planes, 0);
+ cache_ibuf->rect = (unsigned int *)display_buffer;
- cache_ibuf->mall |= IB_rect;
- cache_ibuf->flags |= IB_rect;
+ cache_ibuf->mall |= IB_rect;
+ cache_ibuf->flags |= IB_rect;
- /* store data which is needed to check whether cached buffer could be used for color managed display settings */
- cache_data = MEM_callocN(sizeof(ColormanageCacheData), "color manage cache imbuf data");
- cache_data->look = view_settings->look;
- cache_data->exposure = view_settings->exposure;
- cache_data->gamma = view_settings->gamma;
- cache_data->dither = view_settings->dither;
- cache_data->flag = view_settings->flag;
- cache_data->curve_mapping = curve_mapping;
- cache_data->curve_mapping_timestamp = curve_mapping_timestamp;
+ /* store data which is needed to check whether cached buffer could be used for color managed display settings */
+ cache_data = MEM_callocN(sizeof(ColormanageCacheData), "color manage cache imbuf data");
+ cache_data->look = view_settings->look;
+ cache_data->exposure = view_settings->exposure;
+ cache_data->gamma = view_settings->gamma;
+ cache_data->dither = view_settings->dither;
+ cache_data->flag = view_settings->flag;
+ cache_data->curve_mapping = curve_mapping;
+ cache_data->curve_mapping_timestamp = curve_mapping_timestamp;
- colormanage_cachedata_set(cache_ibuf, cache_data);
+ colormanage_cachedata_set(cache_ibuf, cache_data);
- *cache_handle = cache_ibuf;
+ *cache_handle = cache_ibuf;
- IMB_moviecache_put(moviecache, &key, cache_ibuf);
+ IMB_moviecache_put(moviecache, &key, cache_ibuf);
}
static void colormanage_cache_handle_release(void *cache_handle)
{
- ImBuf *cache_ibuf = cache_handle;
+ ImBuf *cache_ibuf = cache_handle;
- IMB_freeImBuf(cache_ibuf);
+ IMB_freeImBuf(cache_ibuf);
}
/*********************** Initialization / De-initialization *************************/
-static void colormanage_role_color_space_name_get(OCIO_ConstConfigRcPtr *config, char *colorspace_name, const char *role, const char *backup_role)
+static void colormanage_role_color_space_name_get(OCIO_ConstConfigRcPtr *config,
+ char *colorspace_name,
+ const char *role,
+ const char *backup_role)
{
- OCIO_ConstColorSpaceRcPtr *ociocs;
+ OCIO_ConstColorSpaceRcPtr *ociocs;
- ociocs = OCIO_configGetColorSpace(config, role);
+ ociocs = OCIO_configGetColorSpace(config, role);
- if (!ociocs && backup_role)
- ociocs = OCIO_configGetColorSpace(config, backup_role);
+ if (!ociocs && backup_role)
+ ociocs = OCIO_configGetColorSpace(config, backup_role);
- if (ociocs) {
- const char *name = OCIO_colorSpaceGetName(ociocs);
+ if (ociocs) {
+ const char *name = OCIO_colorSpaceGetName(ociocs);
- /* assume function was called with buffer properly allocated to MAX_COLORSPACE_NAME chars */
- BLI_strncpy(colorspace_name, name, MAX_COLORSPACE_NAME);
- OCIO_colorSpaceRelease(ociocs);
- }
- else {
- printf("Color management: Error could not find role %s role.\n", role);
- }
+ /* assume function was called with buffer properly allocated to MAX_COLORSPACE_NAME chars */
+ BLI_strncpy(colorspace_name, name, MAX_COLORSPACE_NAME);
+ OCIO_colorSpaceRelease(ociocs);
+ }
+ else {
+ printf("Color management: Error could not find role %s role.\n", role);
+ }
}
static void colormanage_load_config(OCIO_ConstConfigRcPtr *config)
{
- int tot_colorspace, tot_display, tot_display_view, tot_looks;
- int index, viewindex, viewindex2;
- const char *name;
+ int tot_colorspace, tot_display, tot_display_view, tot_looks;
+ int index, viewindex, viewindex2;
+ const char *name;
- /* get roles */
- colormanage_role_color_space_name_get(config, global_role_scene_linear, OCIO_ROLE_SCENE_LINEAR, NULL);
- colormanage_role_color_space_name_get(config, global_role_color_picking, OCIO_ROLE_COLOR_PICKING, NULL);
- colormanage_role_color_space_name_get(config, global_role_texture_painting, OCIO_ROLE_TEXTURE_PAINT, NULL);
- colormanage_role_color_space_name_get(config, global_role_default_sequencer, OCIO_ROLE_DEFAULT_SEQUENCER, OCIO_ROLE_SCENE_LINEAR);
- colormanage_role_color_space_name_get(config, global_role_default_byte, OCIO_ROLE_DEFAULT_BYTE, OCIO_ROLE_TEXTURE_PAINT);
- colormanage_role_color_space_name_get(config, global_role_default_float, OCIO_ROLE_DEFAULT_FLOAT, OCIO_ROLE_SCENE_LINEAR);
+ /* get roles */
+ colormanage_role_color_space_name_get(
+ config, global_role_scene_linear, OCIO_ROLE_SCENE_LINEAR, NULL);
+ colormanage_role_color_space_name_get(
+ config, global_role_color_picking, OCIO_ROLE_COLOR_PICKING, NULL);
+ colormanage_role_color_space_name_get(
+ config, global_role_texture_painting, OCIO_ROLE_TEXTURE_PAINT, NULL);
+ colormanage_role_color_space_name_get(
+ config, global_role_default_sequencer, OCIO_ROLE_DEFAULT_SEQUENCER, OCIO_ROLE_SCENE_LINEAR);
+ colormanage_role_color_space_name_get(
+ config, global_role_default_byte, OCIO_ROLE_DEFAULT_BYTE, OCIO_ROLE_TEXTURE_PAINT);
+ colormanage_role_color_space_name_get(
+ config, global_role_default_float, OCIO_ROLE_DEFAULT_FLOAT, OCIO_ROLE_SCENE_LINEAR);
- /* load colorspaces */
- tot_colorspace = OCIO_configGetNumColorSpaces(config);
- for (index = 0 ; index < tot_colorspace; index++) {
- OCIO_ConstColorSpaceRcPtr *ocio_colorspace;
- const char *description;
- bool is_invertible, is_data;
+ /* load colorspaces */
+ tot_colorspace = OCIO_configGetNumColorSpaces(config);
+ for (index = 0; index < tot_colorspace; index++) {
+ OCIO_ConstColorSpaceRcPtr *ocio_colorspace;
+ const char *description;
+ bool is_invertible, is_data;
- name = OCIO_configGetColorSpaceNameByIndex(config, index);
+ name = OCIO_configGetColorSpaceNameByIndex(config, index);
- ocio_colorspace = OCIO_configGetColorSpace(config, name);
- description = OCIO_colorSpaceGetDescription(ocio_colorspace);
- is_invertible = OCIO_colorSpaceIsInvertible(ocio_colorspace);
- is_data = OCIO_colorSpaceIsData(ocio_colorspace);
+ ocio_colorspace = OCIO_configGetColorSpace(config, name);
+ description = OCIO_colorSpaceGetDescription(ocio_colorspace);
+ is_invertible = OCIO_colorSpaceIsInvertible(ocio_colorspace);
+ is_data = OCIO_colorSpaceIsData(ocio_colorspace);
- colormanage_colorspace_add(name, description, is_invertible, is_data);
+ colormanage_colorspace_add(name, description, is_invertible, is_data);
- OCIO_colorSpaceRelease(ocio_colorspace);
- }
+ OCIO_colorSpaceRelease(ocio_colorspace);
+ }
- /* load displays */
- viewindex2 = 0;
- tot_display = OCIO_configGetNumDisplays(config);
+ /* load displays */
+ viewindex2 = 0;
+ tot_display = OCIO_configGetNumDisplays(config);
- for (index = 0 ; index < tot_display; index++) {
- const char *displayname;
- ColorManagedDisplay *display;
+ for (index = 0; index < tot_display; index++) {
+ const char *displayname;
+ ColorManagedDisplay *display;
- displayname = OCIO_configGetDisplay(config, index);
+ displayname = OCIO_configGetDisplay(config, index);
- display = colormanage_display_add(displayname);
+ display = colormanage_display_add(displayname);
- /* load views */
- tot_display_view = OCIO_configGetNumViews(config, displayname);
- for (viewindex = 0 ; viewindex < tot_display_view; viewindex++, viewindex2++) {
- const char *viewname;
- ColorManagedView *view;
- LinkData *display_view;
+ /* load views */
+ tot_display_view = OCIO_configGetNumViews(config, displayname);
+ for (viewindex = 0; viewindex < tot_display_view; viewindex++, viewindex2++) {
+ const char *viewname;
+ ColorManagedView *view;
+ LinkData *display_view;
- viewname = OCIO_configGetView(config, displayname, viewindex);
+ viewname = OCIO_configGetView(config, displayname, viewindex);
- /* first check if view transform with given name was already loaded */
- view = colormanage_view_get_named(viewname);
+ /* first check if view transform with given name was already loaded */
+ view = colormanage_view_get_named(viewname);
- if (!view) {
- view = colormanage_view_add(viewname);
- }
+ if (!view) {
+ view = colormanage_view_add(viewname);
+ }
- display_view = BLI_genericNodeN(view);
+ display_view = BLI_genericNodeN(view);
- BLI_addtail(&display->views, display_view);
- }
- }
+ BLI_addtail(&display->views, display_view);
+ }
+ }
- global_tot_display = tot_display;
+ global_tot_display = tot_display;
- /* load looks */
- tot_looks = OCIO_configGetNumLooks(config);
- colormanage_look_add("None", "", true);
- for (index = 0; index < tot_looks; index++) {
- OCIO_ConstLookRcPtr *ocio_look;
- const char *process_space;
+ /* load looks */
+ tot_looks = OCIO_configGetNumLooks(config);
+ colormanage_look_add("None", "", true);
+ for (index = 0; index < tot_looks; index++) {
+ OCIO_ConstLookRcPtr *ocio_look;
+ const char *process_space;
- name = OCIO_configGetLookNameByIndex(config, index);
- ocio_look = OCIO_configGetLook(config, name);
- process_space = OCIO_lookGetProcessSpace(ocio_look);
- OCIO_lookRelease(ocio_look);
+ name = OCIO_configGetLookNameByIndex(config, index);
+ ocio_look = OCIO_configGetLook(config, name);
+ process_space = OCIO_lookGetProcessSpace(ocio_look);
+ OCIO_lookRelease(ocio_look);
- colormanage_look_add(name, process_space, false);
- }
+ colormanage_look_add(name, process_space, false);
+ }
- /* Load luminance coefficients. */
- OCIO_configGetDefaultLumaCoefs(config, imbuf_luma_coefficients);
- OCIO_configGetXYZtoRGB(config, imbuf_xyz_to_rgb);
- invert_m3_m3(imbuf_rgb_to_xyz, imbuf_xyz_to_rgb);
- copy_m3_m3(imbuf_xyz_to_linear_srgb, OCIO_XYZ_TO_LINEAR_SRGB);
- invert_m3_m3(imbuf_linear_srgb_to_xyz, imbuf_xyz_to_linear_srgb);
+ /* Load luminance coefficients. */
+ OCIO_configGetDefaultLumaCoefs(config, imbuf_luma_coefficients);
+ OCIO_configGetXYZtoRGB(config, imbuf_xyz_to_rgb);
+ invert_m3_m3(imbuf_rgb_to_xyz, imbuf_xyz_to_rgb);
+ copy_m3_m3(imbuf_xyz_to_linear_srgb, OCIO_XYZ_TO_LINEAR_SRGB);
+ invert_m3_m3(imbuf_linear_srgb_to_xyz, imbuf_xyz_to_linear_srgb);
}
static void colormanage_free_config(void)
{
- ColorSpace *colorspace;
- ColorManagedDisplay *display;
+ ColorSpace *colorspace;
+ ColorManagedDisplay *display;
- /* free color spaces */
- colorspace = global_colorspaces.first;
- while (colorspace) {
- ColorSpace *colorspace_next = colorspace->next;
+ /* free color spaces */
+ colorspace = global_colorspaces.first;
+ while (colorspace) {
+ ColorSpace *colorspace_next = colorspace->next;
- /* free precomputer processors */
- if (colorspace->to_scene_linear)
- OCIO_processorRelease((OCIO_ConstProcessorRcPtr *) colorspace->to_scene_linear);
+ /* free precomputer processors */
+ if (colorspace->to_scene_linear)
+ OCIO_processorRelease((OCIO_ConstProcessorRcPtr *)colorspace->to_scene_linear);
- if (colorspace->from_scene_linear)
- OCIO_processorRelease((OCIO_ConstProcessorRcPtr *) colorspace->from_scene_linear);
+ if (colorspace->from_scene_linear)
+ OCIO_processorRelease((OCIO_ConstProcessorRcPtr *)colorspace->from_scene_linear);
- /* free color space itself */
- MEM_freeN(colorspace);
+ /* free color space itself */
+ MEM_freeN(colorspace);
- colorspace = colorspace_next;
- }
- BLI_listbase_clear(&global_colorspaces);
- global_tot_colorspace = 0;
+ colorspace = colorspace_next;
+ }
+ BLI_listbase_clear(&global_colorspaces);
+ global_tot_colorspace = 0;
- /* free displays */
- display = global_displays.first;
- while (display) {
- ColorManagedDisplay *display_next = display->next;
+ /* free displays */
+ display = global_displays.first;
+ while (display) {
+ ColorManagedDisplay *display_next = display->next;
- /* free precomputer processors */
- if (display->to_scene_linear)
- OCIO_processorRelease((OCIO_ConstProcessorRcPtr *) display->to_scene_linear);
+ /* free precomputer processors */
+ if (display->to_scene_linear)
+ OCIO_processorRelease((OCIO_ConstProcessorRcPtr *)display->to_scene_linear);
- if (display->from_scene_linear)
- OCIO_processorRelease((OCIO_ConstProcessorRcPtr *) display->from_scene_linear);
+ if (display->from_scene_linear)
+ OCIO_processorRelease((OCIO_ConstProcessorRcPtr *)display->from_scene_linear);
- /* free list of views */
- BLI_freelistN(&display->views);
+ /* free list of views */
+ BLI_freelistN(&display->views);
- MEM_freeN(display);
- display = display_next;
- }
- BLI_listbase_clear(&global_displays);
- global_tot_display = 0;
+ MEM_freeN(display);
+ display = display_next;
+ }
+ BLI_listbase_clear(&global_displays);
+ global_tot_display = 0;
- /* free views */
- BLI_freelistN(&global_views);
- global_tot_view = 0;
+ /* free views */
+ BLI_freelistN(&global_views);
+ global_tot_view = 0;
- /* free looks */
- BLI_freelistN(&global_looks);
- global_tot_looks = 0;
+ /* free looks */
+ BLI_freelistN(&global_looks);
+ global_tot_looks = 0;
- OCIO_exit();
+ OCIO_exit();
}
void colormanagement_init(void)
{
- const char *ocio_env;
- const char *configdir;
- char configfile[FILE_MAX];
- OCIO_ConstConfigRcPtr *config = NULL;
+ const char *ocio_env;
+ const char *configdir;
+ char configfile[FILE_MAX];
+ OCIO_ConstConfigRcPtr *config = NULL;
- OCIO_init();
+ OCIO_init();
- ocio_env = BLI_getenv("OCIO");
+ ocio_env = BLI_getenv("OCIO");
- if (ocio_env && ocio_env[0] != '\0') {
- config = OCIO_configCreateFromEnv();
- if (config != NULL) {
- printf("Color management: Using %s as a configuration file\n", ocio_env);
- }
- }
+ if (ocio_env && ocio_env[0] != '\0') {
+ config = OCIO_configCreateFromEnv();
+ if (config != NULL) {
+ printf("Color management: Using %s as a configuration file\n", ocio_env);
+ }
+ }
- if (config == NULL) {
- configdir = BKE_appdir_folder_id(BLENDER_DATAFILES, "colormanagement");
+ if (config == NULL) {
+ configdir = BKE_appdir_folder_id(BLENDER_DATAFILES, "colormanagement");
- if (configdir) {
- BLI_join_dirfile(configfile, sizeof(configfile), configdir, BCM_CONFIG_FILE);
+ if (configdir) {
+ BLI_join_dirfile(configfile, sizeof(configfile), configdir, BCM_CONFIG_FILE);
#ifdef WIN32
- {
- /* quite a hack to support loading configuration from path with non-acii symbols */
+ {
+ /* quite a hack to support loading configuration from path with non-acii symbols */
- char short_name[256];
- BLI_get_short_name(short_name, configfile);
- config = OCIO_configCreateFromFile(short_name);
- }
+ char short_name[256];
+ BLI_get_short_name(short_name, configfile);
+ config = OCIO_configCreateFromFile(short_name);
+ }
#else
- config = OCIO_configCreateFromFile(configfile);
+ config = OCIO_configCreateFromFile(configfile);
#endif
- }
- }
+ }
+ }
- if (config == NULL) {
- printf("Color management: using fallback mode for management\n");
+ if (config == NULL) {
+ printf("Color management: using fallback mode for management\n");
- config = OCIO_configCreateFallback();
- }
+ config = OCIO_configCreateFallback();
+ }
- if (config) {
- OCIO_setCurrentConfig(config);
+ if (config) {
+ OCIO_setCurrentConfig(config);
- colormanage_load_config(config);
+ colormanage_load_config(config);
- OCIO_configRelease(config);
- }
+ OCIO_configRelease(config);
+ }
- /* If there're no valid display/views, use fallback mode. */
- if (global_tot_display == 0 || global_tot_view == 0) {
- printf("Color management: no displays/views in the config, using fallback mode instead\n");
+ /* If there're no valid display/views, use fallback mode. */
+ if (global_tot_display == 0 || global_tot_view == 0) {
+ printf("Color management: no displays/views in the config, using fallback mode instead\n");
- /* Free old config. */
- colormanage_free_config();
+ /* Free old config. */
+ colormanage_free_config();
- /* Initialize fallback config. */
- config = OCIO_configCreateFallback();
- colormanage_load_config(config);
- }
+ /* Initialize fallback config. */
+ config = OCIO_configCreateFallback();
+ colormanage_load_config(config);
+ }
- BLI_init_srgb_conversion();
+ BLI_init_srgb_conversion();
}
void colormanagement_exit(void)
{
- if (global_glsl_state.processor)
- OCIO_processorRelease(global_glsl_state.processor);
+ if (global_glsl_state.processor)
+ OCIO_processorRelease(global_glsl_state.processor);
- if (global_glsl_state.curve_mapping)
- curvemapping_free(global_glsl_state.curve_mapping);
+ if (global_glsl_state.curve_mapping)
+ curvemapping_free(global_glsl_state.curve_mapping);
- if (global_glsl_state.curve_mapping_settings.lut)
- MEM_freeN(global_glsl_state.curve_mapping_settings.lut);
+ if (global_glsl_state.curve_mapping_settings.lut)
+ MEM_freeN(global_glsl_state.curve_mapping_settings.lut);
- if (global_glsl_state.ocio_glsl_state)
- OCIO_freeOGLState(global_glsl_state.ocio_glsl_state);
+ if (global_glsl_state.ocio_glsl_state)
+ OCIO_freeOGLState(global_glsl_state.ocio_glsl_state);
- if (global_glsl_state.transform_ocio_glsl_state)
- OCIO_freeOGLState(global_glsl_state.transform_ocio_glsl_state);
+ if (global_glsl_state.transform_ocio_glsl_state)
+ OCIO_freeOGLState(global_glsl_state.transform_ocio_glsl_state);
- if (global_color_picking_state.processor_to)
- OCIO_processorRelease(global_color_picking_state.processor_to);
+ if (global_color_picking_state.processor_to)
+ OCIO_processorRelease(global_color_picking_state.processor_to);
- if (global_color_picking_state.processor_from)
- OCIO_processorRelease(global_color_picking_state.processor_from);
+ if (global_color_picking_state.processor_from)
+ OCIO_processorRelease(global_color_picking_state.processor_from);
- memset(&global_glsl_state, 0, sizeof(global_glsl_state));
- memset(&global_color_picking_state, 0, sizeof(global_color_picking_state));
+ memset(&global_glsl_state, 0, sizeof(global_glsl_state));
+ memset(&global_color_picking_state, 0, sizeof(global_color_picking_state));
- colormanage_free_config();
+ colormanage_free_config();
}
/*********************** Internal functions *************************/
void colormanage_cache_free(ImBuf *ibuf)
{
- if (ibuf->display_buffer_flags) {
- MEM_freeN(ibuf->display_buffer_flags);
+ if (ibuf->display_buffer_flags) {
+ MEM_freeN(ibuf->display_buffer_flags);
- ibuf->display_buffer_flags = NULL;
- }
+ ibuf->display_buffer_flags = NULL;
+ }
- if (ibuf->colormanage_cache) {
- ColormanageCacheData *cache_data = colormanage_cachedata_get(ibuf);
- struct MovieCache *moviecache = colormanage_moviecache_get(ibuf);
+ if (ibuf->colormanage_cache) {
+ ColormanageCacheData *cache_data = colormanage_cachedata_get(ibuf);
+ struct MovieCache *moviecache = colormanage_moviecache_get(ibuf);
- if (cache_data) {
- MEM_freeN(cache_data);
- }
+ if (cache_data) {
+ MEM_freeN(cache_data);
+ }
- if (moviecache) {
- IMB_moviecache_free(moviecache);
- }
+ if (moviecache) {
+ IMB_moviecache_free(moviecache);
+ }
- MEM_freeN(ibuf->colormanage_cache);
+ MEM_freeN(ibuf->colormanage_cache);
- ibuf->colormanage_cache = NULL;
- }
+ ibuf->colormanage_cache = NULL;
+ }
}
-void IMB_colormanagement_display_settings_from_ctx(const bContext *C,
- ColorManagedViewSettings **view_settings_r,
- ColorManagedDisplaySettings **display_settings_r)
+void IMB_colormanagement_display_settings_from_ctx(
+ const bContext *C,
+ ColorManagedViewSettings **view_settings_r,
+ ColorManagedDisplaySettings **display_settings_r)
{
- Scene *scene = CTX_data_scene(C);
- SpaceImage *sima = CTX_wm_space_image(C);
+ Scene *scene = CTX_data_scene(C);
+ SpaceImage *sima = CTX_wm_space_image(C);
- *view_settings_r = &scene->view_settings;
- *display_settings_r = &scene->display_settings;
+ *view_settings_r = &scene->view_settings;
+ *display_settings_r = &scene->display_settings;
- if (sima && sima->image) {
- if ((sima->image->flag & IMA_VIEW_AS_RENDER) == 0)
- *view_settings_r = NULL;
- }
+ if (sima && sima->image) {
+ if ((sima->image->flag & IMA_VIEW_AS_RENDER) == 0)
+ *view_settings_r = NULL;
+ }
}
-const char *IMB_colormanagement_get_display_colorspace_name(const ColorManagedViewSettings *view_settings,
- const ColorManagedDisplaySettings *display_settings)
+const char *IMB_colormanagement_get_display_colorspace_name(
+ const ColorManagedViewSettings *view_settings,
+ const ColorManagedDisplaySettings *display_settings)
{
- OCIO_ConstConfigRcPtr *config = OCIO_getCurrentConfig();
+ OCIO_ConstConfigRcPtr *config = OCIO_getCurrentConfig();
- const char *display = display_settings->display_device;
- const char *view = view_settings->view_transform;
- const char *colorspace_name;
+ const char *display = display_settings->display_device;
+ const char *view = view_settings->view_transform;
+ const char *colorspace_name;
- colorspace_name = OCIO_configGetDisplayColorSpaceName(config, display, view);
+ colorspace_name = OCIO_configGetDisplayColorSpaceName(config, display, view);
- OCIO_configRelease(config);
+ OCIO_configRelease(config);
- return colorspace_name;
+ return colorspace_name;
}
-static ColorSpace *display_transform_get_colorspace(const ColorManagedViewSettings *view_settings,
- const ColorManagedDisplaySettings *display_settings)
+static ColorSpace *display_transform_get_colorspace(
+ const ColorManagedViewSettings *view_settings,
+ const ColorManagedDisplaySettings *display_settings)
{
- const char *colorspace_name = IMB_colormanagement_get_display_colorspace_name(view_settings, display_settings);
+ const char *colorspace_name = IMB_colormanagement_get_display_colorspace_name(view_settings,
+ display_settings);
- if (colorspace_name)
- return colormanage_colorspace_get_named(colorspace_name);
+ if (colorspace_name)
+ return colormanage_colorspace_get_named(colorspace_name);
- return NULL;
+ return NULL;
}
static OCIO_ConstProcessorRcPtr *create_display_buffer_processor(const char *look,
const char *view_transform,
const char *display,
- float exposure, float gamma,
+ float exposure,
+ float gamma,
const char *from_colorspace)
{
- OCIO_ConstConfigRcPtr *config = OCIO_getCurrentConfig();
- OCIO_DisplayTransformRcPtr *dt;
- OCIO_ConstProcessorRcPtr *processor;
- ColorManagedLook *look_descr = colormanage_look_get_named(look);
+ OCIO_ConstConfigRcPtr *config = OCIO_getCurrentConfig();
+ OCIO_DisplayTransformRcPtr *dt;
+ OCIO_ConstProcessorRcPtr *processor;
+ ColorManagedLook *look_descr = colormanage_look_get_named(look);
- dt = OCIO_createDisplayTransform();
+ dt = OCIO_createDisplayTransform();
- OCIO_displayTransformSetInputColorSpaceName(dt, from_colorspace);
- OCIO_displayTransformSetView(dt, view_transform);
- OCIO_displayTransformSetDisplay(dt, display);
+ OCIO_displayTransformSetInputColorSpaceName(dt, from_colorspace);
+ OCIO_displayTransformSetView(dt, view_transform);
+ OCIO_displayTransformSetDisplay(dt, display);
- if (look_descr->is_noop == false) {
- OCIO_displayTransformSetLooksOverrideEnabled(dt, true);
- OCIO_displayTransformSetLooksOverride(dt, look);
- }
+ if (look_descr->is_noop == false) {
+ OCIO_displayTransformSetLooksOverrideEnabled(dt, true);
+ OCIO_displayTransformSetLooksOverride(dt, look);
+ }
- /* fstop exposure control */
- if (exposure != 0.0f) {
- OCIO_MatrixTransformRcPtr *mt;
- float gain = powf(2.0f, exposure);
- const float scale4f[] = {gain, gain, gain, 1.0f};
- float m44[16], offset4[4];
+ /* fstop exposure control */
+ if (exposure != 0.0f) {
+ OCIO_MatrixTransformRcPtr *mt;
+ float gain = powf(2.0f, exposure);
+ const float scale4f[] = {gain, gain, gain, 1.0f};
+ float m44[16], offset4[4];
- OCIO_matrixTransformScale(m44, offset4, scale4f);
- mt = OCIO_createMatrixTransform();
- OCIO_matrixTransformSetValue(mt, m44, offset4);
- OCIO_displayTransformSetLinearCC(dt, (OCIO_ConstTransformRcPtr *) mt);
+ OCIO_matrixTransformScale(m44, offset4, scale4f);
+ mt = OCIO_createMatrixTransform();
+ OCIO_matrixTransformSetValue(mt, m44, offset4);
+ OCIO_displayTransformSetLinearCC(dt, (OCIO_ConstTransformRcPtr *)mt);
- OCIO_matrixTransformRelease(mt);
- }
+ OCIO_matrixTransformRelease(mt);
+ }
- /* post-display gamma transform */
- if (gamma != 1.0f) {
- OCIO_ExponentTransformRcPtr *et;
- float exponent = 1.0f / MAX2(FLT_EPSILON, gamma);
- const float exponent4f[] = {exponent, exponent, exponent, exponent};
+ /* post-display gamma transform */
+ if (gamma != 1.0f) {
+ OCIO_ExponentTransformRcPtr *et;
+ float exponent = 1.0f / MAX2(FLT_EPSILON, gamma);
+ const float exponent4f[] = {exponent, exponent, exponent, exponent};
- et = OCIO_createExponentTransform();
- OCIO_exponentTransformSetValue(et, exponent4f);
- OCIO_displayTransformSetDisplayCC(dt, (OCIO_ConstTransformRcPtr *) et);
+ et = OCIO_createExponentTransform();
+ OCIO_exponentTransformSetValue(et, exponent4f);
+ OCIO_displayTransformSetDisplayCC(dt, (OCIO_ConstTransformRcPtr *)et);
- OCIO_exponentTransformRelease(et);
- }
+ OCIO_exponentTransformRelease(et);
+ }
- processor = OCIO_configGetProcessor(config, (OCIO_ConstTransformRcPtr *) dt);
+ processor = OCIO_configGetProcessor(config, (OCIO_ConstTransformRcPtr *)dt);
- OCIO_displayTransformRelease(dt);
- OCIO_configRelease(config);
+ OCIO_displayTransformRelease(dt);
+ OCIO_configRelease(config);
- return processor;
+ return processor;
}
static OCIO_ConstProcessorRcPtr *create_colorspace_transform_processor(const char *from_colorspace,
const char *to_colorspace)
{
- OCIO_ConstConfigRcPtr *config = OCIO_getCurrentConfig();
- OCIO_ConstProcessorRcPtr *processor;
+ OCIO_ConstConfigRcPtr *config = OCIO_getCurrentConfig();
+ OCIO_ConstProcessorRcPtr *processor;
- processor = OCIO_configGetProcessorWithNames(config, from_colorspace, to_colorspace);
+ processor = OCIO_configGetProcessorWithNames(config, from_colorspace, to_colorspace);
- OCIO_configRelease(config);
+ OCIO_configRelease(config);
- return processor;
+ return processor;
}
static OCIO_ConstProcessorRcPtr *colorspace_to_scene_linear_processor(ColorSpace *colorspace)
{
- if (colorspace->to_scene_linear == NULL) {
- BLI_mutex_lock(&processor_lock);
+ if (colorspace->to_scene_linear == NULL) {
+ BLI_mutex_lock(&processor_lock);
- if (colorspace->to_scene_linear == NULL) {
- OCIO_ConstProcessorRcPtr *to_scene_linear;
- to_scene_linear = create_colorspace_transform_processor(colorspace->name, global_role_scene_linear);
- colorspace->to_scene_linear = (struct OCIO_ConstProcessorRcPtr *) to_scene_linear;
- }
+ if (colorspace->to_scene_linear == NULL) {
+ OCIO_ConstProcessorRcPtr *to_scene_linear;
+ to_scene_linear = create_colorspace_transform_processor(colorspace->name,
+ global_role_scene_linear);
+ colorspace->to_scene_linear = (struct OCIO_ConstProcessorRcPtr *)to_scene_linear;
+ }
- BLI_mutex_unlock(&processor_lock);
- }
+ BLI_mutex_unlock(&processor_lock);
+ }
- return (OCIO_ConstProcessorRcPtr *) colorspace->to_scene_linear;
+ return (OCIO_ConstProcessorRcPtr *)colorspace->to_scene_linear;
}
static OCIO_ConstProcessorRcPtr *colorspace_from_scene_linear_processor(ColorSpace *colorspace)
{
- if (colorspace->from_scene_linear == NULL) {
- BLI_mutex_lock(&processor_lock);
+ if (colorspace->from_scene_linear == NULL) {
+ BLI_mutex_lock(&processor_lock);
- if (colorspace->from_scene_linear == NULL) {
- OCIO_ConstProcessorRcPtr *from_scene_linear;
- from_scene_linear = create_colorspace_transform_processor(global_role_scene_linear, colorspace->name);
- colorspace->from_scene_linear = (struct OCIO_ConstProcessorRcPtr *) from_scene_linear;
- }
+ if (colorspace->from_scene_linear == NULL) {
+ OCIO_ConstProcessorRcPtr *from_scene_linear;
+ from_scene_linear = create_colorspace_transform_processor(global_role_scene_linear,
+ colorspace->name);
+ colorspace->from_scene_linear = (struct OCIO_ConstProcessorRcPtr *)from_scene_linear;
+ }
- BLI_mutex_unlock(&processor_lock);
- }
+ BLI_mutex_unlock(&processor_lock);
+ }
- return (OCIO_ConstProcessorRcPtr *) colorspace->from_scene_linear;
+ return (OCIO_ConstProcessorRcPtr *)colorspace->from_scene_linear;
}
static OCIO_ConstProcessorRcPtr *display_from_scene_linear_processor(ColorManagedDisplay *display)
{
- if (display->from_scene_linear == NULL) {
- BLI_mutex_lock(&processor_lock);
+ if (display->from_scene_linear == NULL) {
+ BLI_mutex_lock(&processor_lock);
- if (display->from_scene_linear == NULL) {
- const char *view_name = colormanage_view_get_default_name(display);
- OCIO_ConstConfigRcPtr *config = OCIO_getCurrentConfig();
- OCIO_ConstProcessorRcPtr *processor = NULL;
+ if (display->from_scene_linear == NULL) {
+ const char *view_name = colormanage_view_get_default_name(display);
+ OCIO_ConstConfigRcPtr *config = OCIO_getCurrentConfig();
+ OCIO_ConstProcessorRcPtr *processor = NULL;
- if (view_name && config) {
- const char *view_colorspace = OCIO_configGetDisplayColorSpaceName(config, display->name, view_name);
- processor = OCIO_configGetProcessorWithNames(config, global_role_scene_linear, view_colorspace);
+ if (view_name && config) {
+ const char *view_colorspace = OCIO_configGetDisplayColorSpaceName(
+ config, display->name, view_name);
+ processor = OCIO_configGetProcessorWithNames(
+ config, global_role_scene_linear, view_colorspace);
- OCIO_configRelease(config);
- }
+ OCIO_configRelease(config);
+ }
- display->from_scene_linear = (struct OCIO_ConstProcessorRcPtr *) processor;
- }
+ display->from_scene_linear = (struct OCIO_ConstProcessorRcPtr *)processor;
+ }
- BLI_mutex_unlock(&processor_lock);
- }
+ BLI_mutex_unlock(&processor_lock);
+ }
- return (OCIO_ConstProcessorRcPtr *) display->from_scene_linear;
+ return (OCIO_ConstProcessorRcPtr *)display->from_scene_linear;
}
static OCIO_ConstProcessorRcPtr *display_to_scene_linear_processor(ColorManagedDisplay *display)
{
- if (display->to_scene_linear == NULL) {
- BLI_mutex_lock(&processor_lock);
+ if (display->to_scene_linear == NULL) {
+ BLI_mutex_lock(&processor_lock);
- if (display->to_scene_linear == NULL) {
- const char *view_name = colormanage_view_get_default_name(display);
- OCIO_ConstConfigRcPtr *config = OCIO_getCurrentConfig();
- OCIO_ConstProcessorRcPtr *processor = NULL;
+ if (display->to_scene_linear == NULL) {
+ const char *view_name = colormanage_view_get_default_name(display);
+ OCIO_ConstConfigRcPtr *config = OCIO_getCurrentConfig();
+ OCIO_ConstProcessorRcPtr *processor = NULL;
- if (view_name && config) {
- const char *view_colorspace = OCIO_configGetDisplayColorSpaceName(config, display->name, view_name);
- processor = OCIO_configGetProcessorWithNames(config, view_colorspace, global_role_scene_linear);
+ if (view_name && config) {
+ const char *view_colorspace = OCIO_configGetDisplayColorSpaceName(
+ config, display->name, view_name);
+ processor = OCIO_configGetProcessorWithNames(
+ config, view_colorspace, global_role_scene_linear);
- OCIO_configRelease(config);
- }
+ OCIO_configRelease(config);
+ }
- display->to_scene_linear = (struct OCIO_ConstProcessorRcPtr *) processor;
- }
+ display->to_scene_linear = (struct OCIO_ConstProcessorRcPtr *)processor;
+ }
- BLI_mutex_unlock(&processor_lock);
- }
+ BLI_mutex_unlock(&processor_lock);
+ }
- return (OCIO_ConstProcessorRcPtr *) display->to_scene_linear;
+ return (OCIO_ConstProcessorRcPtr *)display->to_scene_linear;
}
void IMB_colormanagement_init_default_view_settings(
- ColorManagedViewSettings *view_settings,
- const ColorManagedDisplaySettings *display_settings)
-{
- /* First, try use "Default" view transform of the requested device. */
- ColorManagedView *default_view = colormanage_view_get_named_for_display(
- display_settings->display_device, "Default");
- /* If that fails, we fall back to the default view transform of the display
- * as per OCIO configuration. */
- if (default_view == NULL) {
- ColorManagedDisplay *display = colormanage_display_get_named(
- display_settings->display_device);
- if (display != NULL) {
- default_view = colormanage_view_get_default(display);
- }
- }
- if (default_view != NULL) {
- BLI_strncpy(view_settings->view_transform,
- default_view->name,
- sizeof(view_settings->view_transform));
- }
- else {
- view_settings->view_transform[0] = '\0';
- }
- /* TODO(sergey): Find a way to safely/reliable un-hardcode this. */
- BLI_strncpy(view_settings->look, "None", sizeof(view_settings->look));
- /* Initialize rest of the settings. */
- view_settings->flag = 0;
- view_settings->gamma = 1.0f;
- view_settings->exposure = 0.0f;
- view_settings->curve_mapping = NULL;
+ ColorManagedViewSettings *view_settings, const ColorManagedDisplaySettings *display_settings)
+{
+ /* First, try use "Default" view transform of the requested device. */
+ ColorManagedView *default_view = colormanage_view_get_named_for_display(
+ display_settings->display_device, "Default");
+ /* If that fails, we fall back to the default view transform of the display
+ * as per OCIO configuration. */
+ if (default_view == NULL) {
+ ColorManagedDisplay *display = colormanage_display_get_named(display_settings->display_device);
+ if (display != NULL) {
+ default_view = colormanage_view_get_default(display);
+ }
+ }
+ if (default_view != NULL) {
+ BLI_strncpy(
+ view_settings->view_transform, default_view->name, sizeof(view_settings->view_transform));
+ }
+ else {
+ view_settings->view_transform[0] = '\0';
+ }
+ /* TODO(sergey): Find a way to safely/reliable un-hardcode this. */
+ BLI_strncpy(view_settings->look, "None", sizeof(view_settings->look));
+ /* Initialize rest of the settings. */
+ view_settings->flag = 0;
+ view_settings->gamma = 1.0f;
+ view_settings->exposure = 0.0f;
+ view_settings->curve_mapping = NULL;
}
static void curve_mapping_apply_pixel(CurveMapping *curve_mapping, float *pixel, int channels)
{
- if (channels == 1) {
- pixel[0] = curvemap_evaluateF(curve_mapping->cm, pixel[0]);
- }
- else if (channels == 2) {
- pixel[0] = curvemap_evaluateF(curve_mapping->cm, pixel[0]);
- pixel[1] = curvemap_evaluateF(curve_mapping->cm, pixel[1]);
- }
- else {
- curvemapping_evaluate_premulRGBF(curve_mapping, pixel, pixel);
- }
+ if (channels == 1) {
+ pixel[0] = curvemap_evaluateF(curve_mapping->cm, pixel[0]);
+ }
+ else if (channels == 2) {
+ pixel[0] = curvemap_evaluateF(curve_mapping->cm, pixel[0]);
+ pixel[1] = curvemap_evaluateF(curve_mapping->cm, pixel[1]);
+ }
+ else {
+ curvemapping_evaluate_premulRGBF(curve_mapping, pixel, pixel);
+ }
}
void colorspace_set_default_role(char *colorspace, int size, int role)
{
- if (colorspace && colorspace[0] == '\0') {
- const char *role_colorspace;
+ if (colorspace && colorspace[0] == '\0') {
+ const char *role_colorspace;
- role_colorspace = IMB_colormanagement_role_colorspace_name_get(role);
+ role_colorspace = IMB_colormanagement_role_colorspace_name_get(role);
- BLI_strncpy(colorspace, role_colorspace, size);
- }
+ BLI_strncpy(colorspace, role_colorspace, size);
+ }
}
void colormanage_imbuf_set_default_spaces(ImBuf *ibuf)
{
- ibuf->rect_colorspace = colormanage_colorspace_get_named(global_role_default_byte);
+ ibuf->rect_colorspace = colormanage_colorspace_get_named(global_role_default_byte);
}
void colormanage_imbuf_make_linear(ImBuf *ibuf, const char *from_colorspace)
{
- ColorSpace *colorspace = colormanage_colorspace_get_named(from_colorspace);
+ ColorSpace *colorspace = colormanage_colorspace_get_named(from_colorspace);
- if (colorspace && colorspace->is_data) {
- ibuf->colormanage_flag |= IMB_COLORMANAGE_IS_DATA;
- return;
- }
+ if (colorspace && colorspace->is_data) {
+ ibuf->colormanage_flag |= IMB_COLORMANAGE_IS_DATA;
+ return;
+ }
- if (ibuf->rect_float) {
- const char *to_colorspace = global_role_scene_linear;
+ if (ibuf->rect_float) {
+ const char *to_colorspace = global_role_scene_linear;
- if (ibuf->rect)
- imb_freerectImBuf(ibuf);
+ if (ibuf->rect)
+ imb_freerectImBuf(ibuf);
- IMB_colormanagement_transform(ibuf->rect_float, ibuf->x, ibuf->y, ibuf->channels,
- from_colorspace, to_colorspace, true);
- }
+ IMB_colormanagement_transform(
+ ibuf->rect_float, ibuf->x, ibuf->y, ibuf->channels, from_colorspace, to_colorspace, true);
+ }
}
/*********************** Generic functions *************************/
-static void colormanage_check_display_settings(ColorManagedDisplaySettings *display_settings, const char *what,
+static void colormanage_check_display_settings(ColorManagedDisplaySettings *display_settings,
+ const char *what,
const ColorManagedDisplay *default_display)
{
- if (display_settings->display_device[0] == '\0') {
- BLI_strncpy(display_settings->display_device, default_display->name, sizeof(display_settings->display_device));
- }
- else {
- ColorManagedDisplay *display = colormanage_display_get_named(display_settings->display_device);
+ if (display_settings->display_device[0] == '\0') {
+ BLI_strncpy(display_settings->display_device,
+ default_display->name,
+ sizeof(display_settings->display_device));
+ }
+ else {
+ ColorManagedDisplay *display = colormanage_display_get_named(display_settings->display_device);
- if (!display) {
- printf("Color management: display \"%s\" used by %s not found, setting to default (\"%s\").\n",
- display_settings->display_device, what, default_display->name);
+ if (!display) {
+ printf(
+ "Color management: display \"%s\" used by %s not found, setting to default (\"%s\").\n",
+ display_settings->display_device,
+ what,
+ default_display->name);
- BLI_strncpy(display_settings->display_device, default_display->name,
- sizeof(display_settings->display_device));
- }
- }
+ BLI_strncpy(display_settings->display_device,
+ default_display->name,
+ sizeof(display_settings->display_device));
+ }
+ }
}
static void colormanage_check_view_settings(ColorManagedDisplaySettings *display_settings,
- ColorManagedViewSettings *view_settings, const char *what)
-{
- ColorManagedDisplay *display;
- ColorManagedView *default_view = NULL;
- ColorManagedLook *default_look = (ColorManagedLook *) global_looks.first;
-
- if (view_settings->view_transform[0] == '\0') {
- display = colormanage_display_get_named(display_settings->display_device);
-
- if (display)
- default_view = colormanage_view_get_default(display);
-
- if (default_view)
- BLI_strncpy(view_settings->view_transform, default_view->name, sizeof(view_settings->view_transform));
- }
- else {
- ColorManagedView *view = colormanage_view_get_named(view_settings->view_transform);
-
- if (!view) {
- display = colormanage_display_get_named(display_settings->display_device);
-
- if (display)
- default_view = colormanage_view_get_default(display);
-
- if (default_view) {
- printf("Color management: %s view \"%s\" not found, setting default \"%s\".\n",
- what, view_settings->view_transform, default_view->name);
-
- BLI_strncpy(view_settings->view_transform, default_view->name, sizeof(view_settings->view_transform));
- }
- }
- }
-
- if (view_settings->look[0] == '\0') {
- BLI_strncpy(view_settings->look, default_look->name, sizeof(view_settings->look));
- }
- else {
- ColorManagedLook *look = colormanage_look_get_named(view_settings->look);
- if (look == NULL) {
- printf("Color management: %s look \"%s\" not found, setting default \"%s\".\n",
- what, view_settings->look, default_look->name);
-
- BLI_strncpy(view_settings->look, default_look->name, sizeof(view_settings->look));
- }
- }
-
- /* OCIO_TODO: move to do_versions() */
- if (view_settings->exposure == 0.0f && view_settings->gamma == 0.0f) {
- view_settings->exposure = 0.0f;
- view_settings->gamma = 1.0f;
- }
-}
-
-static void colormanage_check_colorspace_settings(ColorManagedColorspaceSettings *colorspace_settings, const char *what)
-{
- if (colorspace_settings->name[0] == '\0') {
- /* pass */
- }
- else {
- ColorSpace *colorspace = colormanage_colorspace_get_named(colorspace_settings->name);
-
- if (!colorspace) {
- printf("Color management: %s colorspace \"%s\" not found, will use default instead.\n",
- what, colorspace_settings->name);
-
- BLI_strncpy(colorspace_settings->name, "", sizeof(colorspace_settings->name));
- }
- }
-
- (void) what;
+ ColorManagedViewSettings *view_settings,
+ const char *what)
+{
+ ColorManagedDisplay *display;
+ ColorManagedView *default_view = NULL;
+ ColorManagedLook *default_look = (ColorManagedLook *)global_looks.first;
+
+ if (view_settings->view_transform[0] == '\0') {
+ display = colormanage_display_get_named(display_settings->display_device);
+
+ if (display)
+ default_view = colormanage_view_get_default(display);
+
+ if (default_view)
+ BLI_strncpy(view_settings->view_transform,
+ default_view->name,
+ sizeof(view_settings->view_transform));
+ }
+ else {
+ ColorManagedView *view = colormanage_view_get_named(view_settings->view_transform);
+
+ if (!view) {
+ display = colormanage_display_get_named(display_settings->display_device);
+
+ if (display)
+ default_view = colormanage_view_get_default(display);
+
+ if (default_view) {
+ printf("Color management: %s view \"%s\" not found, setting default \"%s\".\n",
+ what,
+ view_settings->view_transform,
+ default_view->name);
+
+ BLI_strncpy(view_settings->view_transform,
+ default_view->name,
+ sizeof(view_settings->view_transform));
+ }
+ }
+ }
+
+ if (view_settings->look[0] == '\0') {
+ BLI_strncpy(view_settings->look, default_look->name, sizeof(view_settings->look));
+ }
+ else {
+ ColorManagedLook *look = colormanage_look_get_named(view_settings->look);
+ if (look == NULL) {
+ printf("Color management: %s look \"%s\" not found, setting default \"%s\".\n",
+ what,
+ view_settings->look,
+ default_look->name);
+
+ BLI_strncpy(view_settings->look, default_look->name, sizeof(view_settings->look));
+ }
+ }
+
+ /* OCIO_TODO: move to do_versions() */
+ if (view_settings->exposure == 0.0f && view_settings->gamma == 0.0f) {
+ view_settings->exposure = 0.0f;
+ view_settings->gamma = 1.0f;
+ }
+}
+
+static void colormanage_check_colorspace_settings(
+ ColorManagedColorspaceSettings *colorspace_settings, const char *what)
+{
+ if (colorspace_settings->name[0] == '\0') {
+ /* pass */
+ }
+ else {
+ ColorSpace *colorspace = colormanage_colorspace_get_named(colorspace_settings->name);
+
+ if (!colorspace) {
+ printf("Color management: %s colorspace \"%s\" not found, will use default instead.\n",
+ what,
+ colorspace_settings->name);
+
+ BLI_strncpy(colorspace_settings->name, "", sizeof(colorspace_settings->name));
+ }
+ }
+
+ (void)what;
}
void IMB_colormanagement_check_file_config(Main *bmain)
{
- Scene *scene;
- Image *image;
- MovieClip *clip;
+ Scene *scene;
+ Image *image;
+ MovieClip *clip;
- ColorManagedDisplay *default_display;
+ ColorManagedDisplay *default_display;
- default_display = colormanage_display_get_default();
+ default_display = colormanage_display_get_default();
- if (!default_display) {
- /* happens when OCIO configuration is incorrect */
- return;
- }
+ if (!default_display) {
+ /* happens when OCIO configuration is incorrect */
+ return;
+ }
- for (scene = bmain->scenes.first; scene; scene = scene->id.next) {
- ColorManagedColorspaceSettings *sequencer_colorspace_settings;
+ for (scene = bmain->scenes.first; scene; scene = scene->id.next) {
+ ColorManagedColorspaceSettings *sequencer_colorspace_settings;
- /* check scene color management settings */
- colormanage_check_display_settings(&scene->display_settings, "scene", default_display);
- colormanage_check_view_settings(&scene->display_settings, &scene->view_settings, "scene");
+ /* check scene color management settings */
+ colormanage_check_display_settings(&scene->display_settings, "scene", default_display);
+ colormanage_check_view_settings(&scene->display_settings, &scene->view_settings, "scene");
- sequencer_colorspace_settings = &scene->sequencer_colorspace_settings;
+ sequencer_colorspace_settings = &scene->sequencer_colorspace_settings;
- colormanage_check_colorspace_settings(sequencer_colorspace_settings, "sequencer");
+ colormanage_check_colorspace_settings(sequencer_colorspace_settings, "sequencer");
- if (sequencer_colorspace_settings->name[0] == '\0') {
- BLI_strncpy(sequencer_colorspace_settings->name, global_role_default_sequencer, MAX_COLORSPACE_NAME);
- }
+ if (sequencer_colorspace_settings->name[0] == '\0') {
+ BLI_strncpy(
+ sequencer_colorspace_settings->name, global_role_default_sequencer, MAX_COLORSPACE_NAME);
+ }
- /* check sequencer strip input color space settings */
- Sequence *seq;
- SEQ_BEGIN (scene->ed, seq) {
- if (seq->strip) {
- colormanage_check_colorspace_settings(&seq->strip->colorspace_settings, "sequencer strip");
- }
- } SEQ_END;
- }
+ /* check sequencer strip input color space settings */
+ Sequence *seq;
+ SEQ_BEGIN (scene->ed, seq) {
+ if (seq->strip) {
+ colormanage_check_colorspace_settings(&seq->strip->colorspace_settings, "sequencer strip");
+ }
+ }
+ SEQ_END;
+ }
- /* ** check input color space settings ** */
+ /* ** check input color space settings ** */
- for (image = bmain->images.first; image; image = image->id.next) {
- colormanage_check_colorspace_settings(&image->colorspace_settings, "image");
- }
+ for (image = bmain->images.first; image; image = image->id.next) {
+ colormanage_check_colorspace_settings(&image->colorspace_settings, "image");
+ }
- for (clip = bmain->movieclips.first; clip; clip = clip->id.next) {
- colormanage_check_colorspace_settings(&clip->colorspace_settings, "clip");
- }
+ for (clip = bmain->movieclips.first; clip; clip = clip->id.next) {
+ colormanage_check_colorspace_settings(&clip->colorspace_settings, "clip");
+ }
}
void IMB_colormanagement_validate_settings(const ColorManagedDisplaySettings *display_settings,
ColorManagedViewSettings *view_settings)
{
- ColorManagedDisplay *display;
- ColorManagedView *default_view = NULL;
- LinkData *view_link;
+ ColorManagedDisplay *display;
+ ColorManagedView *default_view = NULL;
+ LinkData *view_link;
- display = colormanage_display_get_named(display_settings->display_device);
+ display = colormanage_display_get_named(display_settings->display_device);
- default_view = colormanage_view_get_default(display);
+ default_view = colormanage_view_get_default(display);
- for (view_link = display->views.first; view_link; view_link = view_link->next) {
- ColorManagedView *view = view_link->data;
+ for (view_link = display->views.first; view_link; view_link = view_link->next) {
+ ColorManagedView *view = view_link->data;
- if (STREQ(view->name, view_settings->view_transform))
- break;
- }
+ if (STREQ(view->name, view_settings->view_transform))
+ break;
+ }
- if (view_link == NULL && default_view)
- BLI_strncpy(view_settings->view_transform, default_view->name, sizeof(view_settings->view_transform));
+ if (view_link == NULL && default_view)
+ BLI_strncpy(
+ view_settings->view_transform, default_view->name, sizeof(view_settings->view_transform));
}
const char *IMB_colormanagement_role_colorspace_name_get(int role)
{
- switch (role) {
- case COLOR_ROLE_SCENE_LINEAR:
- return global_role_scene_linear;
- case COLOR_ROLE_COLOR_PICKING:
- return global_role_color_picking;
- case COLOR_ROLE_TEXTURE_PAINTING:
- return global_role_texture_painting;
- case COLOR_ROLE_DEFAULT_SEQUENCER:
- return global_role_default_sequencer;
- case COLOR_ROLE_DEFAULT_FLOAT:
- return global_role_default_float;
- case COLOR_ROLE_DEFAULT_BYTE:
- return global_role_default_byte;
- default:
- printf("Unknown role was passed to %s\n", __func__);
- BLI_assert(0);
- break;
- }
-
- return NULL;
+ switch (role) {
+ case COLOR_ROLE_SCENE_LINEAR:
+ return global_role_scene_linear;
+ case COLOR_ROLE_COLOR_PICKING:
+ return global_role_color_picking;
+ case COLOR_ROLE_TEXTURE_PAINTING:
+ return global_role_texture_painting;
+ case COLOR_ROLE_DEFAULT_SEQUENCER:
+ return global_role_default_sequencer;
+ case COLOR_ROLE_DEFAULT_FLOAT:
+ return global_role_default_float;
+ case COLOR_ROLE_DEFAULT_BYTE:
+ return global_role_default_byte;
+ default:
+ printf("Unknown role was passed to %s\n", __func__);
+ BLI_assert(0);
+ break;
+ }
+
+ return NULL;
}
void IMB_colormanagement_check_is_data(ImBuf *ibuf, const char *name)
{
- ColorSpace *colorspace = colormanage_colorspace_get_named(name);
+ ColorSpace *colorspace = colormanage_colorspace_get_named(name);
- if (colorspace && colorspace->is_data)
- ibuf->colormanage_flag |= IMB_COLORMANAGE_IS_DATA;
- else
- ibuf->colormanage_flag &= ~IMB_COLORMANAGE_IS_DATA;
+ if (colorspace && colorspace->is_data)
+ ibuf->colormanage_flag |= IMB_COLORMANAGE_IS_DATA;
+ else
+ ibuf->colormanage_flag &= ~IMB_COLORMANAGE_IS_DATA;
}
void IMB_colormanagement_assign_float_colorspace(ImBuf *ibuf, const char *name)
{
- ColorSpace *colorspace = colormanage_colorspace_get_named(name);
+ ColorSpace *colorspace = colormanage_colorspace_get_named(name);
- ibuf->float_colorspace = colorspace;
+ ibuf->float_colorspace = colorspace;
- if (colorspace && colorspace->is_data)
- ibuf->colormanage_flag |= IMB_COLORMANAGE_IS_DATA;
- else
- ibuf->colormanage_flag &= ~IMB_COLORMANAGE_IS_DATA;
+ if (colorspace && colorspace->is_data)
+ ibuf->colormanage_flag |= IMB_COLORMANAGE_IS_DATA;
+ else
+ ibuf->colormanage_flag &= ~IMB_COLORMANAGE_IS_DATA;
}
void IMB_colormanagement_assign_rect_colorspace(ImBuf *ibuf, const char *name)
{
- ColorSpace *colorspace = colormanage_colorspace_get_named(name);
+ ColorSpace *colorspace = colormanage_colorspace_get_named(name);
- ibuf->rect_colorspace = colorspace;
+ ibuf->rect_colorspace = colorspace;
- if (colorspace && colorspace->is_data)
- ibuf->colormanage_flag |= IMB_COLORMANAGE_IS_DATA;
- else
- ibuf->colormanage_flag &= ~IMB_COLORMANAGE_IS_DATA;
+ if (colorspace && colorspace->is_data)
+ ibuf->colormanage_flag |= IMB_COLORMANAGE_IS_DATA;
+ else
+ ibuf->colormanage_flag &= ~IMB_COLORMANAGE_IS_DATA;
}
const char *IMB_colormanagement_get_float_colorspace(ImBuf *ibuf)
{
- if (ibuf->float_colorspace) {
- return ibuf->float_colorspace->name;
- }
- else {
- return IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_SCENE_LINEAR);
- }
+ if (ibuf->float_colorspace) {
+ return ibuf->float_colorspace->name;
+ }
+ else {
+ return IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_SCENE_LINEAR);
+ }
}
const char *IMB_colormanagement_get_rect_colorspace(ImBuf *ibuf)
{
- if (ibuf->rect_colorspace) {
- return ibuf->rect_colorspace->name;
- }
- else {
- return IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_DEFAULT_BYTE);
- }
+ if (ibuf->rect_colorspace) {
+ return ibuf->rect_colorspace->name;
+ }
+ else {
+ return IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_DEFAULT_BYTE);
+ }
}
/*********************** Threaded display buffer transform routines *************************/
typedef struct DisplayBufferThread {
- ColormanageProcessor *cm_processor;
+ ColormanageProcessor *cm_processor;
- const float *buffer;
- unsigned char *byte_buffer;
+ const float *buffer;
+ unsigned char *byte_buffer;
- float *display_buffer;
- unsigned char *display_buffer_byte;
+ float *display_buffer;
+ unsigned char *display_buffer_byte;
- int width;
- int start_line;
- int tot_line;
+ int width;
+ int start_line;
+ int tot_line;
- int channels;
- float dither;
- bool is_data;
+ int channels;
+ float dither;
+ bool is_data;
- const char *byte_colorspace;
- const char *float_colorspace;
+ const char *byte_colorspace;
+ const char *float_colorspace;
} DisplayBufferThread;
typedef struct DisplayBufferInitData {
- ImBuf *ibuf;
- ColormanageProcessor *cm_processor;
- const float *buffer;
- unsigned char *byte_buffer;
+ ImBuf *ibuf;
+ ColormanageProcessor *cm_processor;
+ const float *buffer;
+ unsigned char *byte_buffer;
- float *display_buffer;
- unsigned char *display_buffer_byte;
+ float *display_buffer;
+ unsigned char *display_buffer_byte;
- int width;
+ int width;
- const char *byte_colorspace;
- const char *float_colorspace;
+ const char *byte_colorspace;
+ const char *float_colorspace;
} DisplayBufferInitData;
-static void display_buffer_init_handle(void *handle_v, int start_line, int tot_line, void *init_data_v)
+static void display_buffer_init_handle(void *handle_v,
+ int start_line,
+ int tot_line,
+ void *init_data_v)
{
- DisplayBufferThread *handle = (DisplayBufferThread *) handle_v;
- DisplayBufferInitData *init_data = (DisplayBufferInitData *) init_data_v;
- ImBuf *ibuf = init_data->ibuf;
+ DisplayBufferThread *handle = (DisplayBufferThread *)handle_v;
+ DisplayBufferInitData *init_data = (DisplayBufferInitData *)init_data_v;
+ ImBuf *ibuf = init_data->ibuf;
- int channels = ibuf->channels;
- float dither = ibuf->dither;
- bool is_data = (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA) != 0;
+ int channels = ibuf->channels;
+ float dither = ibuf->dither;
+ bool is_data = (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA) != 0;
- size_t offset = ((size_t)channels) * start_line * ibuf->x;
- size_t display_buffer_byte_offset = ((size_t)DISPLAY_BUFFER_CHANNELS) * start_line * ibuf->x;
+ size_t offset = ((size_t)channels) * start_line * ibuf->x;
+ size_t display_buffer_byte_offset = ((size_t)DISPLAY_BUFFER_CHANNELS) * start_line * ibuf->x;
- memset(handle, 0, sizeof(DisplayBufferThread));
+ memset(handle, 0, sizeof(DisplayBufferThread));
- handle->cm_processor = init_data->cm_processor;
+ handle->cm_processor = init_data->cm_processor;
- if (init_data->buffer)
- handle->buffer = init_data->buffer + offset;
+ if (init_data->buffer)
+ handle->buffer = init_data->buffer + offset;
- if (init_data->byte_buffer)
- handle->byte_buffer = init_data->byte_buffer + offset;
+ if (init_data->byte_buffer)
+ handle->byte_buffer = init_data->byte_buffer + offset;
- if (init_data->display_buffer)
- handle->display_buffer = init_data->display_buffer + offset;
+ if (init_data->display_buffer)
+ handle->display_buffer = init_data->display_buffer + offset;
- if (init_data->display_buffer_byte)
- handle->display_buffer_byte = init_data->display_buffer_byte + display_buffer_byte_offset;
+ if (init_data->display_buffer_byte)
+ handle->display_buffer_byte = init_data->display_buffer_byte + display_buffer_byte_offset;
- handle->width = ibuf->x;
+ handle->width = ibuf->x;
- handle->start_line = start_line;
- handle->tot_line = tot_line;
+ handle->start_line = start_line;
+ handle->tot_line = tot_line;
- handle->channels = channels;
- handle->dither = dither;
- handle->is_data = is_data;
+ handle->channels = channels;
+ handle->dither = dither;
+ handle->is_data = is_data;
- handle->byte_colorspace = init_data->byte_colorspace;
- handle->float_colorspace = init_data->float_colorspace;
+ handle->byte_colorspace = init_data->byte_colorspace;
+ handle->float_colorspace = init_data->float_colorspace;
}
-static void display_buffer_apply_get_linear_buffer(DisplayBufferThread *handle, int height,
- float *linear_buffer, bool *is_straight_alpha)
+static void display_buffer_apply_get_linear_buffer(DisplayBufferThread *handle,
+ int height,
+ float *linear_buffer,
+ bool *is_straight_alpha)
{
- int channels = handle->channels;
- int width = handle->width;
+ int channels = handle->channels;
+ int width = handle->width;
- size_t buffer_size = ((size_t)channels) * width * height;
+ size_t buffer_size = ((size_t)channels) * width * height;
- bool is_data = handle->is_data;
- bool is_data_display = handle->cm_processor->is_data_result;
+ bool is_data = handle->is_data;
+ bool is_data_display = handle->cm_processor->is_data_result;
- if (!handle->buffer) {
- unsigned char *byte_buffer = handle->byte_buffer;
+ if (!handle->buffer) {
+ unsigned char *byte_buffer = handle->byte_buffer;
- const char *from_colorspace = handle->byte_colorspace;
- const char *to_colorspace = global_role_scene_linear;
+ const char *from_colorspace = handle->byte_colorspace;
+ const char *to_colorspace = global_role_scene_linear;
- float *fp;
- unsigned char *cp;
- const size_t i_last = ((size_t)width) * height;
- size_t i;
+ float *fp;
+ unsigned char *cp;
+ const size_t i_last = ((size_t)width) * height;
+ size_t i;
- /* first convert byte buffer to float, keep in image space */
- for (i = 0, fp = linear_buffer, cp = byte_buffer;
- i != i_last;
- i++, fp += channels, cp += channels)
- {
- if (channels == 3) {
- rgb_uchar_to_float(fp, cp);
- }
- else if (channels == 4) {
- rgba_uchar_to_float(fp, cp);
- }
- else {
- BLI_assert(!"Buffers of 3 or 4 channels are only supported here");
- }
- }
+ /* first convert byte buffer to float, keep in image space */
+ for (i = 0, fp = linear_buffer, cp = byte_buffer; i != i_last;
+ i++, fp += channels, cp += channels) {
+ if (channels == 3) {
+ rgb_uchar_to_float(fp, cp);
+ }
+ else if (channels == 4) {
+ rgba_uchar_to_float(fp, cp);
+ }
+ else {
+ BLI_assert(!"Buffers of 3 or 4 channels are only supported here");
+ }
+ }
- if (!is_data && !is_data_display) {
- /* convert float buffer to scene linear space */
- IMB_colormanagement_transform(linear_buffer, width, height, channels,
- from_colorspace, to_colorspace, false);
- }
+ if (!is_data && !is_data_display) {
+ /* convert float buffer to scene linear space */
+ IMB_colormanagement_transform(
+ linear_buffer, width, height, channels, from_colorspace, to_colorspace, false);
+ }
- *is_straight_alpha = true;
- }
- else if (handle->float_colorspace) {
- /* currently float is non-linear only in sequencer, which is working
- * in it's own color space even to handle float buffers.
- * This color space is the same for byte and float images.
- * Need to convert float buffer to linear space before applying display transform
- */
+ *is_straight_alpha = true;
+ }
+ else if (handle->float_colorspace) {
+ /* currently float is non-linear only in sequencer, which is working
+ * in it's own color space even to handle float buffers.
+ * This color space is the same for byte and float images.
+ * Need to convert float buffer to linear space before applying display transform
+ */
- const char *from_colorspace = handle->float_colorspace;
- const char *to_colorspace = global_role_scene_linear;
+ const char *from_colorspace = handle->float_colorspace;
+ const char *to_colorspace = global_role_scene_linear;
- memcpy(linear_buffer, handle->buffer, buffer_size * sizeof(float));
+ memcpy(linear_buffer, handle->buffer, buffer_size * sizeof(float));
- if (!is_data && !is_data_display) {
- IMB_colormanagement_transform(linear_buffer, width, height, channels,
- from_colorspace, to_colorspace, true);
- }
+ if (!is_data && !is_data_display) {
+ IMB_colormanagement_transform(
+ linear_buffer, width, height, channels, from_colorspace, to_colorspace, true);
+ }
- *is_straight_alpha = false;
- }
- else {
- /* some processors would want to modify float original buffer
- * before converting it into display byte buffer, so we need to
- * make sure original's ImBuf buffers wouldn't be modified by
- * using duplicated buffer here
- */
+ *is_straight_alpha = false;
+ }
+ else {
+ /* some processors would want to modify float original buffer
+ * before converting it into display byte buffer, so we need to
+ * make sure original's ImBuf buffers wouldn't be modified by
+ * using duplicated buffer here
+ */
- memcpy(linear_buffer, handle->buffer, buffer_size * sizeof(float));
+ memcpy(linear_buffer, handle->buffer, buffer_size * sizeof(float));
- *is_straight_alpha = false;
- }
+ *is_straight_alpha = false;
+ }
}
static void *do_display_buffer_apply_thread(void *handle_v)
{
- DisplayBufferThread *handle = (DisplayBufferThread *) handle_v;
- ColormanageProcessor *cm_processor = handle->cm_processor;
- float *display_buffer = handle->display_buffer;
- unsigned char *display_buffer_byte = handle->display_buffer_byte;
- int channels = handle->channels;
- int width = handle->width;
- int height = handle->tot_line;
- float dither = handle->dither;
- bool is_data = handle->is_data;
-
- if (cm_processor == NULL) {
- if (display_buffer_byte && display_buffer_byte != handle->byte_buffer) {
- IMB_buffer_byte_from_byte(display_buffer_byte, handle->byte_buffer, IB_PROFILE_SRGB, IB_PROFILE_SRGB,
- false, width, height, width, width);
- }
-
- if (display_buffer) {
- IMB_buffer_float_from_byte(display_buffer, handle->byte_buffer, IB_PROFILE_SRGB, IB_PROFILE_SRGB,
- false, width, height, width, width);
- }
- }
- else {
- bool is_straight_alpha, predivide;
- float *linear_buffer = MEM_mallocN(((size_t)channels) * width * height * sizeof(float),
- "color conversion linear buffer");
-
- display_buffer_apply_get_linear_buffer(handle, height, linear_buffer, &is_straight_alpha);
-
- predivide = is_straight_alpha == false;
-
- if (is_data) {
- /* special case for data buffers - no color space conversions,
- * only generate byte buffers
- */
- }
- else {
- /* apply processor */
- IMB_colormanagement_processor_apply(cm_processor, linear_buffer, width, height, channels,
- predivide);
- }
-
- /* copy result to output buffers */
- if (display_buffer_byte) {
- /* do conversion */
- IMB_buffer_byte_from_float(display_buffer_byte, linear_buffer,
- channels, dither, IB_PROFILE_SRGB, IB_PROFILE_SRGB,
- predivide, width, height, width, width);
- }
-
- if (display_buffer) {
- memcpy(display_buffer, linear_buffer, ((size_t)width) * height * channels * sizeof(float));
-
- if (is_straight_alpha && channels == 4) {
- const size_t i_last = ((size_t)width) * height;
- size_t i;
- float *fp;
-
- for (i = 0, fp = display_buffer;
- i != i_last;
- i++, fp += channels)
- {
- straight_to_premul_v4(fp);
- }
- }
- }
-
- MEM_freeN(linear_buffer);
- }
-
- return NULL;
-}
-
-static void display_buffer_apply_threaded(ImBuf *ibuf, float *buffer, unsigned char *byte_buffer, float *display_buffer,
- unsigned char *display_buffer_byte, ColormanageProcessor *cm_processor)
-{
- DisplayBufferInitData init_data;
-
- init_data.ibuf = ibuf;
- init_data.cm_processor = cm_processor;
- init_data.buffer = buffer;
- init_data.byte_buffer = byte_buffer;
- init_data.display_buffer = display_buffer;
- init_data.display_buffer_byte = display_buffer_byte;
-
- if (ibuf->rect_colorspace != NULL) {
- init_data.byte_colorspace = ibuf->rect_colorspace->name;
- }
- else {
- /* happens for viewer images, which are not so simple to determine where to
- * set image buffer's color spaces
- */
- init_data.byte_colorspace = global_role_default_byte;
- }
-
- if (ibuf->float_colorspace != NULL) {
- /* sequencer stores float buffers in non-linear space */
- init_data.float_colorspace = ibuf->float_colorspace->name;
- }
- else {
- init_data.float_colorspace = NULL;
- }
-
- IMB_processor_apply_threaded(ibuf->y, sizeof(DisplayBufferThread), &init_data,
- display_buffer_init_handle, do_display_buffer_apply_thread);
-}
-
-static bool is_ibuf_rect_in_display_space(ImBuf *ibuf, const ColorManagedViewSettings *view_settings,
+ DisplayBufferThread *handle = (DisplayBufferThread *)handle_v;
+ ColormanageProcessor *cm_processor = handle->cm_processor;
+ float *display_buffer = handle->display_buffer;
+ unsigned char *display_buffer_byte = handle->display_buffer_byte;
+ int channels = handle->channels;
+ int width = handle->width;
+ int height = handle->tot_line;
+ float dither = handle->dither;
+ bool is_data = handle->is_data;
+
+ if (cm_processor == NULL) {
+ if (display_buffer_byte && display_buffer_byte != handle->byte_buffer) {
+ IMB_buffer_byte_from_byte(display_buffer_byte,
+ handle->byte_buffer,
+ IB_PROFILE_SRGB,
+ IB_PROFILE_SRGB,
+ false,
+ width,
+ height,
+ width,
+ width);
+ }
+
+ if (display_buffer) {
+ IMB_buffer_float_from_byte(display_buffer,
+ handle->byte_buffer,
+ IB_PROFILE_SRGB,
+ IB_PROFILE_SRGB,
+ false,
+ width,
+ height,
+ width,
+ width);
+ }
+ }
+ else {
+ bool is_straight_alpha, predivide;
+ float *linear_buffer = MEM_mallocN(((size_t)channels) * width * height * sizeof(float),
+ "color conversion linear buffer");
+
+ display_buffer_apply_get_linear_buffer(handle, height, linear_buffer, &is_straight_alpha);
+
+ predivide = is_straight_alpha == false;
+
+ if (is_data) {
+ /* special case for data buffers - no color space conversions,
+ * only generate byte buffers
+ */
+ }
+ else {
+ /* apply processor */
+ IMB_colormanagement_processor_apply(
+ cm_processor, linear_buffer, width, height, channels, predivide);
+ }
+
+ /* copy result to output buffers */
+ if (display_buffer_byte) {
+ /* do conversion */
+ IMB_buffer_byte_from_float(display_buffer_byte,
+ linear_buffer,
+ channels,
+ dither,
+ IB_PROFILE_SRGB,
+ IB_PROFILE_SRGB,
+ predivide,
+ width,
+ height,
+ width,
+ width);
+ }
+
+ if (display_buffer) {
+ memcpy(display_buffer, linear_buffer, ((size_t)width) * height * channels * sizeof(float));
+
+ if (is_straight_alpha && channels == 4) {
+ const size_t i_last = ((size_t)width) * height;
+ size_t i;
+ float *fp;
+
+ for (i = 0, fp = display_buffer; i != i_last; i++, fp += channels) {
+ straight_to_premul_v4(fp);
+ }
+ }
+ }
+
+ MEM_freeN(linear_buffer);
+ }
+
+ return NULL;
+}
+
+static void display_buffer_apply_threaded(ImBuf *ibuf,
+ float *buffer,
+ unsigned char *byte_buffer,
+ float *display_buffer,
+ unsigned char *display_buffer_byte,
+ ColormanageProcessor *cm_processor)
+{
+ DisplayBufferInitData init_data;
+
+ init_data.ibuf = ibuf;
+ init_data.cm_processor = cm_processor;
+ init_data.buffer = buffer;
+ init_data.byte_buffer = byte_buffer;
+ init_data.display_buffer = display_buffer;
+ init_data.display_buffer_byte = display_buffer_byte;
+
+ if (ibuf->rect_colorspace != NULL) {
+ init_data.byte_colorspace = ibuf->rect_colorspace->name;
+ }
+ else {
+ /* happens for viewer images, which are not so simple to determine where to
+ * set image buffer's color spaces
+ */
+ init_data.byte_colorspace = global_role_default_byte;
+ }
+
+ if (ibuf->float_colorspace != NULL) {
+ /* sequencer stores float buffers in non-linear space */
+ init_data.float_colorspace = ibuf->float_colorspace->name;
+ }
+ else {
+ init_data.float_colorspace = NULL;
+ }
+
+ IMB_processor_apply_threaded(ibuf->y,
+ sizeof(DisplayBufferThread),
+ &init_data,
+ display_buffer_init_handle,
+ do_display_buffer_apply_thread);
+}
+
+static bool is_ibuf_rect_in_display_space(ImBuf *ibuf,
+ const ColorManagedViewSettings *view_settings,
const ColorManagedDisplaySettings *display_settings)
{
- if ((view_settings->flag & COLORMANAGE_VIEW_USE_CURVES) == 0 &&
- view_settings->exposure == 0.0f &&
- view_settings->gamma == 1.0f)
- {
- const char *from_colorspace = ibuf->rect_colorspace->name;
- const char *to_colorspace = IMB_colormanagement_get_display_colorspace_name(view_settings, display_settings);
- ColorManagedLook *look_descr = colormanage_look_get_named(view_settings->look);
- if (look_descr != NULL && !STREQ(look_descr->process_space, "")) {
- return false;
- }
-
- if (to_colorspace && STREQ(from_colorspace, to_colorspace))
- return true;
- }
-
- return false;
-}
-
-static void colormanage_display_buffer_process_ex(ImBuf *ibuf, float *display_buffer, unsigned char *display_buffer_byte,
- const ColorManagedViewSettings *view_settings,
- const ColorManagedDisplaySettings *display_settings)
-{
- ColormanageProcessor *cm_processor = NULL;
- bool skip_transform = false;
-
- /* if we're going to transform byte buffer, check whether transformation would
- * happen to the same color space as byte buffer itself is
- * this would save byte -> float -> byte conversions making display buffer
- * computation noticeable faster
- */
- if (ibuf->rect_float == NULL && ibuf->rect_colorspace) {
- skip_transform = is_ibuf_rect_in_display_space(ibuf, view_settings, display_settings);
- }
-
- if (skip_transform == false)
- cm_processor = IMB_colormanagement_display_processor_new(view_settings, display_settings);
-
- display_buffer_apply_threaded(ibuf, ibuf->rect_float, (unsigned char *) ibuf->rect,
- display_buffer, display_buffer_byte, cm_processor);
-
- if (cm_processor)
- IMB_colormanagement_processor_free(cm_processor);
-}
-
-static void colormanage_display_buffer_process(ImBuf *ibuf, unsigned char *display_buffer,
+ if ((view_settings->flag & COLORMANAGE_VIEW_USE_CURVES) == 0 &&
+ view_settings->exposure == 0.0f && view_settings->gamma == 1.0f) {
+ const char *from_colorspace = ibuf->rect_colorspace->name;
+ const char *to_colorspace = IMB_colormanagement_get_display_colorspace_name(view_settings,
+ display_settings);
+ ColorManagedLook *look_descr = colormanage_look_get_named(view_settings->look);
+ if (look_descr != NULL && !STREQ(look_descr->process_space, "")) {
+ return false;
+ }
+
+ if (to_colorspace && STREQ(from_colorspace, to_colorspace))
+ return true;
+ }
+
+ return false;
+}
+
+static void colormanage_display_buffer_process_ex(
+ ImBuf *ibuf,
+ float *display_buffer,
+ unsigned char *display_buffer_byte,
+ const ColorManagedViewSettings *view_settings,
+ const ColorManagedDisplaySettings *display_settings)
+{
+ ColormanageProcessor *cm_processor = NULL;
+ bool skip_transform = false;
+
+ /* if we're going to transform byte buffer, check whether transformation would
+ * happen to the same color space as byte buffer itself is
+ * this would save byte -> float -> byte conversions making display buffer
+ * computation noticeable faster
+ */
+ if (ibuf->rect_float == NULL && ibuf->rect_colorspace) {
+ skip_transform = is_ibuf_rect_in_display_space(ibuf, view_settings, display_settings);
+ }
+
+ if (skip_transform == false)
+ cm_processor = IMB_colormanagement_display_processor_new(view_settings, display_settings);
+
+ display_buffer_apply_threaded(ibuf,
+ ibuf->rect_float,
+ (unsigned char *)ibuf->rect,
+ display_buffer,
+ display_buffer_byte,
+ cm_processor);
+
+ if (cm_processor)
+ IMB_colormanagement_processor_free(cm_processor);
+}
+
+static void colormanage_display_buffer_process(ImBuf *ibuf,
+ unsigned char *display_buffer,
const ColorManagedViewSettings *view_settings,
const ColorManagedDisplaySettings *display_settings)
{
- colormanage_display_buffer_process_ex(ibuf, NULL, display_buffer, view_settings, display_settings);
+ colormanage_display_buffer_process_ex(
+ ibuf, NULL, display_buffer, view_settings, display_settings);
}
/*********************** Threaded processor transform routines *************************/
typedef struct ProcessorTransformThread {
- ColormanageProcessor *cm_processor;
- unsigned char *byte_buffer;
- float *float_buffer;
- int width;
- int start_line;
- int tot_line;
- int channels;
- bool predivide;
- bool float_from_byte;
+ ColormanageProcessor *cm_processor;
+ unsigned char *byte_buffer;
+ float *float_buffer;
+ int width;
+ int start_line;
+ int tot_line;
+ int channels;
+ bool predivide;
+ bool float_from_byte;
} ProcessorTransformThread;
typedef struct ProcessorTransformInit {
- ColormanageProcessor *cm_processor;
- unsigned char *byte_buffer;
- float *float_buffer;
- int width;
- int height;
- int channels;
- bool predivide;
- bool float_from_byte;
+ ColormanageProcessor *cm_processor;
+ unsigned char *byte_buffer;
+ float *float_buffer;
+ int width;
+ int height;
+ int channels;
+ bool predivide;
+ bool float_from_byte;
} ProcessorTransformInitData;
-static void processor_transform_init_handle(void *handle_v, int start_line, int tot_line, void *init_data_v)
+static void processor_transform_init_handle(void *handle_v,
+ int start_line,
+ int tot_line,
+ void *init_data_v)
{
- ProcessorTransformThread *handle = (ProcessorTransformThread *) handle_v;
- ProcessorTransformInitData *init_data = (ProcessorTransformInitData *) init_data_v;
+ ProcessorTransformThread *handle = (ProcessorTransformThread *)handle_v;
+ ProcessorTransformInitData *init_data = (ProcessorTransformInitData *)init_data_v;
- const int channels = init_data->channels;
- const int width = init_data->width;
- const bool predivide = init_data->predivide;
- const bool float_from_byte = init_data->float_from_byte;
+ const int channels = init_data->channels;
+ const int width = init_data->width;
+ const bool predivide = init_data->predivide;
+ const bool float_from_byte = init_data->float_from_byte;
- const size_t offset = ((size_t)channels) * start_line * width;
+ const size_t offset = ((size_t)channels) * start_line * width;
- memset(handle, 0, sizeof(ProcessorTransformThread));
+ memset(handle, 0, sizeof(ProcessorTransformThread));
- handle->cm_processor = init_data->cm_processor;
+ handle->cm_processor = init_data->cm_processor;
- if (init_data->byte_buffer != NULL) {
- /* TODO(serge): Offset might be different for byte and float buffers. */
- handle->byte_buffer = init_data->byte_buffer + offset;
- }
- if (init_data->float_buffer != NULL) {
- handle->float_buffer = init_data->float_buffer + offset;
- }
+ if (init_data->byte_buffer != NULL) {
+ /* TODO(serge): Offset might be different for byte and float buffers. */
+ handle->byte_buffer = init_data->byte_buffer + offset;
+ }
+ if (init_data->float_buffer != NULL) {
+ handle->float_buffer = init_data->float_buffer + offset;
+ }
- handle->width = width;
+ handle->width = width;
- handle->start_line = start_line;
- handle->tot_line = tot_line;
+ handle->start_line = start_line;
+ handle->tot_line = tot_line;
- handle->channels = channels;
- handle->predivide = predivide;
- handle->float_from_byte = float_from_byte;
+ handle->channels = channels;
+ handle->predivide = predivide;
+ handle->float_from_byte = float_from_byte;
}
static void *do_processor_transform_thread(void *handle_v)
{
- ProcessorTransformThread *handle = (ProcessorTransformThread *) handle_v;
- unsigned char *byte_buffer = handle->byte_buffer;
- float *float_buffer = handle->float_buffer;
- const int channels = handle->channels;
- const int width = handle->width;
- const int height = handle->tot_line;
- const bool predivide = handle->predivide;
- const bool float_from_byte = handle->float_from_byte;
-
- if (float_from_byte) {
- IMB_buffer_float_from_byte(float_buffer, byte_buffer,
- IB_PROFILE_SRGB, IB_PROFILE_SRGB,
- false,
- width, height, width, width);
- IMB_colormanagement_processor_apply(handle->cm_processor,
- float_buffer,
- width, height, channels,
- predivide);
- IMB_premultiply_rect_float(float_buffer, 4, width, height);
- }
- else {
- if (byte_buffer != NULL) {
- IMB_colormanagement_processor_apply_byte(handle->cm_processor,
- byte_buffer,
- width, height, channels);
- }
- if (float_buffer != NULL) {
- IMB_colormanagement_processor_apply(handle->cm_processor,
- float_buffer,
- width, height, channels,
- predivide);
- }
- }
-
- return NULL;
-}
-
-static void processor_transform_apply_threaded(unsigned char *byte_buffer, float *float_buffer,
- const int width, const int height, const int channels,
+ ProcessorTransformThread *handle = (ProcessorTransformThread *)handle_v;
+ unsigned char *byte_buffer = handle->byte_buffer;
+ float *float_buffer = handle->float_buffer;
+ const int channels = handle->channels;
+ const int width = handle->width;
+ const int height = handle->tot_line;
+ const bool predivide = handle->predivide;
+ const bool float_from_byte = handle->float_from_byte;
+
+ if (float_from_byte) {
+ IMB_buffer_float_from_byte(float_buffer,
+ byte_buffer,
+ IB_PROFILE_SRGB,
+ IB_PROFILE_SRGB,
+ false,
+ width,
+ height,
+ width,
+ width);
+ IMB_colormanagement_processor_apply(
+ handle->cm_processor, float_buffer, width, height, channels, predivide);
+ IMB_premultiply_rect_float(float_buffer, 4, width, height);
+ }
+ else {
+ if (byte_buffer != NULL) {
+ IMB_colormanagement_processor_apply_byte(
+ handle->cm_processor, byte_buffer, width, height, channels);
+ }
+ if (float_buffer != NULL) {
+ IMB_colormanagement_processor_apply(
+ handle->cm_processor, float_buffer, width, height, channels, predivide);
+ }
+ }
+
+ return NULL;
+}
+
+static void processor_transform_apply_threaded(unsigned char *byte_buffer,
+ float *float_buffer,
+ const int width,
+ const int height,
+ const int channels,
ColormanageProcessor *cm_processor,
- const bool predivide, const bool float_from_byte)
+ const bool predivide,
+ const bool float_from_byte)
{
- ProcessorTransformInitData init_data;
+ ProcessorTransformInitData init_data;
- init_data.cm_processor = cm_processor;
- init_data.byte_buffer = byte_buffer;
- init_data.float_buffer = float_buffer;
- init_data.width = width;
- init_data.height = height;
- init_data.channels = channels;
- init_data.predivide = predivide;
- init_data.float_from_byte = float_from_byte;
+ init_data.cm_processor = cm_processor;
+ init_data.byte_buffer = byte_buffer;
+ init_data.float_buffer = float_buffer;
+ init_data.width = width;
+ init_data.height = height;
+ init_data.channels = channels;
+ init_data.predivide = predivide;
+ init_data.float_from_byte = float_from_byte;
- IMB_processor_apply_threaded(height, sizeof(ProcessorTransformThread), &init_data,
- processor_transform_init_handle, do_processor_transform_thread);
+ IMB_processor_apply_threaded(height,
+ sizeof(ProcessorTransformThread),
+ &init_data,
+ processor_transform_init_handle,
+ do_processor_transform_thread);
}
/*********************** Color space transformation functions *************************/
/* convert the whole buffer from specified by name color space to another - internal implementation */
-static void colormanagement_transform_ex(unsigned char *byte_buffer, float *float_buffer,
- int width, int height, int channels,
- const char *from_colorspace, const char *to_colorspace,
- bool predivide, bool do_threaded)
-{
- ColormanageProcessor *cm_processor;
-
- if (from_colorspace[0] == '\0') {
- return;
- }
-
- if (STREQ(from_colorspace, to_colorspace)) {
- /* if source and destination color spaces are identical, skip
- * threading overhead and simply do nothing
- */
- return;
- }
-
- cm_processor = IMB_colormanagement_colorspace_processor_new(from_colorspace, to_colorspace);
-
- if (do_threaded) {
- processor_transform_apply_threaded(byte_buffer, float_buffer,
- width, height, channels,
- cm_processor, predivide, false);
- }
- else {
- if (byte_buffer != NULL) {
- IMB_colormanagement_processor_apply_byte(cm_processor, byte_buffer, width, height, channels);
- }
- if (float_buffer != NULL) {
- IMB_colormanagement_processor_apply(cm_processor, float_buffer, width, height, channels, predivide);
- }
- }
-
- IMB_colormanagement_processor_free(cm_processor);
+static void colormanagement_transform_ex(unsigned char *byte_buffer,
+ float *float_buffer,
+ int width,
+ int height,
+ int channels,
+ const char *from_colorspace,
+ const char *to_colorspace,
+ bool predivide,
+ bool do_threaded)
+{
+ ColormanageProcessor *cm_processor;
+
+ if (from_colorspace[0] == '\0') {
+ return;
+ }
+
+ if (STREQ(from_colorspace, to_colorspace)) {
+ /* if source and destination color spaces are identical, skip
+ * threading overhead and simply do nothing
+ */
+ return;
+ }
+
+ cm_processor = IMB_colormanagement_colorspace_processor_new(from_colorspace, to_colorspace);
+
+ if (do_threaded) {
+ processor_transform_apply_threaded(
+ byte_buffer, float_buffer, width, height, channels, cm_processor, predivide, false);
+ }
+ else {
+ if (byte_buffer != NULL) {
+ IMB_colormanagement_processor_apply_byte(cm_processor, byte_buffer, width, height, channels);
+ }
+ if (float_buffer != NULL) {
+ IMB_colormanagement_processor_apply(
+ cm_processor, float_buffer, width, height, channels, predivide);
+ }
+ }
+
+ IMB_colormanagement_processor_free(cm_processor);
}
/* convert the whole buffer from specified by name color space to another */
-void IMB_colormanagement_transform(float *buffer, int width, int height, int channels,
- const char *from_colorspace, const char *to_colorspace, bool predivide)
+void IMB_colormanagement_transform(float *buffer,
+ int width,
+ int height,
+ int channels,
+ const char *from_colorspace,
+ const char *to_colorspace,
+ bool predivide)
{
- colormanagement_transform_ex(NULL, buffer, width, height, channels, from_colorspace, to_colorspace, predivide, false);
+ colormanagement_transform_ex(
+ NULL, buffer, width, height, channels, from_colorspace, to_colorspace, predivide, false);
}
/* convert the whole buffer from specified by name color space to another
* will do threaded conversion
*/
-void IMB_colormanagement_transform_threaded(float *buffer, int width, int height, int channels,
- const char *from_colorspace, const char *to_colorspace, bool predivide)
+void IMB_colormanagement_transform_threaded(float *buffer,
+ int width,
+ int height,
+ int channels,
+ const char *from_colorspace,
+ const char *to_colorspace,
+ bool predivide)
{
- colormanagement_transform_ex(NULL, buffer, width, height, channels, from_colorspace, to_colorspace, predivide, true);
+ colormanagement_transform_ex(
+ NULL, buffer, width, height, channels, from_colorspace, to_colorspace, predivide, true);
}
/* Similar to functions above, but operates on byte buffer. */
-void IMB_colormanagement_transform_byte(unsigned char *buffer, int width, int height, int channels,
- const char *from_colorspace, const char *to_colorspace)
+void IMB_colormanagement_transform_byte(unsigned char *buffer,
+ int width,
+ int height,
+ int channels,
+ const char *from_colorspace,
+ const char *to_colorspace)
{
- colormanagement_transform_ex(buffer, NULL, width, height, channels, from_colorspace, to_colorspace, false, false);
+ colormanagement_transform_ex(
+ buffer, NULL, width, height, channels, from_colorspace, to_colorspace, false, false);
}
-void IMB_colormanagement_transform_byte_threaded(unsigned char *buffer, int width, int height, int channels,
- const char *from_colorspace, const char *to_colorspace)
+void IMB_colormanagement_transform_byte_threaded(unsigned char *buffer,
+ int width,
+ int height,
+ int channels,
+ const char *from_colorspace,
+ const char *to_colorspace)
{
- colormanagement_transform_ex(buffer, NULL, width, height, channels, from_colorspace, to_colorspace, false, true);
+ colormanagement_transform_ex(
+ buffer, NULL, width, height, channels, from_colorspace, to_colorspace, false, true);
}
/* Similar to above, but gets float buffer from display one. */
-void IMB_colormanagement_transform_from_byte(float *float_buffer, unsigned char *byte_buffer,
- int width, int height, int channels,
- const char *from_colorspace, const char *to_colorspace)
-{
- IMB_buffer_float_from_byte(float_buffer, byte_buffer,
- IB_PROFILE_SRGB, IB_PROFILE_SRGB,
- true,
- width, height, width, width);
- IMB_colormanagement_transform(float_buffer,
- width, height, channels,
- from_colorspace, to_colorspace,
- true);
-}
-void IMB_colormanagement_transform_from_byte_threaded(float *float_buffer, unsigned char *byte_buffer,
- int width, int height, int channels,
- const char *from_colorspace, const char *to_colorspace)
-{
- ColormanageProcessor *cm_processor;
- if (from_colorspace == NULL || from_colorspace[0] == '\0') {
- return;
- }
- if (STREQ(from_colorspace, to_colorspace)) {
- /* Because this function always takes a byte buffer and returns a float buffer, it must
- * always do byte-to-float conversion of some kind. To avoid threading overhead
- * IMB_buffer_float_from_byte is used when color spaces are identical. See T51002.
- */
- IMB_buffer_float_from_byte(float_buffer, byte_buffer,
- IB_PROFILE_SRGB, IB_PROFILE_SRGB,
- false,
- width, height, width, width);
- IMB_premultiply_rect_float(float_buffer, 4, width, height);
- return;
- }
- cm_processor = IMB_colormanagement_colorspace_processor_new(from_colorspace, to_colorspace);
- processor_transform_apply_threaded(byte_buffer, float_buffer,
- width, height, channels,
- cm_processor, false, true);
- IMB_colormanagement_processor_free(cm_processor);
-}
-
-void IMB_colormanagement_transform_v4(float pixel[4], const char *from_colorspace, const char *to_colorspace)
-{
- ColormanageProcessor *cm_processor;
-
- if (from_colorspace[0] == '\0') {
- return;
- }
-
- if (STREQ(from_colorspace, to_colorspace)) {
- /* if source and destination color spaces are identical, skip
- * threading overhead and simply do nothing
- */
- return;
- }
-
- cm_processor = IMB_colormanagement_colorspace_processor_new(from_colorspace, to_colorspace);
-
- IMB_colormanagement_processor_apply_v4(cm_processor, pixel);
-
- IMB_colormanagement_processor_free(cm_processor);
+void IMB_colormanagement_transform_from_byte(float *float_buffer,
+ unsigned char *byte_buffer,
+ int width,
+ int height,
+ int channels,
+ const char *from_colorspace,
+ const char *to_colorspace)
+{
+ IMB_buffer_float_from_byte(float_buffer,
+ byte_buffer,
+ IB_PROFILE_SRGB,
+ IB_PROFILE_SRGB,
+ true,
+ width,
+ height,
+ width,
+ width);
+ IMB_colormanagement_transform(
+ float_buffer, width, height, channels, from_colorspace, to_colorspace, true);
+}
+void IMB_colormanagement_transform_from_byte_threaded(float *float_buffer,
+ unsigned char *byte_buffer,
+ int width,
+ int height,
+ int channels,
+ const char *from_colorspace,
+ const char *to_colorspace)
+{
+ ColormanageProcessor *cm_processor;
+ if (from_colorspace == NULL || from_colorspace[0] == '\0') {
+ return;
+ }
+ if (STREQ(from_colorspace, to_colorspace)) {
+ /* Because this function always takes a byte buffer and returns a float buffer, it must
+ * always do byte-to-float conversion of some kind. To avoid threading overhead
+ * IMB_buffer_float_from_byte is used when color spaces are identical. See T51002.
+ */
+ IMB_buffer_float_from_byte(float_buffer,
+ byte_buffer,
+ IB_PROFILE_SRGB,
+ IB_PROFILE_SRGB,
+ false,
+ width,
+ height,
+ width,
+ width);
+ IMB_premultiply_rect_float(float_buffer, 4, width, height);
+ return;
+ }
+ cm_processor = IMB_colormanagement_colorspace_processor_new(from_colorspace, to_colorspace);
+ processor_transform_apply_threaded(
+ byte_buffer, float_buffer, width, height, channels, cm_processor, false, true);
+ IMB_colormanagement_processor_free(cm_processor);
+}
+
+void IMB_colormanagement_transform_v4(float pixel[4],
+ const char *from_colorspace,
+ const char *to_colorspace)
+{
+ ColormanageProcessor *cm_processor;
+
+ if (from_colorspace[0] == '\0') {
+ return;
+ }
+
+ if (STREQ(from_colorspace, to_colorspace)) {
+ /* if source and destination color spaces are identical, skip
+ * threading overhead and simply do nothing
+ */
+ return;
+ }
+
+ cm_processor = IMB_colormanagement_colorspace_processor_new(from_colorspace, to_colorspace);
+
+ IMB_colormanagement_processor_apply_v4(cm_processor, pixel);
+
+ IMB_colormanagement_processor_free(cm_processor);
}
/* convert pixel from specified by descriptor color space to scene linear
@@ -1842,84 +1976,94 @@ void IMB_colormanagement_transform_v4(float pixel[4], const char *from_colorspac
*/
void IMB_colormanagement_colorspace_to_scene_linear_v3(float pixel[3], ColorSpace *colorspace)
{
- OCIO_ConstProcessorRcPtr *processor;
+ OCIO_ConstProcessorRcPtr *processor;
- if (!colorspace) {
- /* should never happen */
- printf("%s: perform conversion from unknown color space\n", __func__);
- return;
- }
+ if (!colorspace) {
+ /* should never happen */
+ printf("%s: perform conversion from unknown color space\n", __func__);
+ return;
+ }
- processor = colorspace_to_scene_linear_processor(colorspace);
+ processor = colorspace_to_scene_linear_processor(colorspace);
- if (processor)
- OCIO_processorApplyRGB(processor, pixel);
+ if (processor)
+ OCIO_processorApplyRGB(processor, pixel);
}
/* same as above, but converts colors in opposite direction */
void IMB_colormanagement_scene_linear_to_colorspace_v3(float pixel[3], ColorSpace *colorspace)
{
- OCIO_ConstProcessorRcPtr *processor;
+ OCIO_ConstProcessorRcPtr *processor;
- if (!colorspace) {
- /* should never happen */
- printf("%s: perform conversion from unknown color space\n", __func__);
- return;
- }
+ if (!colorspace) {
+ /* should never happen */
+ printf("%s: perform conversion from unknown color space\n", __func__);
+ return;
+ }
- processor = colorspace_from_scene_linear_processor(colorspace);
+ processor = colorspace_from_scene_linear_processor(colorspace);
- if (processor)
- OCIO_processorApplyRGB(processor, pixel);
+ if (processor)
+ OCIO_processorApplyRGB(processor, pixel);
}
-void IMB_colormanagement_colorspace_to_scene_linear_v4(float pixel[4], bool predivide, ColorSpace *colorspace)
+void IMB_colormanagement_colorspace_to_scene_linear_v4(float pixel[4],
+ bool predivide,
+ ColorSpace *colorspace)
{
- OCIO_ConstProcessorRcPtr *processor;
+ OCIO_ConstProcessorRcPtr *processor;
- if (!colorspace) {
- /* should never happen */
- printf("%s: perform conversion from unknown color space\n", __func__);
- return;
- }
+ if (!colorspace) {
+ /* should never happen */
+ printf("%s: perform conversion from unknown color space\n", __func__);
+ return;
+ }
- processor = colorspace_to_scene_linear_processor(colorspace);
+ processor = colorspace_to_scene_linear_processor(colorspace);
- if (processor) {
- if (predivide)
- OCIO_processorApplyRGBA_predivide(processor, pixel);
- else
- OCIO_processorApplyRGBA(processor, pixel);
- }
+ if (processor) {
+ if (predivide)
+ OCIO_processorApplyRGBA_predivide(processor, pixel);
+ else
+ OCIO_processorApplyRGBA(processor, pixel);
+ }
}
-void IMB_colormanagement_colorspace_to_scene_linear(float *buffer, int width, int height, int channels, struct ColorSpace *colorspace, bool predivide)
+void IMB_colormanagement_colorspace_to_scene_linear(float *buffer,
+ int width,
+ int height,
+ int channels,
+ struct ColorSpace *colorspace,
+ bool predivide)
{
- OCIO_ConstProcessorRcPtr *processor;
+ OCIO_ConstProcessorRcPtr *processor;
- if (!colorspace) {
- /* should never happen */
- printf("%s: perform conversion from unknown color space\n", __func__);
- return;
- }
+ if (!colorspace) {
+ /* should never happen */
+ printf("%s: perform conversion from unknown color space\n", __func__);
+ return;
+ }
- processor = colorspace_to_scene_linear_processor(colorspace);
+ processor = colorspace_to_scene_linear_processor(colorspace);
- if (processor) {
- OCIO_PackedImageDesc *img;
+ if (processor) {
+ OCIO_PackedImageDesc *img;
- img = OCIO_createOCIO_PackedImageDesc(
- buffer, width, height, channels, sizeof(float),
- (size_t)channels * sizeof(float),
- (size_t)channels * sizeof(float) * width);
+ img = OCIO_createOCIO_PackedImageDesc(buffer,
+ width,
+ height,
+ channels,
+ sizeof(float),
+ (size_t)channels * sizeof(float),
+ (size_t)channels * sizeof(float) * width);
- if (predivide)
- OCIO_processorApply_predivide(processor, img);
- else
- OCIO_processorApply(processor, img);
+ if (predivide)
+ OCIO_processorApply_predivide(processor, img);
+ else
+ OCIO_processorApply(processor, img);
- OCIO_PackedImageDescRelease(img);
- }
+ OCIO_PackedImageDescRelease(img);
+ }
}
/* Conversion between color picking role. Typically we would expect such a
@@ -1932,66 +2076,64 @@ void IMB_colormanagement_colorspace_to_scene_linear(float *buffer, int width, in
*/
void IMB_colormanagement_scene_linear_to_color_picking_v3(float pixel[3])
{
- if (!global_color_picking_state.processor_to && !global_color_picking_state.failed) {
- /* Create processor if none exists. */
- BLI_mutex_lock(&processor_lock);
+ if (!global_color_picking_state.processor_to && !global_color_picking_state.failed) {
+ /* Create processor if none exists. */
+ BLI_mutex_lock(&processor_lock);
- if (!global_color_picking_state.processor_to && !global_color_picking_state.failed) {
- global_color_picking_state.processor_to =
- create_colorspace_transform_processor(global_role_scene_linear,
- global_role_color_picking);
+ if (!global_color_picking_state.processor_to && !global_color_picking_state.failed) {
+ global_color_picking_state.processor_to = create_colorspace_transform_processor(
+ global_role_scene_linear, global_role_color_picking);
- if (!global_color_picking_state.processor_to) {
- global_color_picking_state.failed = true;
- }
- }
+ if (!global_color_picking_state.processor_to) {
+ global_color_picking_state.failed = true;
+ }
+ }
- BLI_mutex_unlock(&processor_lock);
- }
+ BLI_mutex_unlock(&processor_lock);
+ }
- if (global_color_picking_state.processor_to) {
- OCIO_processorApplyRGB(global_color_picking_state.processor_to, pixel);
- }
+ if (global_color_picking_state.processor_to) {
+ OCIO_processorApplyRGB(global_color_picking_state.processor_to, pixel);
+ }
}
void IMB_colormanagement_color_picking_to_scene_linear_v3(float pixel[3])
{
- if (!global_color_picking_state.processor_from && !global_color_picking_state.failed) {
- /* Create processor if none exists. */
- BLI_mutex_lock(&processor_lock);
+ if (!global_color_picking_state.processor_from && !global_color_picking_state.failed) {
+ /* Create processor if none exists. */
+ BLI_mutex_lock(&processor_lock);
- if (!global_color_picking_state.processor_from && !global_color_picking_state.failed) {
- global_color_picking_state.processor_from =
- create_colorspace_transform_processor(global_role_color_picking,
- global_role_scene_linear);
+ if (!global_color_picking_state.processor_from && !global_color_picking_state.failed) {
+ global_color_picking_state.processor_from = create_colorspace_transform_processor(
+ global_role_color_picking, global_role_scene_linear);
- if (!global_color_picking_state.processor_from) {
- global_color_picking_state.failed = true;
- }
- }
+ if (!global_color_picking_state.processor_from) {
+ global_color_picking_state.failed = true;
+ }
+ }
- BLI_mutex_unlock(&processor_lock);
- }
+ BLI_mutex_unlock(&processor_lock);
+ }
- if (global_color_picking_state.processor_from) {
- OCIO_processorApplyRGB(global_color_picking_state.processor_from, pixel);
- }
+ if (global_color_picking_state.processor_from) {
+ OCIO_processorApplyRGB(global_color_picking_state.processor_from, pixel);
+ }
}
/* Conversion between sRGB, for rare cases like hex color or copy/pasting
* between UI theme and scene linear colors. */
void IMB_colormanagement_scene_linear_to_srgb_v3(float pixel[3])
{
- mul_m3_v3(imbuf_rgb_to_xyz, pixel);
- mul_m3_v3(imbuf_xyz_to_linear_srgb, pixel);
- linearrgb_to_srgb_v3_v3(pixel, pixel);
+ mul_m3_v3(imbuf_rgb_to_xyz, pixel);
+ mul_m3_v3(imbuf_xyz_to_linear_srgb, pixel);
+ linearrgb_to_srgb_v3_v3(pixel, pixel);
}
void IMB_colormanagement_srgb_to_scene_linear_v3(float pixel[3])
{
- srgb_to_linearrgb_v3_v3(pixel, pixel);
- mul_m3_v3(imbuf_linear_srgb_to_xyz, pixel);
- mul_m3_v3(imbuf_xyz_to_rgb, pixel);
+ srgb_to_linearrgb_v3_v3(pixel, pixel);
+ mul_m3_v3(imbuf_linear_srgb_to_xyz, pixel);
+ mul_m3_v3(imbuf_xyz_to_rgb, pixel);
}
/* convert pixel from scene linear to display space using default view
@@ -2000,65 +2142,74 @@ void IMB_colormanagement_srgb_to_scene_linear_v3(float pixel[3])
*/
void IMB_colormanagement_scene_linear_to_display_v3(float pixel[3], ColorManagedDisplay *display)
{
- OCIO_ConstProcessorRcPtr *processor;
+ OCIO_ConstProcessorRcPtr *processor;
- processor = display_from_scene_linear_processor(display);
+ processor = display_from_scene_linear_processor(display);
- if (processor)
- OCIO_processorApplyRGB(processor, pixel);
+ if (processor)
+ OCIO_processorApplyRGB(processor, pixel);
}
/* same as above, but converts color in opposite direction */
void IMB_colormanagement_display_to_scene_linear_v3(float pixel[3], ColorManagedDisplay *display)
{
- OCIO_ConstProcessorRcPtr *processor;
+ OCIO_ConstProcessorRcPtr *processor;
- processor = display_to_scene_linear_processor(display);
+ processor = display_to_scene_linear_processor(display);
- if (processor)
- OCIO_processorApplyRGB(processor, pixel);
+ if (processor)
+ OCIO_processorApplyRGB(processor, pixel);
}
-void IMB_colormanagement_pixel_to_display_space_v4(float result[4], const float pixel[4],
- const ColorManagedViewSettings *view_settings,
- const ColorManagedDisplaySettings *display_settings)
+void IMB_colormanagement_pixel_to_display_space_v4(
+ float result[4],
+ const float pixel[4],
+ const ColorManagedViewSettings *view_settings,
+ const ColorManagedDisplaySettings *display_settings)
{
- ColormanageProcessor *cm_processor;
+ ColormanageProcessor *cm_processor;
- copy_v4_v4(result, pixel);
+ copy_v4_v4(result, pixel);
- cm_processor = IMB_colormanagement_display_processor_new(view_settings, display_settings);
- IMB_colormanagement_processor_apply_v4(cm_processor, result);
- IMB_colormanagement_processor_free(cm_processor);
+ cm_processor = IMB_colormanagement_display_processor_new(view_settings, display_settings);
+ IMB_colormanagement_processor_apply_v4(cm_processor, result);
+ IMB_colormanagement_processor_free(cm_processor);
}
-void IMB_colormanagement_pixel_to_display_space_v3(float result[3], const float pixel[3],
- const ColorManagedViewSettings *view_settings,
- const ColorManagedDisplaySettings *display_settings)
+void IMB_colormanagement_pixel_to_display_space_v3(
+ float result[3],
+ const float pixel[3],
+ const ColorManagedViewSettings *view_settings,
+ const ColorManagedDisplaySettings *display_settings)
{
- ColormanageProcessor *cm_processor;
+ ColormanageProcessor *cm_processor;
- copy_v3_v3(result, pixel);
+ copy_v3_v3(result, pixel);
- cm_processor = IMB_colormanagement_display_processor_new(view_settings, display_settings);
- IMB_colormanagement_processor_apply_v3(cm_processor, result);
- IMB_colormanagement_processor_free(cm_processor);
+ cm_processor = IMB_colormanagement_display_processor_new(view_settings, display_settings);
+ IMB_colormanagement_processor_apply_v3(cm_processor, result);
+ IMB_colormanagement_processor_free(cm_processor);
}
-static void colormanagement_imbuf_make_display_space(ImBuf *ibuf, const ColorManagedViewSettings *view_settings,
- const ColorManagedDisplaySettings *display_settings, bool make_byte)
+static void colormanagement_imbuf_make_display_space(
+ ImBuf *ibuf,
+ const ColorManagedViewSettings *view_settings,
+ const ColorManagedDisplaySettings *display_settings,
+ bool make_byte)
{
- if (!ibuf->rect && make_byte)
- imb_addrectImBuf(ibuf);
+ if (!ibuf->rect && make_byte)
+ imb_addrectImBuf(ibuf);
- colormanage_display_buffer_process_ex(ibuf, ibuf->rect_float, (unsigned char *)ibuf->rect,
- view_settings, display_settings);
+ colormanage_display_buffer_process_ex(
+ ibuf, ibuf->rect_float, (unsigned char *)ibuf->rect, view_settings, display_settings);
}
-void IMB_colormanagement_imbuf_make_display_space(ImBuf *ibuf, const ColorManagedViewSettings *view_settings,
- const ColorManagedDisplaySettings *display_settings)
+void IMB_colormanagement_imbuf_make_display_space(
+ ImBuf *ibuf,
+ const ColorManagedViewSettings *view_settings,
+ const ColorManagedDisplaySettings *display_settings)
{
- colormanagement_imbuf_make_display_space(ibuf, view_settings, display_settings, false);
+ colormanagement_imbuf_make_display_space(ibuf, view_settings, display_settings, false);
}
/* prepare image buffer to be saved on disk, applying color management if needed
@@ -2072,809 +2223,861 @@ void IMB_colormanagement_imbuf_make_display_space(ImBuf *ibuf, const ColorManage
* in image format write callback and if float_colorspace is not NULL, no color
* space transformation should be applied on this buffer.
*/
-ImBuf *IMB_colormanagement_imbuf_for_write(ImBuf *ibuf, bool save_as_render, bool allocate_result, const ColorManagedViewSettings *view_settings,
- const ColorManagedDisplaySettings *display_settings, ImageFormatData *image_format_data)
-{
- ImBuf *colormanaged_ibuf = ibuf;
- bool do_colormanagement;
- bool is_movie = BKE_imtype_is_movie(image_format_data->imtype);
- bool requires_linear_float = BKE_imtype_requires_linear_float(image_format_data->imtype);
- bool do_alpha_under = image_format_data->planes != R_IMF_PLANES_RGBA;
-
- if (ibuf->rect_float && ibuf->rect &&
- (ibuf->userflags & (IB_DISPLAY_BUFFER_INVALID | IB_RECT_INVALID)) != 0)
- {
- IMB_rect_from_float(ibuf);
- ibuf->userflags &= ~(IB_RECT_INVALID | IB_DISPLAY_BUFFER_INVALID);
- }
-
- do_colormanagement = save_as_render && (is_movie || !requires_linear_float);
-
- if (do_colormanagement || do_alpha_under) {
- if (allocate_result) {
- colormanaged_ibuf = IMB_dupImBuf(ibuf);
- }
- else {
- /* render pipeline is constructing image buffer itself, but it's re-using byte and float buffers from render result
- * make copy of this buffers here sine this buffers would be transformed to other color space here
- */
-
- if (ibuf->rect && (ibuf->mall & IB_rect) == 0) {
- ibuf->rect = MEM_dupallocN(ibuf->rect);
- ibuf->mall |= IB_rect;
- }
-
- if (ibuf->rect_float && (ibuf->mall & IB_rectfloat) == 0) {
- ibuf->rect_float = MEM_dupallocN(ibuf->rect_float);
- ibuf->mall |= IB_rectfloat;
- }
- }
- }
-
- /* If we're saving from RGBA to RGB buffer then it's not
- * so much useful to just ignore alpha -- it leads to bad
- * artifacts especially when saving byte images.
- *
- * What we do here is we're overlaying our image on top of
- * background color (which is currently black).
- *
- * This is quite much the same as what Gimp does and it
- * seems to be what artists expects from saving.
- *
- * Do a conversion here, so image format writers could
- * happily assume all the alpha tricks were made already.
- * helps keep things locally here, not spreading it to
- * all possible image writers we've got.
- */
- if (do_alpha_under) {
- float color[3] = {0, 0, 0};
-
- if (colormanaged_ibuf->rect_float && colormanaged_ibuf->channels == 4) {
- IMB_alpha_under_color_float(colormanaged_ibuf->rect_float, colormanaged_ibuf->x,
- colormanaged_ibuf->y, color);
- }
-
- if (colormanaged_ibuf->rect) {
- IMB_alpha_under_color_byte((unsigned char *)colormanaged_ibuf->rect,
- colormanaged_ibuf->x, colormanaged_ibuf->y,
- color);
- }
- }
-
- if (do_colormanagement) {
- bool make_byte = false;
- const ImFileType *type;
-
- /* for proper check whether byte buffer is required by a format or not
- * should be pretty safe since this image buffer is supposed to be used for
- * saving only and ftype would be overwritten a bit later by BKE_imbuf_write
- */
- colormanaged_ibuf->ftype = BKE_image_imtype_to_ftype(image_format_data->imtype, &colormanaged_ibuf->foptions);
-
- /* if file format isn't able to handle float buffer itself,
- * we need to allocate byte buffer and store color managed
- * image there
- */
- for (type = IMB_FILE_TYPES; type < IMB_FILE_TYPES_LAST; type++) {
- if (type->save && type->ftype(type, colormanaged_ibuf)) {
- if ((type->flag & IM_FTYPE_FLOAT) == 0)
- make_byte = true;
-
- break;
- }
- }
-
- /* perform color space conversions */
- colormanagement_imbuf_make_display_space(colormanaged_ibuf, view_settings, display_settings, make_byte);
-
- if (colormanaged_ibuf->rect_float) {
- /* float buffer isn't linear anymore,
- * image format write callback should check for this flag and assume
- * no space conversion should happen if ibuf->float_colorspace != NULL
- */
- colormanaged_ibuf->float_colorspace = display_transform_get_colorspace(view_settings, display_settings);
- }
- }
-
- if (colormanaged_ibuf != ibuf) {
- IMB_metadata_copy(colormanaged_ibuf, ibuf);
- }
-
- return colormanaged_ibuf;
-}
-
-void IMB_colormanagement_buffer_make_display_space(float *buffer, unsigned char *display_buffer,
- int width, int height, int channels, float dither,
- const ColorManagedViewSettings *view_settings,
- const ColorManagedDisplaySettings *display_settings)
-{
- ColormanageProcessor *cm_processor;
- size_t float_buffer_size = ((size_t)width) * height * channels * sizeof(float);
- float *display_buffer_float = MEM_mallocN(float_buffer_size, "byte_buffer_make_display_space");
-
- /* TODO(sergey): Convert float directly to byte buffer. */
-
- memcpy(display_buffer_float, buffer, float_buffer_size);
-
- cm_processor = IMB_colormanagement_display_processor_new(view_settings, display_settings);
-
- processor_transform_apply_threaded(NULL, display_buffer_float, width, height, channels,
- cm_processor, true, false);
-
- IMB_buffer_byte_from_float(display_buffer, display_buffer_float,
- channels, dither, IB_PROFILE_SRGB, IB_PROFILE_SRGB,
- true, width, height, width, width);
-
- MEM_freeN(display_buffer_float);
- IMB_colormanagement_processor_free(cm_processor);
+ImBuf *IMB_colormanagement_imbuf_for_write(ImBuf *ibuf,
+ bool save_as_render,
+ bool allocate_result,
+ const ColorManagedViewSettings *view_settings,
+ const ColorManagedDisplaySettings *display_settings,
+ ImageFormatData *image_format_data)
+{
+ ImBuf *colormanaged_ibuf = ibuf;
+ bool do_colormanagement;
+ bool is_movie = BKE_imtype_is_movie(image_format_data->imtype);
+ bool requires_linear_float = BKE_imtype_requires_linear_float(image_format_data->imtype);
+ bool do_alpha_under = image_format_data->planes != R_IMF_PLANES_RGBA;
+
+ if (ibuf->rect_float && ibuf->rect &&
+ (ibuf->userflags & (IB_DISPLAY_BUFFER_INVALID | IB_RECT_INVALID)) != 0) {
+ IMB_rect_from_float(ibuf);
+ ibuf->userflags &= ~(IB_RECT_INVALID | IB_DISPLAY_BUFFER_INVALID);
+ }
+
+ do_colormanagement = save_as_render && (is_movie || !requires_linear_float);
+
+ if (do_colormanagement || do_alpha_under) {
+ if (allocate_result) {
+ colormanaged_ibuf = IMB_dupImBuf(ibuf);
+ }
+ else {
+ /* render pipeline is constructing image buffer itself, but it's re-using byte and float buffers from render result
+ * make copy of this buffers here sine this buffers would be transformed to other color space here
+ */
+
+ if (ibuf->rect && (ibuf->mall & IB_rect) == 0) {
+ ibuf->rect = MEM_dupallocN(ibuf->rect);
+ ibuf->mall |= IB_rect;
+ }
+
+ if (ibuf->rect_float && (ibuf->mall & IB_rectfloat) == 0) {
+ ibuf->rect_float = MEM_dupallocN(ibuf->rect_float);
+ ibuf->mall |= IB_rectfloat;
+ }
+ }
+ }
+
+ /* If we're saving from RGBA to RGB buffer then it's not
+ * so much useful to just ignore alpha -- it leads to bad
+ * artifacts especially when saving byte images.
+ *
+ * What we do here is we're overlaying our image on top of
+ * background color (which is currently black).
+ *
+ * This is quite much the same as what Gimp does and it
+ * seems to be what artists expects from saving.
+ *
+ * Do a conversion here, so image format writers could
+ * happily assume all the alpha tricks were made already.
+ * helps keep things locally here, not spreading it to
+ * all possible image writers we've got.
+ */
+ if (do_alpha_under) {
+ float color[3] = {0, 0, 0};
+
+ if (colormanaged_ibuf->rect_float && colormanaged_ibuf->channels == 4) {
+ IMB_alpha_under_color_float(
+ colormanaged_ibuf->rect_float, colormanaged_ibuf->x, colormanaged_ibuf->y, color);
+ }
+
+ if (colormanaged_ibuf->rect) {
+ IMB_alpha_under_color_byte((unsigned char *)colormanaged_ibuf->rect,
+ colormanaged_ibuf->x,
+ colormanaged_ibuf->y,
+ color);
+ }
+ }
+
+ if (do_colormanagement) {
+ bool make_byte = false;
+ const ImFileType *type;
+
+ /* for proper check whether byte buffer is required by a format or not
+ * should be pretty safe since this image buffer is supposed to be used for
+ * saving only and ftype would be overwritten a bit later by BKE_imbuf_write
+ */
+ colormanaged_ibuf->ftype = BKE_image_imtype_to_ftype(image_format_data->imtype,
+ &colormanaged_ibuf->foptions);
+
+ /* if file format isn't able to handle float buffer itself,
+ * we need to allocate byte buffer and store color managed
+ * image there
+ */
+ for (type = IMB_FILE_TYPES; type < IMB_FILE_TYPES_LAST; type++) {
+ if (type->save && type->ftype(type, colormanaged_ibuf)) {
+ if ((type->flag & IM_FTYPE_FLOAT) == 0)
+ make_byte = true;
+
+ break;
+ }
+ }
+
+ /* perform color space conversions */
+ colormanagement_imbuf_make_display_space(
+ colormanaged_ibuf, view_settings, display_settings, make_byte);
+
+ if (colormanaged_ibuf->rect_float) {
+ /* float buffer isn't linear anymore,
+ * image format write callback should check for this flag and assume
+ * no space conversion should happen if ibuf->float_colorspace != NULL
+ */
+ colormanaged_ibuf->float_colorspace = display_transform_get_colorspace(view_settings,
+ display_settings);
+ }
+ }
+
+ if (colormanaged_ibuf != ibuf) {
+ IMB_metadata_copy(colormanaged_ibuf, ibuf);
+ }
+
+ return colormanaged_ibuf;
+}
+
+void IMB_colormanagement_buffer_make_display_space(
+ float *buffer,
+ unsigned char *display_buffer,
+ int width,
+ int height,
+ int channels,
+ float dither,
+ const ColorManagedViewSettings *view_settings,
+ const ColorManagedDisplaySettings *display_settings)
+{
+ ColormanageProcessor *cm_processor;
+ size_t float_buffer_size = ((size_t)width) * height * channels * sizeof(float);
+ float *display_buffer_float = MEM_mallocN(float_buffer_size, "byte_buffer_make_display_space");
+
+ /* TODO(sergey): Convert float directly to byte buffer. */
+
+ memcpy(display_buffer_float, buffer, float_buffer_size);
+
+ cm_processor = IMB_colormanagement_display_processor_new(view_settings, display_settings);
+
+ processor_transform_apply_threaded(
+ NULL, display_buffer_float, width, height, channels, cm_processor, true, false);
+
+ IMB_buffer_byte_from_float(display_buffer,
+ display_buffer_float,
+ channels,
+ dither,
+ IB_PROFILE_SRGB,
+ IB_PROFILE_SRGB,
+ true,
+ width,
+ height,
+ width,
+ width);
+
+ MEM_freeN(display_buffer_float);
+ IMB_colormanagement_processor_free(cm_processor);
}
/*********************** Public display buffers interfaces *************************/
/* acquire display buffer for given image buffer using specified view and display settings */
-unsigned char *IMB_display_buffer_acquire(ImBuf *ibuf, const ColorManagedViewSettings *view_settings,
- const ColorManagedDisplaySettings *display_settings, void **cache_handle)
-{
- unsigned char *display_buffer;
- size_t buffer_size;
- ColormanageCacheViewSettings cache_view_settings;
- ColormanageCacheDisplaySettings cache_display_settings;
- ColorManagedViewSettings default_view_settings;
- const ColorManagedViewSettings *applied_view_settings;
-
- *cache_handle = NULL;
-
- if (!ibuf->x || !ibuf->y)
- return NULL;
-
- if (view_settings) {
- applied_view_settings = view_settings;
- }
- else {
- /* If no view settings were specified, use default ones, which will
- * attempt not to do any extra color correction. */
- IMB_colormanagement_init_default_view_settings(
- &default_view_settings, display_settings);
- applied_view_settings = &default_view_settings;
- }
-
- /* early out: no float buffer and byte buffer is already in display space,
- * let's just use if
- */
- if (ibuf->rect_float == NULL && ibuf->rect_colorspace && ibuf->channels == 4) {
- if (is_ibuf_rect_in_display_space(ibuf, applied_view_settings, display_settings))
- return (unsigned char *) ibuf->rect;
- }
-
- colormanage_view_settings_to_cache(ibuf, &cache_view_settings, applied_view_settings);
- colormanage_display_settings_to_cache(&cache_display_settings, display_settings);
-
- if (ibuf->invalid_rect.xmin != ibuf->invalid_rect.xmax) {
- if ((ibuf->userflags & IB_DISPLAY_BUFFER_INVALID) == 0) {
- IMB_partial_display_buffer_update_threaded(ibuf,
- ibuf->rect_float,
- (unsigned char *) ibuf->rect,
- ibuf->x,
- 0, 0,
- applied_view_settings,
- display_settings,
- ibuf->invalid_rect.xmin,
- ibuf->invalid_rect.ymin,
- ibuf->invalid_rect.xmax,
- ibuf->invalid_rect.ymax,
- false);
- }
-
- BLI_rcti_init(&ibuf->invalid_rect, 0, 0, 0, 0);
- }
-
- BLI_thread_lock(LOCK_COLORMANAGE);
-
- /* ensure color management bit fields exists */
- if (!ibuf->display_buffer_flags) {
- ibuf->display_buffer_flags = MEM_callocN(sizeof(unsigned int) * global_tot_display, "imbuf display_buffer_flags");
- }
- else if (ibuf->userflags & IB_DISPLAY_BUFFER_INVALID) {
- /* all display buffers were marked as invalid from other areas,
- * now propagate this flag to internal color management routines
- */
- memset(ibuf->display_buffer_flags, 0, global_tot_display * sizeof(unsigned int));
-
- ibuf->userflags &= ~IB_DISPLAY_BUFFER_INVALID;
- }
-
- display_buffer = colormanage_cache_get(ibuf, &cache_view_settings, &cache_display_settings, cache_handle);
-
- if (display_buffer) {
- BLI_thread_unlock(LOCK_COLORMANAGE);
- return display_buffer;
- }
-
- buffer_size = DISPLAY_BUFFER_CHANNELS * ((size_t)ibuf->x) * ibuf->y * sizeof(char);
- display_buffer = MEM_callocN(buffer_size, "imbuf display buffer");
-
- colormanage_display_buffer_process(ibuf, display_buffer, applied_view_settings, display_settings);
-
- colormanage_cache_put(ibuf, &cache_view_settings, &cache_display_settings, display_buffer, cache_handle);
-
- BLI_thread_unlock(LOCK_COLORMANAGE);
-
- return display_buffer;
+unsigned char *IMB_display_buffer_acquire(ImBuf *ibuf,
+ const ColorManagedViewSettings *view_settings,
+ const ColorManagedDisplaySettings *display_settings,
+ void **cache_handle)
+{
+ unsigned char *display_buffer;
+ size_t buffer_size;
+ ColormanageCacheViewSettings cache_view_settings;
+ ColormanageCacheDisplaySettings cache_display_settings;
+ ColorManagedViewSettings default_view_settings;
+ const ColorManagedViewSettings *applied_view_settings;
+
+ *cache_handle = NULL;
+
+ if (!ibuf->x || !ibuf->y)
+ return NULL;
+
+ if (view_settings) {
+ applied_view_settings = view_settings;
+ }
+ else {
+ /* If no view settings were specified, use default ones, which will
+ * attempt not to do any extra color correction. */
+ IMB_colormanagement_init_default_view_settings(&default_view_settings, display_settings);
+ applied_view_settings = &default_view_settings;
+ }
+
+ /* early out: no float buffer and byte buffer is already in display space,
+ * let's just use if
+ */
+ if (ibuf->rect_float == NULL && ibuf->rect_colorspace && ibuf->channels == 4) {
+ if (is_ibuf_rect_in_display_space(ibuf, applied_view_settings, display_settings))
+ return (unsigned char *)ibuf->rect;
+ }
+
+ colormanage_view_settings_to_cache(ibuf, &cache_view_settings, applied_view_settings);
+ colormanage_display_settings_to_cache(&cache_display_settings, display_settings);
+
+ if (ibuf->invalid_rect.xmin != ibuf->invalid_rect.xmax) {
+ if ((ibuf->userflags & IB_DISPLAY_BUFFER_INVALID) == 0) {
+ IMB_partial_display_buffer_update_threaded(ibuf,
+ ibuf->rect_float,
+ (unsigned char *)ibuf->rect,
+ ibuf->x,
+ 0,
+ 0,
+ applied_view_settings,
+ display_settings,
+ ibuf->invalid_rect.xmin,
+ ibuf->invalid_rect.ymin,
+ ibuf->invalid_rect.xmax,
+ ibuf->invalid_rect.ymax,
+ false);
+ }
+
+ BLI_rcti_init(&ibuf->invalid_rect, 0, 0, 0, 0);
+ }
+
+ BLI_thread_lock(LOCK_COLORMANAGE);
+
+ /* ensure color management bit fields exists */
+ if (!ibuf->display_buffer_flags) {
+ ibuf->display_buffer_flags = MEM_callocN(sizeof(unsigned int) * global_tot_display,
+ "imbuf display_buffer_flags");
+ }
+ else if (ibuf->userflags & IB_DISPLAY_BUFFER_INVALID) {
+ /* all display buffers were marked as invalid from other areas,
+ * now propagate this flag to internal color management routines
+ */
+ memset(ibuf->display_buffer_flags, 0, global_tot_display * sizeof(unsigned int));
+
+ ibuf->userflags &= ~IB_DISPLAY_BUFFER_INVALID;
+ }
+
+ display_buffer = colormanage_cache_get(
+ ibuf, &cache_view_settings, &cache_display_settings, cache_handle);
+
+ if (display_buffer) {
+ BLI_thread_unlock(LOCK_COLORMANAGE);
+ return display_buffer;
+ }
+
+ buffer_size = DISPLAY_BUFFER_CHANNELS * ((size_t)ibuf->x) * ibuf->y * sizeof(char);
+ display_buffer = MEM_callocN(buffer_size, "imbuf display buffer");
+
+ colormanage_display_buffer_process(
+ ibuf, display_buffer, applied_view_settings, display_settings);
+
+ colormanage_cache_put(
+ ibuf, &cache_view_settings, &cache_display_settings, display_buffer, cache_handle);
+
+ BLI_thread_unlock(LOCK_COLORMANAGE);
+
+ return display_buffer;
}
/* same as IMB_display_buffer_acquire but gets view and display settings from context */
unsigned char *IMB_display_buffer_acquire_ctx(const bContext *C, ImBuf *ibuf, void **cache_handle)
{
- ColorManagedViewSettings *view_settings;
- ColorManagedDisplaySettings *display_settings;
+ ColorManagedViewSettings *view_settings;
+ ColorManagedDisplaySettings *display_settings;
- IMB_colormanagement_display_settings_from_ctx(C, &view_settings, &display_settings);
+ IMB_colormanagement_display_settings_from_ctx(C, &view_settings, &display_settings);
- return IMB_display_buffer_acquire(ibuf, view_settings, display_settings, cache_handle);
+ return IMB_display_buffer_acquire(ibuf, view_settings, display_settings, cache_handle);
}
-void IMB_display_buffer_transform_apply(unsigned char *display_buffer, float *linear_buffer, int width, int height,
- int channels, const ColorManagedViewSettings *view_settings,
- const ColorManagedDisplaySettings *display_settings, bool predivide)
+void IMB_display_buffer_transform_apply(unsigned char *display_buffer,
+ float *linear_buffer,
+ int width,
+ int height,
+ int channels,
+ const ColorManagedViewSettings *view_settings,
+ const ColorManagedDisplaySettings *display_settings,
+ bool predivide)
{
- float *buffer;
- ColormanageProcessor *cm_processor = IMB_colormanagement_display_processor_new(view_settings, display_settings);
+ float *buffer;
+ ColormanageProcessor *cm_processor = IMB_colormanagement_display_processor_new(view_settings,
+ display_settings);
- buffer = MEM_mallocN((size_t)channels * width * height * sizeof(float), "display transform temp buffer");
- memcpy(buffer, linear_buffer, (size_t)channels * width * height * sizeof(float));
+ buffer = MEM_mallocN((size_t)channels * width * height * sizeof(float),
+ "display transform temp buffer");
+ memcpy(buffer, linear_buffer, (size_t)channels * width * height * sizeof(float));
- IMB_colormanagement_processor_apply(cm_processor, buffer, width, height, channels, predivide);
+ IMB_colormanagement_processor_apply(cm_processor, buffer, width, height, channels, predivide);
- IMB_colormanagement_processor_free(cm_processor);
+ IMB_colormanagement_processor_free(cm_processor);
- IMB_buffer_byte_from_float(display_buffer, buffer, channels, 0.0f, IB_PROFILE_SRGB, IB_PROFILE_SRGB,
- false, width, height, width, width);
+ IMB_buffer_byte_from_float(display_buffer,
+ buffer,
+ channels,
+ 0.0f,
+ IB_PROFILE_SRGB,
+ IB_PROFILE_SRGB,
+ false,
+ width,
+ height,
+ width,
+ width);
- MEM_freeN(buffer);
+ MEM_freeN(buffer);
}
void IMB_display_buffer_release(void *cache_handle)
{
- if (cache_handle) {
- BLI_thread_lock(LOCK_COLORMANAGE);
+ if (cache_handle) {
+ BLI_thread_lock(LOCK_COLORMANAGE);
- colormanage_cache_handle_release(cache_handle);
+ colormanage_cache_handle_release(cache_handle);
- BLI_thread_unlock(LOCK_COLORMANAGE);
- }
+ BLI_thread_unlock(LOCK_COLORMANAGE);
+ }
}
/*********************** Display functions *************************/
const char *colormanage_display_get_default_name(void)
{
- OCIO_ConstConfigRcPtr *config = OCIO_getCurrentConfig();
- const char *display_name;
+ OCIO_ConstConfigRcPtr *config = OCIO_getCurrentConfig();
+ const char *display_name;
- display_name = OCIO_configGetDefaultDisplay(config);
+ display_name = OCIO_configGetDefaultDisplay(config);
- OCIO_configRelease(config);
+ OCIO_configRelease(config);
- return display_name;
+ return display_name;
}
ColorManagedDisplay *colormanage_display_get_default(void)
{
- const char *display_name = colormanage_display_get_default_name();
+ const char *display_name = colormanage_display_get_default_name();
- if (display_name[0] == '\0')
- return NULL;
+ if (display_name[0] == '\0')
+ return NULL;
- return colormanage_display_get_named(display_name);
+ return colormanage_display_get_named(display_name);
}
ColorManagedDisplay *colormanage_display_add(const char *name)
{
- ColorManagedDisplay *display;
- int index = 0;
+ ColorManagedDisplay *display;
+ int index = 0;
- if (global_displays.last) {
- ColorManagedDisplay *last_display = global_displays.last;
+ if (global_displays.last) {
+ ColorManagedDisplay *last_display = global_displays.last;
- index = last_display->index;
- }
+ index = last_display->index;
+ }
- display = MEM_callocN(sizeof(ColorManagedDisplay), "ColorManagedDisplay");
+ display = MEM_callocN(sizeof(ColorManagedDisplay), "ColorManagedDisplay");
- display->index = index + 1;
+ display->index = index + 1;
- BLI_strncpy(display->name, name, sizeof(display->name));
+ BLI_strncpy(display->name, name, sizeof(display->name));
- BLI_addtail(&global_displays, display);
+ BLI_addtail(&global_displays, display);
- return display;
+ return display;
}
ColorManagedDisplay *colormanage_display_get_named(const char *name)
{
- ColorManagedDisplay *display;
+ ColorManagedDisplay *display;
- for (display = global_displays.first; display; display = display->next) {
- if (STREQ(display->name, name))
- return display;
- }
+ for (display = global_displays.first; display; display = display->next) {
+ if (STREQ(display->name, name))
+ return display;
+ }
- return NULL;
+ return NULL;
}
ColorManagedDisplay *colormanage_display_get_indexed(int index)
{
- /* display indices are 1-based */
- return BLI_findlink(&global_displays, index - 1);
+ /* display indices are 1-based */
+ return BLI_findlink(&global_displays, index - 1);
}
int IMB_colormanagement_display_get_named_index(const char *name)
{
- ColorManagedDisplay *display;
+ ColorManagedDisplay *display;
- display = colormanage_display_get_named(name);
+ display = colormanage_display_get_named(name);
- if (display) {
- return display->index;
- }
+ if (display) {
+ return display->index;
+ }
- return 0;
+ return 0;
}
const char *IMB_colormanagement_display_get_indexed_name(int index)
{
- ColorManagedDisplay *display;
+ ColorManagedDisplay *display;
- display = colormanage_display_get_indexed(index);
+ display = colormanage_display_get_indexed(index);
- if (display) {
- return display->name;
- }
+ if (display) {
+ return display->name;
+ }
- return NULL;
+ return NULL;
}
const char *IMB_colormanagement_display_get_default_name(void)
{
- ColorManagedDisplay *display = colormanage_display_get_default();
+ ColorManagedDisplay *display = colormanage_display_get_default();
- return display->name;
+ return display->name;
}
/* used by performance-critical pixel processing areas, such as color widgets */
ColorManagedDisplay *IMB_colormanagement_display_get_named(const char *name)
{
- return colormanage_display_get_named(name);
+ return colormanage_display_get_named(name);
}
const char *IMB_colormanagement_display_get_none_name(void)
{
- if (colormanage_display_get_named("None") != NULL)
- return "None";
+ if (colormanage_display_get_named("None") != NULL)
+ return "None";
- return colormanage_display_get_default_name();
+ return colormanage_display_get_default_name();
}
const char *IMB_colormanagement_display_get_default_view_transform_name(
- struct ColorManagedDisplay *display)
+ struct ColorManagedDisplay *display)
{
- return colormanage_view_get_default_name(display);
+ return colormanage_view_get_default_name(display);
}
/*********************** View functions *************************/
const char *colormanage_view_get_default_name(const ColorManagedDisplay *display)
{
- OCIO_ConstConfigRcPtr *config = OCIO_getCurrentConfig();
- const char *name;
+ OCIO_ConstConfigRcPtr *config = OCIO_getCurrentConfig();
+ const char *name;
- name = OCIO_configGetDefaultView(config, display->name);
+ name = OCIO_configGetDefaultView(config, display->name);
- OCIO_configRelease(config);
+ OCIO_configRelease(config);
- return name;
+ return name;
}
ColorManagedView *colormanage_view_get_default(const ColorManagedDisplay *display)
{
- const char *name = colormanage_view_get_default_name(display);
+ const char *name = colormanage_view_get_default_name(display);
- if (!name || name[0] == '\0')
- return NULL;
+ if (!name || name[0] == '\0')
+ return NULL;
- return colormanage_view_get_named(name);
+ return colormanage_view_get_named(name);
}
ColorManagedView *colormanage_view_add(const char *name)
{
- ColorManagedView *view;
- int index = global_tot_view;
+ ColorManagedView *view;
+ int index = global_tot_view;
- view = MEM_callocN(sizeof(ColorManagedView), "ColorManagedView");
- view->index = index + 1;
- BLI_strncpy(view->name, name, sizeof(view->name));
+ view = MEM_callocN(sizeof(ColorManagedView), "ColorManagedView");
+ view->index = index + 1;
+ BLI_strncpy(view->name, name, sizeof(view->name));
- BLI_addtail(&global_views, view);
+ BLI_addtail(&global_views, view);
- global_tot_view++;
+ global_tot_view++;
- return view;
+ return view;
}
ColorManagedView *colormanage_view_get_named(const char *name)
{
- ColorManagedView *view;
+ ColorManagedView *view;
- for (view = global_views.first; view; view = view->next) {
- if (STREQ(view->name, name))
- return view;
- }
+ for (view = global_views.first; view; view = view->next) {
+ if (STREQ(view->name, name))
+ return view;
+ }
- return NULL;
+ return NULL;
}
ColorManagedView *colormanage_view_get_indexed(int index)
{
- /* view transform indices are 1-based */
- return BLI_findlink(&global_views, index - 1);
+ /* view transform indices are 1-based */
+ return BLI_findlink(&global_views, index - 1);
}
-ColorManagedView *colormanage_view_get_named_for_display(
- const char *display_name, const char *name)
+ColorManagedView *colormanage_view_get_named_for_display(const char *display_name,
+ const char *name)
{
- ColorManagedDisplay *display = colormanage_display_get_named(display_name);
- if (display == NULL) {
- return NULL;
- }
- LISTBASE_FOREACH(LinkData *, view_link, &display->views) {
- ColorManagedView *view = view_link->data;
- if (STRCASEEQ(name, view->name)) {
- return view;
- }
- }
- return NULL;
+ ColorManagedDisplay *display = colormanage_display_get_named(display_name);
+ if (display == NULL) {
+ return NULL;
+ }
+ LISTBASE_FOREACH (LinkData *, view_link, &display->views) {
+ ColorManagedView *view = view_link->data;
+ if (STRCASEEQ(name, view->name)) {
+ return view;
+ }
+ }
+ return NULL;
}
int IMB_colormanagement_view_get_named_index(const char *name)
{
- ColorManagedView *view = colormanage_view_get_named(name);
+ ColorManagedView *view = colormanage_view_get_named(name);
- if (view) {
- return view->index;
- }
+ if (view) {
+ return view->index;
+ }
- return 0;
+ return 0;
}
const char *IMB_colormanagement_view_get_indexed_name(int index)
{
- ColorManagedView *view = colormanage_view_get_indexed(index);
+ ColorManagedView *view = colormanage_view_get_indexed(index);
- if (view) {
- return view->name;
- }
+ if (view) {
+ return view->name;
+ }
- return NULL;
+ return NULL;
}
const char *IMB_colormanagement_view_get_default_name(const char *display_name)
{
- ColorManagedDisplay *display = colormanage_display_get_named(display_name);
- ColorManagedView *view = NULL;
+ ColorManagedDisplay *display = colormanage_display_get_named(display_name);
+ ColorManagedView *view = NULL;
- if (display)
- view = colormanage_view_get_default(display);
+ if (display)
+ view = colormanage_view_get_default(display);
- if (view)
- return view->name;
+ if (view)
+ return view->name;
- return NULL;
+ return NULL;
}
/*********************** Color space functions *************************/
static void colormanage_description_strip(char *description)
{
- int i, n;
+ int i, n;
- for (i = (int)strlen(description) - 1; i >= 0; i--) {
- if (ELEM(description[i], '\r', '\n')) {
- description[i] = '\0';
- }
- else {
- break;
- }
- }
+ for (i = (int)strlen(description) - 1; i >= 0; i--) {
+ if (ELEM(description[i], '\r', '\n')) {
+ description[i] = '\0';
+ }
+ else {
+ break;
+ }
+ }
- for (i = 0, n = strlen(description); i < n; i++) {
- if (ELEM(description[i], '\r', '\n')) {
- description[i] = ' ';
- }
- }
+ for (i = 0, n = strlen(description); i < n; i++) {
+ if (ELEM(description[i], '\r', '\n')) {
+ description[i] = ' ';
+ }
+ }
}
-ColorSpace *colormanage_colorspace_add(const char *name, const char *description, bool is_invertible, bool is_data)
+ColorSpace *colormanage_colorspace_add(const char *name,
+ const char *description,
+ bool is_invertible,
+ bool is_data)
{
- ColorSpace *colorspace, *prev_space;
- int counter = 1;
+ ColorSpace *colorspace, *prev_space;
+ int counter = 1;
- colorspace = MEM_callocN(sizeof(ColorSpace), "ColorSpace");
+ colorspace = MEM_callocN(sizeof(ColorSpace), "ColorSpace");
- BLI_strncpy(colorspace->name, name, sizeof(colorspace->name));
+ BLI_strncpy(colorspace->name, name, sizeof(colorspace->name));
- if (description) {
- BLI_strncpy(colorspace->description, description, sizeof(colorspace->description));
+ if (description) {
+ BLI_strncpy(colorspace->description, description, sizeof(colorspace->description));
- colormanage_description_strip(colorspace->description);
- }
+ colormanage_description_strip(colorspace->description);
+ }
- colorspace->is_invertible = is_invertible;
- colorspace->is_data = is_data;
+ colorspace->is_invertible = is_invertible;
+ colorspace->is_data = is_data;
- for (prev_space = global_colorspaces.first; prev_space; prev_space = prev_space->next) {
- if (BLI_strcasecmp(prev_space->name, colorspace->name) > 0)
- break;
+ for (prev_space = global_colorspaces.first; prev_space; prev_space = prev_space->next) {
+ if (BLI_strcasecmp(prev_space->name, colorspace->name) > 0)
+ break;
- prev_space->index = counter++;
- }
+ prev_space->index = counter++;
+ }
- if (!prev_space)
- BLI_addtail(&global_colorspaces, colorspace);
- else
- BLI_insertlinkbefore(&global_colorspaces, prev_space, colorspace);
+ if (!prev_space)
+ BLI_addtail(&global_colorspaces, colorspace);
+ else
+ BLI_insertlinkbefore(&global_colorspaces, prev_space, colorspace);
- colorspace->index = counter++;
- for (; prev_space; prev_space = prev_space->next) {
- prev_space->index = counter++;
- }
+ colorspace->index = counter++;
+ for (; prev_space; prev_space = prev_space->next) {
+ prev_space->index = counter++;
+ }
- global_tot_colorspace++;
+ global_tot_colorspace++;
- return colorspace;
+ return colorspace;
}
ColorSpace *colormanage_colorspace_get_named(const char *name)
{
- ColorSpace *colorspace;
+ ColorSpace *colorspace;
- for (colorspace = global_colorspaces.first; colorspace; colorspace = colorspace->next) {
- if (STREQ(colorspace->name, name))
- return colorspace;
- }
+ for (colorspace = global_colorspaces.first; colorspace; colorspace = colorspace->next) {
+ if (STREQ(colorspace->name, name))
+ return colorspace;
+ }
- return NULL;
+ return NULL;
}
ColorSpace *colormanage_colorspace_get_roled(int role)
{
- const char *role_colorspace = IMB_colormanagement_role_colorspace_name_get(role);
+ const char *role_colorspace = IMB_colormanagement_role_colorspace_name_get(role);
- return colormanage_colorspace_get_named(role_colorspace);
+ return colormanage_colorspace_get_named(role_colorspace);
}
ColorSpace *colormanage_colorspace_get_indexed(int index)
{
- /* color space indices are 1-based */
- return BLI_findlink(&global_colorspaces, index - 1);
+ /* color space indices are 1-based */
+ return BLI_findlink(&global_colorspaces, index - 1);
}
int IMB_colormanagement_colorspace_get_named_index(const char *name)
{
- ColorSpace *colorspace;
+ ColorSpace *colorspace;
- colorspace = colormanage_colorspace_get_named(name);
+ colorspace = colormanage_colorspace_get_named(name);
- if (colorspace) {
- return colorspace->index;
- }
+ if (colorspace) {
+ return colorspace->index;
+ }
- return 0;
+ return 0;
}
const char *IMB_colormanagement_colorspace_get_indexed_name(int index)
{
- ColorSpace *colorspace;
+ ColorSpace *colorspace;
- colorspace = colormanage_colorspace_get_indexed(index);
+ colorspace = colormanage_colorspace_get_indexed(index);
- if (colorspace) {
- return colorspace->name;
- }
+ if (colorspace) {
+ return colorspace->name;
+ }
- return "";
+ return "";
}
-void IMB_colormanagement_colorspace_from_ibuf_ftype(ColorManagedColorspaceSettings *colorspace_settings, ImBuf *ibuf)
+void IMB_colormanagement_colorspace_from_ibuf_ftype(
+ ColorManagedColorspaceSettings *colorspace_settings, ImBuf *ibuf)
{
- /* Don't modify non-color data space, it does not change with file type. */
- ColorSpace *colorspace = colormanage_colorspace_get_named(colorspace_settings->name);
+ /* Don't modify non-color data space, it does not change with file type. */
+ ColorSpace *colorspace = colormanage_colorspace_get_named(colorspace_settings->name);
- if (colorspace && colorspace->is_data) {
- return;
- }
+ if (colorspace && colorspace->is_data) {
+ return;
+ }
- /* Get color space from file type. */
- const ImFileType *type;
+ /* Get color space from file type. */
+ const ImFileType *type;
- for (type = IMB_FILE_TYPES; type < IMB_FILE_TYPES_LAST; type++) {
- if (type->save && type->ftype(type, ibuf)) {
- const char *role_colorspace;
+ for (type = IMB_FILE_TYPES; type < IMB_FILE_TYPES_LAST; type++) {
+ if (type->save && type->ftype(type, ibuf)) {
+ const char *role_colorspace;
- role_colorspace = IMB_colormanagement_role_colorspace_name_get(type->default_save_role);
+ role_colorspace = IMB_colormanagement_role_colorspace_name_get(type->default_save_role);
- BLI_strncpy(colorspace_settings->name, role_colorspace, sizeof(colorspace_settings->name));
- }
- }
+ BLI_strncpy(colorspace_settings->name, role_colorspace, sizeof(colorspace_settings->name));
+ }
+ }
}
/*********************** Looks functions *************************/
ColorManagedLook *colormanage_look_add(const char *name, const char *process_space, bool is_noop)
{
- ColorManagedLook *look;
- int index = global_tot_looks;
+ ColorManagedLook *look;
+ int index = global_tot_looks;
- look = MEM_callocN(sizeof(ColorManagedLook), "ColorManagedLook");
- look->index = index + 1;
- BLI_strncpy(look->name, name, sizeof(look->name));
- BLI_strncpy(look->ui_name, name, sizeof(look->ui_name));
- BLI_strncpy(look->process_space, process_space, sizeof(look->process_space));
- look->is_noop = is_noop;
+ look = MEM_callocN(sizeof(ColorManagedLook), "ColorManagedLook");
+ look->index = index + 1;
+ BLI_strncpy(look->name, name, sizeof(look->name));
+ BLI_strncpy(look->ui_name, name, sizeof(look->ui_name));
+ BLI_strncpy(look->process_space, process_space, sizeof(look->process_space));
+ look->is_noop = is_noop;
- /* Detect view specific looks. */
- const char *separator_offset = strstr(look->name, " - ");
- if (separator_offset) {
- BLI_strncpy(look->view, look->name, separator_offset - look->name + 1);
- BLI_strncpy(look->ui_name, separator_offset + strlen(" - "), sizeof(look->ui_name));
- }
+ /* Detect view specific looks. */
+ const char *separator_offset = strstr(look->name, " - ");
+ if (separator_offset) {
+ BLI_strncpy(look->view, look->name, separator_offset - look->name + 1);
+ BLI_strncpy(look->ui_name, separator_offset + strlen(" - "), sizeof(look->ui_name));
+ }
- BLI_addtail(&global_looks, look);
+ BLI_addtail(&global_looks, look);
- global_tot_looks++;
+ global_tot_looks++;
- return look;
+ return look;
}
ColorManagedLook *colormanage_look_get_named(const char *name)
{
- ColorManagedLook *look;
+ ColorManagedLook *look;
- for (look = global_looks.first; look; look = look->next) {
- if (STREQ(look->name, name)) {
- return look;
- }
- }
+ for (look = global_looks.first; look; look = look->next) {
+ if (STREQ(look->name, name)) {
+ return look;
+ }
+ }
- return NULL;
+ return NULL;
}
ColorManagedLook *colormanage_look_get_indexed(int index)
{
- /* look indices are 1-based */
- return BLI_findlink(&global_looks, index - 1);
+ /* look indices are 1-based */
+ return BLI_findlink(&global_looks, index - 1);
}
int IMB_colormanagement_look_get_named_index(const char *name)
{
- ColorManagedLook *look;
+ ColorManagedLook *look;
- look = colormanage_look_get_named(name);
+ look = colormanage_look_get_named(name);
- if (look) {
- return look->index;
- }
+ if (look) {
+ return look->index;
+ }
- return 0;
+ return 0;
}
const char *IMB_colormanagement_look_get_indexed_name(int index)
{
- ColorManagedLook *look;
+ ColorManagedLook *look;
- look = colormanage_look_get_indexed(index);
+ look = colormanage_look_get_indexed(index);
- if (look) {
- return look->name;
- }
+ if (look) {
+ return look->name;
+ }
- return NULL;
+ return NULL;
}
/*********************** RNA helper functions *************************/
void IMB_colormanagement_display_items_add(EnumPropertyItem **items, int *totitem)
{
- ColorManagedDisplay *display;
+ ColorManagedDisplay *display;
- for (display = global_displays.first; display; display = display->next) {
- EnumPropertyItem item;
+ for (display = global_displays.first; display; display = display->next) {
+ EnumPropertyItem item;
- item.value = display->index;
- item.name = display->name;
- item.identifier = display->name;
- item.icon = 0;
- item.description = "";
+ item.value = display->index;
+ item.name = display->name;
+ item.identifier = display->name;
+ item.icon = 0;
+ item.description = "";
- RNA_enum_item_add(items, totitem, &item);
- }
+ RNA_enum_item_add(items, totitem, &item);
+ }
}
-static void colormanagement_view_item_add(EnumPropertyItem **items, int *totitem, ColorManagedView *view)
+static void colormanagement_view_item_add(EnumPropertyItem **items,
+ int *totitem,
+ ColorManagedView *view)
{
- EnumPropertyItem item;
+ EnumPropertyItem item;
- item.value = view->index;
- item.name = view->name;
- item.identifier = view->name;
- item.icon = 0;
- item.description = "";
+ item.value = view->index;
+ item.name = view->name;
+ item.identifier = view->name;
+ item.icon = 0;
+ item.description = "";
- RNA_enum_item_add(items, totitem, &item);
+ RNA_enum_item_add(items, totitem, &item);
}
-void IMB_colormanagement_view_items_add(EnumPropertyItem **items, int *totitem, const char *display_name)
+void IMB_colormanagement_view_items_add(EnumPropertyItem **items,
+ int *totitem,
+ const char *display_name)
{
- ColorManagedDisplay *display = colormanage_display_get_named(display_name);
- ColorManagedView *view;
+ ColorManagedDisplay *display = colormanage_display_get_named(display_name);
+ ColorManagedView *view;
- if (display) {
- LinkData *display_view;
+ if (display) {
+ LinkData *display_view;
- for (display_view = display->views.first; display_view; display_view = display_view->next) {
- view = display_view->data;
+ for (display_view = display->views.first; display_view; display_view = display_view->next) {
+ view = display_view->data;
- colormanagement_view_item_add(items, totitem, view);
- }
- }
+ colormanagement_view_item_add(items, totitem, view);
+ }
+ }
}
-void IMB_colormanagement_look_items_add(struct EnumPropertyItem **items, int *totitem, const char *view_name)
+void IMB_colormanagement_look_items_add(struct EnumPropertyItem **items,
+ int *totitem,
+ const char *view_name)
{
- ColorManagedLook *look;
- const char *view_filter = NULL;
+ ColorManagedLook *look;
+ const char *view_filter = NULL;
- /* Test if this view transform is limited to specific looks. */
- for (look = global_looks.first; look; look = look->next) {
- if (STREQ(look->view, view_name)) {
- view_filter = view_name;
- }
- }
+ /* Test if this view transform is limited to specific looks. */
+ for (look = global_looks.first; look; look = look->next) {
+ if (STREQ(look->view, view_name)) {
+ view_filter = view_name;
+ }
+ }
- for (look = global_looks.first; look; look = look->next) {
- if (!look->is_noop && view_filter && !STREQ(look->view, view_filter)) {
- continue;
- }
+ for (look = global_looks.first; look; look = look->next) {
+ if (!look->is_noop && view_filter && !STREQ(look->view, view_filter)) {
+ continue;
+ }
- EnumPropertyItem item;
+ EnumPropertyItem item;
- item.value = look->index;
- item.name = look->ui_name;
- item.identifier = look->name;
- item.icon = 0;
- item.description = "";
+ item.value = look->index;
+ item.name = look->ui_name;
+ item.identifier = look->name;
+ item.icon = 0;
+ item.description = "";
- RNA_enum_item_add(items, totitem, &item);
- }
+ RNA_enum_item_add(items, totitem, &item);
+ }
}
void IMB_colormanagement_colorspace_items_add(EnumPropertyItem **items, int *totitem)
{
- ColorSpace *colorspace;
+ ColorSpace *colorspace;
- for (colorspace = global_colorspaces.first; colorspace; colorspace = colorspace->next) {
- EnumPropertyItem item;
+ for (colorspace = global_colorspaces.first; colorspace; colorspace = colorspace->next) {
+ EnumPropertyItem item;
- if (!colorspace->is_invertible)
- continue;
+ if (!colorspace->is_invertible)
+ continue;
- item.value = colorspace->index;
- item.name = colorspace->name;
- item.identifier = colorspace->name;
- item.icon = 0;
- item.description = colorspace->description;
+ item.value = colorspace->index;
+ item.name = colorspace->name;
+ item.identifier = colorspace->name;
+ item.icon = 0;
+ item.description = colorspace->description;
- RNA_enum_item_add(items, totitem, &item);
- }
+ RNA_enum_item_add(items, totitem, &item);
+ }
}
/*********************** Partial display buffer update *************************/
@@ -2896,633 +3099,684 @@ static void partial_buffer_update_rect(ImBuf *ibuf,
const unsigned char *byte_buffer,
int display_stride,
int linear_stride,
- int linear_offset_x, int linear_offset_y,
+ int linear_offset_x,
+ int linear_offset_y,
ColormanageProcessor *cm_processor,
- const int xmin, const int ymin,
- const int xmax, const int ymax)
-{
- int x, y;
- int channels = ibuf->channels;
- float dither = ibuf->dither;
- ColorSpace *rect_colorspace = ibuf->rect_colorspace;
- float *display_buffer_float = NULL;
- const int width = xmax - xmin;
- const int height = ymax - ymin;
- bool is_data = (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA) != 0;
-
- if (dither != 0.0f) {
- /* cm_processor is NULL in cases byte_buffer's space matches display
- * buffer's space
- * in this case we could skip extra transform and only apply dither
- * use 4 channels for easier byte->float->byte conversion here so
- * (this is only needed to apply dither, in other cases we'll convert
- * byte buffer to display directly)
- */
- if (!cm_processor)
- channels = 4;
-
- display_buffer_float = MEM_callocN((size_t)channels * width * height * sizeof(float), "display buffer for dither");
- }
-
- if (cm_processor) {
- for (y = ymin; y < ymax; y++) {
- for (x = xmin; x < xmax; x++) {
- size_t display_index = ((size_t)y * display_stride + x) * 4;
- size_t linear_index = ((size_t)(y - linear_offset_y) * linear_stride + (x - linear_offset_x)) * channels;
- float pixel[4];
-
- if (linear_buffer) {
- if (channels == 4) {
- copy_v4_v4(pixel, (float *) linear_buffer + linear_index);
- }
- else if (channels == 3) {
- copy_v3_v3(pixel, (float *) linear_buffer + linear_index);
- pixel[3] = 1.0f;
- }
- else if (channels == 1) {
- pixel[0] = linear_buffer[linear_index];
- }
- else {
- BLI_assert(!"Unsupported number of channels in partial buffer update");
- }
- }
- else if (byte_buffer) {
- rgba_uchar_to_float(pixel, byte_buffer + linear_index);
- IMB_colormanagement_colorspace_to_scene_linear_v3(pixel, rect_colorspace);
- straight_to_premul_v4(pixel);
- }
-
- if (!is_data) {
- IMB_colormanagement_processor_apply_pixel(cm_processor, pixel, channels);
- }
-
- if (display_buffer_float) {
- size_t index = ((size_t)(y - ymin) * width + (x - xmin)) * channels;
-
- if (channels == 4) {
- copy_v4_v4(display_buffer_float + index, pixel);
- }
- else if (channels == 3) {
- copy_v3_v3(display_buffer_float + index, pixel);
- }
- else /* if (channels == 1) */ {
- display_buffer_float[index] = pixel[0];
- }
- }
- else {
- if (channels == 4) {
- float pixel_straight[4];
- premul_to_straight_v4_v4(pixel_straight, pixel);
- rgba_float_to_uchar(display_buffer + display_index, pixel_straight);
- }
- else if (channels == 3) {
- rgb_float_to_uchar(display_buffer + display_index, pixel);
- display_buffer[display_index + 3] = 255;
- }
- else /* if (channels == 1) */ {
- display_buffer[display_index] =
- display_buffer[display_index + 1] =
- display_buffer[display_index + 2] =
- display_buffer[display_index + 3] = unit_float_to_uchar_clamp(pixel[0]);
- }
- }
- }
- }
- }
- else {
- if (display_buffer_float) {
- /* huh, for dither we need float buffer first, no cheaper way. currently */
- IMB_buffer_float_from_byte(display_buffer_float, byte_buffer,
- IB_PROFILE_SRGB, IB_PROFILE_SRGB, true,
- width, height, width, display_stride);
- }
- else {
- int i;
-
- for (i = ymin; i < ymax; i++) {
- size_t byte_offset = ((size_t)linear_stride * i + xmin) * 4;
- size_t display_offset = ((size_t)display_stride * i + xmin) * 4;
-
- memcpy(display_buffer + display_offset, byte_buffer + byte_offset, 4 * sizeof(char) * width);
- }
- }
- }
-
- if (display_buffer_float) {
- size_t display_index = ((size_t)ymin * display_stride + xmin) * channels;
-
- IMB_buffer_byte_from_float(display_buffer + display_index, display_buffer_float, channels, dither,
- IB_PROFILE_SRGB, IB_PROFILE_SRGB, true, width, height, display_stride, width);
-
- MEM_freeN(display_buffer_float);
- }
+ const int xmin,
+ const int ymin,
+ const int xmax,
+ const int ymax)
+{
+ int x, y;
+ int channels = ibuf->channels;
+ float dither = ibuf->dither;
+ ColorSpace *rect_colorspace = ibuf->rect_colorspace;
+ float *display_buffer_float = NULL;
+ const int width = xmax - xmin;
+ const int height = ymax - ymin;
+ bool is_data = (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA) != 0;
+
+ if (dither != 0.0f) {
+ /* cm_processor is NULL in cases byte_buffer's space matches display
+ * buffer's space
+ * in this case we could skip extra transform and only apply dither
+ * use 4 channels for easier byte->float->byte conversion here so
+ * (this is only needed to apply dither, in other cases we'll convert
+ * byte buffer to display directly)
+ */
+ if (!cm_processor)
+ channels = 4;
+
+ display_buffer_float = MEM_callocN((size_t)channels * width * height * sizeof(float),
+ "display buffer for dither");
+ }
+
+ if (cm_processor) {
+ for (y = ymin; y < ymax; y++) {
+ for (x = xmin; x < xmax; x++) {
+ size_t display_index = ((size_t)y * display_stride + x) * 4;
+ size_t linear_index = ((size_t)(y - linear_offset_y) * linear_stride +
+ (x - linear_offset_x)) *
+ channels;
+ float pixel[4];
+
+ if (linear_buffer) {
+ if (channels == 4) {
+ copy_v4_v4(pixel, (float *)linear_buffer + linear_index);
+ }
+ else if (channels == 3) {
+ copy_v3_v3(pixel, (float *)linear_buffer + linear_index);
+ pixel[3] = 1.0f;
+ }
+ else if (channels == 1) {
+ pixel[0] = linear_buffer[linear_index];
+ }
+ else {
+ BLI_assert(!"Unsupported number of channels in partial buffer update");
+ }
+ }
+ else if (byte_buffer) {
+ rgba_uchar_to_float(pixel, byte_buffer + linear_index);
+ IMB_colormanagement_colorspace_to_scene_linear_v3(pixel, rect_colorspace);
+ straight_to_premul_v4(pixel);
+ }
+
+ if (!is_data) {
+ IMB_colormanagement_processor_apply_pixel(cm_processor, pixel, channels);
+ }
+
+ if (display_buffer_float) {
+ size_t index = ((size_t)(y - ymin) * width + (x - xmin)) * channels;
+
+ if (channels == 4) {
+ copy_v4_v4(display_buffer_float + index, pixel);
+ }
+ else if (channels == 3) {
+ copy_v3_v3(display_buffer_float + index, pixel);
+ }
+ else /* if (channels == 1) */ {
+ display_buffer_float[index] = pixel[0];
+ }
+ }
+ else {
+ if (channels == 4) {
+ float pixel_straight[4];
+ premul_to_straight_v4_v4(pixel_straight, pixel);
+ rgba_float_to_uchar(display_buffer + display_index, pixel_straight);
+ }
+ else if (channels == 3) {
+ rgb_float_to_uchar(display_buffer + display_index, pixel);
+ display_buffer[display_index + 3] = 255;
+ }
+ else /* if (channels == 1) */ {
+ display_buffer[display_index] = display_buffer[display_index + 1] =
+ display_buffer[display_index + 2] = display_buffer[display_index + 3] =
+ unit_float_to_uchar_clamp(pixel[0]);
+ }
+ }
+ }
+ }
+ }
+ else {
+ if (display_buffer_float) {
+ /* huh, for dither we need float buffer first, no cheaper way. currently */
+ IMB_buffer_float_from_byte(display_buffer_float,
+ byte_buffer,
+ IB_PROFILE_SRGB,
+ IB_PROFILE_SRGB,
+ true,
+ width,
+ height,
+ width,
+ display_stride);
+ }
+ else {
+ int i;
+
+ for (i = ymin; i < ymax; i++) {
+ size_t byte_offset = ((size_t)linear_stride * i + xmin) * 4;
+ size_t display_offset = ((size_t)display_stride * i + xmin) * 4;
+
+ memcpy(
+ display_buffer + display_offset, byte_buffer + byte_offset, 4 * sizeof(char) * width);
+ }
+ }
+ }
+
+ if (display_buffer_float) {
+ size_t display_index = ((size_t)ymin * display_stride + xmin) * channels;
+
+ IMB_buffer_byte_from_float(display_buffer + display_index,
+ display_buffer_float,
+ channels,
+ dither,
+ IB_PROFILE_SRGB,
+ IB_PROFILE_SRGB,
+ true,
+ width,
+ height,
+ display_stride,
+ width);
+
+ MEM_freeN(display_buffer_float);
+ }
}
typedef struct PartialThreadData {
- ImBuf *ibuf;
- unsigned char *display_buffer;
- const float *linear_buffer;
- const unsigned char *byte_buffer;
- int display_stride;
- int linear_stride;
- int linear_offset_x, linear_offset_y;
- ColormanageProcessor *cm_processor;
- int xmin, ymin, xmax;
+ ImBuf *ibuf;
+ unsigned char *display_buffer;
+ const float *linear_buffer;
+ const unsigned char *byte_buffer;
+ int display_stride;
+ int linear_stride;
+ int linear_offset_x, linear_offset_y;
+ ColormanageProcessor *cm_processor;
+ int xmin, ymin, xmax;
} PartialThreadData;
static void partial_buffer_update_rect_thread_do(void *data_v,
int start_scanline,
int num_scanlines)
{
- PartialThreadData *data = (PartialThreadData *)data_v;
- int ymin = data->ymin + start_scanline;
- partial_buffer_update_rect(data->ibuf,
- data->display_buffer,
- data->linear_buffer,
- data->byte_buffer,
- data->display_stride,
- data->linear_stride,
- data->linear_offset_x,
- data->linear_offset_y,
- data->cm_processor,
- data->xmin,
- ymin,
- data->xmax,
- ymin + num_scanlines);
-}
-
-static void imb_partial_display_buffer_update_ex(ImBuf *ibuf,
- const float *linear_buffer,
- const unsigned char *byte_buffer,
- int stride,
- int offset_x, int offset_y,
- const ColorManagedViewSettings *view_settings,
- const ColorManagedDisplaySettings *display_settings,
- int xmin, int ymin,
- int xmax, int ymax,
- bool copy_display_to_byte_buffer,
- bool do_threads)
-{
- ColormanageCacheViewSettings cache_view_settings;
- ColormanageCacheDisplaySettings cache_display_settings;
- void *cache_handle = NULL;
- unsigned char *display_buffer = NULL;
- int buffer_width = ibuf->x;
-
- if (ibuf->display_buffer_flags) {
- int view_flag, display_index;
-
- colormanage_view_settings_to_cache(ibuf, &cache_view_settings, view_settings);
- colormanage_display_settings_to_cache(&cache_display_settings, display_settings);
-
- view_flag = 1 << (cache_view_settings.view - 1);
- display_index = cache_display_settings.display - 1;
-
- BLI_thread_lock(LOCK_COLORMANAGE);
-
- if ((ibuf->userflags & IB_DISPLAY_BUFFER_INVALID) == 0) {
- display_buffer = colormanage_cache_get(ibuf,
- &cache_view_settings,
- &cache_display_settings,
- &cache_handle);
- }
-
- /* In some rare cases buffer's dimension could be changing directly from
- * different thread
- * this i.e. happens when image editor acquires render result
- */
- buffer_width = ibuf->x;
-
- /* Mark all other buffers as invalid. */
- memset(ibuf->display_buffer_flags, 0, global_tot_display * sizeof(unsigned int));
- ibuf->display_buffer_flags[display_index] |= view_flag;
-
- BLI_thread_unlock(LOCK_COLORMANAGE);
- }
-
- if (display_buffer == NULL) {
- if (copy_display_to_byte_buffer) {
- display_buffer = (unsigned char *) ibuf->rect;
- }
- }
-
- if (display_buffer) {
- ColormanageProcessor *cm_processor = NULL;
- bool skip_transform = false;
-
- /* Byte buffer is assumed to be in imbuf's rect space, so if byte buffer
- * is known we could skip display->linear->display conversion in case
- * display color space matches imbuf's rect space.
- *
- * But if there's a float buffer it's likely operation was performed on
- * it first and byte buffer is likely to be out of date here.
- */
- if (linear_buffer == NULL && byte_buffer != NULL) {
- skip_transform = is_ibuf_rect_in_display_space(ibuf,
- view_settings,
- display_settings);
- }
-
- if (!skip_transform) {
- cm_processor = IMB_colormanagement_display_processor_new(
- view_settings, display_settings);
- }
-
- if (do_threads) {
- PartialThreadData data;
- data.ibuf = ibuf;
- data.display_buffer = display_buffer;
- data.linear_buffer = linear_buffer;
- data.byte_buffer = byte_buffer;
- data.display_stride = buffer_width;
- data.linear_stride = stride;
- data.linear_offset_x = offset_x;
- data.linear_offset_y = offset_y;
- data.cm_processor = cm_processor;
- data.xmin = xmin;
- data.ymin = ymin;
- data.xmax = xmax;
- IMB_processor_apply_threaded_scanlines(
- ymax - ymin, partial_buffer_update_rect_thread_do, &data);
- }
- else {
- partial_buffer_update_rect(ibuf,
- display_buffer, linear_buffer, byte_buffer,
- buffer_width,
- stride,
- offset_x, offset_y,
- cm_processor,
- xmin, ymin, xmax, ymax);
- }
-
- if (cm_processor) {
- IMB_colormanagement_processor_free(cm_processor);
- }
-
- IMB_display_buffer_release(cache_handle);
- }
-
- if (copy_display_to_byte_buffer && (unsigned char *) ibuf->rect != display_buffer) {
- int y;
- for (y = ymin; y < ymax; y++) {
- size_t index = (size_t)y * buffer_width * 4;
- memcpy((unsigned char *)ibuf->rect + index,
- display_buffer + index,
- (size_t)(xmax - xmin) * 4);
- }
- }
+ PartialThreadData *data = (PartialThreadData *)data_v;
+ int ymin = data->ymin + start_scanline;
+ partial_buffer_update_rect(data->ibuf,
+ data->display_buffer,
+ data->linear_buffer,
+ data->byte_buffer,
+ data->display_stride,
+ data->linear_stride,
+ data->linear_offset_x,
+ data->linear_offset_y,
+ data->cm_processor,
+ data->xmin,
+ ymin,
+ data->xmax,
+ ymin + num_scanlines);
+}
+
+static void imb_partial_display_buffer_update_ex(
+ ImBuf *ibuf,
+ const float *linear_buffer,
+ const unsigned char *byte_buffer,
+ int stride,
+ int offset_x,
+ int offset_y,
+ const ColorManagedViewSettings *view_settings,
+ const ColorManagedDisplaySettings *display_settings,
+ int xmin,
+ int ymin,
+ int xmax,
+ int ymax,
+ bool copy_display_to_byte_buffer,
+ bool do_threads)
+{
+ ColormanageCacheViewSettings cache_view_settings;
+ ColormanageCacheDisplaySettings cache_display_settings;
+ void *cache_handle = NULL;
+ unsigned char *display_buffer = NULL;
+ int buffer_width = ibuf->x;
+
+ if (ibuf->display_buffer_flags) {
+ int view_flag, display_index;
+
+ colormanage_view_settings_to_cache(ibuf, &cache_view_settings, view_settings);
+ colormanage_display_settings_to_cache(&cache_display_settings, display_settings);
+
+ view_flag = 1 << (cache_view_settings.view - 1);
+ display_index = cache_display_settings.display - 1;
+
+ BLI_thread_lock(LOCK_COLORMANAGE);
+
+ if ((ibuf->userflags & IB_DISPLAY_BUFFER_INVALID) == 0) {
+ display_buffer = colormanage_cache_get(
+ ibuf, &cache_view_settings, &cache_display_settings, &cache_handle);
+ }
+
+ /* In some rare cases buffer's dimension could be changing directly from
+ * different thread
+ * this i.e. happens when image editor acquires render result
+ */
+ buffer_width = ibuf->x;
+
+ /* Mark all other buffers as invalid. */
+ memset(ibuf->display_buffer_flags, 0, global_tot_display * sizeof(unsigned int));
+ ibuf->display_buffer_flags[display_index] |= view_flag;
+
+ BLI_thread_unlock(LOCK_COLORMANAGE);
+ }
+
+ if (display_buffer == NULL) {
+ if (copy_display_to_byte_buffer) {
+ display_buffer = (unsigned char *)ibuf->rect;
+ }
+ }
+
+ if (display_buffer) {
+ ColormanageProcessor *cm_processor = NULL;
+ bool skip_transform = false;
+
+ /* Byte buffer is assumed to be in imbuf's rect space, so if byte buffer
+ * is known we could skip display->linear->display conversion in case
+ * display color space matches imbuf's rect space.
+ *
+ * But if there's a float buffer it's likely operation was performed on
+ * it first and byte buffer is likely to be out of date here.
+ */
+ if (linear_buffer == NULL && byte_buffer != NULL) {
+ skip_transform = is_ibuf_rect_in_display_space(ibuf, view_settings, display_settings);
+ }
+
+ if (!skip_transform) {
+ cm_processor = IMB_colormanagement_display_processor_new(view_settings, display_settings);
+ }
+
+ if (do_threads) {
+ PartialThreadData data;
+ data.ibuf = ibuf;
+ data.display_buffer = display_buffer;
+ data.linear_buffer = linear_buffer;
+ data.byte_buffer = byte_buffer;
+ data.display_stride = buffer_width;
+ data.linear_stride = stride;
+ data.linear_offset_x = offset_x;
+ data.linear_offset_y = offset_y;
+ data.cm_processor = cm_processor;
+ data.xmin = xmin;
+ data.ymin = ymin;
+ data.xmax = xmax;
+ IMB_processor_apply_threaded_scanlines(
+ ymax - ymin, partial_buffer_update_rect_thread_do, &data);
+ }
+ else {
+ partial_buffer_update_rect(ibuf,
+ display_buffer,
+ linear_buffer,
+ byte_buffer,
+ buffer_width,
+ stride,
+ offset_x,
+ offset_y,
+ cm_processor,
+ xmin,
+ ymin,
+ xmax,
+ ymax);
+ }
+
+ if (cm_processor) {
+ IMB_colormanagement_processor_free(cm_processor);
+ }
+
+ IMB_display_buffer_release(cache_handle);
+ }
+
+ if (copy_display_to_byte_buffer && (unsigned char *)ibuf->rect != display_buffer) {
+ int y;
+ for (y = ymin; y < ymax; y++) {
+ size_t index = (size_t)y * buffer_width * 4;
+ memcpy(
+ (unsigned char *)ibuf->rect + index, display_buffer + index, (size_t)(xmax - xmin) * 4);
+ }
+ }
}
void IMB_partial_display_buffer_update(ImBuf *ibuf,
const float *linear_buffer,
const unsigned char *byte_buffer,
int stride,
- int offset_x, int offset_y,
+ int offset_x,
+ int offset_y,
const ColorManagedViewSettings *view_settings,
const ColorManagedDisplaySettings *display_settings,
- int xmin, int ymin,
- int xmax, int ymax,
+ int xmin,
+ int ymin,
+ int xmax,
+ int ymax,
bool copy_display_to_byte_buffer)
{
- imb_partial_display_buffer_update_ex(ibuf,
- linear_buffer,
- byte_buffer,
- stride,
- offset_x, offset_y,
- view_settings,
- display_settings,
- xmin, ymin,
- xmax, ymax,
- copy_display_to_byte_buffer,
- false);
-
-}
-
-void IMB_partial_display_buffer_update_threaded(struct ImBuf *ibuf,
- const float *linear_buffer,
- const unsigned char *byte_buffer,
- int stride,
- int offset_x, int offset_y,
- const struct ColorManagedViewSettings *view_settings,
- const struct ColorManagedDisplaySettings *display_settings,
- int xmin, int ymin, int xmax, int ymax,
- bool copy_display_to_byte_buffer)
-{
- int width = xmax - xmin;
- int height = ymax - ymin;
- bool do_threads = (((size_t)width) * height >= 64 * 64);
- imb_partial_display_buffer_update_ex(ibuf,
- linear_buffer,
- byte_buffer,
- stride,
- offset_x, offset_y,
- view_settings,
- display_settings,
- xmin, ymin,
- xmax, ymax,
- copy_display_to_byte_buffer,
- do_threads);
+ imb_partial_display_buffer_update_ex(ibuf,
+ linear_buffer,
+ byte_buffer,
+ stride,
+ offset_x,
+ offset_y,
+ view_settings,
+ display_settings,
+ xmin,
+ ymin,
+ xmax,
+ ymax,
+ copy_display_to_byte_buffer,
+ false);
+}
+
+void IMB_partial_display_buffer_update_threaded(
+ struct ImBuf *ibuf,
+ const float *linear_buffer,
+ const unsigned char *byte_buffer,
+ int stride,
+ int offset_x,
+ int offset_y,
+ const struct ColorManagedViewSettings *view_settings,
+ const struct ColorManagedDisplaySettings *display_settings,
+ int xmin,
+ int ymin,
+ int xmax,
+ int ymax,
+ bool copy_display_to_byte_buffer)
+{
+ int width = xmax - xmin;
+ int height = ymax - ymin;
+ bool do_threads = (((size_t)width) * height >= 64 * 64);
+ imb_partial_display_buffer_update_ex(ibuf,
+ linear_buffer,
+ byte_buffer,
+ stride,
+ offset_x,
+ offset_y,
+ view_settings,
+ display_settings,
+ xmin,
+ ymin,
+ xmax,
+ ymax,
+ copy_display_to_byte_buffer,
+ do_threads);
}
void IMB_partial_display_buffer_update_delayed(ImBuf *ibuf, int xmin, int ymin, int xmax, int ymax)
{
- if (ibuf->invalid_rect.xmin == ibuf->invalid_rect.xmax) {
- BLI_rcti_init(&ibuf->invalid_rect, xmin, xmax, ymin, ymax);
- }
- else {
- rcti rect;
- BLI_rcti_init(&rect, xmin, xmax, ymin, ymax);
- BLI_rcti_union(&ibuf->invalid_rect, &rect);
- }
+ if (ibuf->invalid_rect.xmin == ibuf->invalid_rect.xmax) {
+ BLI_rcti_init(&ibuf->invalid_rect, xmin, xmax, ymin, ymax);
+ }
+ else {
+ rcti rect;
+ BLI_rcti_init(&rect, xmin, xmax, ymin, ymax);
+ BLI_rcti_union(&ibuf->invalid_rect, &rect);
+ }
}
/*********************** Pixel processor functions *************************/
-ColormanageProcessor *IMB_colormanagement_display_processor_new(const ColorManagedViewSettings *view_settings,
- const ColorManagedDisplaySettings *display_settings)
+ColormanageProcessor *IMB_colormanagement_display_processor_new(
+ const ColorManagedViewSettings *view_settings,
+ const ColorManagedDisplaySettings *display_settings)
{
- ColormanageProcessor *cm_processor;
- ColorManagedViewSettings default_view_settings;
- const ColorManagedViewSettings *applied_view_settings;
- ColorSpace *display_space;
+ ColormanageProcessor *cm_processor;
+ ColorManagedViewSettings default_view_settings;
+ const ColorManagedViewSettings *applied_view_settings;
+ ColorSpace *display_space;
- cm_processor = MEM_callocN(sizeof(ColormanageProcessor), "colormanagement processor");
+ cm_processor = MEM_callocN(sizeof(ColormanageProcessor), "colormanagement processor");
- if (view_settings) {
- applied_view_settings = view_settings;
- }
- else {
- IMB_colormanagement_init_default_view_settings(
- &default_view_settings, display_settings);
- applied_view_settings = &default_view_settings;
- }
+ if (view_settings) {
+ applied_view_settings = view_settings;
+ }
+ else {
+ IMB_colormanagement_init_default_view_settings(&default_view_settings, display_settings);
+ applied_view_settings = &default_view_settings;
+ }
- display_space = display_transform_get_colorspace(applied_view_settings, display_settings);
- if (display_space)
- cm_processor->is_data_result = display_space->is_data;
+ display_space = display_transform_get_colorspace(applied_view_settings, display_settings);
+ if (display_space)
+ cm_processor->is_data_result = display_space->is_data;
- cm_processor->processor = create_display_buffer_processor(applied_view_settings->look,
- applied_view_settings->view_transform,
- display_settings->display_device,
- applied_view_settings->exposure,
- applied_view_settings->gamma,
- global_role_scene_linear);
+ cm_processor->processor = create_display_buffer_processor(applied_view_settings->look,
+ applied_view_settings->view_transform,
+ display_settings->display_device,
+ applied_view_settings->exposure,
+ applied_view_settings->gamma,
+ global_role_scene_linear);
- if (applied_view_settings->flag & COLORMANAGE_VIEW_USE_CURVES) {
- cm_processor->curve_mapping = curvemapping_copy(applied_view_settings->curve_mapping);
- curvemapping_premultiply(cm_processor->curve_mapping, false);
- }
+ if (applied_view_settings->flag & COLORMANAGE_VIEW_USE_CURVES) {
+ cm_processor->curve_mapping = curvemapping_copy(applied_view_settings->curve_mapping);
+ curvemapping_premultiply(cm_processor->curve_mapping, false);
+ }
- return cm_processor;
+ return cm_processor;
}
-ColormanageProcessor *IMB_colormanagement_colorspace_processor_new(const char *from_colorspace, const char *to_colorspace)
+ColormanageProcessor *IMB_colormanagement_colorspace_processor_new(const char *from_colorspace,
+ const char *to_colorspace)
{
- ColormanageProcessor *cm_processor;
- ColorSpace *color_space;
+ ColormanageProcessor *cm_processor;
+ ColorSpace *color_space;
- cm_processor = MEM_callocN(sizeof(ColormanageProcessor), "colormanagement processor");
+ cm_processor = MEM_callocN(sizeof(ColormanageProcessor), "colormanagement processor");
- color_space = colormanage_colorspace_get_named(to_colorspace);
- cm_processor->is_data_result = color_space->is_data;
+ color_space = colormanage_colorspace_get_named(to_colorspace);
+ cm_processor->is_data_result = color_space->is_data;
- cm_processor->processor = create_colorspace_transform_processor(from_colorspace, to_colorspace);
+ cm_processor->processor = create_colorspace_transform_processor(from_colorspace, to_colorspace);
- return cm_processor;
+ return cm_processor;
}
void IMB_colormanagement_processor_apply_v4(ColormanageProcessor *cm_processor, float pixel[4])
{
- if (cm_processor->curve_mapping)
- curvemapping_evaluate_premulRGBF(cm_processor->curve_mapping, pixel, pixel);
+ if (cm_processor->curve_mapping)
+ curvemapping_evaluate_premulRGBF(cm_processor->curve_mapping, pixel, pixel);
- if (cm_processor->processor)
- OCIO_processorApplyRGBA(cm_processor->processor, pixel);
+ if (cm_processor->processor)
+ OCIO_processorApplyRGBA(cm_processor->processor, pixel);
}
-void IMB_colormanagement_processor_apply_v4_predivide(ColormanageProcessor *cm_processor, float pixel[4])
+void IMB_colormanagement_processor_apply_v4_predivide(ColormanageProcessor *cm_processor,
+ float pixel[4])
{
- if (cm_processor->curve_mapping)
- curvemapping_evaluate_premulRGBF(cm_processor->curve_mapping, pixel, pixel);
+ if (cm_processor->curve_mapping)
+ curvemapping_evaluate_premulRGBF(cm_processor->curve_mapping, pixel, pixel);
- if (cm_processor->processor)
- OCIO_processorApplyRGBA_predivide(cm_processor->processor, pixel);
+ if (cm_processor->processor)
+ OCIO_processorApplyRGBA_predivide(cm_processor->processor, pixel);
}
void IMB_colormanagement_processor_apply_v3(ColormanageProcessor *cm_processor, float pixel[3])
{
- if (cm_processor->curve_mapping)
- curvemapping_evaluate_premulRGBF(cm_processor->curve_mapping, pixel, pixel);
-
- if (cm_processor->processor)
- OCIO_processorApplyRGB(cm_processor->processor, pixel);
-}
-
-void IMB_colormanagement_processor_apply_pixel(struct ColormanageProcessor *cm_processor, float *pixel, int channels)
-{
- if (channels == 4) {
- IMB_colormanagement_processor_apply_v4_predivide(cm_processor, pixel);
- }
- else if (channels == 3) {
- IMB_colormanagement_processor_apply_v3(cm_processor, pixel);
- }
- else if (channels == 1) {
- if (cm_processor->curve_mapping) {
- curve_mapping_apply_pixel(cm_processor->curve_mapping, pixel, 1);
- }
- }
- else {
- BLI_assert(!"Incorrect number of channels passed to IMB_colormanagement_processor_apply_pixel");
- }
-}
-
-void IMB_colormanagement_processor_apply(ColormanageProcessor *cm_processor, float *buffer, int width, int height,
- int channels, bool predivide)
-{
- /* apply curve mapping */
- if (cm_processor->curve_mapping) {
- int x, y;
-
- for (y = 0; y < height; y++) {
- for (x = 0; x < width; x++) {
- float *pixel = buffer + channels * (((size_t)y) * width + x);
-
- curve_mapping_apply_pixel(cm_processor->curve_mapping, pixel, channels);
- }
- }
- }
-
- if (cm_processor->processor && channels >= 3) {
- OCIO_PackedImageDesc *img;
-
- /* apply OCIO processor */
- img = OCIO_createOCIO_PackedImageDesc(
- buffer, width, height, channels, sizeof(float),
- (size_t)channels * sizeof(float),
- (size_t)channels * sizeof(float) * width);
-
- if (predivide)
- OCIO_processorApply_predivide(cm_processor->processor, img);
- else
- OCIO_processorApply(cm_processor->processor, img);
-
- OCIO_PackedImageDescRelease(img);
- }
-}
-
-void IMB_colormanagement_processor_apply_byte(ColormanageProcessor *cm_processor,
- unsigned char *buffer,
- int width, int height, int channels)
-{
- /* TODO(sergey): Would be nice to support arbitrary channels configurations,
- * but for now it's not so important.
- */
- BLI_assert(channels == 4);
- float pixel[4];
- for (int y = 0; y < height; y++) {
- for (int x = 0; x < width; x++) {
- size_t offset = channels * (((size_t)y) * width + x);
- rgba_uchar_to_float(pixel, buffer + offset);
- IMB_colormanagement_processor_apply_v4(cm_processor, pixel);
- rgba_float_to_uchar(buffer + offset, pixel);
- }
- }
+ if (cm_processor->curve_mapping)
+ curvemapping_evaluate_premulRGBF(cm_processor->curve_mapping, pixel, pixel);
+
+ if (cm_processor->processor)
+ OCIO_processorApplyRGB(cm_processor->processor, pixel);
+}
+
+void IMB_colormanagement_processor_apply_pixel(struct ColormanageProcessor *cm_processor,
+ float *pixel,
+ int channels)
+{
+ if (channels == 4) {
+ IMB_colormanagement_processor_apply_v4_predivide(cm_processor, pixel);
+ }
+ else if (channels == 3) {
+ IMB_colormanagement_processor_apply_v3(cm_processor, pixel);
+ }
+ else if (channels == 1) {
+ if (cm_processor->curve_mapping) {
+ curve_mapping_apply_pixel(cm_processor->curve_mapping, pixel, 1);
+ }
+ }
+ else {
+ BLI_assert(
+ !"Incorrect number of channels passed to IMB_colormanagement_processor_apply_pixel");
+ }
+}
+
+void IMB_colormanagement_processor_apply(ColormanageProcessor *cm_processor,
+ float *buffer,
+ int width,
+ int height,
+ int channels,
+ bool predivide)
+{
+ /* apply curve mapping */
+ if (cm_processor->curve_mapping) {
+ int x, y;
+
+ for (y = 0; y < height; y++) {
+ for (x = 0; x < width; x++) {
+ float *pixel = buffer + channels * (((size_t)y) * width + x);
+
+ curve_mapping_apply_pixel(cm_processor->curve_mapping, pixel, channels);
+ }
+ }
+ }
+
+ if (cm_processor->processor && channels >= 3) {
+ OCIO_PackedImageDesc *img;
+
+ /* apply OCIO processor */
+ img = OCIO_createOCIO_PackedImageDesc(buffer,
+ width,
+ height,
+ channels,
+ sizeof(float),
+ (size_t)channels * sizeof(float),
+ (size_t)channels * sizeof(float) * width);
+
+ if (predivide)
+ OCIO_processorApply_predivide(cm_processor->processor, img);
+ else
+ OCIO_processorApply(cm_processor->processor, img);
+
+ OCIO_PackedImageDescRelease(img);
+ }
+}
+
+void IMB_colormanagement_processor_apply_byte(
+ ColormanageProcessor *cm_processor, unsigned char *buffer, int width, int height, int channels)
+{
+ /* TODO(sergey): Would be nice to support arbitrary channels configurations,
+ * but for now it's not so important.
+ */
+ BLI_assert(channels == 4);
+ float pixel[4];
+ for (int y = 0; y < height; y++) {
+ for (int x = 0; x < width; x++) {
+ size_t offset = channels * (((size_t)y) * width + x);
+ rgba_uchar_to_float(pixel, buffer + offset);
+ IMB_colormanagement_processor_apply_v4(cm_processor, pixel);
+ rgba_float_to_uchar(buffer + offset, pixel);
+ }
+ }
}
void IMB_colormanagement_processor_free(ColormanageProcessor *cm_processor)
{
- if (cm_processor->curve_mapping)
- curvemapping_free(cm_processor->curve_mapping);
- if (cm_processor->processor)
- OCIO_processorRelease(cm_processor->processor);
+ if (cm_processor->curve_mapping)
+ curvemapping_free(cm_processor->curve_mapping);
+ if (cm_processor->processor)
+ OCIO_processorRelease(cm_processor->processor);
- MEM_freeN(cm_processor);
+ MEM_freeN(cm_processor);
}
/* **** OpenGL drawing routines using GLSL for color space transform ***** */
-static bool check_glsl_display_processor_changed(const ColorManagedViewSettings *view_settings,
- const ColorManagedDisplaySettings *display_settings,
- const char *from_colorspace)
+static bool check_glsl_display_processor_changed(
+ const ColorManagedViewSettings *view_settings,
+ const ColorManagedDisplaySettings *display_settings,
+ const char *from_colorspace)
{
- return !(global_glsl_state.exposure == view_settings->exposure &&
- global_glsl_state.gamma == view_settings->gamma &&
- STREQ(global_glsl_state.look, view_settings->look) &&
- STREQ(global_glsl_state.view, view_settings->view_transform) &&
- STREQ(global_glsl_state.display, display_settings->display_device) &&
- STREQ(global_glsl_state.input, from_colorspace));
+ return !(global_glsl_state.exposure == view_settings->exposure &&
+ global_glsl_state.gamma == view_settings->gamma &&
+ STREQ(global_glsl_state.look, view_settings->look) &&
+ STREQ(global_glsl_state.view, view_settings->view_transform) &&
+ STREQ(global_glsl_state.display, display_settings->display_device) &&
+ STREQ(global_glsl_state.input, from_colorspace));
}
static void curve_mapping_to_ocio_settings(CurveMapping *curve_mapping,
OCIO_CurveMappingSettings *curve_mapping_settings)
{
- int i;
+ int i;
- curvemapping_initialize(curve_mapping);
- curvemapping_premultiply(curve_mapping, false);
- curvemapping_table_RGBA(curve_mapping,
- &curve_mapping_settings->lut,
- &curve_mapping_settings->lut_size);
+ curvemapping_initialize(curve_mapping);
+ curvemapping_premultiply(curve_mapping, false);
+ curvemapping_table_RGBA(
+ curve_mapping, &curve_mapping_settings->lut, &curve_mapping_settings->lut_size);
- for (i = 0; i < 4; i++) {
- CurveMap *cuma = curve_mapping->cm + i;
- curve_mapping_settings->use_extend_extrapolate[i] = (cuma->flag & CUMA_EXTEND_EXTRAPOLATE) != 0;
- curve_mapping_settings->range[i] = cuma->range;
- curve_mapping_settings->mintable[i] = cuma->mintable;
- curve_mapping_settings->ext_in_x[i] = cuma->ext_in[0];
- curve_mapping_settings->ext_in_y[i] = cuma->ext_in[1];
- curve_mapping_settings->ext_out_x[i] = cuma->ext_out[0];
- curve_mapping_settings->ext_out_y[i] = cuma->ext_out[1];
- curve_mapping_settings->first_x[i] = cuma->table[0].x;
- curve_mapping_settings->first_y[i] = cuma->table[0].y;
- curve_mapping_settings->last_x[i] = cuma->table[CM_TABLE].x;
- curve_mapping_settings->last_y[i] = cuma->table[CM_TABLE].y;
- }
+ for (i = 0; i < 4; i++) {
+ CurveMap *cuma = curve_mapping->cm + i;
+ curve_mapping_settings->use_extend_extrapolate[i] = (cuma->flag & CUMA_EXTEND_EXTRAPOLATE) !=
+ 0;
+ curve_mapping_settings->range[i] = cuma->range;
+ curve_mapping_settings->mintable[i] = cuma->mintable;
+ curve_mapping_settings->ext_in_x[i] = cuma->ext_in[0];
+ curve_mapping_settings->ext_in_y[i] = cuma->ext_in[1];
+ curve_mapping_settings->ext_out_x[i] = cuma->ext_out[0];
+ curve_mapping_settings->ext_out_y[i] = cuma->ext_out[1];
+ curve_mapping_settings->first_x[i] = cuma->table[0].x;
+ curve_mapping_settings->first_y[i] = cuma->table[0].y;
+ curve_mapping_settings->last_x[i] = cuma->table[CM_TABLE].x;
+ curve_mapping_settings->last_y[i] = cuma->table[CM_TABLE].y;
+ }
- copy_v3_v3(curve_mapping_settings->black, curve_mapping->black);
- copy_v3_v3(curve_mapping_settings->bwmul, curve_mapping->bwmul);
+ copy_v3_v3(curve_mapping_settings->black, curve_mapping->black);
+ copy_v3_v3(curve_mapping_settings->bwmul, curve_mapping->bwmul);
- curve_mapping_settings->cache_id = (size_t) curve_mapping;
+ curve_mapping_settings->cache_id = (size_t)curve_mapping;
}
static void update_glsl_display_processor(const ColorManagedViewSettings *view_settings,
const ColorManagedDisplaySettings *display_settings,
const char *from_colorspace)
{
- bool use_curve_mapping = (view_settings->flag & COLORMANAGE_VIEW_USE_CURVES) != 0;
- bool need_update = false;
-
- need_update = global_glsl_state.processor == NULL ||
- check_glsl_display_processor_changed(view_settings, display_settings, from_colorspace) ||
- use_curve_mapping != global_glsl_state.use_curve_mapping;
-
- if (use_curve_mapping && need_update == false) {
- need_update |= view_settings->curve_mapping->changed_timestamp != global_glsl_state.curve_mapping_timestamp ||
- view_settings->curve_mapping != global_glsl_state.orig_curve_mapping;
- }
-
- /* Update state if there's no processor yet or
- * processor settings has been changed.
- */
- if (need_update) {
- OCIO_CurveMappingSettings *curve_mapping_settings = &global_glsl_state.curve_mapping_settings;
- CurveMapping *new_curve_mapping = NULL;
-
- /* Store settings of processor for further comparison. */
- BLI_strncpy(global_glsl_state.look, view_settings->look, MAX_COLORSPACE_NAME);
- BLI_strncpy(global_glsl_state.view, view_settings->view_transform, MAX_COLORSPACE_NAME);
- BLI_strncpy(global_glsl_state.display, display_settings->display_device, MAX_COLORSPACE_NAME);
- BLI_strncpy(global_glsl_state.input, from_colorspace, MAX_COLORSPACE_NAME);
- global_glsl_state.exposure = view_settings->exposure;
- global_glsl_state.gamma = view_settings->gamma;
-
- /* We're using curve mapping's address as a cache ID,
- * so we need to make sure re-allocation gives new address here.
- * We do this by allocating new curve mapping before freeing ol one.
- */
- if (use_curve_mapping) {
- new_curve_mapping = curvemapping_copy(view_settings->curve_mapping);
- }
-
- if (global_glsl_state.curve_mapping) {
- curvemapping_free(global_glsl_state.curve_mapping);
- MEM_freeN(curve_mapping_settings->lut);
- global_glsl_state.curve_mapping = NULL;
- curve_mapping_settings->lut = NULL;
- }
-
- /* Fill in OCIO's curve mapping settings. */
- if (use_curve_mapping) {
- curve_mapping_to_ocio_settings(new_curve_mapping, &global_glsl_state.curve_mapping_settings);
-
- global_glsl_state.curve_mapping = new_curve_mapping;
- global_glsl_state.curve_mapping_timestamp = view_settings->curve_mapping->changed_timestamp;
- global_glsl_state.orig_curve_mapping = view_settings->curve_mapping;
- global_glsl_state.use_curve_mapping = true;
- }
- else {
- global_glsl_state.orig_curve_mapping = NULL;
- global_glsl_state.use_curve_mapping = false;
- }
-
- /* Free old processor, if any. */
- if (global_glsl_state.processor)
- OCIO_processorRelease(global_glsl_state.processor);
-
- /* We're using display OCIO processor, no RGB curves yet. */
- global_glsl_state.processor =
- create_display_buffer_processor(global_glsl_state.look,
- global_glsl_state.view,
- global_glsl_state.display,
- global_glsl_state.exposure,
- global_glsl_state.gamma,
- global_glsl_state.input);
- }
+ bool use_curve_mapping = (view_settings->flag & COLORMANAGE_VIEW_USE_CURVES) != 0;
+ bool need_update = false;
+
+ need_update = global_glsl_state.processor == NULL ||
+ check_glsl_display_processor_changed(
+ view_settings, display_settings, from_colorspace) ||
+ use_curve_mapping != global_glsl_state.use_curve_mapping;
+
+ if (use_curve_mapping && need_update == false) {
+ need_update |= view_settings->curve_mapping->changed_timestamp !=
+ global_glsl_state.curve_mapping_timestamp ||
+ view_settings->curve_mapping != global_glsl_state.orig_curve_mapping;
+ }
+
+ /* Update state if there's no processor yet or
+ * processor settings has been changed.
+ */
+ if (need_update) {
+ OCIO_CurveMappingSettings *curve_mapping_settings = &global_glsl_state.curve_mapping_settings;
+ CurveMapping *new_curve_mapping = NULL;
+
+ /* Store settings of processor for further comparison. */
+ BLI_strncpy(global_glsl_state.look, view_settings->look, MAX_COLORSPACE_NAME);
+ BLI_strncpy(global_glsl_state.view, view_settings->view_transform, MAX_COLORSPACE_NAME);
+ BLI_strncpy(global_glsl_state.display, display_settings->display_device, MAX_COLORSPACE_NAME);
+ BLI_strncpy(global_glsl_state.input, from_colorspace, MAX_COLORSPACE_NAME);
+ global_glsl_state.exposure = view_settings->exposure;
+ global_glsl_state.gamma = view_settings->gamma;
+
+ /* We're using curve mapping's address as a cache ID,
+ * so we need to make sure re-allocation gives new address here.
+ * We do this by allocating new curve mapping before freeing ol one.
+ */
+ if (use_curve_mapping) {
+ new_curve_mapping = curvemapping_copy(view_settings->curve_mapping);
+ }
+
+ if (global_glsl_state.curve_mapping) {
+ curvemapping_free(global_glsl_state.curve_mapping);
+ MEM_freeN(curve_mapping_settings->lut);
+ global_glsl_state.curve_mapping = NULL;
+ curve_mapping_settings->lut = NULL;
+ }
+
+ /* Fill in OCIO's curve mapping settings. */
+ if (use_curve_mapping) {
+ curve_mapping_to_ocio_settings(new_curve_mapping, &global_glsl_state.curve_mapping_settings);
+
+ global_glsl_state.curve_mapping = new_curve_mapping;
+ global_glsl_state.curve_mapping_timestamp = view_settings->curve_mapping->changed_timestamp;
+ global_glsl_state.orig_curve_mapping = view_settings->curve_mapping;
+ global_glsl_state.use_curve_mapping = true;
+ }
+ else {
+ global_glsl_state.orig_curve_mapping = NULL;
+ global_glsl_state.use_curve_mapping = false;
+ }
+
+ /* Free old processor, if any. */
+ if (global_glsl_state.processor)
+ OCIO_processorRelease(global_glsl_state.processor);
+
+ /* We're using display OCIO processor, no RGB curves yet. */
+ global_glsl_state.processor = create_display_buffer_processor(global_glsl_state.look,
+ global_glsl_state.view,
+ global_glsl_state.display,
+ global_glsl_state.exposure,
+ global_glsl_state.gamma,
+ global_glsl_state.input);
+ }
}
bool IMB_colormanagement_support_glsl_draw(const ColorManagedViewSettings *UNUSED(view_settings))
{
- return OCIO_supportGLSLDraw();
+ return OCIO_supportGLSLDraw();
}
/**
@@ -3538,73 +3792,82 @@ bool IMB_colormanagement_support_glsl_draw(const ColorManagedViewSettings *UNUSE
* This is low-level function, use glaDrawImBuf_glsl_ctx if you
* only need to display given image buffer
*/
-bool IMB_colormanagement_setup_glsl_draw_from_space(const ColorManagedViewSettings *view_settings,
- const ColorManagedDisplaySettings *display_settings,
- struct ColorSpace *from_colorspace,
- float dither, bool predivide)
-{
- ColorManagedViewSettings default_view_settings;
- const ColorManagedViewSettings *applied_view_settings;
-
- if (view_settings) {
- applied_view_settings = view_settings;
- }
- else {
- /* If no view settings were specified, use default ones, which will
- * attempt not to do any extra color correction. */
- IMB_colormanagement_init_default_view_settings(
- &default_view_settings, display_settings);
- applied_view_settings = &default_view_settings;
- }
-
- /* Make sure OCIO processor is up-to-date. */
- update_glsl_display_processor(applied_view_settings, display_settings,
- from_colorspace ? from_colorspace->name : global_role_scene_linear);
-
- if (global_glsl_state.processor == NULL) {
- /* Happens when requesting non-existing color space or LUT in the
- * configuration file does not exist.
- */
- return false;
- }
-
- return OCIO_setupGLSLDraw(&global_glsl_state.ocio_glsl_state, global_glsl_state.processor,
- global_glsl_state.use_curve_mapping ? &global_glsl_state.curve_mapping_settings : NULL,
- dither, predivide);
+bool IMB_colormanagement_setup_glsl_draw_from_space(
+ const ColorManagedViewSettings *view_settings,
+ const ColorManagedDisplaySettings *display_settings,
+ struct ColorSpace *from_colorspace,
+ float dither,
+ bool predivide)
+{
+ ColorManagedViewSettings default_view_settings;
+ const ColorManagedViewSettings *applied_view_settings;
+
+ if (view_settings) {
+ applied_view_settings = view_settings;
+ }
+ else {
+ /* If no view settings were specified, use default ones, which will
+ * attempt not to do any extra color correction. */
+ IMB_colormanagement_init_default_view_settings(&default_view_settings, display_settings);
+ applied_view_settings = &default_view_settings;
+ }
+
+ /* Make sure OCIO processor is up-to-date. */
+ update_glsl_display_processor(applied_view_settings,
+ display_settings,
+ from_colorspace ? from_colorspace->name :
+ global_role_scene_linear);
+
+ if (global_glsl_state.processor == NULL) {
+ /* Happens when requesting non-existing color space or LUT in the
+ * configuration file does not exist.
+ */
+ return false;
+ }
+
+ return OCIO_setupGLSLDraw(
+ &global_glsl_state.ocio_glsl_state,
+ global_glsl_state.processor,
+ global_glsl_state.use_curve_mapping ? &global_glsl_state.curve_mapping_settings : NULL,
+ dither,
+ predivide);
}
/* Configures GLSL shader for conversion from scene linear to display space */
bool IMB_colormanagement_setup_glsl_draw(const ColorManagedViewSettings *view_settings,
const ColorManagedDisplaySettings *display_settings,
- float dither, bool predivide)
+ float dither,
+ bool predivide)
{
- return IMB_colormanagement_setup_glsl_draw_from_space(view_settings, display_settings,
- NULL, dither, predivide);
+ return IMB_colormanagement_setup_glsl_draw_from_space(
+ view_settings, display_settings, NULL, dither, predivide);
}
/* Same as setup_glsl_draw_from_space, but color management settings are guessing from a given context */
-bool IMB_colormanagement_setup_glsl_draw_from_space_ctx(const bContext *C, struct ColorSpace *from_colorspace,
- float dither, bool predivide)
+bool IMB_colormanagement_setup_glsl_draw_from_space_ctx(const bContext *C,
+ struct ColorSpace *from_colorspace,
+ float dither,
+ bool predivide)
{
- ColorManagedViewSettings *view_settings;
- ColorManagedDisplaySettings *display_settings;
+ ColorManagedViewSettings *view_settings;
+ ColorManagedDisplaySettings *display_settings;
- IMB_colormanagement_display_settings_from_ctx(C, &view_settings, &display_settings);
+ IMB_colormanagement_display_settings_from_ctx(C, &view_settings, &display_settings);
- return IMB_colormanagement_setup_glsl_draw_from_space(view_settings, display_settings, from_colorspace,
- dither, predivide);
+ return IMB_colormanagement_setup_glsl_draw_from_space(
+ view_settings, display_settings, from_colorspace, dither, predivide);
}
/* Same as setup_glsl_draw, but color management settings are guessing from a given context */
bool IMB_colormanagement_setup_glsl_draw_ctx(const bContext *C, float dither, bool predivide)
{
- return IMB_colormanagement_setup_glsl_draw_from_space_ctx(C, NULL, dither, predivide);
+ return IMB_colormanagement_setup_glsl_draw_from_space_ctx(C, NULL, dither, predivide);
}
/* Finish GLSL-based display space conversion */
void IMB_colormanagement_finish_glsl_draw(void)
{
- if (global_glsl_state.ocio_glsl_state != NULL) {
- OCIO_finishGLSLDraw(global_glsl_state.ocio_glsl_state);
- }
+ if (global_glsl_state.ocio_glsl_state != NULL) {
+ OCIO_finishGLSLDraw(global_glsl_state.ocio_glsl_state);
+ }
}
diff --git a/source/blender/imbuf/intern/colormanagement_inline.c b/source/blender/imbuf/intern/colormanagement_inline.c
index 2200c1d8c52..42c90b8414f 100644
--- a/source/blender/imbuf/intern/colormanagement_inline.c
+++ b/source/blender/imbuf/intern/colormanagement_inline.c
@@ -40,29 +40,29 @@
float IMB_colormanagement_get_luminance(const float rgb[3])
{
- return dot_v3v3(imbuf_luma_coefficients, rgb);
+ return dot_v3v3(imbuf_luma_coefficients, rgb);
}
/* Byte equivalent of IMB_colormanagement_get_luminance(). */
unsigned char IMB_colormanagement_get_luminance_byte(const unsigned char rgb[3])
{
- float rgbf[3];
- float val;
+ float rgbf[3];
+ float val;
- rgb_uchar_to_float(rgbf, rgb);
- val = dot_v3v3(imbuf_luma_coefficients, rgbf);
+ rgb_uchar_to_float(rgbf, rgb);
+ val = dot_v3v3(imbuf_luma_coefficients, rgbf);
- return unit_float_to_uchar_clamp(val);
+ return unit_float_to_uchar_clamp(val);
}
void IMB_colormangement_xyz_to_rgb(float rgb[3], const float xyz[3])
{
- mul_v3_m3v3(rgb, imbuf_xyz_to_rgb, xyz);
+ mul_v3_m3v3(rgb, imbuf_xyz_to_rgb, xyz);
}
void IMB_colormangement_rgb_to_xyz(float xyz[3], const float rgb[3])
{
- mul_v3_m3v3(xyz, imbuf_rgb_to_xyz, rgb);
+ mul_v3_m3v3(xyz, imbuf_rgb_to_xyz, rgb);
}
-#endif /* __IMB_COLORMANAGEMENT_INLINE_H__ */
+#endif /* __IMB_COLORMANAGEMENT_INLINE_H__ */
diff --git a/source/blender/imbuf/intern/dds/BlockDXT.cpp b/source/blender/imbuf/intern/dds/BlockDXT.cpp
index aae769d9882..9211f6a7ba6 100644
--- a/source/blender/imbuf/intern/dds/BlockDXT.cpp
+++ b/source/blender/imbuf/intern/dds/BlockDXT.cpp
@@ -18,7 +18,6 @@
* \ingroup imbdds
*/
-
/*
* This file is based on a similar file from the NVIDIA texture tools
* (http://nvidia-texture-tools.googlecode.com/)
@@ -55,607 +54,599 @@
#include <BlockDXT.h>
/*----------------------------------------------------------------------------
- BlockDXT1
+ BlockDXT1
----------------------------------------------------------------------------*/
uint BlockDXT1::evaluatePalette(Color32 color_array[4]) const
{
- // Does bit expansion before interpolation.
- color_array[0].b = (col0.b << 3) | (col0.b >> 2);
- color_array[0].g = (col0.g << 2) | (col0.g >> 4);
- color_array[0].r = (col0.r << 3) | (col0.r >> 2);
- color_array[0].a = 0xFF;
-
- // @@ Same as above, but faster?
-// Color32 c;
-// c.u = ((col0.u << 3) & 0xf8) | ((col0.u << 5) & 0xfc00) | ((col0.u << 8) & 0xf80000);
-// c.u |= (c.u >> 5) & 0x070007;
-// c.u |= (c.u >> 6) & 0x000300;
-// color_array[0].u = c.u;
-
- color_array[1].r = (col1.r << 3) | (col1.r >> 2);
- color_array[1].g = (col1.g << 2) | (col1.g >> 4);
- color_array[1].b = (col1.b << 3) | (col1.b >> 2);
- color_array[1].a = 0xFF;
-
- // @@ Same as above, but faster?
-// c.u = ((col1.u << 3) & 0xf8) | ((col1.u << 5) & 0xfc00) | ((col1.u << 8) & 0xf80000);
-// c.u |= (c.u >> 5) & 0x070007;
-// c.u |= (c.u >> 6) & 0x000300;
-// color_array[1].u = c.u;
-
- if ( col0.u > col1.u ) {
- // Four-color block: derive the other two colors.
- color_array[2].r = (2 * color_array[0].r + color_array[1].r) / 3;
- color_array[2].g = (2 * color_array[0].g + color_array[1].g) / 3;
- color_array[2].b = (2 * color_array[0].b + color_array[1].b) / 3;
- color_array[2].a = 0xFF;
-
- color_array[3].r = (2 * color_array[1].r + color_array[0].r) / 3;
- color_array[3].g = (2 * color_array[1].g + color_array[0].g) / 3;
- color_array[3].b = (2 * color_array[1].b + color_array[0].b) / 3;
- color_array[3].a = 0xFF;
-
- return 4;
- }
- else {
- // Three-color block: derive the other color.
- color_array[2].r = (color_array[0].r + color_array[1].r) / 2;
- color_array[2].g = (color_array[0].g + color_array[1].g) / 2;
- color_array[2].b = (color_array[0].b + color_array[1].b) / 2;
- color_array[2].a = 0xFF;
-
- // Set all components to 0 to match DXT specs.
- color_array[3].r = 0x00; // color_array[2].r;
- color_array[3].g = 0x00; // color_array[2].g;
- color_array[3].b = 0x00; // color_array[2].b;
- color_array[3].a = 0x00;
-
- return 3;
- }
+ // Does bit expansion before interpolation.
+ color_array[0].b = (col0.b << 3) | (col0.b >> 2);
+ color_array[0].g = (col0.g << 2) | (col0.g >> 4);
+ color_array[0].r = (col0.r << 3) | (col0.r >> 2);
+ color_array[0].a = 0xFF;
+
+ // @@ Same as above, but faster?
+ // Color32 c;
+ // c.u = ((col0.u << 3) & 0xf8) | ((col0.u << 5) & 0xfc00) | ((col0.u << 8) & 0xf80000);
+ // c.u |= (c.u >> 5) & 0x070007;
+ // c.u |= (c.u >> 6) & 0x000300;
+ // color_array[0].u = c.u;
+
+ color_array[1].r = (col1.r << 3) | (col1.r >> 2);
+ color_array[1].g = (col1.g << 2) | (col1.g >> 4);
+ color_array[1].b = (col1.b << 3) | (col1.b >> 2);
+ color_array[1].a = 0xFF;
+
+ // @@ Same as above, but faster?
+ // c.u = ((col1.u << 3) & 0xf8) | ((col1.u << 5) & 0xfc00) | ((col1.u << 8) & 0xf80000);
+ // c.u |= (c.u >> 5) & 0x070007;
+ // c.u |= (c.u >> 6) & 0x000300;
+ // color_array[1].u = c.u;
+
+ if (col0.u > col1.u) {
+ // Four-color block: derive the other two colors.
+ color_array[2].r = (2 * color_array[0].r + color_array[1].r) / 3;
+ color_array[2].g = (2 * color_array[0].g + color_array[1].g) / 3;
+ color_array[2].b = (2 * color_array[0].b + color_array[1].b) / 3;
+ color_array[2].a = 0xFF;
+
+ color_array[3].r = (2 * color_array[1].r + color_array[0].r) / 3;
+ color_array[3].g = (2 * color_array[1].g + color_array[0].g) / 3;
+ color_array[3].b = (2 * color_array[1].b + color_array[0].b) / 3;
+ color_array[3].a = 0xFF;
+
+ return 4;
+ }
+ else {
+ // Three-color block: derive the other color.
+ color_array[2].r = (color_array[0].r + color_array[1].r) / 2;
+ color_array[2].g = (color_array[0].g + color_array[1].g) / 2;
+ color_array[2].b = (color_array[0].b + color_array[1].b) / 2;
+ color_array[2].a = 0xFF;
+
+ // Set all components to 0 to match DXT specs.
+ color_array[3].r = 0x00; // color_array[2].r;
+ color_array[3].g = 0x00; // color_array[2].g;
+ color_array[3].b = 0x00; // color_array[2].b;
+ color_array[3].a = 0x00;
+
+ return 3;
+ }
}
-
uint BlockDXT1::evaluatePaletteNV5x(Color32 color_array[4]) const
{
- // Does bit expansion before interpolation.
- color_array[0].b = (3 * col0.b * 22) / 8;
- color_array[0].g = (col0.g << 2) | (col0.g >> 4);
- color_array[0].r = (3 * col0.r * 22) / 8;
- color_array[0].a = 0xFF;
-
- color_array[1].r = (3 * col1.r * 22) / 8;
- color_array[1].g = (col1.g << 2) | (col1.g >> 4);
- color_array[1].b = (3 * col1.b * 22) / 8;
- color_array[1].a = 0xFF;
-
- int gdiff = color_array[1].g - color_array[0].g;
-
- if ( col0.u > col1.u ) {
- // Four-color block: derive the other two colors.
- color_array[2].r = ((2 * col0.r + col1.r) * 22) / 8;
- color_array[2].g = (256 * color_array[0].g + gdiff / 4 + 128 + gdiff * 80) / 256;
- color_array[2].b = ((2 * col0.b + col1.b) * 22) / 8;
- color_array[2].a = 0xFF;
-
- color_array[3].r = ((2 * col1.r + col0.r) * 22) / 8;
- color_array[3].g = (256 * color_array[1].g - gdiff / 4 + 128 - gdiff * 80) / 256;
- color_array[3].b = ((2 * col1.b + col0.b) * 22) / 8;
- color_array[3].a = 0xFF;
-
- return 4;
- }
- else {
- // Three-color block: derive the other color.
- color_array[2].r = ((col0.r + col1.r) * 33) / 8;
- color_array[2].g = (256 * color_array[0].g + gdiff / 4 + 128 + gdiff * 128) / 256;
- color_array[2].b = ((col0.b + col1.b) * 33) / 8;
- color_array[2].a = 0xFF;
-
- // Set all components to 0 to match DXT specs.
- color_array[3].r = 0x00; // color_array[2].r;
- color_array[3].g = 0x00; // color_array[2].g;
- color_array[3].b = 0x00; // color_array[2].b;
- color_array[3].a = 0x00;
-
- return 3;
- }
+ // Does bit expansion before interpolation.
+ color_array[0].b = (3 * col0.b * 22) / 8;
+ color_array[0].g = (col0.g << 2) | (col0.g >> 4);
+ color_array[0].r = (3 * col0.r * 22) / 8;
+ color_array[0].a = 0xFF;
+
+ color_array[1].r = (3 * col1.r * 22) / 8;
+ color_array[1].g = (col1.g << 2) | (col1.g >> 4);
+ color_array[1].b = (3 * col1.b * 22) / 8;
+ color_array[1].a = 0xFF;
+
+ int gdiff = color_array[1].g - color_array[0].g;
+
+ if (col0.u > col1.u) {
+ // Four-color block: derive the other two colors.
+ color_array[2].r = ((2 * col0.r + col1.r) * 22) / 8;
+ color_array[2].g = (256 * color_array[0].g + gdiff / 4 + 128 + gdiff * 80) / 256;
+ color_array[2].b = ((2 * col0.b + col1.b) * 22) / 8;
+ color_array[2].a = 0xFF;
+
+ color_array[3].r = ((2 * col1.r + col0.r) * 22) / 8;
+ color_array[3].g = (256 * color_array[1].g - gdiff / 4 + 128 - gdiff * 80) / 256;
+ color_array[3].b = ((2 * col1.b + col0.b) * 22) / 8;
+ color_array[3].a = 0xFF;
+
+ return 4;
+ }
+ else {
+ // Three-color block: derive the other color.
+ color_array[2].r = ((col0.r + col1.r) * 33) / 8;
+ color_array[2].g = (256 * color_array[0].g + gdiff / 4 + 128 + gdiff * 128) / 256;
+ color_array[2].b = ((col0.b + col1.b) * 33) / 8;
+ color_array[2].a = 0xFF;
+
+ // Set all components to 0 to match DXT specs.
+ color_array[3].r = 0x00; // color_array[2].r;
+ color_array[3].g = 0x00; // color_array[2].g;
+ color_array[3].b = 0x00; // color_array[2].b;
+ color_array[3].a = 0x00;
+
+ return 3;
+ }
}
// Evaluate palette assuming 3 color block.
void BlockDXT1::evaluatePalette3(Color32 color_array[4]) const
{
- color_array[0].b = (col0.b << 3) | (col0.b >> 2);
- color_array[0].g = (col0.g << 2) | (col0.g >> 4);
- color_array[0].r = (col0.r << 3) | (col0.r >> 2);
- color_array[0].a = 0xFF;
+ color_array[0].b = (col0.b << 3) | (col0.b >> 2);
+ color_array[0].g = (col0.g << 2) | (col0.g >> 4);
+ color_array[0].r = (col0.r << 3) | (col0.r >> 2);
+ color_array[0].a = 0xFF;
- color_array[1].r = (col1.r << 3) | (col1.r >> 2);
- color_array[1].g = (col1.g << 2) | (col1.g >> 4);
- color_array[1].b = (col1.b << 3) | (col1.b >> 2);
- color_array[1].a = 0xFF;
+ color_array[1].r = (col1.r << 3) | (col1.r >> 2);
+ color_array[1].g = (col1.g << 2) | (col1.g >> 4);
+ color_array[1].b = (col1.b << 3) | (col1.b >> 2);
+ color_array[1].a = 0xFF;
- // Three-color block: derive the other color.
- color_array[2].r = (color_array[0].r + color_array[1].r) / 2;
- color_array[2].g = (color_array[0].g + color_array[1].g) / 2;
- color_array[2].b = (color_array[0].b + color_array[1].b) / 2;
- color_array[2].a = 0xFF;
+ // Three-color block: derive the other color.
+ color_array[2].r = (color_array[0].r + color_array[1].r) / 2;
+ color_array[2].g = (color_array[0].g + color_array[1].g) / 2;
+ color_array[2].b = (color_array[0].b + color_array[1].b) / 2;
+ color_array[2].a = 0xFF;
- // Set all components to 0 to match DXT specs.
- color_array[3].r = 0x00; // color_array[2].r;
- color_array[3].g = 0x00; // color_array[2].g;
- color_array[3].b = 0x00; // color_array[2].b;
- color_array[3].a = 0x00;
+ // Set all components to 0 to match DXT specs.
+ color_array[3].r = 0x00; // color_array[2].r;
+ color_array[3].g = 0x00; // color_array[2].g;
+ color_array[3].b = 0x00; // color_array[2].b;
+ color_array[3].a = 0x00;
}
// Evaluate palette assuming 4 color block.
void BlockDXT1::evaluatePalette4(Color32 color_array[4]) const
{
- color_array[0].b = (col0.b << 3) | (col0.b >> 2);
- color_array[0].g = (col0.g << 2) | (col0.g >> 4);
- color_array[0].r = (col0.r << 3) | (col0.r >> 2);
- color_array[0].a = 0xFF;
+ color_array[0].b = (col0.b << 3) | (col0.b >> 2);
+ color_array[0].g = (col0.g << 2) | (col0.g >> 4);
+ color_array[0].r = (col0.r << 3) | (col0.r >> 2);
+ color_array[0].a = 0xFF;
- color_array[1].r = (col1.r << 3) | (col1.r >> 2);
- color_array[1].g = (col1.g << 2) | (col1.g >> 4);
- color_array[1].b = (col1.b << 3) | (col1.b >> 2);
- color_array[1].a = 0xFF;
+ color_array[1].r = (col1.r << 3) | (col1.r >> 2);
+ color_array[1].g = (col1.g << 2) | (col1.g >> 4);
+ color_array[1].b = (col1.b << 3) | (col1.b >> 2);
+ color_array[1].a = 0xFF;
- // Four-color block: derive the other two colors.
- color_array[2].r = (2 * color_array[0].r + color_array[1].r) / 3;
- color_array[2].g = (2 * color_array[0].g + color_array[1].g) / 3;
- color_array[2].b = (2 * color_array[0].b + color_array[1].b) / 3;
- color_array[2].a = 0xFF;
+ // Four-color block: derive the other two colors.
+ color_array[2].r = (2 * color_array[0].r + color_array[1].r) / 3;
+ color_array[2].g = (2 * color_array[0].g + color_array[1].g) / 3;
+ color_array[2].b = (2 * color_array[0].b + color_array[1].b) / 3;
+ color_array[2].a = 0xFF;
- color_array[3].r = (2 * color_array[1].r + color_array[0].r) / 3;
- color_array[3].g = (2 * color_array[1].g + color_array[0].g) / 3;
- color_array[3].b = (2 * color_array[1].b + color_array[0].b) / 3;
- color_array[3].a = 0xFF;
+ color_array[3].r = (2 * color_array[1].r + color_array[0].r) / 3;
+ color_array[3].g = (2 * color_array[1].g + color_array[0].g) / 3;
+ color_array[3].b = (2 * color_array[1].b + color_array[0].b) / 3;
+ color_array[3].a = 0xFF;
}
-
void BlockDXT1::decodeBlock(ColorBlock *block) const
{
- // Decode color block.
- Color32 color_array[4];
- evaluatePalette(color_array);
+ // Decode color block.
+ Color32 color_array[4];
+ evaluatePalette(color_array);
- // Write color block.
- for ( uint j = 0; j < 4; j++ ) {
- for ( uint i = 0; i < 4; i++ ) {
- uint idx = (row[j] >> (2 * i)) & 3;
- block->color(i, j) = color_array[idx];
- }
- }
+ // Write color block.
+ for (uint j = 0; j < 4; j++) {
+ for (uint i = 0; i < 4; i++) {
+ uint idx = (row[j] >> (2 * i)) & 3;
+ block->color(i, j) = color_array[idx];
+ }
+ }
}
void BlockDXT1::decodeBlockNV5x(ColorBlock *block) const
{
- // Decode color block.
- Color32 color_array[4];
- evaluatePaletteNV5x(color_array);
+ // Decode color block.
+ Color32 color_array[4];
+ evaluatePaletteNV5x(color_array);
- // Write color block.
- for ( uint j = 0; j < 4; j++ ) {
- for ( uint i = 0; i < 4; i++ ) {
- uint idx = (row[j] >> (2 * i)) & 3;
- block->color(i, j) = color_array[idx];
- }
- }
+ // Write color block.
+ for (uint j = 0; j < 4; j++) {
+ for (uint i = 0; i < 4; i++) {
+ uint idx = (row[j] >> (2 * i)) & 3;
+ block->color(i, j) = color_array[idx];
+ }
+ }
}
void BlockDXT1::setIndices(int *idx)
{
- indices = 0;
- for (uint i = 0; i < 16; i++) {
- indices |= (idx[i] & 3) << (2 * i);
- }
+ indices = 0;
+ for (uint i = 0; i < 16; i++) {
+ indices |= (idx[i] & 3) << (2 * i);
+ }
}
-
/// Flip DXT1 block vertically.
inline void BlockDXT1::flip4()
{
- swap(row[0], row[3]);
- swap(row[1], row[2]);
+ swap(row[0], row[3]);
+ swap(row[1], row[2]);
}
/// Flip half DXT1 block vertically.
inline void BlockDXT1::flip2()
{
- swap(row[0], row[1]);
+ swap(row[0], row[1]);
}
-
/*----------------------------------------------------------------------------
- BlockDXT3
+ BlockDXT3
----------------------------------------------------------------------------*/
void BlockDXT3::decodeBlock(ColorBlock *block) const
{
- // Decode color.
- color.decodeBlock(block);
+ // Decode color.
+ color.decodeBlock(block);
- // Decode alpha.
- alpha.decodeBlock(block);
+ // Decode alpha.
+ alpha.decodeBlock(block);
}
void BlockDXT3::decodeBlockNV5x(ColorBlock *block) const
{
- color.decodeBlockNV5x(block);
- alpha.decodeBlock(block);
+ color.decodeBlockNV5x(block);
+ alpha.decodeBlock(block);
}
void AlphaBlockDXT3::decodeBlock(ColorBlock *block) const
{
- block->color(0x0).a = (alpha0 << 4) | alpha0;
- block->color(0x1).a = (alpha1 << 4) | alpha1;
- block->color(0x2).a = (alpha2 << 4) | alpha2;
- block->color(0x3).a = (alpha3 << 4) | alpha3;
- block->color(0x4).a = (alpha4 << 4) | alpha4;
- block->color(0x5).a = (alpha5 << 4) | alpha5;
- block->color(0x6).a = (alpha6 << 4) | alpha6;
- block->color(0x7).a = (alpha7 << 4) | alpha7;
- block->color(0x8).a = (alpha8 << 4) | alpha8;
- block->color(0x9).a = (alpha9 << 4) | alpha9;
- block->color(0xA).a = (alphaA << 4) | alphaA;
- block->color(0xB).a = (alphaB << 4) | alphaB;
- block->color(0xC).a = (alphaC << 4) | alphaC;
- block->color(0xD).a = (alphaD << 4) | alphaD;
- block->color(0xE).a = (alphaE << 4) | alphaE;
- block->color(0xF).a = (alphaF << 4) | alphaF;
+ block->color(0x0).a = (alpha0 << 4) | alpha0;
+ block->color(0x1).a = (alpha1 << 4) | alpha1;
+ block->color(0x2).a = (alpha2 << 4) | alpha2;
+ block->color(0x3).a = (alpha3 << 4) | alpha3;
+ block->color(0x4).a = (alpha4 << 4) | alpha4;
+ block->color(0x5).a = (alpha5 << 4) | alpha5;
+ block->color(0x6).a = (alpha6 << 4) | alpha6;
+ block->color(0x7).a = (alpha7 << 4) | alpha7;
+ block->color(0x8).a = (alpha8 << 4) | alpha8;
+ block->color(0x9).a = (alpha9 << 4) | alpha9;
+ block->color(0xA).a = (alphaA << 4) | alphaA;
+ block->color(0xB).a = (alphaB << 4) | alphaB;
+ block->color(0xC).a = (alphaC << 4) | alphaC;
+ block->color(0xD).a = (alphaD << 4) | alphaD;
+ block->color(0xE).a = (alphaE << 4) | alphaE;
+ block->color(0xF).a = (alphaF << 4) | alphaF;
}
/// Flip DXT3 alpha block vertically.
void AlphaBlockDXT3::flip4()
{
- swap(row[0], row[3]);
- swap(row[1], row[2]);
+ swap(row[0], row[3]);
+ swap(row[1], row[2]);
}
/// Flip half DXT3 alpha block vertically.
void AlphaBlockDXT3::flip2()
{
- swap(row[0], row[1]);
+ swap(row[0], row[1]);
}
/// Flip DXT3 block vertically.
void BlockDXT3::flip4()
{
- alpha.flip4();
- color.flip4();
+ alpha.flip4();
+ color.flip4();
}
/// Flip half DXT3 block vertically.
void BlockDXT3::flip2()
{
- alpha.flip2();
- color.flip2();
+ alpha.flip2();
+ color.flip2();
}
-
/*----------------------------------------------------------------------------
- BlockDXT5
+ BlockDXT5
----------------------------------------------------------------------------*/
void AlphaBlockDXT5::evaluatePalette(uint8 alpha[8]) const
{
- if (alpha0() > alpha1()) {
- evaluatePalette8(alpha);
- }
- else {
- evaluatePalette6(alpha);
- }
+ if (alpha0() > alpha1()) {
+ evaluatePalette8(alpha);
+ }
+ else {
+ evaluatePalette6(alpha);
+ }
}
void AlphaBlockDXT5::evaluatePalette8(uint8 alpha[8]) const
{
- // 8-alpha block: derive the other six alphas.
- // Bit code 000 = alpha0, 001 = alpha1, others are interpolated.
- alpha[0] = alpha0();
- alpha[1] = alpha1();
- alpha[2] = (6 * alpha[0] + 1 * alpha[1]) / 7; // bit code 010
- alpha[3] = (5 * alpha[0] + 2 * alpha[1]) / 7; // bit code 011
- alpha[4] = (4 * alpha[0] + 3 * alpha[1]) / 7; // bit code 100
- alpha[5] = (3 * alpha[0] + 4 * alpha[1]) / 7; // bit code 101
- alpha[6] = (2 * alpha[0] + 5 * alpha[1]) / 7; // bit code 110
- alpha[7] = (1 * alpha[0] + 6 * alpha[1]) / 7; // bit code 111
+ // 8-alpha block: derive the other six alphas.
+ // Bit code 000 = alpha0, 001 = alpha1, others are interpolated.
+ alpha[0] = alpha0();
+ alpha[1] = alpha1();
+ alpha[2] = (6 * alpha[0] + 1 * alpha[1]) / 7; // bit code 010
+ alpha[3] = (5 * alpha[0] + 2 * alpha[1]) / 7; // bit code 011
+ alpha[4] = (4 * alpha[0] + 3 * alpha[1]) / 7; // bit code 100
+ alpha[5] = (3 * alpha[0] + 4 * alpha[1]) / 7; // bit code 101
+ alpha[6] = (2 * alpha[0] + 5 * alpha[1]) / 7; // bit code 110
+ alpha[7] = (1 * alpha[0] + 6 * alpha[1]) / 7; // bit code 111
}
void AlphaBlockDXT5::evaluatePalette6(uint8 alpha[8]) const
{
- // 6-alpha block.
- // Bit code 000 = alpha0, 001 = alpha1, others are interpolated.
- alpha[0] = alpha0();
- alpha[1] = alpha1();
- alpha[2] = (4 * alpha[0] + 1 * alpha[1]) / 5; // Bit code 010
- alpha[3] = (3 * alpha[0] + 2 * alpha[1]) / 5; // Bit code 011
- alpha[4] = (2 * alpha[0] + 3 * alpha[1]) / 5; // Bit code 100
- alpha[5] = (1 * alpha[0] + 4 * alpha[1]) / 5; // Bit code 101
- alpha[6] = 0x00; // Bit code 110
- alpha[7] = 0xFF; // Bit code 111
+ // 6-alpha block.
+ // Bit code 000 = alpha0, 001 = alpha1, others are interpolated.
+ alpha[0] = alpha0();
+ alpha[1] = alpha1();
+ alpha[2] = (4 * alpha[0] + 1 * alpha[1]) / 5; // Bit code 010
+ alpha[3] = (3 * alpha[0] + 2 * alpha[1]) / 5; // Bit code 011
+ alpha[4] = (2 * alpha[0] + 3 * alpha[1]) / 5; // Bit code 100
+ alpha[5] = (1 * alpha[0] + 4 * alpha[1]) / 5; // Bit code 101
+ alpha[6] = 0x00; // Bit code 110
+ alpha[7] = 0xFF; // Bit code 111
}
void AlphaBlockDXT5::indices(uint8 index_array[16]) const
{
- index_array[0x0] = bits0();
- index_array[0x1] = bits1();
- index_array[0x2] = bits2();
- index_array[0x3] = bits3();
- index_array[0x4] = bits4();
- index_array[0x5] = bits5();
- index_array[0x6] = bits6();
- index_array[0x7] = bits7();
- index_array[0x8] = bits8();
- index_array[0x9] = bits9();
- index_array[0xA] = bitsA();
- index_array[0xB] = bitsB();
- index_array[0xC] = bitsC();
- index_array[0xD] = bitsD();
- index_array[0xE] = bitsE();
- index_array[0xF] = bitsF();
+ index_array[0x0] = bits0();
+ index_array[0x1] = bits1();
+ index_array[0x2] = bits2();
+ index_array[0x3] = bits3();
+ index_array[0x4] = bits4();
+ index_array[0x5] = bits5();
+ index_array[0x6] = bits6();
+ index_array[0x7] = bits7();
+ index_array[0x8] = bits8();
+ index_array[0x9] = bits9();
+ index_array[0xA] = bitsA();
+ index_array[0xB] = bitsB();
+ index_array[0xC] = bitsC();
+ index_array[0xD] = bitsD();
+ index_array[0xE] = bitsE();
+ index_array[0xF] = bitsF();
}
uint AlphaBlockDXT5::index(uint index) const
{
- int offset = (3 * index + 16);
- return uint((this->u >> offset) & 0x7);
+ int offset = (3 * index + 16);
+ return uint((this->u >> offset) & 0x7);
}
void AlphaBlockDXT5::setIndex(uint index, uint value)
{
- int offset = (3 * index + 16);
- uint64 mask = uint64(0x7) << offset;
- this->u = (this->u & ~mask) | (uint64(value) << offset);
+ int offset = (3 * index + 16);
+ uint64 mask = uint64(0x7) << offset;
+ this->u = (this->u & ~mask) | (uint64(value) << offset);
}
void AlphaBlockDXT5::decodeBlock(ColorBlock *block) const
{
- uint8 alpha_array[8];
- evaluatePalette(alpha_array);
+ uint8 alpha_array[8];
+ evaluatePalette(alpha_array);
- uint8 index_array[16];
- indices(index_array);
+ uint8 index_array[16];
+ indices(index_array);
- for (uint i = 0; i < 16; i++) {
- block->color(i).a = alpha_array[index_array[i]];
- }
+ for (uint i = 0; i < 16; i++) {
+ block->color(i).a = alpha_array[index_array[i]];
+ }
}
void AlphaBlockDXT5::flip4()
{
- uint64 *b = (uint64 *)this;
+ uint64 *b = (uint64 *)this;
- // @@ The masks might have to be byte swapped.
- uint64 tmp = (*b & (uint64)(0x000000000000FFFFLL));
- tmp |= (*b & (uint64)(0x000000000FFF0000LL)) << 36;
- tmp |= (*b & (uint64)(0x000000FFF0000000LL)) << 12;
- tmp |= (*b & (uint64)(0x000FFF0000000000LL)) >> 12;
- tmp |= (*b & (uint64)(0xFFF0000000000000LL)) >> 36;
+ // @@ The masks might have to be byte swapped.
+ uint64 tmp = (*b & (uint64)(0x000000000000FFFFLL));
+ tmp |= (*b & (uint64)(0x000000000FFF0000LL)) << 36;
+ tmp |= (*b & (uint64)(0x000000FFF0000000LL)) << 12;
+ tmp |= (*b & (uint64)(0x000FFF0000000000LL)) >> 12;
+ tmp |= (*b & (uint64)(0xFFF0000000000000LL)) >> 36;
- *b = tmp;
+ *b = tmp;
}
void AlphaBlockDXT5::flip2()
{
- uint *b = (uint *)this;
+ uint *b = (uint *)this;
- // @@ The masks might have to be byte swapped.
- uint tmp = (*b & 0xFF000000);
- tmp |= (*b & 0x00000FFF) << 12;
- tmp |= (*b & 0x00FFF000) >> 12;
+ // @@ The masks might have to be byte swapped.
+ uint tmp = (*b & 0xFF000000);
+ tmp |= (*b & 0x00000FFF) << 12;
+ tmp |= (*b & 0x00FFF000) >> 12;
- *b = tmp;
+ *b = tmp;
}
void BlockDXT5::decodeBlock(ColorBlock *block) const
{
- // Decode color.
- color.decodeBlock(block);
+ // Decode color.
+ color.decodeBlock(block);
- // Decode alpha.
- alpha.decodeBlock(block);
+ // Decode alpha.
+ alpha.decodeBlock(block);
}
void BlockDXT5::decodeBlockNV5x(ColorBlock *block) const
{
- // Decode color.
- color.decodeBlockNV5x(block);
+ // Decode color.
+ color.decodeBlockNV5x(block);
- // Decode alpha.
- alpha.decodeBlock(block);
+ // Decode alpha.
+ alpha.decodeBlock(block);
}
/// Flip DXT5 block vertically.
void BlockDXT5::flip4()
{
- alpha.flip4();
- color.flip4();
+ alpha.flip4();
+ color.flip4();
}
/// Flip half DXT5 block vertically.
void BlockDXT5::flip2()
{
- alpha.flip2();
- color.flip2();
+ alpha.flip2();
+ color.flip2();
}
-
/// Decode ATI1 block.
void BlockATI1::decodeBlock(ColorBlock *block) const
{
- uint8 alpha_array[8];
- alpha.evaluatePalette(alpha_array);
+ uint8 alpha_array[8];
+ alpha.evaluatePalette(alpha_array);
- uint8 index_array[16];
- alpha.indices(index_array);
+ uint8 index_array[16];
+ alpha.indices(index_array);
- for (uint i = 0; i < 16; i++) {
- Color32 & c = block->color(i);
- c.b = c.g = c.r = alpha_array[index_array[i]];
- c.a = 255;
- }
+ for (uint i = 0; i < 16; i++) {
+ Color32 &c = block->color(i);
+ c.b = c.g = c.r = alpha_array[index_array[i]];
+ c.a = 255;
+ }
}
/// Flip ATI1 block vertically.
void BlockATI1::flip4()
{
- alpha.flip4();
+ alpha.flip4();
}
/// Flip half ATI1 block vertically.
void BlockATI1::flip2()
{
- alpha.flip2();
+ alpha.flip2();
}
-
/// Decode ATI2 block.
void BlockATI2::decodeBlock(ColorBlock *block) const
{
- uint8 alpha_array[8];
- uint8 index_array[16];
+ uint8 alpha_array[8];
+ uint8 index_array[16];
- x.evaluatePalette(alpha_array);
- x.indices(index_array);
+ x.evaluatePalette(alpha_array);
+ x.indices(index_array);
- for (uint i = 0; i < 16; i++) {
- Color32 & c = block->color(i);
- c.r = alpha_array[index_array[i]];
- }
+ for (uint i = 0; i < 16; i++) {
+ Color32 &c = block->color(i);
+ c.r = alpha_array[index_array[i]];
+ }
- y.evaluatePalette(alpha_array);
- y.indices(index_array);
+ y.evaluatePalette(alpha_array);
+ y.indices(index_array);
- for (uint i = 0; i < 16; i++) {
- Color32 & c = block->color(i);
- c.g = alpha_array[index_array[i]];
- c.b = 0;
- c.a = 255;
- }
+ for (uint i = 0; i < 16; i++) {
+ Color32 &c = block->color(i);
+ c.g = alpha_array[index_array[i]];
+ c.b = 0;
+ c.a = 255;
+ }
}
/// Flip ATI2 block vertically.
void BlockATI2::flip4()
{
- x.flip4();
- y.flip4();
+ x.flip4();
+ y.flip4();
}
/// Flip half ATI2 block vertically.
void BlockATI2::flip2()
{
- x.flip2();
- y.flip2();
+ x.flip2();
+ y.flip2();
}
-
void BlockCTX1::evaluatePalette(Color32 color_array[4]) const
{
- // Does bit expansion before interpolation.
- color_array[0].b = 0x00;
- color_array[0].g = col0[1];
- color_array[0].r = col0[0];
- color_array[0].a = 0xFF;
+ // Does bit expansion before interpolation.
+ color_array[0].b = 0x00;
+ color_array[0].g = col0[1];
+ color_array[0].r = col0[0];
+ color_array[0].a = 0xFF;
- color_array[1].r = 0x00;
- color_array[1].g = col0[1];
- color_array[1].b = col1[0];
- color_array[1].a = 0xFF;
+ color_array[1].r = 0x00;
+ color_array[1].g = col0[1];
+ color_array[1].b = col1[0];
+ color_array[1].a = 0xFF;
- color_array[2].r = 0x00;
- color_array[2].g = (2 * color_array[0].g + color_array[1].g) / 3;
- color_array[2].b = (2 * color_array[0].b + color_array[1].b) / 3;
- color_array[2].a = 0xFF;
+ color_array[2].r = 0x00;
+ color_array[2].g = (2 * color_array[0].g + color_array[1].g) / 3;
+ color_array[2].b = (2 * color_array[0].b + color_array[1].b) / 3;
+ color_array[2].a = 0xFF;
- color_array[3].r = 0x00;
- color_array[3].g = (2 * color_array[1].g + color_array[0].g) / 3;
- color_array[3].b = (2 * color_array[1].b + color_array[0].b) / 3;
- color_array[3].a = 0xFF;
+ color_array[3].r = 0x00;
+ color_array[3].g = (2 * color_array[1].g + color_array[0].g) / 3;
+ color_array[3].b = (2 * color_array[1].b + color_array[0].b) / 3;
+ color_array[3].a = 0xFF;
}
void BlockCTX1::decodeBlock(ColorBlock *block) const
{
- // Decode color block.
- Color32 color_array[4];
- evaluatePalette(color_array);
+ // Decode color block.
+ Color32 color_array[4];
+ evaluatePalette(color_array);
- // Write color block.
- for ( uint j = 0; j < 4; j++ ) {
- for ( uint i = 0; i < 4; i++ ) {
- uint idx = (row[j] >> (2 * i)) & 3;
- block->color(i, j) = color_array[idx];
- }
- }
+ // Write color block.
+ for (uint j = 0; j < 4; j++) {
+ for (uint i = 0; i < 4; i++) {
+ uint idx = (row[j] >> (2 * i)) & 3;
+ block->color(i, j) = color_array[idx];
+ }
+ }
}
void BlockCTX1::setIndices(int *idx)
{
- indices = 0;
- for (uint i = 0; i < 16; i++) {
- indices |= (idx[i] & 3) << (2 * i);
- }
+ indices = 0;
+ for (uint i = 0; i < 16; i++) {
+ indices |= (idx[i] & 3) << (2 * i);
+ }
}
-
/// Flip CTX1 block vertically.
inline void BlockCTX1::flip4()
{
- swap(row[0], row[3]);
- swap(row[1], row[2]);
+ swap(row[0], row[3]);
+ swap(row[1], row[2]);
}
/// Flip half CTX1 block vertically.
inline void BlockCTX1::flip2()
{
- swap(row[0], row[1]);
+ swap(row[0], row[1]);
}
-void mem_read(Stream & mem, BlockDXT1 & block)
+void mem_read(Stream &mem, BlockDXT1 &block)
{
- mem_read(mem, block.col0.u);
- mem_read(mem, block.col1.u);
- mem_read(mem, block.indices);
+ mem_read(mem, block.col0.u);
+ mem_read(mem, block.col1.u);
+ mem_read(mem, block.indices);
}
-void mem_read(Stream & mem, AlphaBlockDXT3 & block)
+void mem_read(Stream &mem, AlphaBlockDXT3 &block)
{
- for (unsigned int i = 0; i < 4; i++) mem_read(mem, block.row[i]);
+ for (unsigned int i = 0; i < 4; i++)
+ mem_read(mem, block.row[i]);
}
-void mem_read(Stream & mem, BlockDXT3 & block)
+void mem_read(Stream &mem, BlockDXT3 &block)
{
- mem_read(mem, block.alpha);
- mem_read(mem, block.color);
+ mem_read(mem, block.alpha);
+ mem_read(mem, block.color);
}
-void mem_read(Stream & mem, AlphaBlockDXT5 & block)
+void mem_read(Stream &mem, AlphaBlockDXT5 &block)
{
- mem_read(mem, block.u);
+ mem_read(mem, block.u);
}
-void mem_read(Stream & mem, BlockDXT5 & block)
+void mem_read(Stream &mem, BlockDXT5 &block)
{
- mem_read(mem, block.alpha);
- mem_read(mem, block.color);
+ mem_read(mem, block.alpha);
+ mem_read(mem, block.color);
}
-void mem_read(Stream & mem, BlockATI1 & block)
+void mem_read(Stream &mem, BlockATI1 &block)
{
- mem_read(mem, block.alpha);
+ mem_read(mem, block.alpha);
}
-void mem_read(Stream & mem, BlockATI2 & block)
+void mem_read(Stream &mem, BlockATI2 &block)
{
- mem_read(mem, block.x);
- mem_read(mem, block.y);
+ mem_read(mem, block.x);
+ mem_read(mem, block.y);
}
-void mem_read(Stream & mem, BlockCTX1 & block)
+void mem_read(Stream &mem, BlockCTX1 &block)
{
- mem_read(mem, block.col0[0]);
- mem_read(mem, block.col0[1]);
- mem_read(mem, block.col1[0]);
- mem_read(mem, block.col1[1]);
- mem_read(mem, block.indices);
+ mem_read(mem, block.col0[0]);
+ mem_read(mem, block.col0[1]);
+ mem_read(mem, block.col1[0]);
+ mem_read(mem, block.col1[1]);
+ mem_read(mem, block.indices);
}
diff --git a/source/blender/imbuf/intern/dds/BlockDXT.h b/source/blender/imbuf/intern/dds/BlockDXT.h
index 82ec5b45d4e..c13fa42dcdc 100644
--- a/source/blender/imbuf/intern/dds/BlockDXT.h
+++ b/source/blender/imbuf/intern/dds/BlockDXT.h
@@ -18,7 +18,6 @@
* \ingroup imbdds
*/
-
/*
* This file is based on a similar file from the NVIDIA texture tools
* (http://nvidia-texture-tools.googlecode.com/)
@@ -59,202 +58,252 @@
/// DXT1 block.
struct BlockDXT1 {
- Color16 col0;
- Color16 col1;
- union {
- uint8 row[4];
- uint indices;
- };
+ Color16 col0;
+ Color16 col1;
+ union {
+ uint8 row[4];
+ uint indices;
+ };
- bool isFourColorMode() const;
+ bool isFourColorMode() const;
- uint evaluatePalette(Color32 color_array[4]) const;
- uint evaluatePaletteNV5x(Color32 color_array[4]) const;
+ uint evaluatePalette(Color32 color_array[4]) const;
+ uint evaluatePaletteNV5x(Color32 color_array[4]) const;
- void evaluatePalette3(Color32 color_array[4]) const;
- void evaluatePalette4(Color32 color_array[4]) const;
+ void evaluatePalette3(Color32 color_array[4]) const;
+ void evaluatePalette4(Color32 color_array[4]) const;
- void decodeBlock(ColorBlock * block) const;
- void decodeBlockNV5x(ColorBlock * block) const;
+ void decodeBlock(ColorBlock *block) const;
+ void decodeBlockNV5x(ColorBlock *block) const;
- void setIndices(int * idx);
+ void setIndices(int *idx);
- void flip4();
- void flip2();
+ void flip4();
+ void flip2();
};
/// Return true if the block uses four color mode, false otherwise.
inline bool BlockDXT1::isFourColorMode() const
{
- return col0.u > col1.u;
+ return col0.u > col1.u;
}
-
/// DXT3 alpha block with explicit alpha.
struct AlphaBlockDXT3 {
- union {
- struct {
- uint alpha0 : 4;
- uint alpha1 : 4;
- uint alpha2 : 4;
- uint alpha3 : 4;
- uint alpha4 : 4;
- uint alpha5 : 4;
- uint alpha6 : 4;
- uint alpha7 : 4;
- uint alpha8 : 4;
- uint alpha9 : 4;
- uint alphaA : 4;
- uint alphaB : 4;
- uint alphaC : 4;
- uint alphaD : 4;
- uint alphaE : 4;
- uint alphaF : 4;
- };
- uint16 row[4];
- };
-
- void decodeBlock(ColorBlock * block) const;
-
- void flip4();
- void flip2();
+ union {
+ struct {
+ uint alpha0 : 4;
+ uint alpha1 : 4;
+ uint alpha2 : 4;
+ uint alpha3 : 4;
+ uint alpha4 : 4;
+ uint alpha5 : 4;
+ uint alpha6 : 4;
+ uint alpha7 : 4;
+ uint alpha8 : 4;
+ uint alpha9 : 4;
+ uint alphaA : 4;
+ uint alphaB : 4;
+ uint alphaC : 4;
+ uint alphaD : 4;
+ uint alphaE : 4;
+ uint alphaF : 4;
+ };
+ uint16 row[4];
+ };
+
+ void decodeBlock(ColorBlock *block) const;
+
+ void flip4();
+ void flip2();
};
-
/// DXT3 block.
struct BlockDXT3 {
- AlphaBlockDXT3 alpha;
- BlockDXT1 color;
+ AlphaBlockDXT3 alpha;
+ BlockDXT1 color;
- void decodeBlock(ColorBlock * block) const;
- void decodeBlockNV5x(ColorBlock * block) const;
+ void decodeBlock(ColorBlock *block) const;
+ void decodeBlockNV5x(ColorBlock *block) const;
- void flip4();
- void flip2();
+ void flip4();
+ void flip2();
};
-
/// DXT5 alpha block.
struct AlphaBlockDXT5 {
- // uint64 unions do not compile on all platforms
+ // uint64 unions do not compile on all platforms
#if 0
- union {
- struct {
- uint64 alpha0 : 8; // 8
- uint64 alpha1 : 8; // 16
- uint64 bits0 : 3; // 3 - 19
- uint64 bits1 : 3; // 6 - 22
- uint64 bits2 : 3; // 9 - 25
- uint64 bits3 : 3; // 12 - 28
- uint64 bits4 : 3; // 15 - 31
- uint64 bits5 : 3; // 18 - 34
- uint64 bits6 : 3; // 21 - 37
- uint64 bits7 : 3; // 24 - 40
- uint64 bits8 : 3; // 27 - 43
- uint64 bits9 : 3; // 30 - 46
- uint64 bitsA : 3; // 33 - 49
- uint64 bitsB : 3; // 36 - 52
- uint64 bitsC : 3; // 39 - 55
- uint64 bitsD : 3; // 42 - 58
- uint64 bitsE : 3; // 45 - 61
- uint64 bitsF : 3; // 48 - 64
- };
- uint64 u;
- };
+ union {
+ struct {
+ uint64 alpha0 : 8; // 8
+ uint64 alpha1 : 8; // 16
+ uint64 bits0 : 3; // 3 - 19
+ uint64 bits1 : 3; // 6 - 22
+ uint64 bits2 : 3; // 9 - 25
+ uint64 bits3 : 3; // 12 - 28
+ uint64 bits4 : 3; // 15 - 31
+ uint64 bits5 : 3; // 18 - 34
+ uint64 bits6 : 3; // 21 - 37
+ uint64 bits7 : 3; // 24 - 40
+ uint64 bits8 : 3; // 27 - 43
+ uint64 bits9 : 3; // 30 - 46
+ uint64 bitsA : 3; // 33 - 49
+ uint64 bitsB : 3; // 36 - 52
+ uint64 bitsC : 3; // 39 - 55
+ uint64 bitsD : 3; // 42 - 58
+ uint64 bitsE : 3; // 45 - 61
+ uint64 bitsF : 3; // 48 - 64
+ };
+ uint64 u;
+ };
#endif
- uint64 u;
- uint8 alpha0() const { return u & 0xffLL; }
- uint8 alpha1() const { return (u >> 8) & 0xffLL; }
- uint8 bits0() const { return (u >> 16) & 0x7LL; }
- uint8 bits1() const { return (u >> 19) & 0x7LL; }
- uint8 bits2() const { return (u >> 22) & 0x7LL; }
- uint8 bits3() const { return (u >> 25) & 0x7LL; }
- uint8 bits4() const { return (u >> 28) & 0x7LL; }
- uint8 bits5() const { return (u >> 31) & 0x7LL; }
- uint8 bits6() const { return (u >> 34) & 0x7LL; }
- uint8 bits7() const { return (u >> 37) & 0x7LL; }
- uint8 bits8() const { return (u >> 40) & 0x7LL; }
- uint8 bits9() const { return (u >> 43) & 0x7LL; }
- uint8 bitsA() const { return (u >> 46) & 0x7LL; }
- uint8 bitsB() const { return (u >> 49) & 0x7LL; }
- uint8 bitsC() const { return (u >> 52) & 0x7LL; }
- uint8 bitsD() const { return (u >> 55) & 0x7LL; }
- uint8 bitsE() const { return (u >> 58) & 0x7LL; }
- uint8 bitsF() const { return (u >> 61) & 0x7LL; }
-
- void evaluatePalette(uint8 alpha[8]) const;
- void evaluatePalette8(uint8 alpha[8]) const;
- void evaluatePalette6(uint8 alpha[8]) const;
- void indices(uint8 index_array[16]) const;
-
- uint index(uint index) const;
- void setIndex(uint index, uint value);
-
- void decodeBlock(ColorBlock * block) const;
-
- void flip4();
- void flip2();
+ uint64 u;
+ uint8 alpha0() const
+ {
+ return u & 0xffLL;
+ }
+ uint8 alpha1() const
+ {
+ return (u >> 8) & 0xffLL;
+ }
+ uint8 bits0() const
+ {
+ return (u >> 16) & 0x7LL;
+ }
+ uint8 bits1() const
+ {
+ return (u >> 19) & 0x7LL;
+ }
+ uint8 bits2() const
+ {
+ return (u >> 22) & 0x7LL;
+ }
+ uint8 bits3() const
+ {
+ return (u >> 25) & 0x7LL;
+ }
+ uint8 bits4() const
+ {
+ return (u >> 28) & 0x7LL;
+ }
+ uint8 bits5() const
+ {
+ return (u >> 31) & 0x7LL;
+ }
+ uint8 bits6() const
+ {
+ return (u >> 34) & 0x7LL;
+ }
+ uint8 bits7() const
+ {
+ return (u >> 37) & 0x7LL;
+ }
+ uint8 bits8() const
+ {
+ return (u >> 40) & 0x7LL;
+ }
+ uint8 bits9() const
+ {
+ return (u >> 43) & 0x7LL;
+ }
+ uint8 bitsA() const
+ {
+ return (u >> 46) & 0x7LL;
+ }
+ uint8 bitsB() const
+ {
+ return (u >> 49) & 0x7LL;
+ }
+ uint8 bitsC() const
+ {
+ return (u >> 52) & 0x7LL;
+ }
+ uint8 bitsD() const
+ {
+ return (u >> 55) & 0x7LL;
+ }
+ uint8 bitsE() const
+ {
+ return (u >> 58) & 0x7LL;
+ }
+ uint8 bitsF() const
+ {
+ return (u >> 61) & 0x7LL;
+ }
+
+ void evaluatePalette(uint8 alpha[8]) const;
+ void evaluatePalette8(uint8 alpha[8]) const;
+ void evaluatePalette6(uint8 alpha[8]) const;
+ void indices(uint8 index_array[16]) const;
+
+ uint index(uint index) const;
+ void setIndex(uint index, uint value);
+
+ void decodeBlock(ColorBlock *block) const;
+
+ void flip4();
+ void flip2();
};
-
/// DXT5 block.
struct BlockDXT5 {
- AlphaBlockDXT5 alpha;
- BlockDXT1 color;
+ AlphaBlockDXT5 alpha;
+ BlockDXT1 color;
- void decodeBlock(ColorBlock * block) const;
- void decodeBlockNV5x(ColorBlock * block) const;
+ void decodeBlock(ColorBlock *block) const;
+ void decodeBlockNV5x(ColorBlock *block) const;
- void flip4();
- void flip2();
+ void flip4();
+ void flip2();
};
/// ATI1 block.
struct BlockATI1 {
- AlphaBlockDXT5 alpha;
+ AlphaBlockDXT5 alpha;
- void decodeBlock(ColorBlock * block) const;
+ void decodeBlock(ColorBlock *block) const;
- void flip4();
- void flip2();
+ void flip4();
+ void flip2();
};
/// ATI2 block.
struct BlockATI2 {
- AlphaBlockDXT5 x;
- AlphaBlockDXT5 y;
+ AlphaBlockDXT5 x;
+ AlphaBlockDXT5 y;
- void decodeBlock(ColorBlock * block) const;
+ void decodeBlock(ColorBlock *block) const;
- void flip4();
- void flip2();
+ void flip4();
+ void flip2();
};
/// CTX1 block.
struct BlockCTX1 {
- uint8 col0[2];
- uint8 col1[2];
- union {
- uint8 row[4];
- uint indices;
- };
+ uint8 col0[2];
+ uint8 col1[2];
+ union {
+ uint8 row[4];
+ uint indices;
+ };
- void evaluatePalette(Color32 color_array[4]) const;
- void setIndices(int * idx);
+ void evaluatePalette(Color32 color_array[4]) const;
+ void setIndices(int *idx);
- void decodeBlock(ColorBlock * block) const;
+ void decodeBlock(ColorBlock *block) const;
- void flip4();
- void flip2();
+ void flip4();
+ void flip2();
};
-void mem_read(Stream & mem, BlockDXT1 & block);
-void mem_read(Stream & mem, AlphaBlockDXT3 & block);
-void mem_read(Stream & mem, BlockDXT3 & block);
-void mem_read(Stream & mem, AlphaBlockDXT5 & block);
-void mem_read(Stream & mem, BlockDXT5 & block);
-void mem_read(Stream & mem, BlockATI1 & block);
-void mem_read(Stream & mem, BlockATI2 & block);
-void mem_read(Stream & mem, BlockCTX1 & block);
+void mem_read(Stream &mem, BlockDXT1 &block);
+void mem_read(Stream &mem, AlphaBlockDXT3 &block);
+void mem_read(Stream &mem, BlockDXT3 &block);
+void mem_read(Stream &mem, AlphaBlockDXT5 &block);
+void mem_read(Stream &mem, BlockDXT5 &block);
+void mem_read(Stream &mem, BlockATI1 &block);
+void mem_read(Stream &mem, BlockATI2 &block);
+void mem_read(Stream &mem, BlockCTX1 &block);
-#endif /* __BLOCKDXT_H__ */
+#endif /* __BLOCKDXT_H__ */
diff --git a/source/blender/imbuf/intern/dds/CMakeLists.txt b/source/blender/imbuf/intern/dds/CMakeLists.txt
index c68608f4cff..2ec1ea9eb36 100644
--- a/source/blender/imbuf/intern/dds/CMakeLists.txt
+++ b/source/blender/imbuf/intern/dds/CMakeLists.txt
@@ -19,14 +19,14 @@
# ***** END GPL LICENSE BLOCK *****
set(INC
- .
- ..
- ../..
- ../../../blenkernel
- ../../../blenlib
- ../../../makesdna
- ../../../../../intern/guardedalloc
- ../../../../../intern/utfconv
+ .
+ ..
+ ../..
+ ../../../blenkernel
+ ../../../blenlib
+ ../../../makesdna
+ ../../../../../intern/guardedalloc
+ ../../../../../intern/utfconv
)
set(INC_SYS
@@ -34,31 +34,31 @@ set(INC_SYS
)
set(SRC
- BlockDXT.h
- Color.h
- ColorBlock.h
- Common.h
- DirectDrawSurface.h
- FlipDXT.h
- Image.h
- PixelFormat.h
- Stream.h
- dds_api.h
+ BlockDXT.h
+ Color.h
+ ColorBlock.h
+ Common.h
+ DirectDrawSurface.h
+ FlipDXT.h
+ Image.h
+ PixelFormat.h
+ Stream.h
+ dds_api.h
- BlockDXT.cpp
- ColorBlock.cpp
- DirectDrawSurface.cpp
- FlipDXT.cpp
- Image.cpp
- Stream.cpp
- dds_api.cpp
+ BlockDXT.cpp
+ ColorBlock.cpp
+ DirectDrawSurface.cpp
+ FlipDXT.cpp
+ Image.cpp
+ Stream.cpp
+ dds_api.cpp
)
set(LIB
)
if(WITH_IMAGE_DDS)
- add_definitions(-DWITH_DDS)
+ add_definitions(-DWITH_DDS)
endif()
blender_add_lib(bf_imbuf_dds "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/source/blender/imbuf/intern/dds/Color.h b/source/blender/imbuf/intern/dds/Color.h
index da7b77c2854..16432ffa715 100644
--- a/source/blender/imbuf/intern/dds/Color.h
+++ b/source/blender/imbuf/intern/dds/Color.h
@@ -18,7 +18,6 @@
* \ingroup imbdds
*/
-
/*
* This file is based on a similar file from the NVIDIA texture tools
* (http://nvidia-texture-tools.googlecode.com/)
@@ -32,62 +31,79 @@
#define __COLOR_H__
/// 32 bit color stored as BGRA.
-class Color32
-{
-public:
- Color32() { }
- Color32(const Color32 & c) : u(c.u) { }
- Color32(unsigned char R, unsigned char G, unsigned char B) { setRGBA(R, G, B, 0xFF); }
- Color32(unsigned char R, unsigned char G, unsigned char B, unsigned char A) { setRGBA( R, G, B, A); }
- //Color32(unsigned char c[4]) { setRGBA(c[0], c[1], c[2], c[3]); }
- //Color32(float R, float G, float B) { setRGBA(uint(R*255), uint(G*255), uint(B*255), 0xFF); }
- //Color32(float R, float G, float B, float A) { setRGBA(uint(R*255), uint(G*255), uint(B*255), uint(A*255)); }
- Color32(unsigned int U) : u(U) { }
+class Color32 {
+ public:
+ Color32()
+ {
+ }
+ Color32(const Color32 &c) : u(c.u)
+ {
+ }
+ Color32(unsigned char R, unsigned char G, unsigned char B)
+ {
+ setRGBA(R, G, B, 0xFF);
+ }
+ Color32(unsigned char R, unsigned char G, unsigned char B, unsigned char A)
+ {
+ setRGBA(R, G, B, A);
+ }
+ //Color32(unsigned char c[4]) { setRGBA(c[0], c[1], c[2], c[3]); }
+ //Color32(float R, float G, float B) { setRGBA(uint(R*255), uint(G*255), uint(B*255), 0xFF); }
+ //Color32(float R, float G, float B, float A) { setRGBA(uint(R*255), uint(G*255), uint(B*255), uint(A*255)); }
+ Color32(unsigned int U) : u(U)
+ {
+ }
- void setRGBA(unsigned char R, unsigned char G, unsigned char B, unsigned char A)
- {
- r = R;
- g = G;
- b = B;
- a = A;
- }
+ void setRGBA(unsigned char R, unsigned char G, unsigned char B, unsigned char A)
+ {
+ r = R;
+ g = G;
+ b = B;
+ a = A;
+ }
- void setBGRA(unsigned char B, unsigned char G, unsigned char R, unsigned char A = 0xFF)
- {
- r = R;
- g = G;
- b = B;
- a = A;
- }
+ void setBGRA(unsigned char B, unsigned char G, unsigned char R, unsigned char A = 0xFF)
+ {
+ r = R;
+ g = G;
+ b = B;
+ a = A;
+ }
- operator unsigned int () const {
- return u;
- }
+ operator unsigned int() const
+ {
+ return u;
+ }
- union {
- struct {
- unsigned char b, g, r, a;
- };
- unsigned int u;
- };
+ union {
+ struct {
+ unsigned char b, g, r, a;
+ };
+ unsigned int u;
+ };
};
/// 16 bit 565 BGR color.
-class Color16
-{
-public:
- Color16() { }
- Color16(const Color16 & c) : u(c.u) { }
- explicit Color16(unsigned short U) : u(U) { }
+class Color16 {
+ public:
+ Color16()
+ {
+ }
+ Color16(const Color16 &c) : u(c.u)
+ {
+ }
+ explicit Color16(unsigned short U) : u(U)
+ {
+ }
- union {
- struct {
- unsigned short b : 5;
- unsigned short g : 6;
- unsigned short r : 5;
- };
- unsigned short u;
- };
+ union {
+ struct {
+ unsigned short b : 5;
+ unsigned short g : 6;
+ unsigned short r : 5;
+ };
+ unsigned short u;
+ };
};
-#endif /* __COLOR_H__ */
+#endif /* __COLOR_H__ */
diff --git a/source/blender/imbuf/intern/dds/ColorBlock.cpp b/source/blender/imbuf/intern/dds/ColorBlock.cpp
index e0c1c168d50..73397cd036e 100644
--- a/source/blender/imbuf/intern/dds/ColorBlock.cpp
+++ b/source/blender/imbuf/intern/dds/ColorBlock.cpp
@@ -18,7 +18,6 @@
* \ingroup imbdds
*/
-
/*
* This file is based on a similar file from the NVIDIA texture tools
* (http://nvidia-texture-tools.googlecode.com/)
@@ -33,20 +32,19 @@
#include <Common.h>
#if 0
- // Get approximate luminance.
- inline static uint colorLuminance(Color32 c)
- {
- return c.r + c.g + c.b;
- }
-
- // Get the euclidean distance between the given colors.
- inline static uint colorDistance(Color32 c0, Color32 c1)
- {
- return (c0.r - c1.r) * (c0.r - c1.r) + (c0.g - c1.g) * (c0.g - c1.g) + (c0.b - c1.b) * (c0.b - c1.b);
- }
+ // Get approximate luminance.
+ inline static uint colorLuminance(Color32 c)
+ {
+ return c.r + c.g + c.b;
+ }
+
+ // Get the euclidean distance between the given colors.
+ inline static uint colorDistance(Color32 c0, Color32 c1)
+ {
+ return (c0.r - c1.r) * (c0.r - c1.r) + (c0.g - c1.g) * (c0.g - c1.g) + (c0.b - c1.b) * (c0.b - c1.b);
+ }
#endif
-
/// Default constructor.
ColorBlock::ColorBlock()
{
@@ -55,138 +53,143 @@ ColorBlock::ColorBlock()
/// Init the color block from an array of colors.
ColorBlock::ColorBlock(const uint *linearImage)
{
- for (uint i = 0; i < 16; i++) {
- color(i) = Color32(linearImage[i]);
- }
+ for (uint i = 0; i < 16; i++) {
+ color(i) = Color32(linearImage[i]);
+ }
}
/// Init the color block with the contents of the given block.
-ColorBlock::ColorBlock(const ColorBlock & block)
+ColorBlock::ColorBlock(const ColorBlock &block)
{
- for (uint i = 0; i < 16; i++) {
- color(i) = block.color(i);
- }
+ for (uint i = 0; i < 16; i++) {
+ color(i) = block.color(i);
+ }
}
-
/// Initialize this color block.
ColorBlock::ColorBlock(const Image *img, uint x, uint y)
{
- init(img, x, y);
+ init(img, x, y);
}
void ColorBlock::init(const Image *img, uint x, uint y)
{
- init(img->width(), img->height(), (const uint *)img->pixels(), x, y);
+ init(img->width(), img->height(), (const uint *)img->pixels(), x, y);
}
void ColorBlock::init(uint w, uint h, const uint *data, uint x, uint y)
{
- const uint bw = MIN(w - x, 4U);
- const uint bh = MIN(h - y, 4U);
+ const uint bw = MIN(w - x, 4U);
+ const uint bh = MIN(h - y, 4U);
- // Blocks that are smaller than 4x4 are handled by repeating the pixels.
- // @@ Thats only correct when block size is 1, 2 or 4, but not with 3. :(
- // @@ Ideally we should zero the weights of the pixels out of range.
+ // Blocks that are smaller than 4x4 are handled by repeating the pixels.
+ // @@ Thats only correct when block size is 1, 2 or 4, but not with 3. :(
+ // @@ Ideally we should zero the weights of the pixels out of range.
- for (uint i = 0; i < 4; i++) {
- const int by = i % bh;
+ for (uint i = 0; i < 4; i++) {
+ const int by = i % bh;
- for (uint e = 0; e < 4; e++) {
- const int bx = e % bw;
- const uint idx = (y + by) * w + x + bx;
+ for (uint e = 0; e < 4; e++) {
+ const int bx = e % bw;
+ const uint idx = (y + by) * w + x + bx;
- color(e, i).u = data[idx];
- }
- }
+ color(e, i).u = data[idx];
+ }
+ }
}
void ColorBlock::init(uint w, uint h, const float *data, uint x, uint y)
{
- const uint bw = MIN(w - x, 4U);
- const uint bh = MIN(h - y, 4U);
-
- // Blocks that are smaller than 4x4 are handled by repeating the pixels.
- // @@ Thats only correct when block size is 1, 2 or 4, but not with 3. :(
- // @@ Ideally we should zero the weights of the pixels out of range.
-
- uint srcPlane = w * h;
-
- for (uint i = 0; i < 4; i++) {
- const uint by = i % bh;
-
- for (uint e = 0; e < 4; e++) {
- const uint bx = e % bw;
- const uint idx = ((y + by) * w + x + bx);
-
- Color32 & c = color(e, i);
- c.r = uint8(255 * CLAMP(data[idx + 0 * srcPlane], 0.0f, 1.0f)); // @@ Is this the right way to quantize floats to bytes?
- c.g = uint8(255 * CLAMP(data[idx + 1 * srcPlane], 0.0f, 1.0f));
- c.b = uint8(255 * CLAMP(data[idx + 2 * srcPlane], 0.0f, 1.0f));
- c.a = uint8(255 * CLAMP(data[idx + 3 * srcPlane], 0.0f, 1.0f));
- }
- }
+ const uint bw = MIN(w - x, 4U);
+ const uint bh = MIN(h - y, 4U);
+
+ // Blocks that are smaller than 4x4 are handled by repeating the pixels.
+ // @@ Thats only correct when block size is 1, 2 or 4, but not with 3. :(
+ // @@ Ideally we should zero the weights of the pixels out of range.
+
+ uint srcPlane = w * h;
+
+ for (uint i = 0; i < 4; i++) {
+ const uint by = i % bh;
+
+ for (uint e = 0; e < 4; e++) {
+ const uint bx = e % bw;
+ const uint idx = ((y + by) * w + x + bx);
+
+ Color32 &c = color(e, i);
+ c.r = uint8(255 * CLAMP(data[idx + 0 * srcPlane],
+ 0.0f,
+ 1.0f)); // @@ Is this the right way to quantize floats to bytes?
+ c.g = uint8(255 * CLAMP(data[idx + 1 * srcPlane], 0.0f, 1.0f));
+ c.b = uint8(255 * CLAMP(data[idx + 2 * srcPlane], 0.0f, 1.0f));
+ c.a = uint8(255 * CLAMP(data[idx + 3 * srcPlane], 0.0f, 1.0f));
+ }
+ }
}
static inline uint8 component(Color32 c, uint i)
{
- if (i == 0) return c.r;
- if (i == 1) return c.g;
- if (i == 2) return c.b;
- if (i == 3) return c.a;
- if (i == 4) return 0xFF;
- return 0;
+ if (i == 0)
+ return c.r;
+ if (i == 1)
+ return c.g;
+ if (i == 2)
+ return c.b;
+ if (i == 3)
+ return c.a;
+ if (i == 4)
+ return 0xFF;
+ return 0;
}
void ColorBlock::swizzle(uint x, uint y, uint z, uint w)
{
- for (int i = 0; i < 16; i++) {
- Color32 c = m_color[i];
- m_color[i].r = component(c, x);
- m_color[i].g = component(c, y);
- m_color[i].b = component(c, z);
- m_color[i].a = component(c, w);
- }
+ for (int i = 0; i < 16; i++) {
+ Color32 c = m_color[i];
+ m_color[i].r = component(c, x);
+ m_color[i].g = component(c, y);
+ m_color[i].b = component(c, z);
+ m_color[i].a = component(c, w);
+ }
}
-
/// Returns true if the block has a single color.
-bool ColorBlock::isSingleColor(Color32 mask/*= Color32(0xFF, 0xFF, 0xFF, 0x00)*/) const
+bool ColorBlock::isSingleColor(Color32 mask /*= Color32(0xFF, 0xFF, 0xFF, 0x00)*/) const
{
- uint u = m_color[0].u & mask.u;
+ uint u = m_color[0].u & mask.u;
- for (int i = 1; i < 16; i++) {
- if (u != (m_color[i].u & mask.u)) {
- return false;
- }
- }
+ for (int i = 1; i < 16; i++) {
+ if (u != (m_color[i].u & mask.u)) {
+ return false;
+ }
+ }
- return true;
+ return true;
}
#if 0
/// Returns true if the block has a single color, ignoring transparent pixels.
bool ColorBlock::isSingleColorNoAlpha() const
{
- Color32 c;
- int i;
- for (i = 0; i < 16; i++)
- {
- if (m_color[i].a != 0) c = m_color[i];
- }
-
- Color32 mask(0xFF, 0xFF, 0xFF, 0x00);
- uint u = c.u & mask.u;
-
- for (; i < 16; i++)
- {
- if (u != (m_color[i].u & mask.u))
- {
- return false;
- }
- }
-
- return true;
+ Color32 c;
+ int i;
+ for (i = 0; i < 16; i++)
+ {
+ if (m_color[i].a != 0) c = m_color[i];
+ }
+
+ Color32 mask(0xFF, 0xFF, 0xFF, 0x00);
+ uint u = c.u & mask.u;
+
+ for (; i < 16; i++)
+ {
+ if (u != (m_color[i].u & mask.u))
+ {
+ return false;
+ }
+ }
+
+ return true;
}
#endif
@@ -194,24 +197,24 @@ bool ColorBlock::isSingleColorNoAlpha() const
/// Count number of unique colors in this color block.
uint ColorBlock::countUniqueColors() const
{
- uint count = 0;
-
- // @@ This does not have to be o(n^2)
- for (int i = 0; i < 16; i++)
- {
- bool unique = true;
- for (int j = 0; j < i; j++) {
- if ( m_color[i] != m_color[j] ) {
- unique = false;
- }
- }
-
- if ( unique ) {
- count++;
- }
- }
-
- return count;
+ uint count = 0;
+
+ // @@ This does not have to be o(n^2)
+ for (int i = 0; i < 16; i++)
+ {
+ bool unique = true;
+ for (int j = 0; j < i; j++) {
+ if ( m_color[i] != m_color[j] ) {
+ unique = false;
+ }
+ }
+
+ if ( unique ) {
+ count++;
+ }
+ }
+
+ return count;
}
#endif
@@ -219,27 +222,28 @@ uint ColorBlock::countUniqueColors() const
/// Get average color of the block.
Color32 ColorBlock::averageColor() const
{
- uint r, g, b, a;
- r = g = b = a = 0;
+ uint r, g, b, a;
+ r = g = b = a = 0;
- for (uint i = 0; i < 16; i++) {
- r += m_color[i].r;
- g += m_color[i].g;
- b += m_color[i].b;
- a += m_color[i].a;
- }
+ for (uint i = 0; i < 16; i++) {
+ r += m_color[i].r;
+ g += m_color[i].g;
+ b += m_color[i].b;
+ a += m_color[i].a;
+ }
- return Color32(uint8(r / 16), uint8(g / 16), uint8(b / 16), uint8(a / 16));
+ return Color32(uint8(r / 16), uint8(g / 16), uint8(b / 16), uint8(a / 16));
}
#endif
/// Return true if the block is not fully opaque.
bool ColorBlock::hasAlpha() const
{
- for (uint i = 0; i < 16; i++) {
- if (m_color[i].a != 255) return true;
- }
- return false;
+ for (uint i = 0; i < 16; i++) {
+ if (m_color[i].a != 255)
+ return true;
+ }
+ return false;
}
#if 0
@@ -247,121 +251,121 @@ bool ColorBlock::hasAlpha() const
/// Get diameter color range.
void ColorBlock::diameterRange(Color32 *start, Color32 *end) const
{
- Color32 c0, c1;
- uint best_dist = 0;
-
- for (int i = 0; i < 16; i++) {
- for (int j = i+1; j < 16; j++) {
- uint dist = colorDistance(m_color[i], m_color[j]);
- if ( dist > best_dist ) {
- best_dist = dist;
- c0 = m_color[i];
- c1 = m_color[j];
- }
- }
- }
-
- *start = c0;
- *end = c1;
+ Color32 c0, c1;
+ uint best_dist = 0;
+
+ for (int i = 0; i < 16; i++) {
+ for (int j = i+1; j < 16; j++) {
+ uint dist = colorDistance(m_color[i], m_color[j]);
+ if ( dist > best_dist ) {
+ best_dist = dist;
+ c0 = m_color[i];
+ c1 = m_color[j];
+ }
+ }
+ }
+
+ *start = c0;
+ *end = c1;
}
/// Get luminance color range.
void ColorBlock::luminanceRange(Color32 *start, Color32 *end) const
{
- Color32 minColor, maxColor;
- uint minLuminance, maxLuminance;
-
- maxLuminance = minLuminance = colorLuminance(m_color[0]);
-
- for (uint i = 1; i < 16; i++)
- {
- uint luminance = colorLuminance(m_color[i]);
-
- if (luminance > maxLuminance) {
- maxLuminance = luminance;
- maxColor = m_color[i];
- }
- else if (luminance < minLuminance) {
- minLuminance = luminance;
- minColor = m_color[i];
- }
- }
-
- *start = minColor;
- *end = maxColor;
+ Color32 minColor, maxColor;
+ uint minLuminance, maxLuminance;
+
+ maxLuminance = minLuminance = colorLuminance(m_color[0]);
+
+ for (uint i = 1; i < 16; i++)
+ {
+ uint luminance = colorLuminance(m_color[i]);
+
+ if (luminance > maxLuminance) {
+ maxLuminance = luminance;
+ maxColor = m_color[i];
+ }
+ else if (luminance < minLuminance) {
+ minLuminance = luminance;
+ minColor = m_color[i];
+ }
+ }
+
+ *start = minColor;
+ *end = maxColor;
}
/// Get color range based on the bounding box.
void ColorBlock::boundsRange(Color32 *start, Color32 *end) const
{
- Color32 minColor(255, 255, 255);
- Color32 maxColor(0, 0, 0);
-
- for (uint i = 0; i < 16; i++)
- {
- if (m_color[i].r < minColor.r) { minColor.r = m_color[i].r; }
- if (m_color[i].g < minColor.g) { minColor.g = m_color[i].g; }
- if (m_color[i].b < minColor.b) { minColor.b = m_color[i].b; }
- if (m_color[i].r > maxColor.r) { maxColor.r = m_color[i].r; }
- if (m_color[i].g > maxColor.g) { maxColor.g = m_color[i].g; }
- if (m_color[i].b > maxColor.b) { maxColor.b = m_color[i].b; }
- }
-
- // Offset range by 1/16 of the extents
- Color32 inset;
- inset.r = (maxColor.r - minColor.r) >> 4;
- inset.g = (maxColor.g - minColor.g) >> 4;
- inset.b = (maxColor.b - minColor.b) >> 4;
-
- minColor.r = (minColor.r + inset.r <= 255) ? minColor.r + inset.r : 255;
- minColor.g = (minColor.g + inset.g <= 255) ? minColor.g + inset.g : 255;
- minColor.b = (minColor.b + inset.b <= 255) ? minColor.b + inset.b : 255;
-
- maxColor.r = (maxColor.r >= inset.r) ? maxColor.r - inset.r : 0;
- maxColor.g = (maxColor.g >= inset.g) ? maxColor.g - inset.g : 0;
- maxColor.b = (maxColor.b >= inset.b) ? maxColor.b - inset.b : 0;
-
- *start = minColor;
- *end = maxColor;
+ Color32 minColor(255, 255, 255);
+ Color32 maxColor(0, 0, 0);
+
+ for (uint i = 0; i < 16; i++)
+ {
+ if (m_color[i].r < minColor.r) { minColor.r = m_color[i].r; }
+ if (m_color[i].g < minColor.g) { minColor.g = m_color[i].g; }
+ if (m_color[i].b < minColor.b) { minColor.b = m_color[i].b; }
+ if (m_color[i].r > maxColor.r) { maxColor.r = m_color[i].r; }
+ if (m_color[i].g > maxColor.g) { maxColor.g = m_color[i].g; }
+ if (m_color[i].b > maxColor.b) { maxColor.b = m_color[i].b; }
+ }
+
+ // Offset range by 1/16 of the extents
+ Color32 inset;
+ inset.r = (maxColor.r - minColor.r) >> 4;
+ inset.g = (maxColor.g - minColor.g) >> 4;
+ inset.b = (maxColor.b - minColor.b) >> 4;
+
+ minColor.r = (minColor.r + inset.r <= 255) ? minColor.r + inset.r : 255;
+ minColor.g = (minColor.g + inset.g <= 255) ? minColor.g + inset.g : 255;
+ minColor.b = (minColor.b + inset.b <= 255) ? minColor.b + inset.b : 255;
+
+ maxColor.r = (maxColor.r >= inset.r) ? maxColor.r - inset.r : 0;
+ maxColor.g = (maxColor.g >= inset.g) ? maxColor.g - inset.g : 0;
+ maxColor.b = (maxColor.b >= inset.b) ? maxColor.b - inset.b : 0;
+
+ *start = minColor;
+ *end = maxColor;
}
/// Get color range based on the bounding box.
void ColorBlock::boundsRangeAlpha(Color32 *start, Color32 *end) const
{
- Color32 minColor(255, 255, 255, 255);
- Color32 maxColor(0, 0, 0, 0);
-
- for (uint i = 0; i < 16; i++)
- {
- if (m_color[i].r < minColor.r) { minColor.r = m_color[i].r; }
- if (m_color[i].g < minColor.g) { minColor.g = m_color[i].g; }
- if (m_color[i].b < minColor.b) { minColor.b = m_color[i].b; }
- if (m_color[i].a < minColor.a) { minColor.a = m_color[i].a; }
- if (m_color[i].r > maxColor.r) { maxColor.r = m_color[i].r; }
- if (m_color[i].g > maxColor.g) { maxColor.g = m_color[i].g; }
- if (m_color[i].b > maxColor.b) { maxColor.b = m_color[i].b; }
- if (m_color[i].a > maxColor.a) { maxColor.a = m_color[i].a; }
- }
-
- // Offset range by 1/16 of the extents
- Color32 inset;
- inset.r = (maxColor.r - minColor.r) >> 4;
- inset.g = (maxColor.g - minColor.g) >> 4;
- inset.b = (maxColor.b - minColor.b) >> 4;
- inset.a = (maxColor.a - minColor.a) >> 4;
-
- minColor.r = (minColor.r + inset.r <= 255) ? minColor.r + inset.r : 255;
- minColor.g = (minColor.g + inset.g <= 255) ? minColor.g + inset.g : 255;
- minColor.b = (minColor.b + inset.b <= 255) ? minColor.b + inset.b : 255;
- minColor.a = (minColor.a + inset.a <= 255) ? minColor.a + inset.a : 255;
-
- maxColor.r = (maxColor.r >= inset.r) ? maxColor.r - inset.r : 0;
- maxColor.g = (maxColor.g >= inset.g) ? maxColor.g - inset.g : 0;
- maxColor.b = (maxColor.b >= inset.b) ? maxColor.b - inset.b : 0;
- maxColor.a = (maxColor.a >= inset.a) ? maxColor.a - inset.a : 0;
-
- *start = minColor;
- *end = maxColor;
+ Color32 minColor(255, 255, 255, 255);
+ Color32 maxColor(0, 0, 0, 0);
+
+ for (uint i = 0; i < 16; i++)
+ {
+ if (m_color[i].r < minColor.r) { minColor.r = m_color[i].r; }
+ if (m_color[i].g < minColor.g) { minColor.g = m_color[i].g; }
+ if (m_color[i].b < minColor.b) { minColor.b = m_color[i].b; }
+ if (m_color[i].a < minColor.a) { minColor.a = m_color[i].a; }
+ if (m_color[i].r > maxColor.r) { maxColor.r = m_color[i].r; }
+ if (m_color[i].g > maxColor.g) { maxColor.g = m_color[i].g; }
+ if (m_color[i].b > maxColor.b) { maxColor.b = m_color[i].b; }
+ if (m_color[i].a > maxColor.a) { maxColor.a = m_color[i].a; }
+ }
+
+ // Offset range by 1/16 of the extents
+ Color32 inset;
+ inset.r = (maxColor.r - minColor.r) >> 4;
+ inset.g = (maxColor.g - minColor.g) >> 4;
+ inset.b = (maxColor.b - minColor.b) >> 4;
+ inset.a = (maxColor.a - minColor.a) >> 4;
+
+ minColor.r = (minColor.r + inset.r <= 255) ? minColor.r + inset.r : 255;
+ minColor.g = (minColor.g + inset.g <= 255) ? minColor.g + inset.g : 255;
+ minColor.b = (minColor.b + inset.b <= 255) ? minColor.b + inset.b : 255;
+ minColor.a = (minColor.a + inset.a <= 255) ? minColor.a + inset.a : 255;
+
+ maxColor.r = (maxColor.r >= inset.r) ? maxColor.r - inset.r : 0;
+ maxColor.g = (maxColor.g >= inset.g) ? maxColor.g - inset.g : 0;
+ maxColor.b = (maxColor.b >= inset.b) ? maxColor.b - inset.b : 0;
+ maxColor.a = (maxColor.a >= inset.a) ? maxColor.a - inset.a : 0;
+
+ *start = minColor;
+ *end = maxColor;
}
#endif
@@ -369,21 +373,21 @@ void ColorBlock::boundsRangeAlpha(Color32 *start, Color32 *end) const
/// Sort colors by abosolute value in their 16 bit representation.
void ColorBlock::sortColorsByAbsoluteValue()
{
- // Dummy selection sort.
- for ( uint a = 0; a < 16; a++ ) {
- uint max = a;
- Color16 cmax(m_color[a]);
-
- for ( uint b = a+1; b < 16; b++ ) {
- Color16 cb(m_color[b]);
-
- if ( cb.u > cmax.u ) {
- max = b;
- cmax = cb;
- }
- }
- swap( m_color[a], m_color[max] );
- }
+ // Dummy selection sort.
+ for ( uint a = 0; a < 16; a++ ) {
+ uint max = a;
+ Color16 cmax(m_color[a]);
+
+ for ( uint b = a+1; b < 16; b++ ) {
+ Color16 cb(m_color[b]);
+
+ if ( cb.u > cmax.u ) {
+ max = b;
+ cmax = cb;
+ }
+ }
+ swap( m_color[a], m_color[max] );
+ }
}
#endif
@@ -392,29 +396,29 @@ void ColorBlock::sortColorsByAbsoluteValue()
void ColorBlock::computeRange(Vector3::Arg axis, Color32 *start, Color32 *end) const
{
- int mini, maxi;
- mini = maxi = 0;
-
- float min, max;
- min = max = dot(Vector3(m_color[0].r, m_color[0].g, m_color[0].b), axis);
-
- for (uint i = 1; i < 16; i++)
- {
- const Vector3 vec(m_color[i].r, m_color[i].g, m_color[i].b);
-
- float val = dot(vec, axis);
- if ( val < min ) {
- mini = i;
- min = val;
- }
- else if ( val > max ) {
- maxi = i;
- max = val;
- }
- }
-
- *start = m_color[mini];
- *end = m_color[maxi];
+ int mini, maxi;
+ mini = maxi = 0;
+
+ float min, max;
+ min = max = dot(Vector3(m_color[0].r, m_color[0].g, m_color[0].b), axis);
+
+ for (uint i = 1; i < 16; i++)
+ {
+ const Vector3 vec(m_color[i].r, m_color[i].g, m_color[i].b);
+
+ float val = dot(vec, axis);
+ if ( val < min ) {
+ mini = i;
+ min = val;
+ }
+ else if ( val > max ) {
+ maxi = i;
+ max = val;
+ }
+ }
+
+ *start = m_color[mini];
+ *end = m_color[maxi];
}
#endif
@@ -422,24 +426,24 @@ void ColorBlock::computeRange(Vector3::Arg axis, Color32 *start, Color32 *end) c
/// Sort colors in the given axis.
void ColorBlock::sortColors(const Vector3 & axis)
{
- float luma_array[16];
-
- for (uint i = 0; i < 16; i++) {
- const Vector3 vec(m_color[i].r, m_color[i].g, m_color[i].b);
- luma_array[i] = dot(vec, axis);
- }
-
- // Dummy selection sort.
- for ( uint a = 0; a < 16; a++ ) {
- uint min = a;
- for ( uint b = a+1; b < 16; b++ ) {
- if ( luma_array[b] < luma_array[min] ) {
- min = b;
- }
- }
- swap( luma_array[a], luma_array[min] );
- swap( m_color[a], m_color[min] );
- }
+ float luma_array[16];
+
+ for (uint i = 0; i < 16; i++) {
+ const Vector3 vec(m_color[i].r, m_color[i].g, m_color[i].b);
+ luma_array[i] = dot(vec, axis);
+ }
+
+ // Dummy selection sort.
+ for ( uint a = 0; a < 16; a++ ) {
+ uint min = a;
+ for ( uint b = a+1; b < 16; b++ ) {
+ if ( luma_array[b] < luma_array[min] ) {
+ min = b;
+ }
+ }
+ swap( luma_array[a], luma_array[min] );
+ swap( m_color[a], m_color[min] );
+ }
}
#endif
@@ -447,14 +451,14 @@ void ColorBlock::sortColors(const Vector3 & axis)
/// Get the volume of the color block.
float ColorBlock::volume() const
{
- Box bounds;
- bounds.clearBounds();
+ Box bounds;
+ bounds.clearBounds();
- for (int i = 0; i < 16; i++) {
- const Vector3 point(m_color[i].r, m_color[i].g, m_color[i].b);
- bounds.addPointToBounds(point);
- }
+ for (int i = 0; i < 16; i++) {
+ const Vector3 point(m_color[i].r, m_color[i].g, m_color[i].b);
+ bounds.addPointToBounds(point);
+ }
- return bounds.volume();
+ return bounds.volume();
}
#endif
diff --git a/source/blender/imbuf/intern/dds/ColorBlock.h b/source/blender/imbuf/intern/dds/ColorBlock.h
index 66d1ed4e2c5..2e8a6bbda7f 100644
--- a/source/blender/imbuf/intern/dds/ColorBlock.h
+++ b/source/blender/imbuf/intern/dds/ColorBlock.h
@@ -18,7 +18,6 @@
* \ingroup imbdds
*/
-
/*
* This file is based on a similar file from the NVIDIA texture tools
* (http://nvidia-texture-tools.googlecode.com/)
@@ -36,65 +35,61 @@
/// Uncompressed 4x4 color block.
struct ColorBlock {
- ColorBlock();
- ColorBlock(const uint * linearImage);
- ColorBlock(const ColorBlock & block);
- ColorBlock(const Image *img, uint x, uint y);
-
- void init(const Image *img, uint x, uint y);
- void init(uint w, uint h, const uint * data, uint x, uint y);
- void init(uint w, uint h, const float * data, uint x, uint y);
-
- void swizzle(uint x, uint y, uint z, uint w); // 0=r, 1=g, 2=b, 3=a, 4=0xFF, 5=0
+ ColorBlock();
+ ColorBlock(const uint *linearImage);
+ ColorBlock(const ColorBlock &block);
+ ColorBlock(const Image *img, uint x, uint y);
- bool isSingleColor(Color32 mask = Color32(0xFF, 0xFF, 0xFF, 0x00)) const;
- bool hasAlpha() const;
+ void init(const Image *img, uint x, uint y);
+ void init(uint w, uint h, const uint *data, uint x, uint y);
+ void init(uint w, uint h, const float *data, uint x, uint y);
+ void swizzle(uint x, uint y, uint z, uint w); // 0=r, 1=g, 2=b, 3=a, 4=0xFF, 5=0
- // Accessors
- const Color32 * colors() const;
+ bool isSingleColor(Color32 mask = Color32(0xFF, 0xFF, 0xFF, 0x00)) const;
+ bool hasAlpha() const;
- Color32 color(uint i) const;
- Color32 & color(uint i);
+ // Accessors
+ const Color32 *colors() const;
- Color32 color(uint x, uint y) const;
- Color32 & color(uint x, uint y);
+ Color32 color(uint i) const;
+ Color32 &color(uint i);
-private:
-
- Color32 m_color[4 * 4];
+ Color32 color(uint x, uint y) const;
+ Color32 &color(uint x, uint y);
+ private:
+ Color32 m_color[4 * 4];
};
-
/// Get pointer to block colors.
-inline const Color32 * ColorBlock::colors() const
+inline const Color32 *ColorBlock::colors() const
{
- return m_color;
+ return m_color;
}
/// Get block color.
inline Color32 ColorBlock::color(uint i) const
{
- return m_color[i];
+ return m_color[i];
}
/// Get block color.
-inline Color32 & ColorBlock::color(uint i)
+inline Color32 &ColorBlock::color(uint i)
{
- return m_color[i];
+ return m_color[i];
}
/// Get block color.
inline Color32 ColorBlock::color(uint x, uint y) const
{
- return m_color[y * 4 + x];
+ return m_color[y * 4 + x];
}
/// Get block color.
-inline Color32 & ColorBlock::color(uint x, uint y)
+inline Color32 &ColorBlock::color(uint x, uint y)
{
- return m_color[y * 4 + x];
+ return m_color[y * 4 + x];
}
-#endif /* __COLORBLOCK_H__ */
+#endif /* __COLORBLOCK_H__ */
diff --git a/source/blender/imbuf/intern/dds/Common.h b/source/blender/imbuf/intern/dds/Common.h
index 1a7d087ec2e..56f5d54cf42 100644
--- a/source/blender/imbuf/intern/dds/Common.h
+++ b/source/blender/imbuf/intern/dds/Common.h
@@ -18,39 +18,36 @@
* \ingroup imbdds
*/
-
#ifndef __COMMON_H__
#define __COMMON_H__
#ifndef MIN
-#define MIN(a,b) ((a) <= (b) ? (a) : (b))
+# define MIN(a, b) ((a) <= (b) ? (a) : (b))
#endif
#ifndef MAX
-#define MAX(a,b) ((a) >= (b) ? (a) : (b))
+# define MAX(a, b) ((a) >= (b) ? (a) : (b))
#endif
#ifndef CLAMP
-#define CLAMP(x,a,b) MIN(MAX((x), (a)), (b))
+# define CLAMP(x, a, b) MIN(MAX((x), (a)), (b))
#endif
-template<typename T>
-inline void
-swap(T & a, T & b)
+template<typename T> inline void swap(T &a, T &b)
{
- T tmp = a;
- a = b;
- b = tmp;
+ T tmp = a;
+ a = b;
+ b = tmp;
}
-typedef unsigned char uint8;
-typedef unsigned short uint16;
-typedef unsigned int uint;
-typedef unsigned int uint32;
+typedef unsigned char uint8;
+typedef unsigned short uint16;
+typedef unsigned int uint;
+typedef unsigned int uint32;
typedef unsigned long long uint64;
// copied from nvtt src/nvimage/nvimage.h
inline uint computePitch(uint w, uint bitsize, uint alignment)
{
- return ((w * bitsize + 8 * alignment - 1) / (8 * alignment)) * alignment;
+ return ((w * bitsize + 8 * alignment - 1) / (8 * alignment)) * alignment;
}
#endif
diff --git a/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp b/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp
index 76de84cdee5..3db9b65c461 100644
--- a/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp
+++ b/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp
@@ -18,7 +18,6 @@
* \ingroup imbdds
*/
-
/*
* This file is based on a similar file from the NVIDIA texture tools
* (http://nvidia-texture-tools.googlecode.com/)
@@ -53,17 +52,17 @@
#include <BlockDXT.h>
#include <PixelFormat.h>
-#include <stdio.h> // printf
+#include <stdio.h> // printf
#include <stdlib.h> // malloc
-#include <math.h> // sqrt
+#include <math.h> // sqrt
#include <sys/types.h>
/*** declarations ***/
#if !defined(DDS_MAKEFOURCC)
-# define DDS_MAKEFOURCC(ch0, ch1, ch2, ch3) \
- (uint(uint8(ch0)) | (uint(uint8(ch1)) << 8) | \
- (uint(uint8(ch2)) << 16) | (uint(uint8(ch3)) << 24 ))
+# define DDS_MAKEFOURCC(ch0, ch1, ch2, ch3) \
+ (uint(uint8(ch0)) | (uint(uint8(ch1)) << 8) | (uint(uint8(ch2)) << 16) | \
+ (uint(uint8(ch3)) << 24))
#endif
static const uint FOURCC_NVTT = DDS_MAKEFOURCC('N', 'V', 'T', 'T');
@@ -159,727 +158,716 @@ static const uint DDPF_ALPHAPREMULT = 0x00008000U;
static const uint DDPF_NORMAL = 0x80000000U;
static const uint DDPF_SRGB = 0x40000000U;
- // DX10 formats.
- enum DXGI_FORMAT
- {
- DXGI_FORMAT_UNKNOWN = 0,
-
- DXGI_FORMAT_R32G32B32A32_TYPELESS = 1,
- DXGI_FORMAT_R32G32B32A32_FLOAT = 2,
- DXGI_FORMAT_R32G32B32A32_UINT = 3,
- DXGI_FORMAT_R32G32B32A32_SINT = 4,
-
- DXGI_FORMAT_R32G32B32_TYPELESS = 5,
- DXGI_FORMAT_R32G32B32_FLOAT = 6,
- DXGI_FORMAT_R32G32B32_UINT = 7,
- DXGI_FORMAT_R32G32B32_SINT = 8,
-
- DXGI_FORMAT_R16G16B16A16_TYPELESS = 9,
- DXGI_FORMAT_R16G16B16A16_FLOAT = 10,
- DXGI_FORMAT_R16G16B16A16_UNORM = 11,
- DXGI_FORMAT_R16G16B16A16_UINT = 12,
- DXGI_FORMAT_R16G16B16A16_SNORM = 13,
- DXGI_FORMAT_R16G16B16A16_SINT = 14,
-
- DXGI_FORMAT_R32G32_TYPELESS = 15,
- DXGI_FORMAT_R32G32_FLOAT = 16,
- DXGI_FORMAT_R32G32_UINT = 17,
- DXGI_FORMAT_R32G32_SINT = 18,
-
- DXGI_FORMAT_R32G8X24_TYPELESS = 19,
- DXGI_FORMAT_D32_FLOAT_S8X24_UINT = 20,
- DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS = 21,
- DXGI_FORMAT_X32_TYPELESS_G8X24_UINT = 22,
-
- DXGI_FORMAT_R10G10B10A2_TYPELESS = 23,
- DXGI_FORMAT_R10G10B10A2_UNORM = 24,
- DXGI_FORMAT_R10G10B10A2_UINT = 25,
-
- DXGI_FORMAT_R11G11B10_FLOAT = 26,
-
- DXGI_FORMAT_R8G8B8A8_TYPELESS = 27,
- DXGI_FORMAT_R8G8B8A8_UNORM = 28,
- DXGI_FORMAT_R8G8B8A8_UNORM_SRGB = 29,
- DXGI_FORMAT_R8G8B8A8_UINT = 30,
- DXGI_FORMAT_R8G8B8A8_SNORM = 31,
- DXGI_FORMAT_R8G8B8A8_SINT = 32,
-
- DXGI_FORMAT_R16G16_TYPELESS = 33,
- DXGI_FORMAT_R16G16_FLOAT = 34,
- DXGI_FORMAT_R16G16_UNORM = 35,
- DXGI_FORMAT_R16G16_UINT = 36,
- DXGI_FORMAT_R16G16_SNORM = 37,
- DXGI_FORMAT_R16G16_SINT = 38,
-
- DXGI_FORMAT_R32_TYPELESS = 39,
- DXGI_FORMAT_D32_FLOAT = 40,
- DXGI_FORMAT_R32_FLOAT = 41,
- DXGI_FORMAT_R32_UINT = 42,
- DXGI_FORMAT_R32_SINT = 43,
-
- DXGI_FORMAT_R24G8_TYPELESS = 44,
- DXGI_FORMAT_D24_UNORM_S8_UINT = 45,
- DXGI_FORMAT_R24_UNORM_X8_TYPELESS = 46,
- DXGI_FORMAT_X24_TYPELESS_G8_UINT = 47,
-
- DXGI_FORMAT_R8G8_TYPELESS = 48,
- DXGI_FORMAT_R8G8_UNORM = 49,
- DXGI_FORMAT_R8G8_UINT = 50,
- DXGI_FORMAT_R8G8_SNORM = 51,
- DXGI_FORMAT_R8G8_SINT = 52,
-
- DXGI_FORMAT_R16_TYPELESS = 53,
- DXGI_FORMAT_R16_FLOAT = 54,
- DXGI_FORMAT_D16_UNORM = 55,
- DXGI_FORMAT_R16_UNORM = 56,
- DXGI_FORMAT_R16_UINT = 57,
- DXGI_FORMAT_R16_SNORM = 58,
- DXGI_FORMAT_R16_SINT = 59,
-
- DXGI_FORMAT_R8_TYPELESS = 60,
- DXGI_FORMAT_R8_UNORM = 61,
- DXGI_FORMAT_R8_UINT = 62,
- DXGI_FORMAT_R8_SNORM = 63,
- DXGI_FORMAT_R8_SINT = 64,
- DXGI_FORMAT_A8_UNORM = 65,
-
- DXGI_FORMAT_R1_UNORM = 66,
-
- DXGI_FORMAT_R9G9B9E5_SHAREDEXP = 67,
-
- DXGI_FORMAT_R8G8_B8G8_UNORM = 68,
- DXGI_FORMAT_G8R8_G8B8_UNORM = 69,
-
- DXGI_FORMAT_BC1_TYPELESS = 70,
- DXGI_FORMAT_BC1_UNORM = 71,
- DXGI_FORMAT_BC1_UNORM_SRGB = 72,
-
- DXGI_FORMAT_BC2_TYPELESS = 73,
- DXGI_FORMAT_BC2_UNORM = 74,
- DXGI_FORMAT_BC2_UNORM_SRGB = 75,
-
- DXGI_FORMAT_BC3_TYPELESS = 76,
- DXGI_FORMAT_BC3_UNORM = 77,
- DXGI_FORMAT_BC3_UNORM_SRGB = 78,
-
- DXGI_FORMAT_BC4_TYPELESS = 79,
- DXGI_FORMAT_BC4_UNORM = 80,
- DXGI_FORMAT_BC4_SNORM = 81,
-
- DXGI_FORMAT_BC5_TYPELESS = 82,
- DXGI_FORMAT_BC5_UNORM = 83,
- DXGI_FORMAT_BC5_SNORM = 84,
-
- DXGI_FORMAT_B5G6R5_UNORM = 85,
- DXGI_FORMAT_B5G5R5A1_UNORM = 86,
- DXGI_FORMAT_B8G8R8A8_UNORM = 87,
- DXGI_FORMAT_B8G8R8X8_UNORM = 88,
-
- DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM = 89,
- DXGI_FORMAT_B8G8R8A8_TYPELESS = 90,
- DXGI_FORMAT_B8G8R8A8_UNORM_SRGB = 91,
- DXGI_FORMAT_B8G8R8X8_TYPELESS = 92,
- DXGI_FORMAT_B8G8R8X8_UNORM_SRGB = 93,
-
- DXGI_FORMAT_BC6H_TYPELESS = 94,
- DXGI_FORMAT_BC6H_UF16 = 95,
- DXGI_FORMAT_BC6H_SF16 = 96,
-
- DXGI_FORMAT_BC7_TYPELESS = 97,
- DXGI_FORMAT_BC7_UNORM = 98,
- DXGI_FORMAT_BC7_UNORM_SRGB = 99,
- };
-
- enum D3D10_RESOURCE_DIMENSION
- {
- D3D10_RESOURCE_DIMENSION_UNKNOWN = 0,
- D3D10_RESOURCE_DIMENSION_BUFFER = 1,
- D3D10_RESOURCE_DIMENSION_TEXTURE1D = 2,
- D3D10_RESOURCE_DIMENSION_TEXTURE2D = 3,
- D3D10_RESOURCE_DIMENSION_TEXTURE3D = 4,
- };
-
-
- static const char * getDxgiFormatString(DXGI_FORMAT dxgiFormat)
- {
-#define CASE(format) case DXGI_FORMAT_##format: return #format
- switch (dxgiFormat)
- {
- CASE(UNKNOWN);
-
- CASE(R32G32B32A32_TYPELESS);
- CASE(R32G32B32A32_FLOAT);
- CASE(R32G32B32A32_UINT);
- CASE(R32G32B32A32_SINT);
-
- CASE(R32G32B32_TYPELESS);
- CASE(R32G32B32_FLOAT);
- CASE(R32G32B32_UINT);
- CASE(R32G32B32_SINT);
-
- CASE(R16G16B16A16_TYPELESS);
- CASE(R16G16B16A16_FLOAT);
- CASE(R16G16B16A16_UNORM);
- CASE(R16G16B16A16_UINT);
- CASE(R16G16B16A16_SNORM);
- CASE(R16G16B16A16_SINT);
-
- CASE(R32G32_TYPELESS);
- CASE(R32G32_FLOAT);
- CASE(R32G32_UINT);
- CASE(R32G32_SINT);
-
- CASE(R32G8X24_TYPELESS);
- CASE(D32_FLOAT_S8X24_UINT);
- CASE(R32_FLOAT_X8X24_TYPELESS);
- CASE(X32_TYPELESS_G8X24_UINT);
-
- CASE(R10G10B10A2_TYPELESS);
- CASE(R10G10B10A2_UNORM);
- CASE(R10G10B10A2_UINT);
-
- CASE(R11G11B10_FLOAT);
-
- CASE(R8G8B8A8_TYPELESS);
- CASE(R8G8B8A8_UNORM);
- CASE(R8G8B8A8_UNORM_SRGB);
- CASE(R8G8B8A8_UINT);
- CASE(R8G8B8A8_SNORM);
- CASE(R8G8B8A8_SINT);
-
- CASE(R16G16_TYPELESS);
- CASE(R16G16_FLOAT);
- CASE(R16G16_UNORM);
- CASE(R16G16_UINT);
- CASE(R16G16_SNORM);
- CASE(R16G16_SINT);
-
- CASE(R32_TYPELESS);
- CASE(D32_FLOAT);
- CASE(R32_FLOAT);
- CASE(R32_UINT);
- CASE(R32_SINT);
-
- CASE(R24G8_TYPELESS);
- CASE(D24_UNORM_S8_UINT);
- CASE(R24_UNORM_X8_TYPELESS);
- CASE(X24_TYPELESS_G8_UINT);
-
- CASE(R8G8_TYPELESS);
- CASE(R8G8_UNORM);
- CASE(R8G8_UINT);
- CASE(R8G8_SNORM);
- CASE(R8G8_SINT);
-
- CASE(R16_TYPELESS);
- CASE(R16_FLOAT);
- CASE(D16_UNORM);
- CASE(R16_UNORM);
- CASE(R16_UINT);
- CASE(R16_SNORM);
- CASE(R16_SINT);
-
- CASE(R8_TYPELESS);
- CASE(R8_UNORM);
- CASE(R8_UINT);
- CASE(R8_SNORM);
- CASE(R8_SINT);
- CASE(A8_UNORM);
-
- CASE(R1_UNORM);
-
- CASE(R9G9B9E5_SHAREDEXP);
-
- CASE(R8G8_B8G8_UNORM);
- CASE(G8R8_G8B8_UNORM);
-
- CASE(BC1_TYPELESS);
- CASE(BC1_UNORM);
- CASE(BC1_UNORM_SRGB);
-
- CASE(BC2_TYPELESS);
- CASE(BC2_UNORM);
- CASE(BC2_UNORM_SRGB);
-
- CASE(BC3_TYPELESS);
- CASE(BC3_UNORM);
- CASE(BC3_UNORM_SRGB);
-
- CASE(BC4_TYPELESS);
- CASE(BC4_UNORM);
- CASE(BC4_SNORM);
-
- CASE(BC5_TYPELESS);
- CASE(BC5_UNORM);
- CASE(BC5_SNORM);
-
- CASE(B5G6R5_UNORM);
- CASE(B5G5R5A1_UNORM);
- CASE(B8G8R8A8_UNORM);
- CASE(B8G8R8X8_UNORM);
-
- default:
- return "UNKNOWN";
- }
+// DX10 formats.
+enum DXGI_FORMAT {
+ DXGI_FORMAT_UNKNOWN = 0,
+
+ DXGI_FORMAT_R32G32B32A32_TYPELESS = 1,
+ DXGI_FORMAT_R32G32B32A32_FLOAT = 2,
+ DXGI_FORMAT_R32G32B32A32_UINT = 3,
+ DXGI_FORMAT_R32G32B32A32_SINT = 4,
+
+ DXGI_FORMAT_R32G32B32_TYPELESS = 5,
+ DXGI_FORMAT_R32G32B32_FLOAT = 6,
+ DXGI_FORMAT_R32G32B32_UINT = 7,
+ DXGI_FORMAT_R32G32B32_SINT = 8,
+
+ DXGI_FORMAT_R16G16B16A16_TYPELESS = 9,
+ DXGI_FORMAT_R16G16B16A16_FLOAT = 10,
+ DXGI_FORMAT_R16G16B16A16_UNORM = 11,
+ DXGI_FORMAT_R16G16B16A16_UINT = 12,
+ DXGI_FORMAT_R16G16B16A16_SNORM = 13,
+ DXGI_FORMAT_R16G16B16A16_SINT = 14,
+
+ DXGI_FORMAT_R32G32_TYPELESS = 15,
+ DXGI_FORMAT_R32G32_FLOAT = 16,
+ DXGI_FORMAT_R32G32_UINT = 17,
+ DXGI_FORMAT_R32G32_SINT = 18,
+
+ DXGI_FORMAT_R32G8X24_TYPELESS = 19,
+ DXGI_FORMAT_D32_FLOAT_S8X24_UINT = 20,
+ DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS = 21,
+ DXGI_FORMAT_X32_TYPELESS_G8X24_UINT = 22,
+
+ DXGI_FORMAT_R10G10B10A2_TYPELESS = 23,
+ DXGI_FORMAT_R10G10B10A2_UNORM = 24,
+ DXGI_FORMAT_R10G10B10A2_UINT = 25,
+
+ DXGI_FORMAT_R11G11B10_FLOAT = 26,
+
+ DXGI_FORMAT_R8G8B8A8_TYPELESS = 27,
+ DXGI_FORMAT_R8G8B8A8_UNORM = 28,
+ DXGI_FORMAT_R8G8B8A8_UNORM_SRGB = 29,
+ DXGI_FORMAT_R8G8B8A8_UINT = 30,
+ DXGI_FORMAT_R8G8B8A8_SNORM = 31,
+ DXGI_FORMAT_R8G8B8A8_SINT = 32,
+
+ DXGI_FORMAT_R16G16_TYPELESS = 33,
+ DXGI_FORMAT_R16G16_FLOAT = 34,
+ DXGI_FORMAT_R16G16_UNORM = 35,
+ DXGI_FORMAT_R16G16_UINT = 36,
+ DXGI_FORMAT_R16G16_SNORM = 37,
+ DXGI_FORMAT_R16G16_SINT = 38,
+
+ DXGI_FORMAT_R32_TYPELESS = 39,
+ DXGI_FORMAT_D32_FLOAT = 40,
+ DXGI_FORMAT_R32_FLOAT = 41,
+ DXGI_FORMAT_R32_UINT = 42,
+ DXGI_FORMAT_R32_SINT = 43,
+
+ DXGI_FORMAT_R24G8_TYPELESS = 44,
+ DXGI_FORMAT_D24_UNORM_S8_UINT = 45,
+ DXGI_FORMAT_R24_UNORM_X8_TYPELESS = 46,
+ DXGI_FORMAT_X24_TYPELESS_G8_UINT = 47,
+
+ DXGI_FORMAT_R8G8_TYPELESS = 48,
+ DXGI_FORMAT_R8G8_UNORM = 49,
+ DXGI_FORMAT_R8G8_UINT = 50,
+ DXGI_FORMAT_R8G8_SNORM = 51,
+ DXGI_FORMAT_R8G8_SINT = 52,
+
+ DXGI_FORMAT_R16_TYPELESS = 53,
+ DXGI_FORMAT_R16_FLOAT = 54,
+ DXGI_FORMAT_D16_UNORM = 55,
+ DXGI_FORMAT_R16_UNORM = 56,
+ DXGI_FORMAT_R16_UINT = 57,
+ DXGI_FORMAT_R16_SNORM = 58,
+ DXGI_FORMAT_R16_SINT = 59,
+
+ DXGI_FORMAT_R8_TYPELESS = 60,
+ DXGI_FORMAT_R8_UNORM = 61,
+ DXGI_FORMAT_R8_UINT = 62,
+ DXGI_FORMAT_R8_SNORM = 63,
+ DXGI_FORMAT_R8_SINT = 64,
+ DXGI_FORMAT_A8_UNORM = 65,
+
+ DXGI_FORMAT_R1_UNORM = 66,
+
+ DXGI_FORMAT_R9G9B9E5_SHAREDEXP = 67,
+
+ DXGI_FORMAT_R8G8_B8G8_UNORM = 68,
+ DXGI_FORMAT_G8R8_G8B8_UNORM = 69,
+
+ DXGI_FORMAT_BC1_TYPELESS = 70,
+ DXGI_FORMAT_BC1_UNORM = 71,
+ DXGI_FORMAT_BC1_UNORM_SRGB = 72,
+
+ DXGI_FORMAT_BC2_TYPELESS = 73,
+ DXGI_FORMAT_BC2_UNORM = 74,
+ DXGI_FORMAT_BC2_UNORM_SRGB = 75,
+
+ DXGI_FORMAT_BC3_TYPELESS = 76,
+ DXGI_FORMAT_BC3_UNORM = 77,
+ DXGI_FORMAT_BC3_UNORM_SRGB = 78,
+
+ DXGI_FORMAT_BC4_TYPELESS = 79,
+ DXGI_FORMAT_BC4_UNORM = 80,
+ DXGI_FORMAT_BC4_SNORM = 81,
+
+ DXGI_FORMAT_BC5_TYPELESS = 82,
+ DXGI_FORMAT_BC5_UNORM = 83,
+ DXGI_FORMAT_BC5_SNORM = 84,
+
+ DXGI_FORMAT_B5G6R5_UNORM = 85,
+ DXGI_FORMAT_B5G5R5A1_UNORM = 86,
+ DXGI_FORMAT_B8G8R8A8_UNORM = 87,
+ DXGI_FORMAT_B8G8R8X8_UNORM = 88,
+
+ DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM = 89,
+ DXGI_FORMAT_B8G8R8A8_TYPELESS = 90,
+ DXGI_FORMAT_B8G8R8A8_UNORM_SRGB = 91,
+ DXGI_FORMAT_B8G8R8X8_TYPELESS = 92,
+ DXGI_FORMAT_B8G8R8X8_UNORM_SRGB = 93,
+
+ DXGI_FORMAT_BC6H_TYPELESS = 94,
+ DXGI_FORMAT_BC6H_UF16 = 95,
+ DXGI_FORMAT_BC6H_SF16 = 96,
+
+ DXGI_FORMAT_BC7_TYPELESS = 97,
+ DXGI_FORMAT_BC7_UNORM = 98,
+ DXGI_FORMAT_BC7_UNORM_SRGB = 99,
+};
+
+enum D3D10_RESOURCE_DIMENSION {
+ D3D10_RESOURCE_DIMENSION_UNKNOWN = 0,
+ D3D10_RESOURCE_DIMENSION_BUFFER = 1,
+ D3D10_RESOURCE_DIMENSION_TEXTURE1D = 2,
+ D3D10_RESOURCE_DIMENSION_TEXTURE2D = 3,
+ D3D10_RESOURCE_DIMENSION_TEXTURE3D = 4,
+};
+
+static const char *getDxgiFormatString(DXGI_FORMAT dxgiFormat)
+{
+#define CASE(format) \
+ case DXGI_FORMAT_##format: \
+ return #format
+ switch (dxgiFormat) {
+ CASE(UNKNOWN);
+
+ CASE(R32G32B32A32_TYPELESS);
+ CASE(R32G32B32A32_FLOAT);
+ CASE(R32G32B32A32_UINT);
+ CASE(R32G32B32A32_SINT);
+
+ CASE(R32G32B32_TYPELESS);
+ CASE(R32G32B32_FLOAT);
+ CASE(R32G32B32_UINT);
+ CASE(R32G32B32_SINT);
+
+ CASE(R16G16B16A16_TYPELESS);
+ CASE(R16G16B16A16_FLOAT);
+ CASE(R16G16B16A16_UNORM);
+ CASE(R16G16B16A16_UINT);
+ CASE(R16G16B16A16_SNORM);
+ CASE(R16G16B16A16_SINT);
+
+ CASE(R32G32_TYPELESS);
+ CASE(R32G32_FLOAT);
+ CASE(R32G32_UINT);
+ CASE(R32G32_SINT);
+
+ CASE(R32G8X24_TYPELESS);
+ CASE(D32_FLOAT_S8X24_UINT);
+ CASE(R32_FLOAT_X8X24_TYPELESS);
+ CASE(X32_TYPELESS_G8X24_UINT);
+
+ CASE(R10G10B10A2_TYPELESS);
+ CASE(R10G10B10A2_UNORM);
+ CASE(R10G10B10A2_UINT);
+
+ CASE(R11G11B10_FLOAT);
+
+ CASE(R8G8B8A8_TYPELESS);
+ CASE(R8G8B8A8_UNORM);
+ CASE(R8G8B8A8_UNORM_SRGB);
+ CASE(R8G8B8A8_UINT);
+ CASE(R8G8B8A8_SNORM);
+ CASE(R8G8B8A8_SINT);
+
+ CASE(R16G16_TYPELESS);
+ CASE(R16G16_FLOAT);
+ CASE(R16G16_UNORM);
+ CASE(R16G16_UINT);
+ CASE(R16G16_SNORM);
+ CASE(R16G16_SINT);
+
+ CASE(R32_TYPELESS);
+ CASE(D32_FLOAT);
+ CASE(R32_FLOAT);
+ CASE(R32_UINT);
+ CASE(R32_SINT);
+
+ CASE(R24G8_TYPELESS);
+ CASE(D24_UNORM_S8_UINT);
+ CASE(R24_UNORM_X8_TYPELESS);
+ CASE(X24_TYPELESS_G8_UINT);
+
+ CASE(R8G8_TYPELESS);
+ CASE(R8G8_UNORM);
+ CASE(R8G8_UINT);
+ CASE(R8G8_SNORM);
+ CASE(R8G8_SINT);
+
+ CASE(R16_TYPELESS);
+ CASE(R16_FLOAT);
+ CASE(D16_UNORM);
+ CASE(R16_UNORM);
+ CASE(R16_UINT);
+ CASE(R16_SNORM);
+ CASE(R16_SINT);
+
+ CASE(R8_TYPELESS);
+ CASE(R8_UNORM);
+ CASE(R8_UINT);
+ CASE(R8_SNORM);
+ CASE(R8_SINT);
+ CASE(A8_UNORM);
+
+ CASE(R1_UNORM);
+
+ CASE(R9G9B9E5_SHAREDEXP);
+
+ CASE(R8G8_B8G8_UNORM);
+ CASE(G8R8_G8B8_UNORM);
+
+ CASE(BC1_TYPELESS);
+ CASE(BC1_UNORM);
+ CASE(BC1_UNORM_SRGB);
+
+ CASE(BC2_TYPELESS);
+ CASE(BC2_UNORM);
+ CASE(BC2_UNORM_SRGB);
+
+ CASE(BC3_TYPELESS);
+ CASE(BC3_UNORM);
+ CASE(BC3_UNORM_SRGB);
+
+ CASE(BC4_TYPELESS);
+ CASE(BC4_UNORM);
+ CASE(BC4_SNORM);
+
+ CASE(BC5_TYPELESS);
+ CASE(BC5_UNORM);
+ CASE(BC5_SNORM);
+
+ CASE(B5G6R5_UNORM);
+ CASE(B5G5R5A1_UNORM);
+ CASE(B8G8R8A8_UNORM);
+ CASE(B8G8R8X8_UNORM);
+
+ default:
+ return "UNKNOWN";
+ }
#undef CASE
- }
-
- static const char * getD3d10ResourceDimensionString(D3D10_RESOURCE_DIMENSION resourceDimension)
- {
- switch (resourceDimension)
- {
- default:
- case D3D10_RESOURCE_DIMENSION_UNKNOWN: return "UNKNOWN";
- case D3D10_RESOURCE_DIMENSION_BUFFER: return "BUFFER";
- case D3D10_RESOURCE_DIMENSION_TEXTURE1D: return "TEXTURE1D";
- case D3D10_RESOURCE_DIMENSION_TEXTURE2D: return "TEXTURE2D";
- case D3D10_RESOURCE_DIMENSION_TEXTURE3D: return "TEXTURE3D";
- }
- }
+}
+
+static const char *getD3d10ResourceDimensionString(D3D10_RESOURCE_DIMENSION resourceDimension)
+{
+ switch (resourceDimension) {
+ default:
+ case D3D10_RESOURCE_DIMENSION_UNKNOWN:
+ return "UNKNOWN";
+ case D3D10_RESOURCE_DIMENSION_BUFFER:
+ return "BUFFER";
+ case D3D10_RESOURCE_DIMENSION_TEXTURE1D:
+ return "TEXTURE1D";
+ case D3D10_RESOURCE_DIMENSION_TEXTURE2D:
+ return "TEXTURE2D";
+ case D3D10_RESOURCE_DIMENSION_TEXTURE3D:
+ return "TEXTURE3D";
+ }
+}
/*** implementation ***/
-void mem_read(Stream & mem, DDSPixelFormat & pf)
+void mem_read(Stream &mem, DDSPixelFormat &pf)
{
- mem_read(mem, pf.size);
- mem_read(mem, pf.flags);
- mem_read(mem, pf.fourcc);
- mem_read(mem, pf.bitcount);
- mem_read(mem, pf.rmask);
- mem_read(mem, pf.gmask);
- mem_read(mem, pf.bmask);
- mem_read(mem, pf.amask);
+ mem_read(mem, pf.size);
+ mem_read(mem, pf.flags);
+ mem_read(mem, pf.fourcc);
+ mem_read(mem, pf.bitcount);
+ mem_read(mem, pf.rmask);
+ mem_read(mem, pf.gmask);
+ mem_read(mem, pf.bmask);
+ mem_read(mem, pf.amask);
}
-void mem_read(Stream & mem, DDSCaps & caps)
+void mem_read(Stream &mem, DDSCaps &caps)
{
- mem_read(mem, caps.caps1);
- mem_read(mem, caps.caps2);
- mem_read(mem, caps.caps3);
- mem_read(mem, caps.caps4);
+ mem_read(mem, caps.caps1);
+ mem_read(mem, caps.caps2);
+ mem_read(mem, caps.caps3);
+ mem_read(mem, caps.caps4);
}
-void mem_read(Stream & mem, DDSHeader10 & header)
+void mem_read(Stream &mem, DDSHeader10 &header)
{
- mem_read(mem, header.dxgiFormat);
- mem_read(mem, header.resourceDimension);
- mem_read(mem, header.miscFlag);
- mem_read(mem, header.arraySize);
- mem_read(mem, header.reserved);
+ mem_read(mem, header.dxgiFormat);
+ mem_read(mem, header.resourceDimension);
+ mem_read(mem, header.miscFlag);
+ mem_read(mem, header.arraySize);
+ mem_read(mem, header.reserved);
}
-void mem_read(Stream & mem, DDSHeader & header)
+void mem_read(Stream &mem, DDSHeader &header)
{
- mem_read(mem, header.fourcc);
- mem_read(mem, header.size);
- mem_read(mem, header.flags);
- mem_read(mem, header.height);
- mem_read(mem, header.width);
- mem_read(mem, header.pitch);
- mem_read(mem, header.depth);
- mem_read(mem, header.mipmapcount);
- for (uint i = 0; i < 11; i++) mem_read(mem, header.reserved[i]);
- mem_read(mem, header.pf);
- mem_read(mem, header.caps);
- mem_read(mem, header.notused);
-
- if (header.hasDX10Header())
- {
- mem_read(mem, header.header10);
- }
+ mem_read(mem, header.fourcc);
+ mem_read(mem, header.size);
+ mem_read(mem, header.flags);
+ mem_read(mem, header.height);
+ mem_read(mem, header.width);
+ mem_read(mem, header.pitch);
+ mem_read(mem, header.depth);
+ mem_read(mem, header.mipmapcount);
+ for (uint i = 0; i < 11; i++)
+ mem_read(mem, header.reserved[i]);
+ mem_read(mem, header.pf);
+ mem_read(mem, header.caps);
+ mem_read(mem, header.notused);
+
+ if (header.hasDX10Header()) {
+ mem_read(mem, header.header10);
+ }
}
-namespace
-{
+namespace {
struct FormatDescriptor {
- uint format;
- uint bitcount;
- uint rmask;
- uint gmask;
- uint bmask;
- uint amask;
+ uint format;
+ uint bitcount;
+ uint rmask;
+ uint gmask;
+ uint bmask;
+ uint amask;
};
-static const FormatDescriptor s_d3dFormats[] =
-{
- { D3DFMT_R8G8B8, 24, 0xFF0000, 0xFF00, 0xFF, 0 },
- { D3DFMT_A8R8G8B8, 32, 0xFF0000, 0xFF00, 0xFF, 0xFF000000 }, /* DXGI_FORMAT_B8G8R8A8_UNORM */
- { D3DFMT_X8R8G8B8, 32, 0xFF0000, 0xFF00, 0xFF, 0 }, /* DXGI_FORMAT_B8G8R8X8_UNORM */
- { D3DFMT_R5G6B5, 16, 0xF800, 0x7E0, 0x1F, 0 }, /* DXGI_FORMAT_B5G6R5_UNORM */
- { D3DFMT_X1R5G5B5, 16, 0x7C00, 0x3E0, 0x1F, 0 },
- { D3DFMT_A1R5G5B5, 16, 0x7C00, 0x3E0, 0x1F, 0x8000 }, /* DXGI_FORMAT_B5G5R5A1_UNORM */
- { D3DFMT_A4R4G4B4, 16, 0xF00, 0xF0, 0xF, 0xF000 },
- { D3DFMT_R3G3B2, 8, 0xE0, 0x1C, 0x3, 0 },
- { D3DFMT_A8, 8, 0, 0, 0, 8 }, /* DXGI_FORMAT_A8_UNORM */
- { D3DFMT_A8R3G3B2, 16, 0xE0, 0x1C, 0x3, 0xFF00 },
- { D3DFMT_X4R4G4B4, 16, 0xF00, 0xF0, 0xF, 0 },
- { D3DFMT_A2B10G10R10, 32, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000 }, /* DXGI_FORMAT_R10G10B10A2 */
- { D3DFMT_A8B8G8R8, 32, 0xFF, 0xFF00, 0xFF0000, 0xFF000000 }, /* DXGI_FORMAT_R8G8B8A8_UNORM */
- { D3DFMT_X8B8G8R8, 32, 0xFF, 0xFF00, 0xFF0000, 0 },
- { D3DFMT_G16R16, 32, 0xFFFF, 0xFFFF0000, 0, 0 }, /* DXGI_FORMAT_R16G16_UNORM */
- { D3DFMT_A2R10G10B10, 32, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000 },
- { D3DFMT_A2B10G10R10, 32, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000 },
-
- { D3DFMT_L8, 8, 8, 0, 0, 0 }, /* DXGI_FORMAT_R8_UNORM */
- { D3DFMT_L16, 16, 16, 0, 0, 0 }, /* DXGI_FORMAT_R16_UNORM */
+static const FormatDescriptor s_d3dFormats[] = {
+ {D3DFMT_R8G8B8, 24, 0xFF0000, 0xFF00, 0xFF, 0},
+ {D3DFMT_A8R8G8B8, 32, 0xFF0000, 0xFF00, 0xFF, 0xFF000000}, /* DXGI_FORMAT_B8G8R8A8_UNORM */
+ {D3DFMT_X8R8G8B8, 32, 0xFF0000, 0xFF00, 0xFF, 0}, /* DXGI_FORMAT_B8G8R8X8_UNORM */
+ {D3DFMT_R5G6B5, 16, 0xF800, 0x7E0, 0x1F, 0}, /* DXGI_FORMAT_B5G6R5_UNORM */
+ {D3DFMT_X1R5G5B5, 16, 0x7C00, 0x3E0, 0x1F, 0},
+ {D3DFMT_A1R5G5B5, 16, 0x7C00, 0x3E0, 0x1F, 0x8000}, /* DXGI_FORMAT_B5G5R5A1_UNORM */
+ {D3DFMT_A4R4G4B4, 16, 0xF00, 0xF0, 0xF, 0xF000},
+ {D3DFMT_R3G3B2, 8, 0xE0, 0x1C, 0x3, 0},
+ {D3DFMT_A8, 8, 0, 0, 0, 8}, /* DXGI_FORMAT_A8_UNORM */
+ {D3DFMT_A8R3G3B2, 16, 0xE0, 0x1C, 0x3, 0xFF00},
+ {D3DFMT_X4R4G4B4, 16, 0xF00, 0xF0, 0xF, 0},
+ {D3DFMT_A2B10G10R10, 32, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000}, /* DXGI_FORMAT_R10G10B10A2 */
+ {D3DFMT_A8B8G8R8, 32, 0xFF, 0xFF00, 0xFF0000, 0xFF000000}, /* DXGI_FORMAT_R8G8B8A8_UNORM */
+ {D3DFMT_X8B8G8R8, 32, 0xFF, 0xFF00, 0xFF0000, 0},
+ {D3DFMT_G16R16, 32, 0xFFFF, 0xFFFF0000, 0, 0}, /* DXGI_FORMAT_R16G16_UNORM */
+ {D3DFMT_A2R10G10B10, 32, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000},
+ {D3DFMT_A2B10G10R10, 32, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000},
+
+ {D3DFMT_L8, 8, 8, 0, 0, 0}, /* DXGI_FORMAT_R8_UNORM */
+ {D3DFMT_L16, 16, 16, 0, 0, 0}, /* DXGI_FORMAT_R16_UNORM */
};
static const uint s_d3dFormatCount = sizeof(s_d3dFormats) / sizeof(s_d3dFormats[0]);
-} // namespace
+} // namespace
static uint findD3D9Format(uint bitcount, uint rmask, uint gmask, uint bmask, uint amask)
{
- for (int i = 0; i < s_d3dFormatCount; i++)
- {
- if (s_d3dFormats[i].bitcount == bitcount &&
- s_d3dFormats[i].rmask == rmask &&
- s_d3dFormats[i].gmask == gmask &&
- s_d3dFormats[i].bmask == bmask &&
- s_d3dFormats[i].amask == amask)
- {
- return s_d3dFormats[i].format;
- }
- }
-
- return 0;
+ for (int i = 0; i < s_d3dFormatCount; i++) {
+ if (s_d3dFormats[i].bitcount == bitcount && s_d3dFormats[i].rmask == rmask &&
+ s_d3dFormats[i].gmask == gmask && s_d3dFormats[i].bmask == bmask &&
+ s_d3dFormats[i].amask == amask) {
+ return s_d3dFormats[i].format;
+ }
+ }
+
+ return 0;
}
-
-
DDSHeader::DDSHeader()
{
- this->fourcc = FOURCC_DDS;
- this->size = 124;
- this->flags = (DDSD_CAPS|DDSD_PIXELFORMAT);
- this->height = 0;
- this->width = 0;
- this->pitch = 0;
- this->depth = 0;
- this->mipmapcount = 0;
- for (uint i = 0; i < 11; i++) this->reserved[i] = 0;
-
- // Store version information on the reserved header attributes.
- this->reserved[9] = FOURCC_NVTT;
- this->reserved[10] = (2 << 16) | (1 << 8) | (0); // major.minor.revision
-
- this->pf.size = 32;
- this->pf.flags = 0;
- this->pf.fourcc = 0;
- this->pf.bitcount = 0;
- this->pf.rmask = 0;
- this->pf.gmask = 0;
- this->pf.bmask = 0;
- this->pf.amask = 0;
- this->caps.caps1 = DDSCAPS_TEXTURE;
- this->caps.caps2 = 0;
- this->caps.caps3 = 0;
- this->caps.caps4 = 0;
- this->notused = 0;
-
- this->header10.dxgiFormat = DXGI_FORMAT_UNKNOWN;
- this->header10.resourceDimension = D3D10_RESOURCE_DIMENSION_UNKNOWN;
- this->header10.miscFlag = 0;
- this->header10.arraySize = 0;
- this->header10.reserved = 0;
+ this->fourcc = FOURCC_DDS;
+ this->size = 124;
+ this->flags = (DDSD_CAPS | DDSD_PIXELFORMAT);
+ this->height = 0;
+ this->width = 0;
+ this->pitch = 0;
+ this->depth = 0;
+ this->mipmapcount = 0;
+ for (uint i = 0; i < 11; i++)
+ this->reserved[i] = 0;
+
+ // Store version information on the reserved header attributes.
+ this->reserved[9] = FOURCC_NVTT;
+ this->reserved[10] = (2 << 16) | (1 << 8) | (0); // major.minor.revision
+
+ this->pf.size = 32;
+ this->pf.flags = 0;
+ this->pf.fourcc = 0;
+ this->pf.bitcount = 0;
+ this->pf.rmask = 0;
+ this->pf.gmask = 0;
+ this->pf.bmask = 0;
+ this->pf.amask = 0;
+ this->caps.caps1 = DDSCAPS_TEXTURE;
+ this->caps.caps2 = 0;
+ this->caps.caps3 = 0;
+ this->caps.caps4 = 0;
+ this->notused = 0;
+
+ this->header10.dxgiFormat = DXGI_FORMAT_UNKNOWN;
+ this->header10.resourceDimension = D3D10_RESOURCE_DIMENSION_UNKNOWN;
+ this->header10.miscFlag = 0;
+ this->header10.arraySize = 0;
+ this->header10.reserved = 0;
}
void DDSHeader::setWidth(uint w)
{
- this->flags |= DDSD_WIDTH;
- this->width = w;
+ this->flags |= DDSD_WIDTH;
+ this->width = w;
}
void DDSHeader::setHeight(uint h)
{
- this->flags |= DDSD_HEIGHT;
- this->height = h;
+ this->flags |= DDSD_HEIGHT;
+ this->height = h;
}
void DDSHeader::setDepth(uint d)
{
- this->flags |= DDSD_DEPTH;
- this->depth = d;
+ this->flags |= DDSD_DEPTH;
+ this->depth = d;
}
void DDSHeader::setMipmapCount(uint count)
{
- if (count == 0 || count == 1)
- {
- this->flags &= ~DDSD_MIPMAPCOUNT;
- this->mipmapcount = 1;
-
- if (this->caps.caps2 == 0) {
- this->caps.caps1 = DDSCAPS_TEXTURE;
- }
- else {
- this->caps.caps1 = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
- }
- }
- else
- {
- this->flags |= DDSD_MIPMAPCOUNT;
- this->mipmapcount = count;
-
- this->caps.caps1 |= DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
- }
+ if (count == 0 || count == 1) {
+ this->flags &= ~DDSD_MIPMAPCOUNT;
+ this->mipmapcount = 1;
+
+ if (this->caps.caps2 == 0) {
+ this->caps.caps1 = DDSCAPS_TEXTURE;
+ }
+ else {
+ this->caps.caps1 = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
+ }
+ }
+ else {
+ this->flags |= DDSD_MIPMAPCOUNT;
+ this->mipmapcount = count;
+
+ this->caps.caps1 |= DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
+ }
}
void DDSHeader::setTexture2D()
{
- this->header10.resourceDimension = D3D10_RESOURCE_DIMENSION_TEXTURE2D;
- this->header10.arraySize = 1;
+ this->header10.resourceDimension = D3D10_RESOURCE_DIMENSION_TEXTURE2D;
+ this->header10.arraySize = 1;
}
void DDSHeader::setTexture3D()
{
- this->caps.caps2 = DDSCAPS2_VOLUME;
+ this->caps.caps2 = DDSCAPS2_VOLUME;
- this->header10.resourceDimension = D3D10_RESOURCE_DIMENSION_TEXTURE3D;
- this->header10.arraySize = 1;
+ this->header10.resourceDimension = D3D10_RESOURCE_DIMENSION_TEXTURE3D;
+ this->header10.arraySize = 1;
}
void DDSHeader::setTextureCube()
{
- this->caps.caps1 |= DDSCAPS_COMPLEX;
- this->caps.caps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALL_FACES;
+ this->caps.caps1 |= DDSCAPS_COMPLEX;
+ this->caps.caps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALL_FACES;
- this->header10.resourceDimension = D3D10_RESOURCE_DIMENSION_TEXTURE2D;
- this->header10.arraySize = 6;
+ this->header10.resourceDimension = D3D10_RESOURCE_DIMENSION_TEXTURE2D;
+ this->header10.arraySize = 6;
}
void DDSHeader::setLinearSize(uint size)
{
- this->flags &= ~DDSD_PITCH;
- this->flags |= DDSD_LINEARSIZE;
- this->pitch = size;
+ this->flags &= ~DDSD_PITCH;
+ this->flags |= DDSD_LINEARSIZE;
+ this->pitch = size;
}
void DDSHeader::setPitch(uint pitch)
{
- this->flags &= ~DDSD_LINEARSIZE;
- this->flags |= DDSD_PITCH;
- this->pitch = pitch;
+ this->flags &= ~DDSD_LINEARSIZE;
+ this->flags |= DDSD_PITCH;
+ this->pitch = pitch;
}
void DDSHeader::setFourCC(uint8 c0, uint8 c1, uint8 c2, uint8 c3)
{
- // set fourcc pixel format.
- this->pf.flags = DDPF_FOURCC;
- this->pf.fourcc = DDS_MAKEFOURCC(c0, c1, c2, c3);
-
- this->pf.bitcount = 0;
- this->pf.rmask = 0;
- this->pf.gmask = 0;
- this->pf.bmask = 0;
- this->pf.amask = 0;
+ // set fourcc pixel format.
+ this->pf.flags = DDPF_FOURCC;
+ this->pf.fourcc = DDS_MAKEFOURCC(c0, c1, c2, c3);
+
+ this->pf.bitcount = 0;
+ this->pf.rmask = 0;
+ this->pf.gmask = 0;
+ this->pf.bmask = 0;
+ this->pf.amask = 0;
}
void DDSHeader::setFormatCode(uint32 code)
{
- // set fourcc pixel format.
- this->pf.flags = DDPF_FOURCC;
- this->pf.fourcc = code;
-
- this->pf.bitcount = 0;
- this->pf.rmask = 0;
- this->pf.gmask = 0;
- this->pf.bmask = 0;
- this->pf.amask = 0;
+ // set fourcc pixel format.
+ this->pf.flags = DDPF_FOURCC;
+ this->pf.fourcc = code;
+
+ this->pf.bitcount = 0;
+ this->pf.rmask = 0;
+ this->pf.gmask = 0;
+ this->pf.bmask = 0;
+ this->pf.amask = 0;
}
void DDSHeader::setSwizzleCode(uint8 c0, uint8 c1, uint8 c2, uint8 c3)
{
- this->pf.bitcount = DDS_MAKEFOURCC(c0, c1, c2, c3);
+ this->pf.bitcount = DDS_MAKEFOURCC(c0, c1, c2, c3);
}
-
void DDSHeader::setPixelFormat(uint bitcount, uint rmask, uint gmask, uint bmask, uint amask)
{
- // Make sure the masks are correct.
- if ((rmask & gmask) ||
- (rmask & bmask) ||
- (rmask & amask) ||
- (gmask & bmask) ||
- (gmask & amask) ||
- (bmask & amask))
- {
- printf("DDS: bad RGBA masks, pixel format not set\n");
- return;
- }
-
- if (rmask != 0 || gmask != 0 || bmask != 0)
- {
- if (gmask == 0 && bmask == 0)
- {
- this->pf.flags = DDPF_LUMINANCE;
- }
- else
- {
- this->pf.flags = DDPF_RGB;
- }
-
- if (amask != 0) {
- this->pf.flags |= DDPF_ALPHAPIXELS;
- }
- }
- else if (amask != 0)
- {
- this->pf.flags |= DDPF_ALPHA;
- }
-
- if (bitcount == 0)
- {
- // Compute bit count from the masks.
- uint total = rmask | gmask | bmask | amask;
- while (total != 0) {
- bitcount++;
- total >>= 1;
- }
- }
-
- // D3DX functions do not like this:
- this->pf.fourcc = 0; //findD3D9Format(bitcount, rmask, gmask, bmask, amask);
- /*if (this->pf.fourcc) {
- this->pf.flags |= DDPF_FOURCC;
- }*/
-
- if (!(bitcount > 0 && bitcount <= 32)) {
- printf("DDS: bad bit count, pixel format not set\n");
- return;
- }
- this->pf.bitcount = bitcount;
- this->pf.rmask = rmask;
- this->pf.gmask = gmask;
- this->pf.bmask = bmask;
- this->pf.amask = amask;
+ // Make sure the masks are correct.
+ if ((rmask & gmask) || (rmask & bmask) || (rmask & amask) || (gmask & bmask) ||
+ (gmask & amask) || (bmask & amask)) {
+ printf("DDS: bad RGBA masks, pixel format not set\n");
+ return;
+ }
+
+ if (rmask != 0 || gmask != 0 || bmask != 0) {
+ if (gmask == 0 && bmask == 0) {
+ this->pf.flags = DDPF_LUMINANCE;
+ }
+ else {
+ this->pf.flags = DDPF_RGB;
+ }
+
+ if (amask != 0) {
+ this->pf.flags |= DDPF_ALPHAPIXELS;
+ }
+ }
+ else if (amask != 0) {
+ this->pf.flags |= DDPF_ALPHA;
+ }
+
+ if (bitcount == 0) {
+ // Compute bit count from the masks.
+ uint total = rmask | gmask | bmask | amask;
+ while (total != 0) {
+ bitcount++;
+ total >>= 1;
+ }
+ }
+
+ // D3DX functions do not like this:
+ this->pf.fourcc = 0; //findD3D9Format(bitcount, rmask, gmask, bmask, amask);
+ /*if (this->pf.fourcc) {
+ this->pf.flags |= DDPF_FOURCC;
+ }*/
+
+ if (!(bitcount > 0 && bitcount <= 32)) {
+ printf("DDS: bad bit count, pixel format not set\n");
+ return;
+ }
+ this->pf.bitcount = bitcount;
+ this->pf.rmask = rmask;
+ this->pf.gmask = gmask;
+ this->pf.bmask = bmask;
+ this->pf.amask = amask;
}
void DDSHeader::setDX10Format(uint format)
{
- //this->pf.flags = 0;
- this->pf.fourcc = FOURCC_DX10;
- this->header10.dxgiFormat = format;
+ //this->pf.flags = 0;
+ this->pf.fourcc = FOURCC_DX10;
+ this->header10.dxgiFormat = format;
}
void DDSHeader::setNormalFlag(bool b)
{
- if (b) this->pf.flags |= DDPF_NORMAL;
- else this->pf.flags &= ~DDPF_NORMAL;
+ if (b)
+ this->pf.flags |= DDPF_NORMAL;
+ else
+ this->pf.flags &= ~DDPF_NORMAL;
}
void DDSHeader::setSrgbFlag(bool b)
{
- if (b) this->pf.flags |= DDPF_SRGB;
- else this->pf.flags &= ~DDPF_SRGB;
+ if (b)
+ this->pf.flags |= DDPF_SRGB;
+ else
+ this->pf.flags &= ~DDPF_SRGB;
}
void DDSHeader::setHasAlphaFlag(bool b)
{
- if (b) this->pf.flags |= DDPF_ALPHAPIXELS;
- else this->pf.flags &= ~DDPF_ALPHAPIXELS;
+ if (b)
+ this->pf.flags |= DDPF_ALPHAPIXELS;
+ else
+ this->pf.flags &= ~DDPF_ALPHAPIXELS;
}
void DDSHeader::setUserVersion(int version)
{
- this->reserved[7] = FOURCC_UVER;
- this->reserved[8] = version;
+ this->reserved[7] = FOURCC_UVER;
+ this->reserved[8] = version;
}
#if 0
void DDSHeader::swapBytes()
{
- this->fourcc = POSH_LittleU32(this->fourcc);
- this->size = POSH_LittleU32(this->size);
- this->flags = POSH_LittleU32(this->flags);
- this->height = POSH_LittleU32(this->height);
- this->width = POSH_LittleU32(this->width);
- this->pitch = POSH_LittleU32(this->pitch);
- this->depth = POSH_LittleU32(this->depth);
- this->mipmapcount = POSH_LittleU32(this->mipmapcount);
-
- for (int i = 0; i < 11; i++) {
- this->reserved[i] = POSH_LittleU32(this->reserved[i]);
- }
-
- this->pf.size = POSH_LittleU32(this->pf.size);
- this->pf.flags = POSH_LittleU32(this->pf.flags);
- this->pf.fourcc = POSH_LittleU32(this->pf.fourcc);
- this->pf.bitcount = POSH_LittleU32(this->pf.bitcount);
- this->pf.rmask = POSH_LittleU32(this->pf.rmask);
- this->pf.gmask = POSH_LittleU32(this->pf.gmask);
- this->pf.bmask = POSH_LittleU32(this->pf.bmask);
- this->pf.amask = POSH_LittleU32(this->pf.amask);
- this->caps.caps1 = POSH_LittleU32(this->caps.caps1);
- this->caps.caps2 = POSH_LittleU32(this->caps.caps2);
- this->caps.caps3 = POSH_LittleU32(this->caps.caps3);
- this->caps.caps4 = POSH_LittleU32(this->caps.caps4);
- this->notused = POSH_LittleU32(this->notused);
-
- this->header10.dxgiFormat = POSH_LittleU32(this->header10.dxgiFormat);
- this->header10.resourceDimension = POSH_LittleU32(this->header10.resourceDimension);
- this->header10.miscFlag = POSH_LittleU32(this->header10.miscFlag);
- this->header10.arraySize = POSH_LittleU32(this->header10.arraySize);
- this->header10.reserved = POSH_LittleU32(this->header10.reserved);
+ this->fourcc = POSH_LittleU32(this->fourcc);
+ this->size = POSH_LittleU32(this->size);
+ this->flags = POSH_LittleU32(this->flags);
+ this->height = POSH_LittleU32(this->height);
+ this->width = POSH_LittleU32(this->width);
+ this->pitch = POSH_LittleU32(this->pitch);
+ this->depth = POSH_LittleU32(this->depth);
+ this->mipmapcount = POSH_LittleU32(this->mipmapcount);
+
+ for (int i = 0; i < 11; i++) {
+ this->reserved[i] = POSH_LittleU32(this->reserved[i]);
+ }
+
+ this->pf.size = POSH_LittleU32(this->pf.size);
+ this->pf.flags = POSH_LittleU32(this->pf.flags);
+ this->pf.fourcc = POSH_LittleU32(this->pf.fourcc);
+ this->pf.bitcount = POSH_LittleU32(this->pf.bitcount);
+ this->pf.rmask = POSH_LittleU32(this->pf.rmask);
+ this->pf.gmask = POSH_LittleU32(this->pf.gmask);
+ this->pf.bmask = POSH_LittleU32(this->pf.bmask);
+ this->pf.amask = POSH_LittleU32(this->pf.amask);
+ this->caps.caps1 = POSH_LittleU32(this->caps.caps1);
+ this->caps.caps2 = POSH_LittleU32(this->caps.caps2);
+ this->caps.caps3 = POSH_LittleU32(this->caps.caps3);
+ this->caps.caps4 = POSH_LittleU32(this->caps.caps4);
+ this->notused = POSH_LittleU32(this->notused);
+
+ this->header10.dxgiFormat = POSH_LittleU32(this->header10.dxgiFormat);
+ this->header10.resourceDimension = POSH_LittleU32(this->header10.resourceDimension);
+ this->header10.miscFlag = POSH_LittleU32(this->header10.miscFlag);
+ this->header10.arraySize = POSH_LittleU32(this->header10.arraySize);
+ this->header10.reserved = POSH_LittleU32(this->header10.reserved);
}
#endif
bool DDSHeader::hasDX10Header() const
{
- return this->pf.fourcc == FOURCC_DX10;
+ return this->pf.fourcc == FOURCC_DX10;
}
uint DDSHeader::signature() const
{
- return this->reserved[9];
+ return this->reserved[9];
}
uint DDSHeader::toolVersion() const
{
- return this->reserved[10];
+ return this->reserved[10];
}
uint DDSHeader::userVersion() const
{
- if (this->reserved[7] == FOURCC_UVER) {
- return this->reserved[8];
- }
- return 0;
+ if (this->reserved[7] == FOURCC_UVER) {
+ return this->reserved[8];
+ }
+ return 0;
}
bool DDSHeader::isNormalMap() const
{
- return (pf.flags & DDPF_NORMAL) != 0;
+ return (pf.flags & DDPF_NORMAL) != 0;
}
bool DDSHeader::isSrgb() const
{
- return (pf.flags & DDPF_SRGB) != 0;
+ return (pf.flags & DDPF_SRGB) != 0;
}
bool DDSHeader::hasAlpha() const
{
- return (pf.flags & DDPF_ALPHAPIXELS) != 0;
+ return (pf.flags & DDPF_ALPHAPIXELS) != 0;
}
uint DDSHeader::d3d9Format() const
{
- if (pf.flags & DDPF_FOURCC) {
- return pf.fourcc;
- }
- else {
- return findD3D9Format(pf.bitcount, pf.rmask, pf.gmask, pf.bmask, pf.amask);
- }
+ if (pf.flags & DDPF_FOURCC) {
+ return pf.fourcc;
+ }
+ else {
+ return findD3D9Format(pf.bitcount, pf.rmask, pf.gmask, pf.bmask, pf.amask);
+ }
}
DirectDrawSurface::DirectDrawSurface(unsigned char *mem, uint size) : stream(mem, size), header()
{
- mem_read(stream, header);
+ mem_read(stream, header);
- // some ATI2 compressed normal maps do not have their
- // normal flag set, so force it here (the original nvtt don't do
- // this, but the decompressor has a -forcenormal flag)
- if (header.pf.fourcc == FOURCC_ATI2) header.setNormalFlag(true);
+ // some ATI2 compressed normal maps do not have their
+ // normal flag set, so force it here (the original nvtt don't do
+ // this, but the decompressor has a -forcenormal flag)
+ if (header.pf.fourcc == FOURCC_ATI2)
+ header.setNormalFlag(true);
}
DirectDrawSurface::~DirectDrawSurface()
@@ -888,666 +876,642 @@ DirectDrawSurface::~DirectDrawSurface()
bool DirectDrawSurface::isValid() const
{
- if (header.fourcc != FOURCC_DDS || header.size != 124)
- {
- return false;
- }
+ if (header.fourcc != FOURCC_DDS || header.size != 124) {
+ return false;
+ }
- const uint required = (DDSD_WIDTH|DDSD_HEIGHT/*|DDSD_CAPS|DDSD_PIXELFORMAT*/);
- if ( (header.flags & required) != required ) {
- return false;
- }
+ const uint required = (DDSD_WIDTH | DDSD_HEIGHT /*|DDSD_CAPS|DDSD_PIXELFORMAT*/);
+ if ((header.flags & required) != required) {
+ return false;
+ }
- if (header.pf.size != 32) {
- return false;
- }
+ if (header.pf.size != 32) {
+ return false;
+ }
- /* in some files DDSCAPS_TEXTURE is missing: silently ignore */
+ /* in some files DDSCAPS_TEXTURE is missing: silently ignore */
#if 0
- if (!(header.caps.caps1 & DDSCAPS_TEXTURE)) {
- return false;
- }
+ if (!(header.caps.caps1 & DDSCAPS_TEXTURE)) {
+ return false;
+ }
#endif
- return true;
+ return true;
}
bool DirectDrawSurface::isSupported() const
{
- if (header.hasDX10Header())
- {
- if (header.header10.dxgiFormat == DXGI_FORMAT_BC1_UNORM ||
- header.header10.dxgiFormat == DXGI_FORMAT_BC2_UNORM ||
- header.header10.dxgiFormat == DXGI_FORMAT_BC3_UNORM ||
- header.header10.dxgiFormat == DXGI_FORMAT_BC4_UNORM ||
- header.header10.dxgiFormat == DXGI_FORMAT_BC5_UNORM)
- {
- return true;
- }
-
- return false;
- }
- else
- {
- if (header.pf.flags & DDPF_FOURCC)
- {
- if (header.pf.fourcc != FOURCC_DXT1 &&
- header.pf.fourcc != FOURCC_DXT2 &&
- header.pf.fourcc != FOURCC_DXT3 &&
- header.pf.fourcc != FOURCC_DXT4 &&
- header.pf.fourcc != FOURCC_DXT5 &&
- header.pf.fourcc != FOURCC_RXGB &&
- header.pf.fourcc != FOURCC_ATI1 &&
- header.pf.fourcc != FOURCC_ATI2)
- {
- // Unknown fourcc code.
- return false;
- }
- }
- else if ((header.pf.flags & DDPF_RGB) || (header.pf.flags & DDPF_LUMINANCE))
- {
- // All RGB and luminance formats are supported now.
- }
- else
- {
- return false;
- }
-
- if (isTextureCube() && (header.caps.caps2 & DDSCAPS2_CUBEMAP_ALL_FACES) != DDSCAPS2_CUBEMAP_ALL_FACES)
- {
- // Cubemaps must contain all faces.
- return false;
- }
-
- if (isTexture3D())
- {
- // @@ 3D textures not supported yet.
- return false;
- }
- }
-
- return true;
+ if (header.hasDX10Header()) {
+ if (header.header10.dxgiFormat == DXGI_FORMAT_BC1_UNORM ||
+ header.header10.dxgiFormat == DXGI_FORMAT_BC2_UNORM ||
+ header.header10.dxgiFormat == DXGI_FORMAT_BC3_UNORM ||
+ header.header10.dxgiFormat == DXGI_FORMAT_BC4_UNORM ||
+ header.header10.dxgiFormat == DXGI_FORMAT_BC5_UNORM) {
+ return true;
+ }
+
+ return false;
+ }
+ else {
+ if (header.pf.flags & DDPF_FOURCC) {
+ if (header.pf.fourcc != FOURCC_DXT1 && header.pf.fourcc != FOURCC_DXT2 &&
+ header.pf.fourcc != FOURCC_DXT3 && header.pf.fourcc != FOURCC_DXT4 &&
+ header.pf.fourcc != FOURCC_DXT5 && header.pf.fourcc != FOURCC_RXGB &&
+ header.pf.fourcc != FOURCC_ATI1 && header.pf.fourcc != FOURCC_ATI2) {
+ // Unknown fourcc code.
+ return false;
+ }
+ }
+ else if ((header.pf.flags & DDPF_RGB) || (header.pf.flags & DDPF_LUMINANCE)) {
+ // All RGB and luminance formats are supported now.
+ }
+ else {
+ return false;
+ }
+
+ if (isTextureCube() &&
+ (header.caps.caps2 & DDSCAPS2_CUBEMAP_ALL_FACES) != DDSCAPS2_CUBEMAP_ALL_FACES) {
+ // Cubemaps must contain all faces.
+ return false;
+ }
+
+ if (isTexture3D()) {
+ // @@ 3D textures not supported yet.
+ return false;
+ }
+ }
+
+ return true;
}
bool DirectDrawSurface::hasAlpha() const
{
- if (header.hasDX10Header())
- {
- /* TODO: Update hasAlpha to handle all DX10 formats. */
- return
- header.header10.dxgiFormat == DXGI_FORMAT_BC1_UNORM ||
- header.header10.dxgiFormat == DXGI_FORMAT_BC2_UNORM ||
- header.header10.dxgiFormat == DXGI_FORMAT_BC3_UNORM;
- }
- else
- {
- if (header.pf.flags & DDPF_RGB)
- {
- return header.pf.amask != 0;
- }
- else if (header.pf.flags & DDPF_FOURCC)
- {
- if (header.pf.fourcc == FOURCC_RXGB ||
- header.pf.fourcc == FOURCC_ATI1 ||
- header.pf.fourcc == FOURCC_ATI2 ||
- header.pf.flags & DDPF_NORMAL)
- {
- return false;
- }
- else
- {
- // @@ Here we could check the ALPHA_PIXELS flag, but nobody sets it. (except us?)
- return true;
- }
- }
-
- return false;
- }
+ if (header.hasDX10Header()) {
+ /* TODO: Update hasAlpha to handle all DX10 formats. */
+ return header.header10.dxgiFormat == DXGI_FORMAT_BC1_UNORM ||
+ header.header10.dxgiFormat == DXGI_FORMAT_BC2_UNORM ||
+ header.header10.dxgiFormat == DXGI_FORMAT_BC3_UNORM;
+ }
+ else {
+ if (header.pf.flags & DDPF_RGB) {
+ return header.pf.amask != 0;
+ }
+ else if (header.pf.flags & DDPF_FOURCC) {
+ if (header.pf.fourcc == FOURCC_RXGB || header.pf.fourcc == FOURCC_ATI1 ||
+ header.pf.fourcc == FOURCC_ATI2 || header.pf.flags & DDPF_NORMAL) {
+ return false;
+ }
+ else {
+ // @@ Here we could check the ALPHA_PIXELS flag, but nobody sets it. (except us?)
+ return true;
+ }
+ }
+
+ return false;
+ }
}
uint DirectDrawSurface::mipmapCount() const
{
- if (header.flags & DDSD_MIPMAPCOUNT) return header.mipmapcount;
- else return 1;
+ if (header.flags & DDSD_MIPMAPCOUNT)
+ return header.mipmapcount;
+ else
+ return 1;
}
uint DirectDrawSurface::fourCC() const
{
- return header.pf.fourcc;
+ return header.pf.fourcc;
}
uint DirectDrawSurface::width() const
{
- if (header.flags & DDSD_WIDTH) return header.width;
- else return 1;
+ if (header.flags & DDSD_WIDTH)
+ return header.width;
+ else
+ return 1;
}
uint DirectDrawSurface::height() const
{
- if (header.flags & DDSD_HEIGHT) return header.height;
- else return 1;
+ if (header.flags & DDSD_HEIGHT)
+ return header.height;
+ else
+ return 1;
}
uint DirectDrawSurface::depth() const
{
- if (header.flags & DDSD_DEPTH) return header.depth;
- else return 1;
+ if (header.flags & DDSD_DEPTH)
+ return header.depth;
+ else
+ return 1;
}
bool DirectDrawSurface::isTexture1D() const
{
- if (header.hasDX10Header())
- {
- return header.header10.resourceDimension == D3D10_RESOURCE_DIMENSION_TEXTURE1D;
- }
- return false;
+ if (header.hasDX10Header()) {
+ return header.header10.resourceDimension == D3D10_RESOURCE_DIMENSION_TEXTURE1D;
+ }
+ return false;
}
bool DirectDrawSurface::isTexture2D() const
{
- if (header.hasDX10Header())
- {
- return header.header10.resourceDimension == D3D10_RESOURCE_DIMENSION_TEXTURE2D;
- }
- else
- {
- return !isTexture3D() && !isTextureCube();
- }
+ if (header.hasDX10Header()) {
+ return header.header10.resourceDimension == D3D10_RESOURCE_DIMENSION_TEXTURE2D;
+ }
+ else {
+ return !isTexture3D() && !isTextureCube();
+ }
}
bool DirectDrawSurface::isTexture3D() const
{
- if (header.hasDX10Header())
- {
- return header.header10.resourceDimension == D3D10_RESOURCE_DIMENSION_TEXTURE3D;
- }
- else
- {
- return (header.caps.caps2 & DDSCAPS2_VOLUME) != 0;
- }
+ if (header.hasDX10Header()) {
+ return header.header10.resourceDimension == D3D10_RESOURCE_DIMENSION_TEXTURE3D;
+ }
+ else {
+ return (header.caps.caps2 & DDSCAPS2_VOLUME) != 0;
+ }
}
bool DirectDrawSurface::isTextureCube() const
{
- return (header.caps.caps2 & DDSCAPS2_CUBEMAP) != 0;
+ return (header.caps.caps2 & DDSCAPS2_CUBEMAP) != 0;
}
void DirectDrawSurface::setNormalFlag(bool b)
{
- header.setNormalFlag(b);
+ header.setNormalFlag(b);
}
void DirectDrawSurface::setHasAlphaFlag(bool b)
{
- header.setHasAlphaFlag(b);
+ header.setHasAlphaFlag(b);
}
void DirectDrawSurface::setUserVersion(int version)
{
- header.setUserVersion(version);
+ header.setUserVersion(version);
}
void DirectDrawSurface::mipmap(Image *img, uint face, uint mipmap)
{
- stream.seek(offset(face, mipmap));
-
- uint w = width();
- uint h = height();
-
- // Compute width and height.
- for (uint m = 0; m < mipmap; m++)
- {
- w = MAX(1U, w / 2);
- h = MAX(1U, h / 2);
- }
-
- img->allocate(w, h);
-
- if (hasAlpha())
- {
- img->setFormat(Image::Format_ARGB);
- }
- else
- {
- img->setFormat(Image::Format_RGB);
- }
-
- if (header.hasDX10Header())
- {
- // So far only block formats supported.
- readBlockImage(img);
- }
- else
- {
- if (header.pf.flags & DDPF_RGB)
- {
- readLinearImage(img);
- }
- else if (header.pf.flags & DDPF_FOURCC)
- {
- readBlockImage(img);
- }
- }
+ stream.seek(offset(face, mipmap));
+
+ uint w = width();
+ uint h = height();
+
+ // Compute width and height.
+ for (uint m = 0; m < mipmap; m++) {
+ w = MAX(1U, w / 2);
+ h = MAX(1U, h / 2);
+ }
+
+ img->allocate(w, h);
+
+ if (hasAlpha()) {
+ img->setFormat(Image::Format_ARGB);
+ }
+ else {
+ img->setFormat(Image::Format_RGB);
+ }
+
+ if (header.hasDX10Header()) {
+ // So far only block formats supported.
+ readBlockImage(img);
+ }
+ else {
+ if (header.pf.flags & DDPF_RGB) {
+ readLinearImage(img);
+ }
+ else if (header.pf.flags & DDPF_FOURCC) {
+ readBlockImage(img);
+ }
+ }
}
// It was easier to copy this function from upstream than to resync.
// This should be removed if a resync ever occurs.
void *DirectDrawSurface::readData(uint &rsize)
{
- uint header_size = 128; // sizeof(DDSHeader);
- if (header.hasDX10Header())
- {
- header_size += 20; // sizeof(DDSHeader10);
- }
+ uint header_size = 128; // sizeof(DDSHeader);
+ if (header.hasDX10Header()) {
+ header_size += 20; // sizeof(DDSHeader10);
+ }
- uint size = stream.size - header_size;
- rsize = size;
+ uint size = stream.size - header_size;
+ rsize = size;
- unsigned char *data = (unsigned char *)malloc(sizeof(*data) * size);
+ unsigned char *data = (unsigned char *)malloc(sizeof(*data) * size);
- stream.seek(header_size);
- mem_read(stream, data, size);
+ stream.seek(header_size);
+ mem_read(stream, data, size);
- if (stream.failed) {
- free(data);
- data = NULL;
- rsize = 0;
- }
+ if (stream.failed) {
+ free(data);
+ data = NULL;
+ rsize = 0;
+ }
- // Maybe check if size == rsize? assert() isn't in this scope...
+ // Maybe check if size == rsize? assert() isn't in this scope...
- return data;
+ return data;
}
void DirectDrawSurface::readLinearImage(Image *img)
{
- const uint w = img->width();
- const uint h = img->height();
+ const uint w = img->width();
+ const uint h = img->height();
- uint rshift, rsize;
- PixelFormat::maskShiftAndSize(header.pf.rmask, &rshift, &rsize);
+ uint rshift, rsize;
+ PixelFormat::maskShiftAndSize(header.pf.rmask, &rshift, &rsize);
- uint gshift, gsize;
- PixelFormat::maskShiftAndSize(header.pf.gmask, &gshift, &gsize);
+ uint gshift, gsize;
+ PixelFormat::maskShiftAndSize(header.pf.gmask, &gshift, &gsize);
- uint bshift, bsize;
- PixelFormat::maskShiftAndSize(header.pf.bmask, &bshift, &bsize);
+ uint bshift, bsize;
+ PixelFormat::maskShiftAndSize(header.pf.bmask, &bshift, &bsize);
- uint ashift, asize;
- PixelFormat::maskShiftAndSize(header.pf.amask, &ashift, &asize);
+ uint ashift, asize;
+ PixelFormat::maskShiftAndSize(header.pf.amask, &ashift, &asize);
- uint byteCount = (header.pf.bitcount + 7) / 8;
+ uint byteCount = (header.pf.bitcount + 7) / 8;
- if (byteCount > 4)
- {
- /* just in case... we could have segfaults later on if byteCount > 4 */
- printf("DDS: bitcount too large");
- return;
- }
+ if (byteCount > 4) {
+ /* just in case... we could have segfaults later on if byteCount > 4 */
+ printf("DDS: bitcount too large");
+ return;
+ }
- // Read linear RGB images.
- for (uint y = 0; y < h; y++)
- {
- for (uint x = 0; x < w; x++)
- {
- uint c = 0;
- mem_read(stream, (unsigned char *)(&c), byteCount);
+ // Read linear RGB images.
+ for (uint y = 0; y < h; y++) {
+ for (uint x = 0; x < w; x++) {
+ uint c = 0;
+ mem_read(stream, (unsigned char *)(&c), byteCount);
- Color32 pixel(0, 0, 0, 0xFF);
- pixel.r = PixelFormat::convert((c & header.pf.rmask) >> rshift, rsize, 8);
- pixel.g = PixelFormat::convert((c & header.pf.gmask) >> gshift, gsize, 8);
- pixel.b = PixelFormat::convert((c & header.pf.bmask) >> bshift, bsize, 8);
- pixel.a = PixelFormat::convert((c & header.pf.amask) >> ashift, asize, 8);
+ Color32 pixel(0, 0, 0, 0xFF);
+ pixel.r = PixelFormat::convert((c & header.pf.rmask) >> rshift, rsize, 8);
+ pixel.g = PixelFormat::convert((c & header.pf.gmask) >> gshift, gsize, 8);
+ pixel.b = PixelFormat::convert((c & header.pf.bmask) >> bshift, bsize, 8);
+ pixel.a = PixelFormat::convert((c & header.pf.amask) >> ashift, asize, 8);
- img->pixel(x, y) = pixel;
- }
- }
+ img->pixel(x, y) = pixel;
+ }
+ }
}
void DirectDrawSurface::readBlockImage(Image *img)
{
- const uint w = img->width();
- const uint h = img->height();
-
- const uint bw = (w + 3) / 4;
- const uint bh = (h + 3) / 4;
-
- for (uint by = 0; by < bh; by++)
- {
- for (uint bx = 0; bx < bw; bx++)
- {
- ColorBlock block;
-
- // Read color block.
- readBlock(&block);
-
- // Write color block.
- for (uint y = 0; y < MIN(4U, h-4*by); y++)
- {
- for (uint x = 0; x < MIN(4U, w-4*bx); x++)
- {
- img->pixel(4*bx+x, 4*by+y) = block.color(x, y);
- }
- }
- }
- }
+ const uint w = img->width();
+ const uint h = img->height();
+
+ const uint bw = (w + 3) / 4;
+ const uint bh = (h + 3) / 4;
+
+ for (uint by = 0; by < bh; by++) {
+ for (uint bx = 0; bx < bw; bx++) {
+ ColorBlock block;
+
+ // Read color block.
+ readBlock(&block);
+
+ // Write color block.
+ for (uint y = 0; y < MIN(4U, h - 4 * by); y++) {
+ for (uint x = 0; x < MIN(4U, w - 4 * bx); x++) {
+ img->pixel(4 * bx + x, 4 * by + y) = block.color(x, y);
+ }
+ }
+ }
+ }
}
static Color32 buildNormal(uint8 x, uint8 y)
{
- float nx = 2 * (x / 255.0f) - 1;
- float ny = 2 * (y / 255.0f) - 1;
- float nz = 0.0f;
- if (1 - nx*nx - ny*ny > 0) nz = sqrt(1 - nx*nx - ny*ny);
- uint8 z = CLAMP(int(255.0f * (nz + 1) / 2.0f), 0, 255);
-
- return Color32(x, y, z);
+ float nx = 2 * (x / 255.0f) - 1;
+ float ny = 2 * (y / 255.0f) - 1;
+ float nz = 0.0f;
+ if (1 - nx * nx - ny * ny > 0)
+ nz = sqrt(1 - nx * nx - ny * ny);
+ uint8 z = CLAMP(int(255.0f * (nz + 1) / 2.0f), 0, 255);
+
+ return Color32(x, y, z);
}
-
void DirectDrawSurface::readBlock(ColorBlock *rgba)
{
- uint fourcc = header.pf.fourcc;
-
- // Map DX10 block formats to fourcc codes.
- if (header.hasDX10Header())
- {
- if (header.header10.dxgiFormat == DXGI_FORMAT_BC1_UNORM) fourcc = FOURCC_DXT1;
- if (header.header10.dxgiFormat == DXGI_FORMAT_BC2_UNORM) fourcc = FOURCC_DXT3;
- if (header.header10.dxgiFormat == DXGI_FORMAT_BC3_UNORM) fourcc = FOURCC_DXT5;
- if (header.header10.dxgiFormat == DXGI_FORMAT_BC4_UNORM) fourcc = FOURCC_ATI1;
- if (header.header10.dxgiFormat == DXGI_FORMAT_BC5_UNORM) fourcc = FOURCC_ATI2;
- }
-
-
- if (fourcc == FOURCC_DXT1)
- {
- BlockDXT1 block;
- mem_read(stream, block);
- block.decodeBlock(rgba);
- }
- else if (fourcc == FOURCC_DXT2 ||
- header.pf.fourcc == FOURCC_DXT3)
- {
- BlockDXT3 block;
- mem_read(stream, block);
- block.decodeBlock(rgba);
- }
- else if (fourcc == FOURCC_DXT4 ||
- header.pf.fourcc == FOURCC_DXT5 ||
- header.pf.fourcc == FOURCC_RXGB)
- {
- BlockDXT5 block;
- mem_read(stream, block);
- block.decodeBlock(rgba);
-
- if (fourcc == FOURCC_RXGB)
- {
- // Swap R & A.
- for (int i = 0; i < 16; i++)
- {
- Color32 & c = rgba->color(i);
- uint tmp = c.r;
- c.r = c.a;
- c.a = tmp;
- }
- }
- }
- else if (fourcc == FOURCC_ATI1)
- {
- BlockATI1 block;
- mem_read(stream, block);
- block.decodeBlock(rgba);
- }
- else if (fourcc == FOURCC_ATI2)
- {
- BlockATI2 block;
- mem_read(stream, block);
- block.decodeBlock(rgba);
- }
-
- // If normal flag set, convert to normal.
- if (header.pf.flags & DDPF_NORMAL)
- {
- if (fourcc == FOURCC_ATI2)
- {
- for (int i = 0; i < 16; i++)
- {
- Color32 & c = rgba->color(i);
- c = buildNormal(c.r, c.g);
- }
- }
- else if (fourcc == FOURCC_DXT5)
- {
- for (int i = 0; i < 16; i++)
- {
- Color32 & c = rgba->color(i);
- c = buildNormal(c.a, c.g);
- }
- }
- }
+ uint fourcc = header.pf.fourcc;
+
+ // Map DX10 block formats to fourcc codes.
+ if (header.hasDX10Header()) {
+ if (header.header10.dxgiFormat == DXGI_FORMAT_BC1_UNORM)
+ fourcc = FOURCC_DXT1;
+ if (header.header10.dxgiFormat == DXGI_FORMAT_BC2_UNORM)
+ fourcc = FOURCC_DXT3;
+ if (header.header10.dxgiFormat == DXGI_FORMAT_BC3_UNORM)
+ fourcc = FOURCC_DXT5;
+ if (header.header10.dxgiFormat == DXGI_FORMAT_BC4_UNORM)
+ fourcc = FOURCC_ATI1;
+ if (header.header10.dxgiFormat == DXGI_FORMAT_BC5_UNORM)
+ fourcc = FOURCC_ATI2;
+ }
+
+ if (fourcc == FOURCC_DXT1) {
+ BlockDXT1 block;
+ mem_read(stream, block);
+ block.decodeBlock(rgba);
+ }
+ else if (fourcc == FOURCC_DXT2 || header.pf.fourcc == FOURCC_DXT3) {
+ BlockDXT3 block;
+ mem_read(stream, block);
+ block.decodeBlock(rgba);
+ }
+ else if (fourcc == FOURCC_DXT4 || header.pf.fourcc == FOURCC_DXT5 ||
+ header.pf.fourcc == FOURCC_RXGB) {
+ BlockDXT5 block;
+ mem_read(stream, block);
+ block.decodeBlock(rgba);
+
+ if (fourcc == FOURCC_RXGB) {
+ // Swap R & A.
+ for (int i = 0; i < 16; i++) {
+ Color32 &c = rgba->color(i);
+ uint tmp = c.r;
+ c.r = c.a;
+ c.a = tmp;
+ }
+ }
+ }
+ else if (fourcc == FOURCC_ATI1) {
+ BlockATI1 block;
+ mem_read(stream, block);
+ block.decodeBlock(rgba);
+ }
+ else if (fourcc == FOURCC_ATI2) {
+ BlockATI2 block;
+ mem_read(stream, block);
+ block.decodeBlock(rgba);
+ }
+
+ // If normal flag set, convert to normal.
+ if (header.pf.flags & DDPF_NORMAL) {
+ if (fourcc == FOURCC_ATI2) {
+ for (int i = 0; i < 16; i++) {
+ Color32 &c = rgba->color(i);
+ c = buildNormal(c.r, c.g);
+ }
+ }
+ else if (fourcc == FOURCC_DXT5) {
+ for (int i = 0; i < 16; i++) {
+ Color32 &c = rgba->color(i);
+ c = buildNormal(c.a, c.g);
+ }
+ }
+ }
}
-
uint DirectDrawSurface::blockSize() const
{
- switch (header.pf.fourcc)
- {
- case FOURCC_DXT1:
- case FOURCC_ATI1:
- return 8;
- case FOURCC_DXT2:
- case FOURCC_DXT3:
- case FOURCC_DXT4:
- case FOURCC_DXT5:
- case FOURCC_RXGB:
- case FOURCC_ATI2:
- return 16;
- case FOURCC_DX10:
- switch (header.header10.dxgiFormat)
- {
- case DXGI_FORMAT_BC1_TYPELESS:
- case DXGI_FORMAT_BC1_UNORM:
- case DXGI_FORMAT_BC1_UNORM_SRGB:
- case DXGI_FORMAT_BC4_TYPELESS:
- case DXGI_FORMAT_BC4_UNORM:
- case DXGI_FORMAT_BC4_SNORM:
- return 8;
- case DXGI_FORMAT_BC2_TYPELESS:
- case DXGI_FORMAT_BC2_UNORM:
- case DXGI_FORMAT_BC2_UNORM_SRGB:
- case DXGI_FORMAT_BC3_TYPELESS:
- case DXGI_FORMAT_BC3_UNORM:
- case DXGI_FORMAT_BC3_UNORM_SRGB:
- case DXGI_FORMAT_BC5_TYPELESS:
- case DXGI_FORMAT_BC5_UNORM:
- case DXGI_FORMAT_BC5_SNORM:
- return 16;
- };
- };
-
- // Not a block image.
- return 0;
+ switch (header.pf.fourcc) {
+ case FOURCC_DXT1:
+ case FOURCC_ATI1:
+ return 8;
+ case FOURCC_DXT2:
+ case FOURCC_DXT3:
+ case FOURCC_DXT4:
+ case FOURCC_DXT5:
+ case FOURCC_RXGB:
+ case FOURCC_ATI2:
+ return 16;
+ case FOURCC_DX10:
+ switch (header.header10.dxgiFormat) {
+ case DXGI_FORMAT_BC1_TYPELESS:
+ case DXGI_FORMAT_BC1_UNORM:
+ case DXGI_FORMAT_BC1_UNORM_SRGB:
+ case DXGI_FORMAT_BC4_TYPELESS:
+ case DXGI_FORMAT_BC4_UNORM:
+ case DXGI_FORMAT_BC4_SNORM:
+ return 8;
+ case DXGI_FORMAT_BC2_TYPELESS:
+ case DXGI_FORMAT_BC2_UNORM:
+ case DXGI_FORMAT_BC2_UNORM_SRGB:
+ case DXGI_FORMAT_BC3_TYPELESS:
+ case DXGI_FORMAT_BC3_UNORM:
+ case DXGI_FORMAT_BC3_UNORM_SRGB:
+ case DXGI_FORMAT_BC5_TYPELESS:
+ case DXGI_FORMAT_BC5_UNORM:
+ case DXGI_FORMAT_BC5_SNORM:
+ return 16;
+ };
+ };
+
+ // Not a block image.
+ return 0;
}
uint DirectDrawSurface::mipmapSize(uint mipmap) const
{
- uint w = width();
- uint h = height();
- uint d = depth();
-
- for (uint m = 0; m < mipmap; m++)
- {
- w = MAX(1U, w / 2);
- h = MAX(1U, h / 2);
- d = MAX(1U, d / 2);
- }
-
- if (header.pf.flags & DDPF_FOURCC)
- {
- // @@ How are 3D textures aligned?
- w = (w + 3) / 4;
- h = (h + 3) / 4;
- return blockSize() * w * h;
- }
- else if (header.pf.flags & DDPF_RGB || (header.pf.flags & DDPF_LUMINANCE))
- {
- uint pitch = computePitch(w, header.pf.bitcount, 8); // Assuming 8 bit alignment, which is the same D3DX expects.
-
- return pitch * h * d;
- }
- else {
- printf("DDS: mipmap format not supported\n");
- return(0);
- };
+ uint w = width();
+ uint h = height();
+ uint d = depth();
+
+ for (uint m = 0; m < mipmap; m++) {
+ w = MAX(1U, w / 2);
+ h = MAX(1U, h / 2);
+ d = MAX(1U, d / 2);
+ }
+
+ if (header.pf.flags & DDPF_FOURCC) {
+ // @@ How are 3D textures aligned?
+ w = (w + 3) / 4;
+ h = (h + 3) / 4;
+ return blockSize() * w * h;
+ }
+ else if (header.pf.flags & DDPF_RGB || (header.pf.flags & DDPF_LUMINANCE)) {
+ uint pitch = computePitch(
+ w, header.pf.bitcount, 8); // Assuming 8 bit alignment, which is the same D3DX expects.
+
+ return pitch * h * d;
+ }
+ else {
+ printf("DDS: mipmap format not supported\n");
+ return (0);
+ };
}
uint DirectDrawSurface::faceSize() const
{
- const uint count = mipmapCount();
- uint size = 0;
+ const uint count = mipmapCount();
+ uint size = 0;
- for (uint m = 0; m < count; m++)
- {
- size += mipmapSize(m);
- }
+ for (uint m = 0; m < count; m++) {
+ size += mipmapSize(m);
+ }
- return size;
+ return size;
}
uint DirectDrawSurface::offset(const uint face, const uint mipmap)
{
- uint size = 128; // sizeof(DDSHeader);
+ uint size = 128; // sizeof(DDSHeader);
- if (header.hasDX10Header())
- {
- size += 20; // sizeof(DDSHeader10);
- }
+ if (header.hasDX10Header()) {
+ size += 20; // sizeof(DDSHeader10);
+ }
- if (face != 0)
- {
- size += face * faceSize();
- }
+ if (face != 0) {
+ size += face * faceSize();
+ }
- for (uint m = 0; m < mipmap; m++)
- {
- size += mipmapSize(m);
- }
+ for (uint m = 0; m < mipmap; m++) {
+ size += mipmapSize(m);
+ }
- return size;
+ return size;
}
-
void DirectDrawSurface::printInfo() const
{
- printf("Flags: 0x%.8X\n", header.flags);
- if (header.flags & DDSD_CAPS) printf("\tDDSD_CAPS\n");
- if (header.flags & DDSD_PIXELFORMAT) printf("\tDDSD_PIXELFORMAT\n");
- if (header.flags & DDSD_WIDTH) printf("\tDDSD_WIDTH\n");
- if (header.flags & DDSD_HEIGHT) printf("\tDDSD_HEIGHT\n");
- if (header.flags & DDSD_DEPTH) printf("\tDDSD_DEPTH\n");
- if (header.flags & DDSD_PITCH) printf("\tDDSD_PITCH\n");
- if (header.flags & DDSD_LINEARSIZE) printf("\tDDSD_LINEARSIZE\n");
- if (header.flags & DDSD_MIPMAPCOUNT) printf("\tDDSD_MIPMAPCOUNT\n");
-
- printf("Height: %u\n", header.height);
- printf("Width: %u\n", header.width);
- printf("Depth: %u\n", header.depth);
- if (header.flags & DDSD_PITCH) printf("Pitch: %u\n", header.pitch);
- else if (header.flags & DDSD_LINEARSIZE) printf("Linear size: %u\n", header.pitch);
- printf("Mipmap count: %u\n", header.mipmapcount);
-
- printf("Pixel Format:\n");
- printf("\tFlags: 0x%.8X\n", header.pf.flags);
- if (header.pf.flags & DDPF_RGB) printf("\t\tDDPF_RGB\n");
- if (header.pf.flags & DDPF_LUMINANCE) printf("\t\tDDPF_LUMINANCE\n");
- if (header.pf.flags & DDPF_FOURCC) printf("\t\tDDPF_FOURCC\n");
- if (header.pf.flags & DDPF_ALPHAPIXELS) printf("\t\tDDPF_ALPHAPIXELS\n");
- if (header.pf.flags & DDPF_ALPHA) printf("\t\tDDPF_ALPHA\n");
- if (header.pf.flags & DDPF_PALETTEINDEXED1) printf("\t\tDDPF_PALETTEINDEXED1\n");
- if (header.pf.flags & DDPF_PALETTEINDEXED2) printf("\t\tDDPF_PALETTEINDEXED2\n");
- if (header.pf.flags & DDPF_PALETTEINDEXED4) printf("\t\tDDPF_PALETTEINDEXED4\n");
- if (header.pf.flags & DDPF_PALETTEINDEXED8) printf("\t\tDDPF_PALETTEINDEXED8\n");
- if (header.pf.flags & DDPF_ALPHAPREMULT) printf("\t\tDDPF_ALPHAPREMULT\n");
- if (header.pf.flags & DDPF_NORMAL) printf("\t\tDDPF_NORMAL\n");
-
- if (header.pf.fourcc != 0) {
- // Display fourcc code even when DDPF_FOURCC flag not set.
- printf("\tFourCC: '%c%c%c%c' (0x%.8X)\n",
- (int)((header.pf.fourcc >> 0) & 0xFF),
- (int)((header.pf.fourcc >> 8) & 0xFF),
- (int)((header.pf.fourcc >> 16) & 0xFF),
- (int)((header.pf.fourcc >> 24) & 0xFF),
- header.pf.fourcc);
- }
-
- if ((header.pf.flags & DDPF_FOURCC) && (header.pf.bitcount != 0))
- {
- printf("\tSwizzle: '%c%c%c%c' (0x%.8X)\n",
- (int)(header.pf.bitcount >> 0) & 0xFF,
- (int)(header.pf.bitcount >> 8) & 0xFF,
- (int)(header.pf.bitcount >> 16) & 0xFF,
- (int)(header.pf.bitcount >> 24) & 0xFF,
- header.pf.bitcount);
- }
- else
- {
- printf("\tBit count: %u\n", header.pf.bitcount);
- }
-
- printf("\tRed mask: 0x%.8X\n", header.pf.rmask);
- printf("\tGreen mask: 0x%.8X\n", header.pf.gmask);
- printf("\tBlue mask: 0x%.8X\n", header.pf.bmask);
- printf("\tAlpha mask: 0x%.8X\n", header.pf.amask);
-
- printf("Caps:\n");
- printf("\tCaps 1: 0x%.8X\n", header.caps.caps1);
- if (header.caps.caps1 & DDSCAPS_COMPLEX) printf("\t\tDDSCAPS_COMPLEX\n");
- if (header.caps.caps1 & DDSCAPS_TEXTURE) printf("\t\tDDSCAPS_TEXTURE\n");
- if (header.caps.caps1 & DDSCAPS_MIPMAP) printf("\t\tDDSCAPS_MIPMAP\n");
-
- printf("\tCaps 2: 0x%.8X\n", header.caps.caps2);
- if (header.caps.caps2 & DDSCAPS2_VOLUME) printf("\t\tDDSCAPS2_VOLUME\n");
- else if (header.caps.caps2 & DDSCAPS2_CUBEMAP)
- {
- printf("\t\tDDSCAPS2_CUBEMAP\n");
- if ((header.caps.caps2 & DDSCAPS2_CUBEMAP_ALL_FACES) == DDSCAPS2_CUBEMAP_ALL_FACES) printf("\t\tDDSCAPS2_CUBEMAP_ALL_FACES\n");
- else {
- if (header.caps.caps2 & DDSCAPS2_CUBEMAP_POSITIVEX) printf("\t\tDDSCAPS2_CUBEMAP_POSITIVEX\n");
- if (header.caps.caps2 & DDSCAPS2_CUBEMAP_NEGATIVEX) printf("\t\tDDSCAPS2_CUBEMAP_NEGATIVEX\n");
- if (header.caps.caps2 & DDSCAPS2_CUBEMAP_POSITIVEY) printf("\t\tDDSCAPS2_CUBEMAP_POSITIVEY\n");
- if (header.caps.caps2 & DDSCAPS2_CUBEMAP_NEGATIVEY) printf("\t\tDDSCAPS2_CUBEMAP_NEGATIVEY\n");
- if (header.caps.caps2 & DDSCAPS2_CUBEMAP_POSITIVEZ) printf("\t\tDDSCAPS2_CUBEMAP_POSITIVEZ\n");
- if (header.caps.caps2 & DDSCAPS2_CUBEMAP_NEGATIVEZ) printf("\t\tDDSCAPS2_CUBEMAP_NEGATIVEZ\n");
- }
- }
-
- printf("\tCaps 3: 0x%.8X\n", header.caps.caps3);
- printf("\tCaps 4: 0x%.8X\n", header.caps.caps4);
-
- if (header.hasDX10Header())
- {
- printf("DX10 Header:\n");
- printf("\tDXGI Format: %u (%s)\n", header.header10.dxgiFormat, getDxgiFormatString((DXGI_FORMAT)header.header10.dxgiFormat));
- printf("\tResource dimension: %u (%s)\n", header.header10.resourceDimension, getD3d10ResourceDimensionString((D3D10_RESOURCE_DIMENSION)header.header10.resourceDimension));
- printf("\tMisc flag: %u\n", header.header10.miscFlag);
- printf("\tArray size: %u\n", header.header10.arraySize);
- }
-
- if (header.reserved[9] == FOURCC_NVTT)
- {
- int major = (header.reserved[10] >> 16) & 0xFF;
- int minor = (header.reserved[10] >> 8) & 0xFF;
- int revision= header.reserved[10] & 0xFF;
-
- printf("Version:\n");
- printf("\tNVIDIA Texture Tools %d.%d.%d\n", major, minor, revision);
- }
-
- if (header.reserved[7] == FOURCC_UVER)
- {
- printf("User Version: %u\n", header.reserved[8]);
- }
+ printf("Flags: 0x%.8X\n", header.flags);
+ if (header.flags & DDSD_CAPS)
+ printf("\tDDSD_CAPS\n");
+ if (header.flags & DDSD_PIXELFORMAT)
+ printf("\tDDSD_PIXELFORMAT\n");
+ if (header.flags & DDSD_WIDTH)
+ printf("\tDDSD_WIDTH\n");
+ if (header.flags & DDSD_HEIGHT)
+ printf("\tDDSD_HEIGHT\n");
+ if (header.flags & DDSD_DEPTH)
+ printf("\tDDSD_DEPTH\n");
+ if (header.flags & DDSD_PITCH)
+ printf("\tDDSD_PITCH\n");
+ if (header.flags & DDSD_LINEARSIZE)
+ printf("\tDDSD_LINEARSIZE\n");
+ if (header.flags & DDSD_MIPMAPCOUNT)
+ printf("\tDDSD_MIPMAPCOUNT\n");
+
+ printf("Height: %u\n", header.height);
+ printf("Width: %u\n", header.width);
+ printf("Depth: %u\n", header.depth);
+ if (header.flags & DDSD_PITCH)
+ printf("Pitch: %u\n", header.pitch);
+ else if (header.flags & DDSD_LINEARSIZE)
+ printf("Linear size: %u\n", header.pitch);
+ printf("Mipmap count: %u\n", header.mipmapcount);
+
+ printf("Pixel Format:\n");
+ printf("\tFlags: 0x%.8X\n", header.pf.flags);
+ if (header.pf.flags & DDPF_RGB)
+ printf("\t\tDDPF_RGB\n");
+ if (header.pf.flags & DDPF_LUMINANCE)
+ printf("\t\tDDPF_LUMINANCE\n");
+ if (header.pf.flags & DDPF_FOURCC)
+ printf("\t\tDDPF_FOURCC\n");
+ if (header.pf.flags & DDPF_ALPHAPIXELS)
+ printf("\t\tDDPF_ALPHAPIXELS\n");
+ if (header.pf.flags & DDPF_ALPHA)
+ printf("\t\tDDPF_ALPHA\n");
+ if (header.pf.flags & DDPF_PALETTEINDEXED1)
+ printf("\t\tDDPF_PALETTEINDEXED1\n");
+ if (header.pf.flags & DDPF_PALETTEINDEXED2)
+ printf("\t\tDDPF_PALETTEINDEXED2\n");
+ if (header.pf.flags & DDPF_PALETTEINDEXED4)
+ printf("\t\tDDPF_PALETTEINDEXED4\n");
+ if (header.pf.flags & DDPF_PALETTEINDEXED8)
+ printf("\t\tDDPF_PALETTEINDEXED8\n");
+ if (header.pf.flags & DDPF_ALPHAPREMULT)
+ printf("\t\tDDPF_ALPHAPREMULT\n");
+ if (header.pf.flags & DDPF_NORMAL)
+ printf("\t\tDDPF_NORMAL\n");
+
+ if (header.pf.fourcc != 0) {
+ // Display fourcc code even when DDPF_FOURCC flag not set.
+ printf("\tFourCC: '%c%c%c%c' (0x%.8X)\n",
+ (int)((header.pf.fourcc >> 0) & 0xFF),
+ (int)((header.pf.fourcc >> 8) & 0xFF),
+ (int)((header.pf.fourcc >> 16) & 0xFF),
+ (int)((header.pf.fourcc >> 24) & 0xFF),
+ header.pf.fourcc);
+ }
+
+ if ((header.pf.flags & DDPF_FOURCC) && (header.pf.bitcount != 0)) {
+ printf("\tSwizzle: '%c%c%c%c' (0x%.8X)\n",
+ (int)(header.pf.bitcount >> 0) & 0xFF,
+ (int)(header.pf.bitcount >> 8) & 0xFF,
+ (int)(header.pf.bitcount >> 16) & 0xFF,
+ (int)(header.pf.bitcount >> 24) & 0xFF,
+ header.pf.bitcount);
+ }
+ else {
+ printf("\tBit count: %u\n", header.pf.bitcount);
+ }
+
+ printf("\tRed mask: 0x%.8X\n", header.pf.rmask);
+ printf("\tGreen mask: 0x%.8X\n", header.pf.gmask);
+ printf("\tBlue mask: 0x%.8X\n", header.pf.bmask);
+ printf("\tAlpha mask: 0x%.8X\n", header.pf.amask);
+
+ printf("Caps:\n");
+ printf("\tCaps 1: 0x%.8X\n", header.caps.caps1);
+ if (header.caps.caps1 & DDSCAPS_COMPLEX)
+ printf("\t\tDDSCAPS_COMPLEX\n");
+ if (header.caps.caps1 & DDSCAPS_TEXTURE)
+ printf("\t\tDDSCAPS_TEXTURE\n");
+ if (header.caps.caps1 & DDSCAPS_MIPMAP)
+ printf("\t\tDDSCAPS_MIPMAP\n");
+
+ printf("\tCaps 2: 0x%.8X\n", header.caps.caps2);
+ if (header.caps.caps2 & DDSCAPS2_VOLUME)
+ printf("\t\tDDSCAPS2_VOLUME\n");
+ else if (header.caps.caps2 & DDSCAPS2_CUBEMAP) {
+ printf("\t\tDDSCAPS2_CUBEMAP\n");
+ if ((header.caps.caps2 & DDSCAPS2_CUBEMAP_ALL_FACES) == DDSCAPS2_CUBEMAP_ALL_FACES)
+ printf("\t\tDDSCAPS2_CUBEMAP_ALL_FACES\n");
+ else {
+ if (header.caps.caps2 & DDSCAPS2_CUBEMAP_POSITIVEX)
+ printf("\t\tDDSCAPS2_CUBEMAP_POSITIVEX\n");
+ if (header.caps.caps2 & DDSCAPS2_CUBEMAP_NEGATIVEX)
+ printf("\t\tDDSCAPS2_CUBEMAP_NEGATIVEX\n");
+ if (header.caps.caps2 & DDSCAPS2_CUBEMAP_POSITIVEY)
+ printf("\t\tDDSCAPS2_CUBEMAP_POSITIVEY\n");
+ if (header.caps.caps2 & DDSCAPS2_CUBEMAP_NEGATIVEY)
+ printf("\t\tDDSCAPS2_CUBEMAP_NEGATIVEY\n");
+ if (header.caps.caps2 & DDSCAPS2_CUBEMAP_POSITIVEZ)
+ printf("\t\tDDSCAPS2_CUBEMAP_POSITIVEZ\n");
+ if (header.caps.caps2 & DDSCAPS2_CUBEMAP_NEGATIVEZ)
+ printf("\t\tDDSCAPS2_CUBEMAP_NEGATIVEZ\n");
+ }
+ }
+
+ printf("\tCaps 3: 0x%.8X\n", header.caps.caps3);
+ printf("\tCaps 4: 0x%.8X\n", header.caps.caps4);
+
+ if (header.hasDX10Header()) {
+ printf("DX10 Header:\n");
+ printf("\tDXGI Format: %u (%s)\n",
+ header.header10.dxgiFormat,
+ getDxgiFormatString((DXGI_FORMAT)header.header10.dxgiFormat));
+ printf("\tResource dimension: %u (%s)\n",
+ header.header10.resourceDimension,
+ getD3d10ResourceDimensionString(
+ (D3D10_RESOURCE_DIMENSION)header.header10.resourceDimension));
+ printf("\tMisc flag: %u\n", header.header10.miscFlag);
+ printf("\tArray size: %u\n", header.header10.arraySize);
+ }
+
+ if (header.reserved[9] == FOURCC_NVTT) {
+ int major = (header.reserved[10] >> 16) & 0xFF;
+ int minor = (header.reserved[10] >> 8) & 0xFF;
+ int revision = header.reserved[10] & 0xFF;
+
+ printf("Version:\n");
+ printf("\tNVIDIA Texture Tools %d.%d.%d\n", major, minor, revision);
+ }
+
+ if (header.reserved[7] == FOURCC_UVER) {
+ printf("User Version: %u\n", header.reserved[8]);
+ }
}
diff --git a/source/blender/imbuf/intern/dds/DirectDrawSurface.h b/source/blender/imbuf/intern/dds/DirectDrawSurface.h
index 8166e6b0831..54bd1ad2dcd 100644
--- a/source/blender/imbuf/intern/dds/DirectDrawSurface.h
+++ b/source/blender/imbuf/intern/dds/DirectDrawSurface.h
@@ -18,7 +18,6 @@
* \ingroup imbdds
*/
-
/*
* This file is based on a similar file from the NVIDIA texture tools
* (http://nvidia-texture-tools.googlecode.com/)
@@ -58,136 +57,132 @@
#include <Image.h>
struct DDSPixelFormat {
- uint size;
- uint flags;
- uint fourcc;
- uint bitcount;
- uint rmask;
- uint gmask;
- uint bmask;
- uint amask;
+ uint size;
+ uint flags;
+ uint fourcc;
+ uint bitcount;
+ uint rmask;
+ uint gmask;
+ uint bmask;
+ uint amask;
};
struct DDSCaps {
- uint caps1;
- uint caps2;
- uint caps3;
- uint caps4;
+ uint caps1;
+ uint caps2;
+ uint caps3;
+ uint caps4;
};
/// DDS file header for DX10.
struct DDSHeader10 {
- uint dxgiFormat;
- uint resourceDimension;
- uint miscFlag;
- uint arraySize;
- uint reserved;
+ uint dxgiFormat;
+ uint resourceDimension;
+ uint miscFlag;
+ uint arraySize;
+ uint reserved;
};
/// DDS file header.
struct DDSHeader {
- uint fourcc;
- uint size;
- uint flags;
- uint height;
- uint width;
- uint pitch;
- uint depth;
- uint mipmapcount;
- uint reserved[11];
- DDSPixelFormat pf;
- DDSCaps caps;
- uint notused;
- DDSHeader10 header10;
-
-
- // Helper methods.
- DDSHeader();
-
- void setWidth(uint w);
- void setHeight(uint h);
- void setDepth(uint d);
- void setMipmapCount(uint count);
- void setTexture2D();
- void setTexture3D();
- void setTextureCube();
- void setLinearSize(uint size);
- void setPitch(uint pitch);
- void setFourCC(uint8 c0, uint8 c1, uint8 c2, uint8 c3);
- void setFormatCode(uint code);
- void setSwizzleCode(uint8 c0, uint8 c1, uint8 c2, uint8 c3);
- void setPixelFormat(uint bitcount, uint rmask, uint gmask, uint bmask, uint amask);
- void setDX10Format(uint format);
- void setNormalFlag(bool b);
- void setSrgbFlag(bool b);
- void setHasAlphaFlag(bool b);
- void setUserVersion(int version);
-
- /*void swapBytes();*/
-
- bool hasDX10Header() const;
- uint signature() const;
- uint toolVersion() const;
- uint userVersion() const;
- bool isNormalMap() const;
- bool isSrgb() const;
- bool hasAlpha() const;
- uint d3d9Format() const;
+ uint fourcc;
+ uint size;
+ uint flags;
+ uint height;
+ uint width;
+ uint pitch;
+ uint depth;
+ uint mipmapcount;
+ uint reserved[11];
+ DDSPixelFormat pf;
+ DDSCaps caps;
+ uint notused;
+ DDSHeader10 header10;
+
+ // Helper methods.
+ DDSHeader();
+
+ void setWidth(uint w);
+ void setHeight(uint h);
+ void setDepth(uint d);
+ void setMipmapCount(uint count);
+ void setTexture2D();
+ void setTexture3D();
+ void setTextureCube();
+ void setLinearSize(uint size);
+ void setPitch(uint pitch);
+ void setFourCC(uint8 c0, uint8 c1, uint8 c2, uint8 c3);
+ void setFormatCode(uint code);
+ void setSwizzleCode(uint8 c0, uint8 c1, uint8 c2, uint8 c3);
+ void setPixelFormat(uint bitcount, uint rmask, uint gmask, uint bmask, uint amask);
+ void setDX10Format(uint format);
+ void setNormalFlag(bool b);
+ void setSrgbFlag(bool b);
+ void setHasAlphaFlag(bool b);
+ void setUserVersion(int version);
+
+ /*void swapBytes();*/
+
+ bool hasDX10Header() const;
+ uint signature() const;
+ uint toolVersion() const;
+ uint userVersion() const;
+ bool isNormalMap() const;
+ bool isSrgb() const;
+ bool hasAlpha() const;
+ uint d3d9Format() const;
};
/// DirectDraw Surface. (DDS)
-class DirectDrawSurface
-{
-public:
- DirectDrawSurface(unsigned char *mem, uint size);
- ~DirectDrawSurface();
-
- bool isValid() const;
- bool isSupported() const;
-
- bool hasAlpha() const;
-
- uint mipmapCount() const;
- uint fourCC() const;
- uint width() const;
- uint height() const;
- uint depth() const;
- bool isTexture1D() const;
- bool isTexture2D() const;
- bool isTexture3D() const;
- bool isTextureCube() const;
-
- void setNormalFlag(bool b);
- void setHasAlphaFlag(bool b);
- void setUserVersion(int version);
-
- void mipmap(Image *img, uint f, uint m);
- void *readData(uint &size);
- // void mipmap(FloatImage *img, uint f, uint m);
-
- void printInfo() const;
-
-private:
-
- uint blockSize() const;
- uint faceSize() const;
- uint mipmapSize(uint m) const;
-
- uint offset(uint f, uint m);
-
- void readLinearImage(Image * img);
- void readBlockImage(Image * img);
- void readBlock(ColorBlock * rgba);
-
-
-private:
- Stream stream; // memory where DDS file resides
- DDSHeader header;
+class DirectDrawSurface {
+ public:
+ DirectDrawSurface(unsigned char *mem, uint size);
+ ~DirectDrawSurface();
+
+ bool isValid() const;
+ bool isSupported() const;
+
+ bool hasAlpha() const;
+
+ uint mipmapCount() const;
+ uint fourCC() const;
+ uint width() const;
+ uint height() const;
+ uint depth() const;
+ bool isTexture1D() const;
+ bool isTexture2D() const;
+ bool isTexture3D() const;
+ bool isTextureCube() const;
+
+ void setNormalFlag(bool b);
+ void setHasAlphaFlag(bool b);
+ void setUserVersion(int version);
+
+ void mipmap(Image *img, uint f, uint m);
+ void *readData(uint &size);
+ // void mipmap(FloatImage *img, uint f, uint m);
+
+ void printInfo() const;
+
+ private:
+ uint blockSize() const;
+ uint faceSize() const;
+ uint mipmapSize(uint m) const;
+
+ uint offset(uint f, uint m);
+
+ void readLinearImage(Image *img);
+ void readBlockImage(Image *img);
+ void readBlock(ColorBlock *rgba);
+
+ private:
+ Stream stream; // memory where DDS file resides
+ DDSHeader header;
};
-void mem_read(Stream & mem, DDSPixelFormat & pf);
-void mem_read(Stream & mem, DDSCaps & caps);
-void mem_read(Stream & mem, DDSHeader & header);
-void mem_read(Stream & mem, DDSHeader10 & header);
+void mem_read(Stream &mem, DDSPixelFormat &pf);
+void mem_read(Stream &mem, DDSCaps &caps);
+void mem_read(Stream &mem, DDSHeader &header);
+void mem_read(Stream &mem, DDSHeader10 &header);
-#endif /* __DIRECTDRAWSURFACE_H__ */
+#endif /* __DIRECTDRAWSURFACE_H__ */
diff --git a/source/blender/imbuf/intern/dds/FlipDXT.cpp b/source/blender/imbuf/intern/dds/FlipDXT.cpp
index 50488b923db..0660d5ce5cc 100644
--- a/source/blender/imbuf/intern/dds/FlipDXT.cpp
+++ b/source/blender/imbuf/intern/dds/FlipDXT.cpp
@@ -50,207 +50,205 @@ typedef void (*FlipBlockFunction)(uint8_t *block);
// Flips a full DXT1 block in the y direction.
static void FlipDXT1BlockFull(uint8_t *block)
{
- // A DXT1 block layout is:
- // [0-1] color0.
- // [2-3] color1.
- // [4-7] color bitmap, 2 bits per pixel.
- // So each of the 4-7 bytes represents one line, flipping a block is just
- // flipping those bytes.
- uint8_t tmp = block[4];
- block[4] = block[7];
- block[7] = tmp;
- tmp = block[5];
- block[5] = block[6];
- block[6] = tmp;
+ // A DXT1 block layout is:
+ // [0-1] color0.
+ // [2-3] color1.
+ // [4-7] color bitmap, 2 bits per pixel.
+ // So each of the 4-7 bytes represents one line, flipping a block is just
+ // flipping those bytes.
+ uint8_t tmp = block[4];
+ block[4] = block[7];
+ block[7] = tmp;
+ tmp = block[5];
+ block[5] = block[6];
+ block[6] = tmp;
}
// Flips the first 2 lines of a DXT1 block in the y direction.
static void FlipDXT1BlockHalf(uint8_t *block)
{
- // See layout above.
- uint8_t tmp = block[4];
- block[4] = block[5];
- block[5] = tmp;
+ // See layout above.
+ uint8_t tmp = block[4];
+ block[4] = block[5];
+ block[5] = tmp;
}
// Flips a full DXT3 block in the y direction.
static void FlipDXT3BlockFull(uint8_t *block)
{
- // A DXT3 block layout is:
- // [0-7] alpha bitmap, 4 bits per pixel.
- // [8-15] a DXT1 block.
-
- // We can flip the alpha bits at the byte level (2 bytes per line).
- uint8_t tmp = block[0];
-
- block[0] = block[6];
- block[6] = tmp;
- tmp = block[1];
- block[1] = block[7];
- block[7] = tmp;
- tmp = block[2];
- block[2] = block[4];
- block[4] = tmp;
- tmp = block[3];
- block[3] = block[5];
- block[5] = tmp;
-
- // And flip the DXT1 block using the above function.
- FlipDXT1BlockFull(block + 8);
+ // A DXT3 block layout is:
+ // [0-7] alpha bitmap, 4 bits per pixel.
+ // [8-15] a DXT1 block.
+
+ // We can flip the alpha bits at the byte level (2 bytes per line).
+ uint8_t tmp = block[0];
+
+ block[0] = block[6];
+ block[6] = tmp;
+ tmp = block[1];
+ block[1] = block[7];
+ block[7] = tmp;
+ tmp = block[2];
+ block[2] = block[4];
+ block[4] = tmp;
+ tmp = block[3];
+ block[3] = block[5];
+ block[5] = tmp;
+
+ // And flip the DXT1 block using the above function.
+ FlipDXT1BlockFull(block + 8);
}
// Flips the first 2 lines of a DXT3 block in the y direction.
static void FlipDXT3BlockHalf(uint8_t *block)
{
- // See layout above.
- uint8_t tmp = block[0];
-
- block[0] = block[2];
- block[2] = tmp;
- tmp = block[1];
- block[1] = block[3];
- block[3] = tmp;
- FlipDXT1BlockHalf(block + 8);
+ // See layout above.
+ uint8_t tmp = block[0];
+
+ block[0] = block[2];
+ block[2] = tmp;
+ tmp = block[1];
+ block[1] = block[3];
+ block[3] = tmp;
+ FlipDXT1BlockHalf(block + 8);
}
// Flips a full DXT5 block in the y direction.
static void FlipDXT5BlockFull(uint8_t *block)
{
- // A DXT5 block layout is:
- // [0] alpha0.
- // [1] alpha1.
- // [2-7] alpha bitmap, 3 bits per pixel.
- // [8-15] a DXT1 block.
-
- // The alpha bitmap doesn't easily map lines to bytes, so we have to
- // interpret it correctly. Extracted from
- // http://www.opengl.org/registry/specs/EXT/texture_compression_s3tc.txt :
- //
- // The 6 "bits" bytes of the block are decoded into one 48-bit integer:
- //
- // bits = bits_0 + 256 * (bits_1 + 256 * (bits_2 + 256 * (bits_3 +
- // 256 * (bits_4 + 256 * bits_5))))
- //
- // bits is a 48-bit unsigned integer, from which a three-bit control code
- // is extracted for a texel at location (x,y) in the block using:
- //
- // code(x,y) = bits[3*(4*y+x)+1..3*(4*y+x)+0]
- //
- // where bit 47 is the most significant and bit 0 is the least
- // significant bit.
- unsigned int line_0_1 = block[2] + 256 * (block[3] + 256 * block[4]);
- unsigned int line_2_3 = block[5] + 256 * (block[6] + 256 * block[7]);
- // swap lines 0 and 1 in line_0_1.
- unsigned int line_1_0 = ((line_0_1 & 0x000fff) << 12) |
- ((line_0_1 & 0xfff000) >> 12);
- // swap lines 2 and 3 in line_2_3.
- unsigned int line_3_2 = ((line_2_3 & 0x000fff) << 12) |
- ((line_2_3 & 0xfff000) >> 12);
-
- block[2] = line_3_2 & 0xff;
- block[3] = (line_3_2 & 0xff00) >> 8;
- block[4] = (line_3_2 & 0xff0000) >> 16;
- block[5] = line_1_0 & 0xff;
- block[6] = (line_1_0 & 0xff00) >> 8;
- block[7] = (line_1_0 & 0xff0000) >> 16;
-
- // And flip the DXT1 block using the above function.
- FlipDXT1BlockFull(block + 8);
+ // A DXT5 block layout is:
+ // [0] alpha0.
+ // [1] alpha1.
+ // [2-7] alpha bitmap, 3 bits per pixel.
+ // [8-15] a DXT1 block.
+
+ // The alpha bitmap doesn't easily map lines to bytes, so we have to
+ // interpret it correctly. Extracted from
+ // http://www.opengl.org/registry/specs/EXT/texture_compression_s3tc.txt :
+ //
+ // The 6 "bits" bytes of the block are decoded into one 48-bit integer:
+ //
+ // bits = bits_0 + 256 * (bits_1 + 256 * (bits_2 + 256 * (bits_3 +
+ // 256 * (bits_4 + 256 * bits_5))))
+ //
+ // bits is a 48-bit unsigned integer, from which a three-bit control code
+ // is extracted for a texel at location (x,y) in the block using:
+ //
+ // code(x,y) = bits[3*(4*y+x)+1..3*(4*y+x)+0]
+ //
+ // where bit 47 is the most significant and bit 0 is the least
+ // significant bit.
+ unsigned int line_0_1 = block[2] + 256 * (block[3] + 256 * block[4]);
+ unsigned int line_2_3 = block[5] + 256 * (block[6] + 256 * block[7]);
+ // swap lines 0 and 1 in line_0_1.
+ unsigned int line_1_0 = ((line_0_1 & 0x000fff) << 12) | ((line_0_1 & 0xfff000) >> 12);
+ // swap lines 2 and 3 in line_2_3.
+ unsigned int line_3_2 = ((line_2_3 & 0x000fff) << 12) | ((line_2_3 & 0xfff000) >> 12);
+
+ block[2] = line_3_2 & 0xff;
+ block[3] = (line_3_2 & 0xff00) >> 8;
+ block[4] = (line_3_2 & 0xff0000) >> 16;
+ block[5] = line_1_0 & 0xff;
+ block[6] = (line_1_0 & 0xff00) >> 8;
+ block[7] = (line_1_0 & 0xff0000) >> 16;
+
+ // And flip the DXT1 block using the above function.
+ FlipDXT1BlockFull(block + 8);
}
// Flips the first 2 lines of a DXT5 block in the y direction.
static void FlipDXT5BlockHalf(uint8_t *block)
{
- // See layout above.
- unsigned int line_0_1 = block[2] + 256 * (block[3] + 256 * block[4]);
- unsigned int line_1_0 = ((line_0_1 & 0x000fff) << 12) |
- ((line_0_1 & 0xfff000) >> 12);
- block[2] = line_1_0 & 0xff;
- block[3] = (line_1_0 & 0xff00) >> 8;
- block[4] = (line_1_0 & 0xff0000) >> 16;
- FlipDXT1BlockHalf(block + 8);
+ // See layout above.
+ unsigned int line_0_1 = block[2] + 256 * (block[3] + 256 * block[4]);
+ unsigned int line_1_0 = ((line_0_1 & 0x000fff) << 12) | ((line_0_1 & 0xfff000) >> 12);
+ block[2] = line_1_0 & 0xff;
+ block[3] = (line_1_0 & 0xff00) >> 8;
+ block[4] = (line_1_0 & 0xff0000) >> 16;
+ FlipDXT1BlockHalf(block + 8);
}
// Flips a DXTC image, by flipping and swapping DXTC blocks as appropriate.
-int FlipDXTCImage(unsigned int width, unsigned int height, unsigned int levels, int fourcc, uint8_t *data)
+int FlipDXTCImage(
+ unsigned int width, unsigned int height, unsigned int levels, int fourcc, uint8_t *data)
{
- // must have valid dimensions
- if (width == 0 || height == 0)
- return 0;
- // height must be a power-of-two
- if ((height & (height - 1)) != 0)
- return 0;
-
- FlipBlockFunction full_block_function;
- FlipBlockFunction half_block_function;
- unsigned int block_bytes = 0;
-
- switch (fourcc) {
- case FOURCC_DXT1:
- full_block_function = FlipDXT1BlockFull;
- half_block_function = FlipDXT1BlockHalf;
- block_bytes = 8;
- break;
- case FOURCC_DXT3:
- full_block_function = FlipDXT3BlockFull;
- half_block_function = FlipDXT3BlockHalf;
- block_bytes = 16;
- break;
- case FOURCC_DXT5:
- full_block_function = FlipDXT5BlockFull;
- half_block_function = FlipDXT5BlockHalf;
- block_bytes = 16;
- break;
- default:
- return 0;
- }
-
- unsigned int mip_width = width;
- unsigned int mip_height = height;
-
- for (unsigned int i = 0; i < levels; ++i) {
- unsigned int blocks_per_row = (mip_width + 3) / 4;
- unsigned int blocks_per_col = (mip_height + 3) / 4;
- unsigned int blocks = blocks_per_row * blocks_per_col;
-
- if (mip_height == 1) {
- // no flip to do, and we're done.
- break;
- }
- else if (mip_height == 2) {
- // flip the first 2 lines in each block.
- for (unsigned int i = 0; i < blocks_per_row; ++i) {
- half_block_function(data + i * block_bytes);
- }
- }
- else {
- // flip each block.
- for (unsigned int i = 0; i < blocks; ++i)
- full_block_function(data + i * block_bytes);
-
- // swap each block line in the first half of the image with the
- // corresponding one in the second half.
- // note that this is a no-op if mip_height is 4.
- unsigned int row_bytes = block_bytes * blocks_per_row;
- uint8_t *temp_line = new uint8_t[row_bytes];
-
- for (unsigned int y = 0; y < blocks_per_col / 2; ++y) {
- uint8_t *line1 = data + y * row_bytes;
- uint8_t *line2 = data + (blocks_per_col - y - 1) * row_bytes;
-
- memcpy(temp_line, line1, row_bytes);
- memcpy(line1, line2, row_bytes);
- memcpy(line2, temp_line, row_bytes);
- }
-
- delete[] temp_line;
- }
-
- // mip levels are contiguous.
- data += block_bytes * blocks;
- mip_width = MAX(1U, mip_width >> 1);
- mip_height = MAX(1U, mip_height >> 1);
- }
-
- return 1;
+ // must have valid dimensions
+ if (width == 0 || height == 0)
+ return 0;
+ // height must be a power-of-two
+ if ((height & (height - 1)) != 0)
+ return 0;
+
+ FlipBlockFunction full_block_function;
+ FlipBlockFunction half_block_function;
+ unsigned int block_bytes = 0;
+
+ switch (fourcc) {
+ case FOURCC_DXT1:
+ full_block_function = FlipDXT1BlockFull;
+ half_block_function = FlipDXT1BlockHalf;
+ block_bytes = 8;
+ break;
+ case FOURCC_DXT3:
+ full_block_function = FlipDXT3BlockFull;
+ half_block_function = FlipDXT3BlockHalf;
+ block_bytes = 16;
+ break;
+ case FOURCC_DXT5:
+ full_block_function = FlipDXT5BlockFull;
+ half_block_function = FlipDXT5BlockHalf;
+ block_bytes = 16;
+ break;
+ default:
+ return 0;
+ }
+
+ unsigned int mip_width = width;
+ unsigned int mip_height = height;
+
+ for (unsigned int i = 0; i < levels; ++i) {
+ unsigned int blocks_per_row = (mip_width + 3) / 4;
+ unsigned int blocks_per_col = (mip_height + 3) / 4;
+ unsigned int blocks = blocks_per_row * blocks_per_col;
+
+ if (mip_height == 1) {
+ // no flip to do, and we're done.
+ break;
+ }
+ else if (mip_height == 2) {
+ // flip the first 2 lines in each block.
+ for (unsigned int i = 0; i < blocks_per_row; ++i) {
+ half_block_function(data + i * block_bytes);
+ }
+ }
+ else {
+ // flip each block.
+ for (unsigned int i = 0; i < blocks; ++i)
+ full_block_function(data + i * block_bytes);
+
+ // swap each block line in the first half of the image with the
+ // corresponding one in the second half.
+ // note that this is a no-op if mip_height is 4.
+ unsigned int row_bytes = block_bytes * blocks_per_row;
+ uint8_t *temp_line = new uint8_t[row_bytes];
+
+ for (unsigned int y = 0; y < blocks_per_col / 2; ++y) {
+ uint8_t *line1 = data + y * row_bytes;
+ uint8_t *line2 = data + (blocks_per_col - y - 1) * row_bytes;
+
+ memcpy(temp_line, line1, row_bytes);
+ memcpy(line1, line2, row_bytes);
+ memcpy(line2, temp_line, row_bytes);
+ }
+
+ delete[] temp_line;
+ }
+
+ // mip levels are contiguous.
+ data += block_bytes * blocks;
+ mip_width = MAX(1U, mip_width >> 1);
+ mip_height = MAX(1U, mip_height >> 1);
+ }
+
+ return 1;
}
diff --git a/source/blender/imbuf/intern/dds/FlipDXT.h b/source/blender/imbuf/intern/dds/FlipDXT.h
index 7d70395f1fa..b7056742430 100644
--- a/source/blender/imbuf/intern/dds/FlipDXT.h
+++ b/source/blender/imbuf/intern/dds/FlipDXT.h
@@ -20,6 +20,7 @@
#include "BLI_sys_types.h"
/* flip compressed DXT image vertically to fit OpenGL convention */
-int FlipDXTCImage(unsigned int width, unsigned int height, unsigned int levels, int fourcc, uint8_t *data);
+int FlipDXTCImage(
+ unsigned int width, unsigned int height, unsigned int levels, int fourcc, uint8_t *data);
#endif
diff --git a/source/blender/imbuf/intern/dds/Image.cpp b/source/blender/imbuf/intern/dds/Image.cpp
index 642194fa39b..6f0fff75818 100644
--- a/source/blender/imbuf/intern/dds/Image.cpp
+++ b/source/blender/imbuf/intern/dds/Image.cpp
@@ -18,7 +18,6 @@
* \ingroup imbdds
*/
-
/*
* This file is based on a similar file from the NVIDIA texture tools
* (http://nvidia-texture-tools.googlecode.com/)
@@ -31,7 +30,7 @@
#include <Color.h>
#include <Image.h>
-#include <stdio.h> // printf
+#include <stdio.h> // printf
Image::Image() : m_width(0), m_height(0), m_format(Format_RGB), m_data(NULL)
{
@@ -39,87 +38,86 @@ Image::Image() : m_width(0), m_height(0), m_format(Format_RGB), m_data(NULL)
Image::~Image()
{
- free();
+ free();
}
void Image::allocate(uint w, uint h)
{
- free();
- m_width = w;
- m_height = h;
- m_data = new Color32[w * h];
+ free();
+ m_width = w;
+ m_height = h;
+ m_data = new Color32[w * h];
}
void Image::free()
{
- if (m_data) delete [] m_data;
- m_data = NULL;
+ if (m_data)
+ delete[] m_data;
+ m_data = NULL;
}
-
uint Image::width() const
{
- return m_width;
+ return m_width;
}
uint Image::height() const
{
- return m_height;
+ return m_height;
}
-const Color32 * Image::scanline(uint h) const
+const Color32 *Image::scanline(uint h) const
{
- if (h >= m_height) {
- printf("DDS: scanline beyond dimensions of image\n");
- return m_data;
- }
- return m_data + h * m_width;
+ if (h >= m_height) {
+ printf("DDS: scanline beyond dimensions of image\n");
+ return m_data;
+ }
+ return m_data + h * m_width;
}
Color32 *Image::scanline(uint h)
{
- if (h >= m_height) {
- printf("DDS: scanline beyond dimensions of image\n");
- return m_data;
- }
- return m_data + h * m_width;
+ if (h >= m_height) {
+ printf("DDS: scanline beyond dimensions of image\n");
+ return m_data;
+ }
+ return m_data + h * m_width;
}
const Color32 *Image::pixels() const
{
- return m_data;
+ return m_data;
}
Color32 *Image::pixels()
{
- return m_data;
+ return m_data;
}
-const Color32 & Image::pixel(uint idx) const
+const Color32 &Image::pixel(uint idx) const
{
- if (idx >= m_width * m_height) {
- printf("DDS: pixel beyond dimensions of image\n");
- return m_data[0];
- }
- return m_data[idx];
+ if (idx >= m_width * m_height) {
+ printf("DDS: pixel beyond dimensions of image\n");
+ return m_data[0];
+ }
+ return m_data[idx];
}
-Color32 & Image::pixel(uint idx)
+Color32 &Image::pixel(uint idx)
{
- if (idx >= m_width * m_height) {
- printf("DDS: pixel beyond dimensions of image\n");
- return m_data[0];
- }
- return m_data[idx];
+ if (idx >= m_width * m_height) {
+ printf("DDS: pixel beyond dimensions of image\n");
+ return m_data[0];
+ }
+ return m_data[idx];
}
-
Image::Format Image::format() const
{
- return m_format;
+ return m_format;
}
void Image::setFormat(Image::Format f)
{
- m_format = f;
+ m_format = f;
}
diff --git a/source/blender/imbuf/intern/dds/Image.h b/source/blender/imbuf/intern/dds/Image.h
index fa8cacd3142..b6191b7e96c 100644
--- a/source/blender/imbuf/intern/dds/Image.h
+++ b/source/blender/imbuf/intern/dds/Image.h
@@ -18,7 +18,6 @@
* \ingroup imbdds
*/
-
/*
* This file is based on a similar file from the NVIDIA texture tools
* (http://nvidia-texture-tools.googlecode.com/)
@@ -35,64 +34,60 @@
#include <Color.h>
/// 32 bit RGBA image.
-class Image
-{
-public:
+class Image {
+ public:
+ enum Format {
+ Format_RGB,
+ Format_ARGB,
+ };
- enum Format
- {
- Format_RGB,
- Format_ARGB,
- };
+ Image();
+ ~Image();
- Image();
- ~Image();
-
- void allocate(uint w, uint h);
+ void allocate(uint w, uint h);
#if 0
- bool load(const char *name);
+ bool load(const char *name);
- void wrap(void *data, uint w, uint h);
- void unwrap();
+ void wrap(void *data, uint w, uint h);
+ void unwrap();
#endif
- uint width() const;
- uint height() const;
+ uint width() const;
+ uint height() const;
- const Color32 *scanline(uint h) const;
- Color32 *scanline(uint h);
+ const Color32 *scanline(uint h) const;
+ Color32 *scanline(uint h);
- const Color32 *pixels() const;
- Color32 *pixels();
+ const Color32 *pixels() const;
+ Color32 *pixels();
- const Color32 & pixel(uint idx) const;
- Color32 & pixel(uint idx);
+ const Color32 &pixel(uint idx) const;
+ Color32 &pixel(uint idx);
- const Color32 & pixel(uint x, uint y) const;
- Color32 & pixel(uint x, uint y);
+ const Color32 &pixel(uint x, uint y) const;
+ Color32 &pixel(uint x, uint y);
- Format format() const;
- void setFormat(Format f);
+ Format format() const;
+ void setFormat(Format f);
-private:
- void free();
+ private:
+ void free();
-private:
- uint m_width;
- uint m_height;
- Format m_format;
- Color32 *m_data;
+ private:
+ uint m_width;
+ uint m_height;
+ Format m_format;
+ Color32 *m_data;
};
-
-inline const Color32 & Image::pixel(uint x, uint y) const
+inline const Color32 &Image::pixel(uint x, uint y) const
{
- return pixel(y * width() + x);
+ return pixel(y * width() + x);
}
-inline Color32 & Image::pixel(uint x, uint y)
+inline Color32 &Image::pixel(uint x, uint y)
{
- return pixel(y * width() + x);
+ return pixel(y * width() + x);
}
-#endif /* __IMAGE_H__ */
+#endif /* __IMAGE_H__ */
diff --git a/source/blender/imbuf/intern/dds/PixelFormat.h b/source/blender/imbuf/intern/dds/PixelFormat.h
index 7c50245858f..07912b86f47 100644
--- a/source/blender/imbuf/intern/dds/PixelFormat.h
+++ b/source/blender/imbuf/intern/dds/PixelFormat.h
@@ -18,7 +18,6 @@
* \ingroup imbdds
*/
-
/*
* This file is based on a similar file from the NVIDIA texture tools
* (http://nvidia-texture-tools.googlecode.com/)
@@ -54,79 +53,78 @@
#include <Common.h>
- namespace PixelFormat
- {
-
- // Convert component \a c having \a inbits to the returned value having \a outbits.
- inline uint convert(uint c, uint inbits, uint outbits)
- {
- if (inbits == 0) {
- return 0;
- }
- else if (inbits >= outbits) {
- // truncate
- return c >> (inbits - outbits);
- }
- else {
- // bitexpand
- return (c << (outbits - inbits)) | convert(c, inbits, outbits - inbits);
- }
- }
-
- // Get pixel component shift and size given its mask.
- inline void maskShiftAndSize(uint mask, uint *shift, uint *size)
- {
- if (!mask) {
- *shift = 0;
- *size = 0;
- return;
- }
-
- *shift = 0;
- while ((mask & 1) == 0) {
- ++(*shift);
- mask >>= 1;
- }
-
- *size = 0;
- while ((mask & 1) == 1) {
- ++(*size);
- mask >>= 1;
- }
- }
-
- inline float quantizeCeil(float f, int inbits, int outbits)
- {
- //uint i = f * (float(1 << inbits) - 1);
- //i = convert(i, inbits, outbits);
- //float result = float(i) / (float(1 << outbits) - 1);
- //nvCheck(result >= f);
- float result;
- int offset = 0;
- do {
- uint i = offset + uint(f * (float(1 << inbits) - 1));
- i = convert(i, inbits, outbits);
- result = float(i) / (float(1 << outbits) - 1);
- offset++;
- } while (result < f);
-
- return result;
- }
+namespace PixelFormat {
+
+// Convert component \a c having \a inbits to the returned value having \a outbits.
+inline uint convert(uint c, uint inbits, uint outbits)
+{
+ if (inbits == 0) {
+ return 0;
+ }
+ else if (inbits >= outbits) {
+ // truncate
+ return c >> (inbits - outbits);
+ }
+ else {
+ // bitexpand
+ return (c << (outbits - inbits)) | convert(c, inbits, outbits - inbits);
+ }
+}
+
+// Get pixel component shift and size given its mask.
+inline void maskShiftAndSize(uint mask, uint *shift, uint *size)
+{
+ if (!mask) {
+ *shift = 0;
+ *size = 0;
+ return;
+ }
+
+ *shift = 0;
+ while ((mask & 1) == 0) {
+ ++(*shift);
+ mask >>= 1;
+ }
+
+ *size = 0;
+ while ((mask & 1) == 1) {
+ ++(*size);
+ mask >>= 1;
+ }
+}
+
+inline float quantizeCeil(float f, int inbits, int outbits)
+{
+ //uint i = f * (float(1 << inbits) - 1);
+ //i = convert(i, inbits, outbits);
+ //float result = float(i) / (float(1 << outbits) - 1);
+ //nvCheck(result >= f);
+ float result;
+ int offset = 0;
+ do {
+ uint i = offset + uint(f * (float(1 << inbits) - 1));
+ i = convert(i, inbits, outbits);
+ result = float(i) / (float(1 << outbits) - 1);
+ offset++;
+ } while (result < f);
+
+ return result;
+}
#if 0
- inline float quantizeRound(float f, int bits)
- {
- float scale = float(1 << bits);
- return fround(f * scale) / scale;
- }
-
- inline float quantizeFloor(float f, int bits)
- {
- float scale = float(1 << bits);
- return floor(f * scale) / scale;
- }
+ inline float quantizeRound(float f, int bits)
+ {
+ float scale = float(1 << bits);
+ return fround(f * scale) / scale;
+ }
+
+ inline float quantizeFloor(float f, int bits)
+ {
+ float scale = float(1 << bits);
+ return floor(f * scale) / scale;
+ }
#endif
- } // PixelFormat namespace
+} // namespace PixelFormat
-#endif /* __PIXELFORMAT_H__ */
+#endif /* __PIXELFORMAT_H__ */
diff --git a/source/blender/imbuf/intern/dds/Stream.cpp b/source/blender/imbuf/intern/dds/Stream.cpp
index 993fa7734ba..271717f165c 100644
--- a/source/blender/imbuf/intern/dds/Stream.cpp
+++ b/source/blender/imbuf/intern/dds/Stream.cpp
@@ -18,86 +18,85 @@
* \ingroup imbdds
*/
-
#include <Stream.h>
-#include <stdio.h> // printf
-#include <string.h> // memcpy
+#include <stdio.h> // printf
+#include <string.h> // memcpy
static const char *msg_error_seek = "DDS: trying to seek beyond end of stream (corrupt file?)";
static const char *msg_error_read = "DDS: trying to read beyond end of stream (corrupt file?)";
unsigned int Stream::seek(unsigned int p)
{
- if (p > size) {
- set_failed(msg_error_seek);
- }
- else {
- pos = p;
- }
+ if (p > size) {
+ set_failed(msg_error_seek);
+ }
+ else {
+ pos = p;
+ }
- return pos;
+ return pos;
}
-unsigned int mem_read(Stream & mem, unsigned long long & i)
+unsigned int mem_read(Stream &mem, unsigned long long &i)
{
- if (mem.pos + 8 > mem.size) {
- mem.set_failed(msg_error_seek);
- return(0);
- }
- memcpy(&i, mem.mem + mem.pos, 8); // @@ todo: make sure little endian
- mem.pos += 8;
- return(8);
+ if (mem.pos + 8 > mem.size) {
+ mem.set_failed(msg_error_seek);
+ return (0);
+ }
+ memcpy(&i, mem.mem + mem.pos, 8); // @@ todo: make sure little endian
+ mem.pos += 8;
+ return (8);
}
-unsigned int mem_read(Stream & mem, unsigned int & i)
+unsigned int mem_read(Stream &mem, unsigned int &i)
{
- if (mem.pos + 4 > mem.size) {
- mem.set_failed(msg_error_read);
- return(0);
- }
- memcpy(&i, mem.mem + mem.pos, 4); // @@ todo: make sure little endian
- mem.pos += 4;
- return(4);
+ if (mem.pos + 4 > mem.size) {
+ mem.set_failed(msg_error_read);
+ return (0);
+ }
+ memcpy(&i, mem.mem + mem.pos, 4); // @@ todo: make sure little endian
+ mem.pos += 4;
+ return (4);
}
-unsigned int mem_read(Stream & mem, unsigned short & i)
+unsigned int mem_read(Stream &mem, unsigned short &i)
{
- if (mem.pos + 2 > mem.size) {
- mem.set_failed(msg_error_read);
- return(0);
- }
- memcpy(&i, mem.mem + mem.pos, 2); // @@ todo: make sure little endian
- mem.pos += 2;
- return(2);
+ if (mem.pos + 2 > mem.size) {
+ mem.set_failed(msg_error_read);
+ return (0);
+ }
+ memcpy(&i, mem.mem + mem.pos, 2); // @@ todo: make sure little endian
+ mem.pos += 2;
+ return (2);
}
-unsigned int mem_read(Stream & mem, unsigned char & i)
+unsigned int mem_read(Stream &mem, unsigned char &i)
{
- if (mem.pos + 1 > mem.size) {
- mem.set_failed(msg_error_read);
- return(0);
- }
- i = (mem.mem + mem.pos)[0];
- mem.pos += 1;
- return(1);
+ if (mem.pos + 1 > mem.size) {
+ mem.set_failed(msg_error_read);
+ return (0);
+ }
+ i = (mem.mem + mem.pos)[0];
+ mem.pos += 1;
+ return (1);
}
-unsigned int mem_read(Stream & mem, unsigned char *i, unsigned int cnt)
+unsigned int mem_read(Stream &mem, unsigned char *i, unsigned int cnt)
{
- if (mem.pos + cnt > mem.size) {
- mem.set_failed(msg_error_read);
- return(0);
- }
- memcpy(i, mem.mem + mem.pos, cnt);
- mem.pos += cnt;
- return(cnt);
+ if (mem.pos + cnt > mem.size) {
+ mem.set_failed(msg_error_read);
+ return (0);
+ }
+ memcpy(i, mem.mem + mem.pos, cnt);
+ mem.pos += cnt;
+ return (cnt);
}
void Stream::set_failed(const char *msg)
{
- if (!failed) {
- puts(msg);
- failed = true;
- }
+ if (!failed) {
+ puts(msg);
+ failed = true;
+ }
}
diff --git a/source/blender/imbuf/intern/dds/Stream.h b/source/blender/imbuf/intern/dds/Stream.h
index b9fba2ef8b2..35662e8f24e 100644
--- a/source/blender/imbuf/intern/dds/Stream.h
+++ b/source/blender/imbuf/intern/dds/Stream.h
@@ -18,26 +18,27 @@
* \ingroup imbdds
*/
-
/* simple memory stream functions with buffer overflow check */
#ifndef __STREAM_H__
#define __STREAM_H__
struct Stream {
- unsigned char *mem; // location in memory
- unsigned int size; // size
- unsigned int pos; // current position
- bool failed; // error occured when seeking
- Stream(unsigned char *m, unsigned int s) : mem(m), size(s), pos(0), failed(false) {}
- unsigned int seek(unsigned int p);
- void set_failed(const char *msg);
+ unsigned char *mem; // location in memory
+ unsigned int size; // size
+ unsigned int pos; // current position
+ bool failed; // error occured when seeking
+ Stream(unsigned char *m, unsigned int s) : mem(m), size(s), pos(0), failed(false)
+ {
+ }
+ unsigned int seek(unsigned int p);
+ void set_failed(const char *msg);
};
-unsigned int mem_read(Stream & mem, unsigned long long & i);
-unsigned int mem_read(Stream & mem, unsigned int & i);
-unsigned int mem_read(Stream & mem, unsigned short & i);
-unsigned int mem_read(Stream & mem, unsigned char & i);
-unsigned int mem_read(Stream & mem, unsigned char *i, unsigned int cnt);
+unsigned int mem_read(Stream &mem, unsigned long long &i);
+unsigned int mem_read(Stream &mem, unsigned int &i);
+unsigned int mem_read(Stream &mem, unsigned short &i);
+unsigned int mem_read(Stream &mem, unsigned char &i);
+unsigned int mem_read(Stream &mem, unsigned char *i, unsigned int cnt);
-#endif /* __STREAM_H__ */
+#endif /* __STREAM_H__ */
diff --git a/source/blender/imbuf/intern/dds/dds_api.cpp b/source/blender/imbuf/intern/dds/dds_api.cpp
index fa88f81b55a..6a76e231e37 100644
--- a/source/blender/imbuf/intern/dds/dds_api.cpp
+++ b/source/blender/imbuf/intern/dds/dds_api.cpp
@@ -18,7 +18,6 @@
* \ingroup imbdds
*/
-
extern "C" {
#include "BLI_utildefines.h"
}
@@ -28,11 +27,11 @@ extern "C" {
#include <Stream.h>
#include <DirectDrawSurface.h>
#include <FlipDXT.h>
-#include <stdio.h> // printf
+#include <stdio.h> // printf
#include <fstream>
-#if defined (WIN32)
-#include "utfconv.h"
+#if defined(WIN32)
+# include "utfconv.h"
#endif
extern "C" {
@@ -47,138 +46,149 @@ extern "C" {
int imb_save_dds(struct ImBuf *ibuf, const char *name, int /*flags*/)
{
- return(0); /* todo: finish this function */
+ return (0); /* todo: finish this function */
- /* check image buffer */
- if (ibuf == 0) return (0);
- if (ibuf->rect == 0) return (0);
+ /* check image buffer */
+ if (ibuf == 0)
+ return (0);
+ if (ibuf->rect == 0)
+ return (0);
- /* open file for writing */
- std::ofstream fildes;
+ /* open file for writing */
+ std::ofstream fildes;
-#if defined (WIN32)
- wchar_t *wname = alloc_utf16_from_8(name, 0);
- fildes.open(wname);
- free(wname);
+#if defined(WIN32)
+ wchar_t *wname = alloc_utf16_from_8(name, 0);
+ fildes.open(wname);
+ free(wname);
#else
- fildes.open(name);
+ fildes.open(name);
#endif
- /* write header */
- fildes << "DDS ";
- fildes.close();
+ /* write header */
+ fildes << "DDS ";
+ fildes.close();
- return(1);
+ return (1);
}
-int imb_is_a_dds(const unsigned char *mem) // note: use at most first 32 bytes
+int imb_is_a_dds(const unsigned char *mem) // note: use at most first 32 bytes
{
- /* heuristic check to see if mem contains a DDS file */
- /* header.fourcc == FOURCC_DDS */
- if ((mem[0] != 'D') || (mem[1] != 'D') || (mem[2] != 'S') || (mem[3] != ' ')) return(0);
- /* header.size == 124 */
- if ((mem[4] != 124) || mem[5] || mem[6] || mem[7]) return(0);
- return(1);
+ /* heuristic check to see if mem contains a DDS file */
+ /* header.fourcc == FOURCC_DDS */
+ if ((mem[0] != 'D') || (mem[1] != 'D') || (mem[2] != 'S') || (mem[3] != ' '))
+ return (0);
+ /* header.size == 124 */
+ if ((mem[4] != 124) || mem[5] || mem[6] || mem[7])
+ return (0);
+ return (1);
}
-struct ImBuf *imb_load_dds(const unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE])
+struct ImBuf *imb_load_dds(const unsigned char *mem,
+ size_t size,
+ int flags,
+ char colorspace[IM_MAX_SPACE])
{
- struct ImBuf *ibuf = NULL;
- DirectDrawSurface dds((unsigned char *)mem, size); /* reads header */
- unsigned char bits_per_pixel;
- unsigned int *rect;
- Image img;
- unsigned int numpixels = 0;
- int col;
- unsigned char *cp = (unsigned char *) &col;
- Color32 pixel;
- Color32 *pixels = 0;
-
- /* OCIO_TODO: never was able to save DDS, so can't test loading
- * but profile used to be set to sRGB and can't see rect_float here, so
- * default byte space should work fine
- */
- colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE);
-
- if (!imb_is_a_dds(mem))
- return (0);
-
- /* check if DDS is valid and supported */
- if (!dds.isValid()) {
- /* no need to print error here, just testing if it is a DDS */
- if (flags & IB_test)
- return (0);
-
- printf("DDS: not valid; header follows\n");
- dds.printInfo();
- return(0);
- }
- if (!dds.isSupported()) {
- printf("DDS: format not supported\n");
- return(0);
- }
- if ((dds.width() > 65535) || (dds.height() > 65535)) {
- printf("DDS: dimensions too large\n");
- return(0);
- }
-
- /* convert DDS into ImBuf */
- dds.mipmap(&img, 0, 0); /* load first face, first mipmap */
- pixels = img.pixels();
- numpixels = dds.width() * dds.height();
- bits_per_pixel = 24;
- if (img.format() == Image::Format_ARGB) {
- /* check that there is effectively an alpha channel */
- for (unsigned int i = 0; i < numpixels; i++) {
- pixel = pixels[i];
- if (pixel.a != 255) {
- bits_per_pixel = 32;
- break;
- }
- }
- }
- ibuf = IMB_allocImBuf(dds.width(), dds.height(), bits_per_pixel, 0);
- if (ibuf == 0) return(0); /* memory allocation failed */
-
- ibuf->ftype = IMB_FTYPE_DDS;
- ibuf->dds_data.fourcc = dds.fourCC();
- ibuf->dds_data.nummipmaps = dds.mipmapCount();
-
- if ((flags & IB_test) == 0) {
- if (!imb_addrectImBuf(ibuf)) return(ibuf);
- if (ibuf->rect == 0) return(ibuf);
-
- rect = ibuf->rect;
- cp[3] = 0xff; /* default alpha if alpha channel is not present */
-
- for (unsigned int i = 0; i < numpixels; i++) {
- pixel = pixels[i];
- cp[0] = pixel.r; /* set R component of col */
- cp[1] = pixel.g; /* set G component of col */
- cp[2] = pixel.b; /* set B component of col */
- if (dds.hasAlpha())
- cp[3] = pixel.a; /* set A component of col */
- rect[i] = col;
- }
-
- if (ibuf->dds_data.fourcc != FOURCC_DDS) {
- ibuf->dds_data.data = (unsigned char *)dds.readData(ibuf->dds_data.size);
-
- /* flip compressed texture */
- if (ibuf->dds_data.data) {
- FlipDXTCImage(dds.width(), dds.height(), dds.mipmapCount(), dds.fourCC(), ibuf->dds_data.data);
- }
- }
- else {
- ibuf->dds_data.data = NULL;
- ibuf->dds_data.size = 0;
- }
-
- /* flip uncompressed texture */
- IMB_flipy(ibuf);
- }
-
- return(ibuf);
+ struct ImBuf *ibuf = NULL;
+ DirectDrawSurface dds((unsigned char *)mem, size); /* reads header */
+ unsigned char bits_per_pixel;
+ unsigned int *rect;
+ Image img;
+ unsigned int numpixels = 0;
+ int col;
+ unsigned char *cp = (unsigned char *)&col;
+ Color32 pixel;
+ Color32 *pixels = 0;
+
+ /* OCIO_TODO: never was able to save DDS, so can't test loading
+ * but profile used to be set to sRGB and can't see rect_float here, so
+ * default byte space should work fine
+ */
+ colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE);
+
+ if (!imb_is_a_dds(mem))
+ return (0);
+
+ /* check if DDS is valid and supported */
+ if (!dds.isValid()) {
+ /* no need to print error here, just testing if it is a DDS */
+ if (flags & IB_test)
+ return (0);
+
+ printf("DDS: not valid; header follows\n");
+ dds.printInfo();
+ return (0);
+ }
+ if (!dds.isSupported()) {
+ printf("DDS: format not supported\n");
+ return (0);
+ }
+ if ((dds.width() > 65535) || (dds.height() > 65535)) {
+ printf("DDS: dimensions too large\n");
+ return (0);
+ }
+
+ /* convert DDS into ImBuf */
+ dds.mipmap(&img, 0, 0); /* load first face, first mipmap */
+ pixels = img.pixels();
+ numpixels = dds.width() * dds.height();
+ bits_per_pixel = 24;
+ if (img.format() == Image::Format_ARGB) {
+ /* check that there is effectively an alpha channel */
+ for (unsigned int i = 0; i < numpixels; i++) {
+ pixel = pixels[i];
+ if (pixel.a != 255) {
+ bits_per_pixel = 32;
+ break;
+ }
+ }
+ }
+ ibuf = IMB_allocImBuf(dds.width(), dds.height(), bits_per_pixel, 0);
+ if (ibuf == 0)
+ return (0); /* memory allocation failed */
+
+ ibuf->ftype = IMB_FTYPE_DDS;
+ ibuf->dds_data.fourcc = dds.fourCC();
+ ibuf->dds_data.nummipmaps = dds.mipmapCount();
+
+ if ((flags & IB_test) == 0) {
+ if (!imb_addrectImBuf(ibuf))
+ return (ibuf);
+ if (ibuf->rect == 0)
+ return (ibuf);
+
+ rect = ibuf->rect;
+ cp[3] = 0xff; /* default alpha if alpha channel is not present */
+
+ for (unsigned int i = 0; i < numpixels; i++) {
+ pixel = pixels[i];
+ cp[0] = pixel.r; /* set R component of col */
+ cp[1] = pixel.g; /* set G component of col */
+ cp[2] = pixel.b; /* set B component of col */
+ if (dds.hasAlpha())
+ cp[3] = pixel.a; /* set A component of col */
+ rect[i] = col;
+ }
+
+ if (ibuf->dds_data.fourcc != FOURCC_DDS) {
+ ibuf->dds_data.data = (unsigned char *)dds.readData(ibuf->dds_data.size);
+
+ /* flip compressed texture */
+ if (ibuf->dds_data.data) {
+ FlipDXTCImage(
+ dds.width(), dds.height(), dds.mipmapCount(), dds.fourCC(), ibuf->dds_data.data);
+ }
+ }
+ else {
+ ibuf->dds_data.data = NULL;
+ ibuf->dds_data.size = 0;
+ }
+
+ /* flip uncompressed texture */
+ IMB_flipy(ibuf);
+ }
+
+ return (ibuf);
}
-} // extern "C"
+} // extern "C"
diff --git a/source/blender/imbuf/intern/dds/dds_api.h b/source/blender/imbuf/intern/dds/dds_api.h
index cbe19ab3e90..12db8aa6416 100644
--- a/source/blender/imbuf/intern/dds/dds_api.h
+++ b/source/blender/imbuf/intern/dds/dds_api.h
@@ -18,7 +18,6 @@
* \ingroup imbdds
*/
-
#ifndef __DDS_API_H__
#define __DDS_API_H__
@@ -28,9 +27,12 @@ extern "C" {
#include "../../IMB_imbuf.h"
-int imb_is_a_dds(const unsigned char *mem); /* use only first 32 bytes of mem */
-int imb_save_dds(struct ImBuf *ibuf, const char *name, int flags);
-struct ImBuf *imb_load_dds(const unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE]);
+int imb_is_a_dds(const unsigned char *mem); /* use only first 32 bytes of mem */
+int imb_save_dds(struct ImBuf *ibuf, const char *name, int flags);
+struct ImBuf *imb_load_dds(const unsigned char *mem,
+ size_t size,
+ int flags,
+ char colorspace[IM_MAX_SPACE]);
#ifdef __cplusplus
}
diff --git a/source/blender/imbuf/intern/divers.c b/source/blender/imbuf/intern/divers.c
index d1997e4612d..fb8dcffe9d4 100644
--- a/source/blender/imbuf/intern/divers.c
+++ b/source/blender/imbuf/intern/divers.c
@@ -33,469 +33,495 @@
#include "IMB_colormanagement.h"
#include "IMB_colormanagement_intern.h"
-
#include "MEM_guardedalloc.h"
/************************* Floyd-Steinberg dithering *************************/
typedef struct DitherContext {
- float dither;
+ float dither;
} DitherContext;
static DitherContext *create_dither_context(float dither)
{
- DitherContext *di;
+ DitherContext *di;
- di = MEM_mallocN(sizeof(DitherContext), "dithering context");
- di->dither = dither;
+ di = MEM_mallocN(sizeof(DitherContext), "dithering context");
+ di->dither = dither;
- return di;
+ return di;
}
static void clear_dither_context(DitherContext *di)
{
- MEM_freeN(di);
+ MEM_freeN(di);
}
-
/************************* Generic Buffer Conversion *************************/
MINLINE void ushort_to_byte_v4(uchar b[4], const unsigned short us[4])
{
- b[0] = unit_ushort_to_uchar(us[0]);
- b[1] = unit_ushort_to_uchar(us[1]);
- b[2] = unit_ushort_to_uchar(us[2]);
- b[3] = unit_ushort_to_uchar(us[3]);
+ b[0] = unit_ushort_to_uchar(us[0]);
+ b[1] = unit_ushort_to_uchar(us[1]);
+ b[2] = unit_ushort_to_uchar(us[2]);
+ b[3] = unit_ushort_to_uchar(us[3]);
}
MINLINE unsigned char ftochar(float value)
{
- return unit_float_to_uchar_clamp(value);
+ return unit_float_to_uchar_clamp(value);
}
-MINLINE void ushort_to_byte_dither_v4(uchar b[4], const unsigned short us[4], DitherContext *di, float s, float t)
+MINLINE void ushort_to_byte_dither_v4(
+ uchar b[4], const unsigned short us[4], DitherContext *di, float s, float t)
{
#define USHORTTOFLOAT(val) ((float)val / 65535.0f)
- float dither_value = dither_random_value(s, t) * 0.005f * di->dither;
+ float dither_value = dither_random_value(s, t) * 0.005f * di->dither;
- b[0] = ftochar(dither_value + USHORTTOFLOAT(us[0]));
- b[1] = ftochar(dither_value + USHORTTOFLOAT(us[1]));
- b[2] = ftochar(dither_value + USHORTTOFLOAT(us[2]));
- b[3] = unit_ushort_to_uchar(us[3]);
+ b[0] = ftochar(dither_value + USHORTTOFLOAT(us[0]));
+ b[1] = ftochar(dither_value + USHORTTOFLOAT(us[1]));
+ b[2] = ftochar(dither_value + USHORTTOFLOAT(us[2]));
+ b[3] = unit_ushort_to_uchar(us[3]);
#undef USHORTTOFLOAT
}
-MINLINE void float_to_byte_dither_v4(uchar b[4], const float f[4], DitherContext *di, float s, float t)
+MINLINE void float_to_byte_dither_v4(
+ uchar b[4], const float f[4], DitherContext *di, float s, float t)
{
- float dither_value = dither_random_value(s, t) * 0.005f * di->dither;
+ float dither_value = dither_random_value(s, t) * 0.005f * di->dither;
- b[0] = ftochar(dither_value + f[0]);
- b[1] = ftochar(dither_value + f[1]);
- b[2] = ftochar(dither_value + f[2]);
- b[3] = unit_float_to_uchar_clamp(f[3]);
+ b[0] = ftochar(dither_value + f[0]);
+ b[1] = ftochar(dither_value + f[1]);
+ b[2] = ftochar(dither_value + f[2]);
+ b[3] = unit_float_to_uchar_clamp(f[3]);
}
/* float to byte pixels, output 4-channel RGBA */
-void IMB_buffer_byte_from_float(uchar *rect_to, const float *rect_from,
- int channels_from, float dither, int profile_to, int profile_from, bool predivide,
- int width, int height, int stride_to, int stride_from)
+void IMB_buffer_byte_from_float(uchar *rect_to,
+ const float *rect_from,
+ int channels_from,
+ float dither,
+ int profile_to,
+ int profile_from,
+ bool predivide,
+ int width,
+ int height,
+ int stride_to,
+ int stride_from)
{
- float tmp[4];
- int x, y;
- DitherContext *di = NULL;
- float inv_width = 1.0f / width;
- float inv_height = 1.0f / height;
-
- /* we need valid profiles */
- BLI_assert(profile_to != IB_PROFILE_NONE);
- BLI_assert(profile_from != IB_PROFILE_NONE);
-
- if (dither)
- di = create_dither_context(dither);
-
- for (y = 0; y < height; y++) {
- float t = y * inv_height;
-
- if (channels_from == 1) {
- /* single channel input */
- const float *from = rect_from + ((size_t)stride_from) * y;
- uchar *to = rect_to + ((size_t)stride_to) * y * 4;
-
- for (x = 0; x < width; x++, from++, to += 4)
- to[0] = to[1] = to[2] = to[3] = unit_float_to_uchar_clamp(from[0]);
- }
- else if (channels_from == 3) {
- /* RGB input */
- const float *from = rect_from + ((size_t)stride_from) * y * 3;
- uchar *to = rect_to + ((size_t)stride_to) * y * 4;
-
- if (profile_to == profile_from) {
- /* no color space conversion */
- for (x = 0; x < width; x++, from += 3, to += 4) {
- rgb_float_to_uchar(to, from);
- to[3] = 255;
- }
- }
- else if (profile_to == IB_PROFILE_SRGB) {
- /* convert from linear to sRGB */
- for (x = 0; x < width; x++, from += 3, to += 4) {
- linearrgb_to_srgb_v3_v3(tmp, from);
- rgb_float_to_uchar(to, tmp);
- to[3] = 255;
- }
- }
- else if (profile_to == IB_PROFILE_LINEAR_RGB) {
- /* convert from sRGB to linear */
- for (x = 0; x < width; x++, from += 3, to += 4) {
- srgb_to_linearrgb_v3_v3(tmp, from);
- rgb_float_to_uchar(to, tmp);
- to[3] = 255;
- }
- }
- }
- else if (channels_from == 4) {
- /* RGBA input */
- const float *from = rect_from + ((size_t)stride_from) * y * 4;
- uchar *to = rect_to + ((size_t)stride_to) * y * 4;
-
- if (profile_to == profile_from) {
- float straight[4];
-
- /* no color space conversion */
- if (dither && predivide) {
- for (x = 0; x < width; x++, from += 4, to += 4) {
- premul_to_straight_v4_v4(straight, from);
- float_to_byte_dither_v4(to, straight, di, (float) x * inv_width, t);
- }
- }
- else if (dither) {
- for (x = 0; x < width; x++, from += 4, to += 4)
- float_to_byte_dither_v4(to, from, di, (float) x * inv_width, t);
- }
- else if (predivide) {
- for (x = 0; x < width; x++, from += 4, to += 4) {
- premul_to_straight_v4_v4(straight, from);
- rgba_float_to_uchar(to, straight);
- }
- }
- else {
- for (x = 0; x < width; x++, from += 4, to += 4)
- rgba_float_to_uchar(to, from);
- }
- }
- else if (profile_to == IB_PROFILE_SRGB) {
- /* convert from linear to sRGB */
- unsigned short us[4];
- float straight[4];
-
- if (dither && predivide) {
- for (x = 0; x < width; x++, from += 4, to += 4) {
- premul_to_straight_v4_v4(straight, from);
- linearrgb_to_srgb_ushort4(us, from);
- ushort_to_byte_dither_v4(to, us, di, (float) x * inv_width, t);
- }
- }
- else if (dither) {
- for (x = 0; x < width; x++, from += 4, to += 4) {
- linearrgb_to_srgb_ushort4(us, from);
- ushort_to_byte_dither_v4(to, us, di, (float) x * inv_width, t);
- }
- }
- else if (predivide) {
- for (x = 0; x < width; x++, from += 4, to += 4) {
- premul_to_straight_v4_v4(straight, from);
- linearrgb_to_srgb_ushort4(us, from);
- ushort_to_byte_v4(to, us);
- }
- }
- else {
- for (x = 0; x < width; x++, from += 4, to += 4) {
- linearrgb_to_srgb_ushort4(us, from);
- ushort_to_byte_v4(to, us);
- }
- }
- }
- else if (profile_to == IB_PROFILE_LINEAR_RGB) {
- /* convert from sRGB to linear */
- if (dither && predivide) {
- for (x = 0; x < width; x++, from += 4, to += 4) {
- srgb_to_linearrgb_predivide_v4(tmp, from);
- float_to_byte_dither_v4(to, tmp, di, (float) x * inv_width, t);
- }
- }
- else if (dither) {
- for (x = 0; x < width; x++, from += 4, to += 4) {
- srgb_to_linearrgb_v4(tmp, from);
- float_to_byte_dither_v4(to, tmp, di, (float) x * inv_width, t);
- }
- }
- else if (predivide) {
- for (x = 0; x < width; x++, from += 4, to += 4) {
- srgb_to_linearrgb_predivide_v4(tmp, from);
- rgba_float_to_uchar(to, tmp);
- }
- }
- else {
- for (x = 0; x < width; x++, from += 4, to += 4) {
- srgb_to_linearrgb_v4(tmp, from);
- rgba_float_to_uchar(to, tmp);
- }
- }
- }
- }
- }
-
- if (dither)
- clear_dither_context(di);
+ float tmp[4];
+ int x, y;
+ DitherContext *di = NULL;
+ float inv_width = 1.0f / width;
+ float inv_height = 1.0f / height;
+
+ /* we need valid profiles */
+ BLI_assert(profile_to != IB_PROFILE_NONE);
+ BLI_assert(profile_from != IB_PROFILE_NONE);
+
+ if (dither)
+ di = create_dither_context(dither);
+
+ for (y = 0; y < height; y++) {
+ float t = y * inv_height;
+
+ if (channels_from == 1) {
+ /* single channel input */
+ const float *from = rect_from + ((size_t)stride_from) * y;
+ uchar *to = rect_to + ((size_t)stride_to) * y * 4;
+
+ for (x = 0; x < width; x++, from++, to += 4)
+ to[0] = to[1] = to[2] = to[3] = unit_float_to_uchar_clamp(from[0]);
+ }
+ else if (channels_from == 3) {
+ /* RGB input */
+ const float *from = rect_from + ((size_t)stride_from) * y * 3;
+ uchar *to = rect_to + ((size_t)stride_to) * y * 4;
+
+ if (profile_to == profile_from) {
+ /* no color space conversion */
+ for (x = 0; x < width; x++, from += 3, to += 4) {
+ rgb_float_to_uchar(to, from);
+ to[3] = 255;
+ }
+ }
+ else if (profile_to == IB_PROFILE_SRGB) {
+ /* convert from linear to sRGB */
+ for (x = 0; x < width; x++, from += 3, to += 4) {
+ linearrgb_to_srgb_v3_v3(tmp, from);
+ rgb_float_to_uchar(to, tmp);
+ to[3] = 255;
+ }
+ }
+ else if (profile_to == IB_PROFILE_LINEAR_RGB) {
+ /* convert from sRGB to linear */
+ for (x = 0; x < width; x++, from += 3, to += 4) {
+ srgb_to_linearrgb_v3_v3(tmp, from);
+ rgb_float_to_uchar(to, tmp);
+ to[3] = 255;
+ }
+ }
+ }
+ else if (channels_from == 4) {
+ /* RGBA input */
+ const float *from = rect_from + ((size_t)stride_from) * y * 4;
+ uchar *to = rect_to + ((size_t)stride_to) * y * 4;
+
+ if (profile_to == profile_from) {
+ float straight[4];
+
+ /* no color space conversion */
+ if (dither && predivide) {
+ for (x = 0; x < width; x++, from += 4, to += 4) {
+ premul_to_straight_v4_v4(straight, from);
+ float_to_byte_dither_v4(to, straight, di, (float)x * inv_width, t);
+ }
+ }
+ else if (dither) {
+ for (x = 0; x < width; x++, from += 4, to += 4)
+ float_to_byte_dither_v4(to, from, di, (float)x * inv_width, t);
+ }
+ else if (predivide) {
+ for (x = 0; x < width; x++, from += 4, to += 4) {
+ premul_to_straight_v4_v4(straight, from);
+ rgba_float_to_uchar(to, straight);
+ }
+ }
+ else {
+ for (x = 0; x < width; x++, from += 4, to += 4)
+ rgba_float_to_uchar(to, from);
+ }
+ }
+ else if (profile_to == IB_PROFILE_SRGB) {
+ /* convert from linear to sRGB */
+ unsigned short us[4];
+ float straight[4];
+
+ if (dither && predivide) {
+ for (x = 0; x < width; x++, from += 4, to += 4) {
+ premul_to_straight_v4_v4(straight, from);
+ linearrgb_to_srgb_ushort4(us, from);
+ ushort_to_byte_dither_v4(to, us, di, (float)x * inv_width, t);
+ }
+ }
+ else if (dither) {
+ for (x = 0; x < width; x++, from += 4, to += 4) {
+ linearrgb_to_srgb_ushort4(us, from);
+ ushort_to_byte_dither_v4(to, us, di, (float)x * inv_width, t);
+ }
+ }
+ else if (predivide) {
+ for (x = 0; x < width; x++, from += 4, to += 4) {
+ premul_to_straight_v4_v4(straight, from);
+ linearrgb_to_srgb_ushort4(us, from);
+ ushort_to_byte_v4(to, us);
+ }
+ }
+ else {
+ for (x = 0; x < width; x++, from += 4, to += 4) {
+ linearrgb_to_srgb_ushort4(us, from);
+ ushort_to_byte_v4(to, us);
+ }
+ }
+ }
+ else if (profile_to == IB_PROFILE_LINEAR_RGB) {
+ /* convert from sRGB to linear */
+ if (dither && predivide) {
+ for (x = 0; x < width; x++, from += 4, to += 4) {
+ srgb_to_linearrgb_predivide_v4(tmp, from);
+ float_to_byte_dither_v4(to, tmp, di, (float)x * inv_width, t);
+ }
+ }
+ else if (dither) {
+ for (x = 0; x < width; x++, from += 4, to += 4) {
+ srgb_to_linearrgb_v4(tmp, from);
+ float_to_byte_dither_v4(to, tmp, di, (float)x * inv_width, t);
+ }
+ }
+ else if (predivide) {
+ for (x = 0; x < width; x++, from += 4, to += 4) {
+ srgb_to_linearrgb_predivide_v4(tmp, from);
+ rgba_float_to_uchar(to, tmp);
+ }
+ }
+ else {
+ for (x = 0; x < width; x++, from += 4, to += 4) {
+ srgb_to_linearrgb_v4(tmp, from);
+ rgba_float_to_uchar(to, tmp);
+ }
+ }
+ }
+ }
+ }
+
+ if (dither)
+ clear_dither_context(di);
}
-
/* float to byte pixels, output 4-channel RGBA */
-void IMB_buffer_byte_from_float_mask(uchar *rect_to, const float *rect_from,
- int channels_from, float dither, bool predivide,
- int width, int height, int stride_to, int stride_from, char *mask)
+void IMB_buffer_byte_from_float_mask(uchar *rect_to,
+ const float *rect_from,
+ int channels_from,
+ float dither,
+ bool predivide,
+ int width,
+ int height,
+ int stride_to,
+ int stride_from,
+ char *mask)
{
- int x, y;
- DitherContext *di = NULL;
- float inv_width = 1.0f / width,
- inv_height = 1.0f / height;
-
- if (dither)
- di = create_dither_context(dither);
-
- for (y = 0; y < height; y++) {
- float t = y * inv_height;
-
- if (channels_from == 1) {
- /* single channel input */
- const float *from = rect_from + ((size_t)stride_from) * y;
- uchar *to = rect_to + ((size_t)stride_to) * y * 4;
-
- for (x = 0; x < width; x++, from++, to += 4)
- if (*mask++ == FILTER_MASK_USED)
- to[0] = to[1] = to[2] = to[3] = unit_float_to_uchar_clamp(from[0]);
- }
- else if (channels_from == 3) {
- /* RGB input */
- const float *from = rect_from + ((size_t)stride_from) * y * 3;
- uchar *to = rect_to + ((size_t)stride_to) * y * 4;
-
- for (x = 0; x < width; x++, from += 3, to += 4) {
- if (*mask++ == FILTER_MASK_USED) {
- rgb_float_to_uchar(to, from);
- to[3] = 255;
- }
- }
- }
- else if (channels_from == 4) {
- /* RGBA input */
- const float *from = rect_from + ((size_t)stride_from) * y * 4;
- uchar *to = rect_to + ((size_t)stride_to) * y * 4;
-
- float straight[4];
-
- if (dither && predivide) {
- for (x = 0; x < width; x++, from += 4, to += 4) {
- if (*mask++ == FILTER_MASK_USED) {
- premul_to_straight_v4_v4(straight, from);
- float_to_byte_dither_v4(to, straight, di, (float) x * inv_width, t);
- }
- }
- }
- else if (dither) {
- for (x = 0; x < width; x++, from += 4, to += 4)
- if (*mask++ == FILTER_MASK_USED)
- float_to_byte_dither_v4(to, from, di, (float) x * inv_width, t);
- }
- else if (predivide) {
- for (x = 0; x < width; x++, from += 4, to += 4) {
- if (*mask++ == FILTER_MASK_USED) {
- premul_to_straight_v4_v4(straight, from);
- rgba_float_to_uchar(to, straight);
- }
- }
- }
- else {
- for (x = 0; x < width; x++, from += 4, to += 4)
- if (*mask++ == FILTER_MASK_USED)
- rgba_float_to_uchar(to, from);
- }
- }
- }
-
- if (dither)
- clear_dither_context(di);
+ int x, y;
+ DitherContext *di = NULL;
+ float inv_width = 1.0f / width, inv_height = 1.0f / height;
+
+ if (dither)
+ di = create_dither_context(dither);
+
+ for (y = 0; y < height; y++) {
+ float t = y * inv_height;
+
+ if (channels_from == 1) {
+ /* single channel input */
+ const float *from = rect_from + ((size_t)stride_from) * y;
+ uchar *to = rect_to + ((size_t)stride_to) * y * 4;
+
+ for (x = 0; x < width; x++, from++, to += 4)
+ if (*mask++ == FILTER_MASK_USED)
+ to[0] = to[1] = to[2] = to[3] = unit_float_to_uchar_clamp(from[0]);
+ }
+ else if (channels_from == 3) {
+ /* RGB input */
+ const float *from = rect_from + ((size_t)stride_from) * y * 3;
+ uchar *to = rect_to + ((size_t)stride_to) * y * 4;
+
+ for (x = 0; x < width; x++, from += 3, to += 4) {
+ if (*mask++ == FILTER_MASK_USED) {
+ rgb_float_to_uchar(to, from);
+ to[3] = 255;
+ }
+ }
+ }
+ else if (channels_from == 4) {
+ /* RGBA input */
+ const float *from = rect_from + ((size_t)stride_from) * y * 4;
+ uchar *to = rect_to + ((size_t)stride_to) * y * 4;
+
+ float straight[4];
+
+ if (dither && predivide) {
+ for (x = 0; x < width; x++, from += 4, to += 4) {
+ if (*mask++ == FILTER_MASK_USED) {
+ premul_to_straight_v4_v4(straight, from);
+ float_to_byte_dither_v4(to, straight, di, (float)x * inv_width, t);
+ }
+ }
+ }
+ else if (dither) {
+ for (x = 0; x < width; x++, from += 4, to += 4)
+ if (*mask++ == FILTER_MASK_USED)
+ float_to_byte_dither_v4(to, from, di, (float)x * inv_width, t);
+ }
+ else if (predivide) {
+ for (x = 0; x < width; x++, from += 4, to += 4) {
+ if (*mask++ == FILTER_MASK_USED) {
+ premul_to_straight_v4_v4(straight, from);
+ rgba_float_to_uchar(to, straight);
+ }
+ }
+ }
+ else {
+ for (x = 0; x < width; x++, from += 4, to += 4)
+ if (*mask++ == FILTER_MASK_USED)
+ rgba_float_to_uchar(to, from);
+ }
+ }
+ }
+
+ if (dither)
+ clear_dither_context(di);
}
/* byte to float pixels, input and output 4-channel RGBA */
-void IMB_buffer_float_from_byte(float *rect_to, const uchar *rect_from,
- int profile_to, int profile_from, bool predivide,
- int width, int height, int stride_to, int stride_from)
+void IMB_buffer_float_from_byte(float *rect_to,
+ const uchar *rect_from,
+ int profile_to,
+ int profile_from,
+ bool predivide,
+ int width,
+ int height,
+ int stride_to,
+ int stride_from)
{
- float tmp[4];
- int x, y;
-
- /* we need valid profiles */
- BLI_assert(profile_to != IB_PROFILE_NONE);
- BLI_assert(profile_from != IB_PROFILE_NONE);
-
- /* RGBA input */
- for (y = 0; y < height; y++) {
- const uchar *from = rect_from + stride_from * y * 4;
- float *to = rect_to + ((size_t)stride_to) * y * 4;
-
- if (profile_to == profile_from) {
- /* no color space conversion */
- for (x = 0; x < width; x++, from += 4, to += 4)
- rgba_uchar_to_float(to, from);
- }
- else if (profile_to == IB_PROFILE_LINEAR_RGB) {
- /* convert sRGB to linear */
- if (predivide) {
- for (x = 0; x < width; x++, from += 4, to += 4) {
- srgb_to_linearrgb_uchar4_predivide(to, from);
- }
- }
- else {
- for (x = 0; x < width; x++, from += 4, to += 4) {
- srgb_to_linearrgb_uchar4(to, from);
- }
- }
- }
- else if (profile_to == IB_PROFILE_SRGB) {
- /* convert linear to sRGB */
- if (predivide) {
- for (x = 0; x < width; x++, from += 4, to += 4) {
- rgba_uchar_to_float(tmp, from);
- linearrgb_to_srgb_predivide_v4(to, tmp);
- }
- }
- else {
- for (x = 0; x < width; x++, from += 4, to += 4) {
- rgba_uchar_to_float(tmp, from);
- linearrgb_to_srgb_v4(to, tmp);
- }
- }
- }
- }
+ float tmp[4];
+ int x, y;
+
+ /* we need valid profiles */
+ BLI_assert(profile_to != IB_PROFILE_NONE);
+ BLI_assert(profile_from != IB_PROFILE_NONE);
+
+ /* RGBA input */
+ for (y = 0; y < height; y++) {
+ const uchar *from = rect_from + stride_from * y * 4;
+ float *to = rect_to + ((size_t)stride_to) * y * 4;
+
+ if (profile_to == profile_from) {
+ /* no color space conversion */
+ for (x = 0; x < width; x++, from += 4, to += 4)
+ rgba_uchar_to_float(to, from);
+ }
+ else if (profile_to == IB_PROFILE_LINEAR_RGB) {
+ /* convert sRGB to linear */
+ if (predivide) {
+ for (x = 0; x < width; x++, from += 4, to += 4) {
+ srgb_to_linearrgb_uchar4_predivide(to, from);
+ }
+ }
+ else {
+ for (x = 0; x < width; x++, from += 4, to += 4) {
+ srgb_to_linearrgb_uchar4(to, from);
+ }
+ }
+ }
+ else if (profile_to == IB_PROFILE_SRGB) {
+ /* convert linear to sRGB */
+ if (predivide) {
+ for (x = 0; x < width; x++, from += 4, to += 4) {
+ rgba_uchar_to_float(tmp, from);
+ linearrgb_to_srgb_predivide_v4(to, tmp);
+ }
+ }
+ else {
+ for (x = 0; x < width; x++, from += 4, to += 4) {
+ rgba_uchar_to_float(tmp, from);
+ linearrgb_to_srgb_v4(to, tmp);
+ }
+ }
+ }
+ }
}
/* float to float pixels, output 4-channel RGBA */
-void IMB_buffer_float_from_float(float *rect_to, const float *rect_from,
- int channels_from, int profile_to, int profile_from, bool predivide,
- int width, int height, int stride_to, int stride_from)
+void IMB_buffer_float_from_float(float *rect_to,
+ const float *rect_from,
+ int channels_from,
+ int profile_to,
+ int profile_from,
+ bool predivide,
+ int width,
+ int height,
+ int stride_to,
+ int stride_from)
{
- int x, y;
-
- /* we need valid profiles */
- BLI_assert(profile_to != IB_PROFILE_NONE);
- BLI_assert(profile_from != IB_PROFILE_NONE);
-
- if (channels_from == 1) {
- /* single channel input */
- for (y = 0; y < height; y++) {
- const float *from = rect_from + ((size_t)stride_from) * y;
- float *to = rect_to + ((size_t)stride_to) * y * 4;
-
- for (x = 0; x < width; x++, from++, to += 4)
- to[0] = to[1] = to[2] = to[3] = from[0];
- }
- }
- else if (channels_from == 3) {
- /* RGB input */
- for (y = 0; y < height; y++) {
- const float *from = rect_from + ((size_t)stride_from) * y * 3;
- float *to = rect_to + ((size_t)stride_to) * y * 4;
-
- if (profile_to == profile_from) {
- /* no color space conversion */
- for (x = 0; x < width; x++, from += 3, to += 4) {
- copy_v3_v3(to, from);
- to[3] = 1.0f;
- }
- }
- else if (profile_to == IB_PROFILE_LINEAR_RGB) {
- /* convert from sRGB to linear */
- for (x = 0; x < width; x++, from += 3, to += 4) {
- srgb_to_linearrgb_v3_v3(to, from);
- to[3] = 1.0f;
- }
- }
- else if (profile_to == IB_PROFILE_SRGB) {
- /* convert from linear to sRGB */
- for (x = 0; x < width; x++, from += 3, to += 4) {
- linearrgb_to_srgb_v3_v3(to, from);
- to[3] = 1.0f;
- }
- }
- }
- }
- else if (channels_from == 4) {
- /* RGBA input */
- for (y = 0; y < height; y++) {
- const float *from = rect_from + ((size_t)stride_from) * y * 4;
- float *to = rect_to + ((size_t)stride_to) * y * 4;
-
- if (profile_to == profile_from) {
- /* same profile, copy */
- memcpy(to, from, sizeof(float) * ((size_t)4) * width);
- }
- else if (profile_to == IB_PROFILE_LINEAR_RGB) {
- /* convert to sRGB to linear */
- if (predivide) {
- for (x = 0; x < width; x++, from += 4, to += 4)
- srgb_to_linearrgb_predivide_v4(to, from);
- }
- else {
- for (x = 0; x < width; x++, from += 4, to += 4)
- srgb_to_linearrgb_v4(to, from);
- }
- }
- else if (profile_to == IB_PROFILE_SRGB) {
- /* convert from linear to sRGB */
- if (predivide) {
- for (x = 0; x < width; x++, from += 4, to += 4)
- linearrgb_to_srgb_predivide_v4(to, from);
- }
- else {
- for (x = 0; x < width; x++, from += 4, to += 4)
- linearrgb_to_srgb_v4(to, from);
- }
- }
- }
- }
+ int x, y;
+
+ /* we need valid profiles */
+ BLI_assert(profile_to != IB_PROFILE_NONE);
+ BLI_assert(profile_from != IB_PROFILE_NONE);
+
+ if (channels_from == 1) {
+ /* single channel input */
+ for (y = 0; y < height; y++) {
+ const float *from = rect_from + ((size_t)stride_from) * y;
+ float *to = rect_to + ((size_t)stride_to) * y * 4;
+
+ for (x = 0; x < width; x++, from++, to += 4)
+ to[0] = to[1] = to[2] = to[3] = from[0];
+ }
+ }
+ else if (channels_from == 3) {
+ /* RGB input */
+ for (y = 0; y < height; y++) {
+ const float *from = rect_from + ((size_t)stride_from) * y * 3;
+ float *to = rect_to + ((size_t)stride_to) * y * 4;
+
+ if (profile_to == profile_from) {
+ /* no color space conversion */
+ for (x = 0; x < width; x++, from += 3, to += 4) {
+ copy_v3_v3(to, from);
+ to[3] = 1.0f;
+ }
+ }
+ else if (profile_to == IB_PROFILE_LINEAR_RGB) {
+ /* convert from sRGB to linear */
+ for (x = 0; x < width; x++, from += 3, to += 4) {
+ srgb_to_linearrgb_v3_v3(to, from);
+ to[3] = 1.0f;
+ }
+ }
+ else if (profile_to == IB_PROFILE_SRGB) {
+ /* convert from linear to sRGB */
+ for (x = 0; x < width; x++, from += 3, to += 4) {
+ linearrgb_to_srgb_v3_v3(to, from);
+ to[3] = 1.0f;
+ }
+ }
+ }
+ }
+ else if (channels_from == 4) {
+ /* RGBA input */
+ for (y = 0; y < height; y++) {
+ const float *from = rect_from + ((size_t)stride_from) * y * 4;
+ float *to = rect_to + ((size_t)stride_to) * y * 4;
+
+ if (profile_to == profile_from) {
+ /* same profile, copy */
+ memcpy(to, from, sizeof(float) * ((size_t)4) * width);
+ }
+ else if (profile_to == IB_PROFILE_LINEAR_RGB) {
+ /* convert to sRGB to linear */
+ if (predivide) {
+ for (x = 0; x < width; x++, from += 4, to += 4)
+ srgb_to_linearrgb_predivide_v4(to, from);
+ }
+ else {
+ for (x = 0; x < width; x++, from += 4, to += 4)
+ srgb_to_linearrgb_v4(to, from);
+ }
+ }
+ else if (profile_to == IB_PROFILE_SRGB) {
+ /* convert from linear to sRGB */
+ if (predivide) {
+ for (x = 0; x < width; x++, from += 4, to += 4)
+ linearrgb_to_srgb_predivide_v4(to, from);
+ }
+ else {
+ for (x = 0; x < width; x++, from += 4, to += 4)
+ linearrgb_to_srgb_v4(to, from);
+ }
+ }
+ }
+ }
}
typedef struct FloatToFloatThreadData {
- float *rect_to;
- const float *rect_from;
- int channels_from;
- int profile_to;
- int profile_from;
- bool predivide;
- int width;
- int stride_to;
- int stride_from;
+ float *rect_to;
+ const float *rect_from;
+ int channels_from;
+ int profile_to;
+ int profile_from;
+ bool predivide;
+ int width;
+ int stride_to;
+ int stride_from;
} FloatToFloatThreadData;
static void imb_buffer_float_from_float_thread_do(void *data_v,
int start_scanline,
int num_scanlines)
{
- FloatToFloatThreadData *data = (FloatToFloatThreadData *)data_v;
- size_t offset_from = ((size_t)start_scanline) * data->stride_from * data->channels_from;
- size_t offset_to = ((size_t)start_scanline) * data->stride_to * data->channels_from;
- IMB_buffer_float_from_float(data->rect_to + offset_to,
- data->rect_from + offset_from,
- data->channels_from,
- data->profile_to,
- data->profile_from,
- data->predivide,
- data->width,
- num_scanlines,
- data->stride_to,
- data->stride_from);
+ FloatToFloatThreadData *data = (FloatToFloatThreadData *)data_v;
+ size_t offset_from = ((size_t)start_scanline) * data->stride_from * data->channels_from;
+ size_t offset_to = ((size_t)start_scanline) * data->stride_to * data->channels_from;
+ IMB_buffer_float_from_float(data->rect_to + offset_to,
+ data->rect_from + offset_from,
+ data->channels_from,
+ data->profile_to,
+ data->profile_from,
+ data->predivide,
+ data->width,
+ num_scanlines,
+ data->stride_to,
+ data->stride_from);
}
void IMB_buffer_float_from_float_threaded(float *rect_to,
@@ -509,183 +535,209 @@ void IMB_buffer_float_from_float_threaded(float *rect_to,
int stride_to,
int stride_from)
{
- if (((size_t)width) * height < 64 * 64) {
- IMB_buffer_float_from_float(rect_to,
- rect_from,
- channels_from,
- profile_to,
- profile_from,
- predivide,
- width,
- height,
- stride_to,
- stride_from);
- }
- else {
- FloatToFloatThreadData data;
- data.rect_to = rect_to;
- data.rect_from = rect_from;
- data.channels_from = channels_from;
- data.profile_to = profile_to;
- data.profile_from = profile_from;
- data.predivide = predivide;
- data.width = width;
- data.stride_to = stride_to;
- data.stride_from = stride_from;
- IMB_processor_apply_threaded_scanlines(
- height, imb_buffer_float_from_float_thread_do, &data);
- }
+ if (((size_t)width) * height < 64 * 64) {
+ IMB_buffer_float_from_float(rect_to,
+ rect_from,
+ channels_from,
+ profile_to,
+ profile_from,
+ predivide,
+ width,
+ height,
+ stride_to,
+ stride_from);
+ }
+ else {
+ FloatToFloatThreadData data;
+ data.rect_to = rect_to;
+ data.rect_from = rect_from;
+ data.channels_from = channels_from;
+ data.profile_to = profile_to;
+ data.profile_from = profile_from;
+ data.predivide = predivide;
+ data.width = width;
+ data.stride_to = stride_to;
+ data.stride_from = stride_from;
+ IMB_processor_apply_threaded_scanlines(height, imb_buffer_float_from_float_thread_do, &data);
+ }
}
/* float to float pixels, output 4-channel RGBA */
-void IMB_buffer_float_from_float_mask(float *rect_to, const float *rect_from, int channels_from,
- int width, int height, int stride_to, int stride_from, char *mask)
+void IMB_buffer_float_from_float_mask(float *rect_to,
+ const float *rect_from,
+ int channels_from,
+ int width,
+ int height,
+ int stride_to,
+ int stride_from,
+ char *mask)
{
- int x, y;
-
- if (channels_from == 1) {
- /* single channel input */
- for (y = 0; y < height; y++) {
- const float *from = rect_from + ((size_t)stride_from) * y;
- float *to = rect_to + ((size_t)stride_to) * y * 4;
-
- for (x = 0; x < width; x++, from++, to += 4)
- if (*mask++ == FILTER_MASK_USED)
- to[0] = to[1] = to[2] = to[3] = from[0];
- }
- }
- else if (channels_from == 3) {
- /* RGB input */
- for (y = 0; y < height; y++) {
- const float *from = rect_from + ((size_t)stride_from) * y * 3;
- float *to = rect_to + ((size_t)stride_to) * y * 4;
-
- for (x = 0; x < width; x++, from += 3, to += 4) {
- if (*mask++ == FILTER_MASK_USED) {
- copy_v3_v3(to, from);
- to[3] = 1.0f;
- }
- }
- }
- }
- else if (channels_from == 4) {
- /* RGBA input */
- for (y = 0; y < height; y++) {
- const float *from = rect_from + ((size_t)stride_from) * y * 4;
- float *to = rect_to + ((size_t)stride_to) * y * 4;
-
- for (x = 0; x < width; x++, from += 4, to += 4)
- if (*mask++ == FILTER_MASK_USED)
- copy_v4_v4(to, from);
- }
- }
+ int x, y;
+
+ if (channels_from == 1) {
+ /* single channel input */
+ for (y = 0; y < height; y++) {
+ const float *from = rect_from + ((size_t)stride_from) * y;
+ float *to = rect_to + ((size_t)stride_to) * y * 4;
+
+ for (x = 0; x < width; x++, from++, to += 4)
+ if (*mask++ == FILTER_MASK_USED)
+ to[0] = to[1] = to[2] = to[3] = from[0];
+ }
+ }
+ else if (channels_from == 3) {
+ /* RGB input */
+ for (y = 0; y < height; y++) {
+ const float *from = rect_from + ((size_t)stride_from) * y * 3;
+ float *to = rect_to + ((size_t)stride_to) * y * 4;
+
+ for (x = 0; x < width; x++, from += 3, to += 4) {
+ if (*mask++ == FILTER_MASK_USED) {
+ copy_v3_v3(to, from);
+ to[3] = 1.0f;
+ }
+ }
+ }
+ }
+ else if (channels_from == 4) {
+ /* RGBA input */
+ for (y = 0; y < height; y++) {
+ const float *from = rect_from + ((size_t)stride_from) * y * 4;
+ float *to = rect_to + ((size_t)stride_to) * y * 4;
+
+ for (x = 0; x < width; x++, from += 4, to += 4)
+ if (*mask++ == FILTER_MASK_USED)
+ copy_v4_v4(to, from);
+ }
+ }
}
/* byte to byte pixels, input and output 4-channel RGBA */
-void IMB_buffer_byte_from_byte(uchar *rect_to, const uchar *rect_from,
- int profile_to, int profile_from, bool predivide,
- int width, int height, int stride_to, int stride_from)
+void IMB_buffer_byte_from_byte(uchar *rect_to,
+ const uchar *rect_from,
+ int profile_to,
+ int profile_from,
+ bool predivide,
+ int width,
+ int height,
+ int stride_to,
+ int stride_from)
{
- float tmp[4];
- int x, y;
-
- /* we need valid profiles */
- BLI_assert(profile_to != IB_PROFILE_NONE);
- BLI_assert(profile_from != IB_PROFILE_NONE);
-
- /* always RGBA input */
- for (y = 0; y < height; y++) {
- const uchar *from = rect_from + ((size_t)stride_from) * y * 4;
- uchar *to = rect_to + ((size_t)stride_to) * y * 4;
-
- if (profile_to == profile_from) {
- /* same profile, copy */
- memcpy(to, from, sizeof(uchar) * 4 * width);
- }
- else if (profile_to == IB_PROFILE_LINEAR_RGB) {
- /* convert to sRGB to linear */
- if (predivide) {
- for (x = 0; x < width; x++, from += 4, to += 4) {
- rgba_uchar_to_float(tmp, from);
- srgb_to_linearrgb_predivide_v4(tmp, tmp);
- rgba_float_to_uchar(to, tmp);
- }
- }
- else {
- for (x = 0; x < width; x++, from += 4, to += 4) {
- rgba_uchar_to_float(tmp, from);
- srgb_to_linearrgb_v4(tmp, tmp);
- rgba_float_to_uchar(to, tmp);
- }
- }
- }
- else if (profile_to == IB_PROFILE_SRGB) {
- /* convert from linear to sRGB */
- if (predivide) {
- for (x = 0; x < width; x++, from += 4, to += 4) {
- rgba_uchar_to_float(tmp, from);
- linearrgb_to_srgb_predivide_v4(tmp, tmp);
- rgba_float_to_uchar(to, tmp);
- }
- }
- else {
- for (x = 0; x < width; x++, from += 4, to += 4) {
- rgba_uchar_to_float(tmp, from);
- linearrgb_to_srgb_v4(tmp, tmp);
- rgba_float_to_uchar(to, tmp);
- }
- }
- }
- }
+ float tmp[4];
+ int x, y;
+
+ /* we need valid profiles */
+ BLI_assert(profile_to != IB_PROFILE_NONE);
+ BLI_assert(profile_from != IB_PROFILE_NONE);
+
+ /* always RGBA input */
+ for (y = 0; y < height; y++) {
+ const uchar *from = rect_from + ((size_t)stride_from) * y * 4;
+ uchar *to = rect_to + ((size_t)stride_to) * y * 4;
+
+ if (profile_to == profile_from) {
+ /* same profile, copy */
+ memcpy(to, from, sizeof(uchar) * 4 * width);
+ }
+ else if (profile_to == IB_PROFILE_LINEAR_RGB) {
+ /* convert to sRGB to linear */
+ if (predivide) {
+ for (x = 0; x < width; x++, from += 4, to += 4) {
+ rgba_uchar_to_float(tmp, from);
+ srgb_to_linearrgb_predivide_v4(tmp, tmp);
+ rgba_float_to_uchar(to, tmp);
+ }
+ }
+ else {
+ for (x = 0; x < width; x++, from += 4, to += 4) {
+ rgba_uchar_to_float(tmp, from);
+ srgb_to_linearrgb_v4(tmp, tmp);
+ rgba_float_to_uchar(to, tmp);
+ }
+ }
+ }
+ else if (profile_to == IB_PROFILE_SRGB) {
+ /* convert from linear to sRGB */
+ if (predivide) {
+ for (x = 0; x < width; x++, from += 4, to += 4) {
+ rgba_uchar_to_float(tmp, from);
+ linearrgb_to_srgb_predivide_v4(tmp, tmp);
+ rgba_float_to_uchar(to, tmp);
+ }
+ }
+ else {
+ for (x = 0; x < width; x++, from += 4, to += 4) {
+ rgba_uchar_to_float(tmp, from);
+ linearrgb_to_srgb_v4(tmp, tmp);
+ rgba_float_to_uchar(to, tmp);
+ }
+ }
+ }
+ }
}
/****************************** ImBuf Conversion *****************************/
void IMB_rect_from_float(ImBuf *ibuf)
{
- float *buffer;
- const char *from_colorspace;
-
- /* verify we have a float buffer */
- if (ibuf->rect_float == NULL)
- return;
-
- /* create byte rect if it didn't exist yet */
- if (ibuf->rect == NULL) {
- if (imb_addrectImBuf(ibuf) == 0)
- return;
- }
-
- if (ibuf->float_colorspace == NULL)
- from_colorspace = IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_SCENE_LINEAR);
- else
- from_colorspace = ibuf->float_colorspace->name;
-
- buffer = MEM_dupallocN(ibuf->rect_float);
-
- /* first make float buffer in byte space */
- IMB_colormanagement_transform(buffer, ibuf->x, ibuf->y, ibuf->channels, from_colorspace, ibuf->rect_colorspace->name, true);
-
- /* convert from float's premul alpha to byte's straight alpha */
- IMB_unpremultiply_rect_float(buffer, ibuf->channels, ibuf->x, ibuf->y);
-
- /* convert float to byte */
- 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);
-
- MEM_freeN(buffer);
-
- /* ensure user flag is reset */
- ibuf->userflags &= ~IB_RECT_INVALID;
+ float *buffer;
+ const char *from_colorspace;
+
+ /* verify we have a float buffer */
+ if (ibuf->rect_float == NULL)
+ return;
+
+ /* create byte rect if it didn't exist yet */
+ if (ibuf->rect == NULL) {
+ if (imb_addrectImBuf(ibuf) == 0)
+ return;
+ }
+
+ if (ibuf->float_colorspace == NULL)
+ from_colorspace = IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_SCENE_LINEAR);
+ else
+ from_colorspace = ibuf->float_colorspace->name;
+
+ buffer = MEM_dupallocN(ibuf->rect_float);
+
+ /* first make float buffer in byte space */
+ IMB_colormanagement_transform(buffer,
+ ibuf->x,
+ ibuf->y,
+ ibuf->channels,
+ from_colorspace,
+ ibuf->rect_colorspace->name,
+ true);
+
+ /* convert from float's premul alpha to byte's straight alpha */
+ IMB_unpremultiply_rect_float(buffer, ibuf->channels, ibuf->x, ibuf->y);
+
+ /* convert float to byte */
+ 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);
+
+ MEM_freeN(buffer);
+
+ /* ensure user flag is reset */
+ ibuf->userflags &= ~IB_RECT_INVALID;
}
typedef struct PartialThreadData {
- ImBuf *ibuf;
- float *buffer;
- uchar *rect_byte;
- const float *rect_float;
- int width;
- bool is_data;
+ ImBuf *ibuf;
+ float *buffer;
+ uchar *rect_byte;
+ const float *rect_float;
+ int width;
+ bool is_data;
} PartialThreadData;
static void partial_rect_from_float_slice(float *buffer,
@@ -696,128 +748,145 @@ static void partial_rect_from_float_slice(float *buffer,
const int h,
const bool is_data)
{
- const int profile_from = IB_PROFILE_LINEAR_RGB;
- if (is_data) {
- /* exception for non-color data, just copy float */
- IMB_buffer_float_from_float(buffer, rect_float,
- ibuf->channels, IB_PROFILE_LINEAR_RGB, IB_PROFILE_LINEAR_RGB, 0,
- w, h, w, ibuf->x);
-
- /* and do color space conversion to byte */
- IMB_buffer_byte_from_float(rect_byte, rect_float,
- 4, ibuf->dither, IB_PROFILE_SRGB, profile_from, true,
- w, h, ibuf->x, w);
- }
- else {
- IMB_buffer_float_from_float(buffer, rect_float,
- ibuf->channels, IB_PROFILE_SRGB, profile_from, true,
- w, h, w, ibuf->x);
-
- IMB_buffer_float_unpremultiply(buffer, w, h);
- /* XXX: need to convert to image buffer's rect space */
- IMB_buffer_byte_from_float(rect_byte, buffer,
- 4, ibuf->dither, IB_PROFILE_SRGB, IB_PROFILE_SRGB, 0,
- w, h, ibuf->x, w);
- }
+ const int profile_from = IB_PROFILE_LINEAR_RGB;
+ if (is_data) {
+ /* exception for non-color data, just copy float */
+ IMB_buffer_float_from_float(buffer,
+ rect_float,
+ ibuf->channels,
+ IB_PROFILE_LINEAR_RGB,
+ IB_PROFILE_LINEAR_RGB,
+ 0,
+ w,
+ h,
+ w,
+ ibuf->x);
+
+ /* and do color space conversion to byte */
+ IMB_buffer_byte_from_float(rect_byte,
+ rect_float,
+ 4,
+ ibuf->dither,
+ IB_PROFILE_SRGB,
+ profile_from,
+ true,
+ w,
+ h,
+ ibuf->x,
+ w);
+ }
+ else {
+ IMB_buffer_float_from_float(
+ buffer, rect_float, ibuf->channels, IB_PROFILE_SRGB, profile_from, true, w, h, w, ibuf->x);
+
+ IMB_buffer_float_unpremultiply(buffer, w, h);
+ /* XXX: need to convert to image buffer's rect space */
+ IMB_buffer_byte_from_float(
+ rect_byte, buffer, 4, ibuf->dither, IB_PROFILE_SRGB, IB_PROFILE_SRGB, 0, w, h, ibuf->x, w);
+ }
}
-static void partial_rect_from_float_thread_do(void *data_v,
- int start_scanline,
- int num_scanlines)
+static void partial_rect_from_float_thread_do(void *data_v, int start_scanline, int num_scanlines)
{
- PartialThreadData *data = (PartialThreadData *)data_v;
- ImBuf *ibuf = data->ibuf;
- size_t global_offset = ((size_t)ibuf->x) * start_scanline;
- size_t local_offset = ((size_t)data->width) * start_scanline;
- partial_rect_from_float_slice(data->buffer + local_offset * ibuf->channels,
- data->rect_byte + global_offset * 4,
- ibuf,
- data->rect_float + global_offset * ibuf->channels,
- data->width,
- num_scanlines,
- data->is_data);
+ PartialThreadData *data = (PartialThreadData *)data_v;
+ ImBuf *ibuf = data->ibuf;
+ size_t global_offset = ((size_t)ibuf->x) * start_scanline;
+ size_t local_offset = ((size_t)data->width) * start_scanline;
+ partial_rect_from_float_slice(data->buffer + local_offset * ibuf->channels,
+ data->rect_byte + global_offset * 4,
+ ibuf,
+ data->rect_float + global_offset * ibuf->channels,
+ data->width,
+ num_scanlines,
+ data->is_data);
}
/* converts from linear float to sRGB byte for part of the texture, buffer will hold the changed part */
-void IMB_partial_rect_from_float(ImBuf *ibuf, float *buffer, int x, int y, int w, int h, bool is_data)
+void IMB_partial_rect_from_float(
+ ImBuf *ibuf, float *buffer, int x, int y, int w, int h, bool is_data)
{
- const float *rect_float;
- uchar *rect_byte;
-
- /* verify we have a float buffer */
- if (ibuf->rect_float == NULL || buffer == NULL)
- return;
-
- /* create byte rect if it didn't exist yet */
- if (ibuf->rect == NULL)
- imb_addrectImBuf(ibuf);
-
- /* do conversion */
- rect_float = ibuf->rect_float + (x + ((size_t)y) * ibuf->x) * ibuf->channels;
- rect_byte = (uchar *)ibuf->rect + (x + ((size_t)y) * ibuf->x) * 4;
-
- if (((size_t)w) * h < 64 * 64) {
- partial_rect_from_float_slice(
- buffer, rect_byte, ibuf, rect_float, w, h, is_data);
- }
- else {
- PartialThreadData data;
- data.ibuf = ibuf;
- data.buffer = buffer;
- data.rect_byte = rect_byte;
- data.rect_float = rect_float;
- data.width = w;
- data.is_data = is_data;
- IMB_processor_apply_threaded_scanlines(
- h, partial_rect_from_float_thread_do, &data);
- }
-
- /* ensure user flag is reset */
- ibuf->userflags &= ~IB_RECT_INVALID;
+ const float *rect_float;
+ uchar *rect_byte;
+
+ /* verify we have a float buffer */
+ if (ibuf->rect_float == NULL || buffer == NULL)
+ return;
+
+ /* create byte rect if it didn't exist yet */
+ if (ibuf->rect == NULL)
+ imb_addrectImBuf(ibuf);
+
+ /* do conversion */
+ rect_float = ibuf->rect_float + (x + ((size_t)y) * ibuf->x) * ibuf->channels;
+ rect_byte = (uchar *)ibuf->rect + (x + ((size_t)y) * ibuf->x) * 4;
+
+ if (((size_t)w) * h < 64 * 64) {
+ partial_rect_from_float_slice(buffer, rect_byte, ibuf, rect_float, w, h, is_data);
+ }
+ else {
+ PartialThreadData data;
+ data.ibuf = ibuf;
+ data.buffer = buffer;
+ data.rect_byte = rect_byte;
+ data.rect_float = rect_float;
+ data.width = w;
+ data.is_data = is_data;
+ IMB_processor_apply_threaded_scanlines(h, partial_rect_from_float_thread_do, &data);
+ }
+
+ /* ensure user flag is reset */
+ ibuf->userflags &= ~IB_RECT_INVALID;
}
void IMB_float_from_rect(ImBuf *ibuf)
{
- float *rect_float;
-
- /* verify if we byte and float buffers */
- if (ibuf->rect == NULL)
- return;
-
- /* allocate float buffer outside of image buffer,
- * so work-in-progress color space conversion doesn't
- * interfere with other parts of blender
- */
- rect_float = ibuf->rect_float;
- if (rect_float == NULL) {
- size_t size;
-
- size = ((size_t)ibuf->x) * ibuf->y;
- size = size * 4 * sizeof(float);
- ibuf->channels = 4;
-
- rect_float = MEM_mapallocN(size, "IMB_float_from_rect");
-
- if (rect_float == NULL)
- return;
- }
-
- /* first, create float buffer in non-linear space */
- IMB_buffer_float_from_byte(rect_float, (unsigned char *) ibuf->rect, IB_PROFILE_SRGB, IB_PROFILE_SRGB,
- false, ibuf->x, ibuf->y, ibuf->x, ibuf->x);
-
- /* then make float be in linear space */
- IMB_colormanagement_colorspace_to_scene_linear(rect_float, ibuf->x, ibuf->y, ibuf->channels,
- ibuf->rect_colorspace, false);
-
- /* byte buffer is straight alpha, float should always be premul */
- IMB_premultiply_rect_float(rect_float, ibuf->channels, ibuf->x, ibuf->y);
-
- if (ibuf->rect_float == NULL) {
- ibuf->rect_float = rect_float;
- ibuf->mall |= IB_rectfloat;
- ibuf->flags |= IB_rectfloat;
- }
+ float *rect_float;
+
+ /* verify if we byte and float buffers */
+ if (ibuf->rect == NULL)
+ return;
+
+ /* allocate float buffer outside of image buffer,
+ * so work-in-progress color space conversion doesn't
+ * interfere with other parts of blender
+ */
+ rect_float = ibuf->rect_float;
+ if (rect_float == NULL) {
+ size_t size;
+
+ size = ((size_t)ibuf->x) * ibuf->y;
+ size = size * 4 * sizeof(float);
+ ibuf->channels = 4;
+
+ rect_float = MEM_mapallocN(size, "IMB_float_from_rect");
+
+ if (rect_float == NULL)
+ return;
+ }
+
+ /* first, create float buffer in non-linear space */
+ IMB_buffer_float_from_byte(rect_float,
+ (unsigned char *)ibuf->rect,
+ IB_PROFILE_SRGB,
+ IB_PROFILE_SRGB,
+ false,
+ ibuf->x,
+ ibuf->y,
+ ibuf->x,
+ ibuf->x);
+
+ /* then make float be in linear space */
+ IMB_colormanagement_colorspace_to_scene_linear(
+ rect_float, ibuf->x, ibuf->y, ibuf->channels, ibuf->rect_colorspace, false);
+
+ /* byte buffer is straight alpha, float should always be premul */
+ IMB_premultiply_rect_float(rect_float, ibuf->channels, ibuf->x, ibuf->y);
+
+ if (ibuf->rect_float == NULL) {
+ ibuf->rect_float = rect_float;
+ ibuf->mall |= IB_rectfloat;
+ ibuf->flags |= IB_rectfloat;
+ }
}
/**************************** Color to Grayscale *****************************/
@@ -825,72 +894,72 @@ void IMB_float_from_rect(ImBuf *ibuf)
/* no profile conversion */
void IMB_color_to_bw(ImBuf *ibuf)
{
- float *rct_fl = ibuf->rect_float;
- uchar *rct = (uchar *)ibuf->rect;
- size_t i;
-
- if (rct_fl) {
- for (i = ((size_t)ibuf->x) * ibuf->y; i > 0; i--, rct_fl += 4)
- rct_fl[0] = rct_fl[1] = rct_fl[2] = IMB_colormanagement_get_luminance(rct_fl);
- }
-
- if (rct) {
- for (i = ((size_t)ibuf->x * ibuf->y); i > 0; i--, rct += 4)
- rct[0] = rct[1] = rct[2] = IMB_colormanagement_get_luminance_byte(rct);
- }
+ float *rct_fl = ibuf->rect_float;
+ uchar *rct = (uchar *)ibuf->rect;
+ size_t i;
+
+ if (rct_fl) {
+ for (i = ((size_t)ibuf->x) * ibuf->y; i > 0; i--, rct_fl += 4)
+ rct_fl[0] = rct_fl[1] = rct_fl[2] = IMB_colormanagement_get_luminance(rct_fl);
+ }
+
+ if (rct) {
+ for (i = ((size_t)ibuf->x * ibuf->y); i > 0; i--, rct += 4)
+ rct[0] = rct[1] = rct[2] = IMB_colormanagement_get_luminance_byte(rct);
+ }
}
void IMB_buffer_float_clamp(float *buf, int width, int height)
{
- size_t i, total = ((size_t)width) * height * 4;
- for (i = 0; i < total; i++) {
- buf[i] = min_ff(1.0, buf[i]);
- }
+ size_t i, total = ((size_t)width) * height * 4;
+ for (i = 0; i < total; i++) {
+ buf[i] = min_ff(1.0, buf[i]);
+ }
}
void IMB_buffer_float_unpremultiply(float *buf, int width, int height)
{
- size_t total = ((size_t)width) * height;
- float *fp = buf;
- while (total--) {
- premul_to_straight_v4(fp);
- fp += 4;
- }
+ size_t total = ((size_t)width) * height;
+ float *fp = buf;
+ while (total--) {
+ premul_to_straight_v4(fp);
+ fp += 4;
+ }
}
void IMB_buffer_float_premultiply(float *buf, int width, int height)
{
- size_t total = ((size_t)width) * height;
- float *fp = buf;
- while (total--) {
- straight_to_premul_v4(fp);
- fp += 4;
- }
+ size_t total = ((size_t)width) * height;
+ float *fp = buf;
+ while (total--) {
+ straight_to_premul_v4(fp);
+ fp += 4;
+ }
}
/**************************** alter saturation *****************************/
void IMB_saturation(ImBuf *ibuf, float sat)
{
- size_t i;
- unsigned char *rct = (unsigned char *)ibuf->rect;
- float *rct_fl = ibuf->rect_float;
- float hsv[3];
-
- if (rct) {
- float rgb[3];
- for (i = ((size_t)ibuf->x) * ibuf->y; i > 0; i--, rct += 4) {
- rgb_uchar_to_float(rgb, rct);
- rgb_to_hsv_v(rgb, hsv);
- hsv_to_rgb(hsv[0], hsv[1] * sat, hsv[2], rgb, rgb + 1, rgb + 2);
- rgb_float_to_uchar(rct, rgb);
- }
- }
-
- if (rct_fl) {
- for (i = ((size_t)ibuf->x) * ibuf->y; i > 0; i--, rct_fl += 4) {
- rgb_to_hsv_v(rct_fl, hsv);
- hsv_to_rgb(hsv[0], hsv[1] * sat, hsv[2], rct_fl, rct_fl + 1, rct_fl + 2);
- }
- }
+ size_t i;
+ unsigned char *rct = (unsigned char *)ibuf->rect;
+ float *rct_fl = ibuf->rect_float;
+ float hsv[3];
+
+ if (rct) {
+ float rgb[3];
+ for (i = ((size_t)ibuf->x) * ibuf->y; i > 0; i--, rct += 4) {
+ rgb_uchar_to_float(rgb, rct);
+ rgb_to_hsv_v(rgb, hsv);
+ hsv_to_rgb(hsv[0], hsv[1] * sat, hsv[2], rgb, rgb + 1, rgb + 2);
+ rgb_float_to_uchar(rct, rgb);
+ }
+ }
+
+ if (rct_fl) {
+ for (i = ((size_t)ibuf->x) * ibuf->y; i > 0; i--, rct_fl += 4) {
+ rgb_to_hsv_v(rct_fl, hsv);
+ hsv_to_rgb(hsv[0], hsv[1] * sat, hsv[2], rct_fl, rct_fl + 1, rct_fl + 2);
+ }
+ }
}
diff --git a/source/blender/imbuf/intern/filetype.c b/source/blender/imbuf/intern/filetype.c
index e02141b6038..7056e901f65 100644
--- a/source/blender/imbuf/intern/filetype.c
+++ b/source/blender/imbuf/intern/filetype.c
@@ -18,7 +18,6 @@
* \ingroup imbuf
*/
-
#include <stddef.h>
#include "BLI_utildefines.h"
@@ -30,74 +29,218 @@
#include "IMB_colormanagement.h"
#ifdef WITH_OPENIMAGEIO
-#include "oiio/openimageio_api.h"
+# include "oiio/openimageio_api.h"
#endif
#ifdef WITH_OPENEXR
-#include "openexr/openexr_api.h"
+# include "openexr/openexr_api.h"
#endif
#ifdef WITH_DDS
-#include "dds/dds_api.h"
+# include "dds/dds_api.h"
#endif
static int imb_ftype_default(const ImFileType *type, ImBuf *ibuf)
{
- return (ibuf->ftype == type->filetype);
+ return (ibuf->ftype == type->filetype);
}
static int imb_ftype_iris(const ImFileType *type, ImBuf *ibuf)
{
- (void)type;
- return (ibuf->ftype == IMB_FTYPE_IMAGIC);
+ (void)type;
+ return (ibuf->ftype == IMB_FTYPE_IMAGIC);
}
const ImFileType IMB_FILE_TYPES[] = {
- {NULL, NULL, imb_is_a_jpeg, NULL, imb_ftype_default, imb_load_jpeg, NULL, imb_savejpeg, NULL, 0, IMB_FTYPE_JPG, COLOR_ROLE_DEFAULT_BYTE},
- {NULL, NULL, imb_is_a_png, NULL, imb_ftype_default, imb_loadpng, NULL, imb_savepng, NULL, 0, IMB_FTYPE_PNG, COLOR_ROLE_DEFAULT_BYTE},
- {NULL, NULL, imb_is_a_bmp, NULL, imb_ftype_default, imb_bmp_decode, NULL, imb_savebmp, NULL, 0, IMB_FTYPE_BMP, COLOR_ROLE_DEFAULT_BYTE},
- {NULL, NULL, imb_is_a_targa, NULL, imb_ftype_default, imb_loadtarga, NULL, imb_savetarga, NULL, 0, IMB_FTYPE_TGA, COLOR_ROLE_DEFAULT_BYTE},
- {NULL, NULL, imb_is_a_iris, NULL, imb_ftype_iris, imb_loadiris, NULL, imb_saveiris, NULL, 0, IMB_FTYPE_IMAGIC, COLOR_ROLE_DEFAULT_BYTE},
+ {NULL,
+ NULL,
+ imb_is_a_jpeg,
+ NULL,
+ imb_ftype_default,
+ imb_load_jpeg,
+ NULL,
+ imb_savejpeg,
+ NULL,
+ 0,
+ IMB_FTYPE_JPG,
+ COLOR_ROLE_DEFAULT_BYTE},
+ {NULL,
+ NULL,
+ imb_is_a_png,
+ NULL,
+ imb_ftype_default,
+ imb_loadpng,
+ NULL,
+ imb_savepng,
+ NULL,
+ 0,
+ IMB_FTYPE_PNG,
+ COLOR_ROLE_DEFAULT_BYTE},
+ {NULL,
+ NULL,
+ imb_is_a_bmp,
+ NULL,
+ imb_ftype_default,
+ imb_bmp_decode,
+ NULL,
+ imb_savebmp,
+ NULL,
+ 0,
+ IMB_FTYPE_BMP,
+ COLOR_ROLE_DEFAULT_BYTE},
+ {NULL,
+ NULL,
+ imb_is_a_targa,
+ NULL,
+ imb_ftype_default,
+ imb_loadtarga,
+ NULL,
+ imb_savetarga,
+ NULL,
+ 0,
+ IMB_FTYPE_TGA,
+ COLOR_ROLE_DEFAULT_BYTE},
+ {NULL,
+ NULL,
+ imb_is_a_iris,
+ NULL,
+ imb_ftype_iris,
+ imb_loadiris,
+ NULL,
+ imb_saveiris,
+ NULL,
+ 0,
+ IMB_FTYPE_IMAGIC,
+ COLOR_ROLE_DEFAULT_BYTE},
#ifdef WITH_CINEON
- {NULL, NULL, imb_is_dpx, NULL, imb_ftype_default, imb_load_dpx, NULL, imb_save_dpx, NULL, IM_FTYPE_FLOAT, IMB_FTYPE_DPX, COLOR_ROLE_DEFAULT_FLOAT},
- {NULL, NULL, imb_is_cineon, NULL, imb_ftype_default, imb_load_cineon, NULL, imb_save_cineon, NULL, IM_FTYPE_FLOAT, IMB_FTYPE_CINEON, COLOR_ROLE_DEFAULT_FLOAT},
+ {NULL,
+ NULL,
+ imb_is_dpx,
+ NULL,
+ imb_ftype_default,
+ imb_load_dpx,
+ NULL,
+ imb_save_dpx,
+ NULL,
+ IM_FTYPE_FLOAT,
+ IMB_FTYPE_DPX,
+ COLOR_ROLE_DEFAULT_FLOAT},
+ {NULL,
+ NULL,
+ imb_is_cineon,
+ NULL,
+ imb_ftype_default,
+ imb_load_cineon,
+ NULL,
+ imb_save_cineon,
+ NULL,
+ IM_FTYPE_FLOAT,
+ IMB_FTYPE_CINEON,
+ COLOR_ROLE_DEFAULT_FLOAT},
#endif
#ifdef WITH_TIFF
- {imb_inittiff, NULL, imb_is_a_tiff, NULL, imb_ftype_default, imb_loadtiff, NULL, imb_savetiff, imb_loadtiletiff, 0, IMB_FTYPE_TIF, COLOR_ROLE_DEFAULT_BYTE},
+ {imb_inittiff,
+ NULL,
+ imb_is_a_tiff,
+ NULL,
+ imb_ftype_default,
+ imb_loadtiff,
+ NULL,
+ imb_savetiff,
+ imb_loadtiletiff,
+ 0,
+ IMB_FTYPE_TIF,
+ COLOR_ROLE_DEFAULT_BYTE},
#endif
#ifdef WITH_HDR
- {NULL, NULL, imb_is_a_hdr, NULL, imb_ftype_default, imb_loadhdr, NULL, imb_savehdr, NULL, IM_FTYPE_FLOAT, IMB_FTYPE_RADHDR, COLOR_ROLE_DEFAULT_FLOAT},
+ {NULL,
+ NULL,
+ imb_is_a_hdr,
+ NULL,
+ imb_ftype_default,
+ imb_loadhdr,
+ NULL,
+ imb_savehdr,
+ NULL,
+ IM_FTYPE_FLOAT,
+ IMB_FTYPE_RADHDR,
+ COLOR_ROLE_DEFAULT_FLOAT},
#endif
#ifdef WITH_OPENEXR
- {imb_initopenexr, imb_exitopenexr, imb_is_a_openexr, NULL, imb_ftype_default, imb_load_openexr, NULL, imb_save_openexr, NULL, IM_FTYPE_FLOAT, IMB_FTYPE_OPENEXR, COLOR_ROLE_DEFAULT_FLOAT},
+ {imb_initopenexr,
+ imb_exitopenexr,
+ imb_is_a_openexr,
+ NULL,
+ imb_ftype_default,
+ imb_load_openexr,
+ NULL,
+ imb_save_openexr,
+ NULL,
+ IM_FTYPE_FLOAT,
+ IMB_FTYPE_OPENEXR,
+ COLOR_ROLE_DEFAULT_FLOAT},
#endif
#ifdef WITH_OPENJPEG
- {NULL, NULL, imb_is_a_jp2, NULL, imb_ftype_default, imb_load_jp2, NULL, imb_save_jp2, NULL, IM_FTYPE_FLOAT, IMB_FTYPE_JP2, COLOR_ROLE_DEFAULT_BYTE},
+ {NULL,
+ NULL,
+ imb_is_a_jp2,
+ NULL,
+ imb_ftype_default,
+ imb_load_jp2,
+ NULL,
+ imb_save_jp2,
+ NULL,
+ IM_FTYPE_FLOAT,
+ IMB_FTYPE_JP2,
+ COLOR_ROLE_DEFAULT_BYTE},
#endif
#ifdef WITH_DDS
- {NULL, NULL, imb_is_a_dds, NULL, imb_ftype_default, imb_load_dds, NULL, NULL, NULL, 0, IMB_FTYPE_DDS, COLOR_ROLE_DEFAULT_BYTE},
+ {NULL,
+ NULL,
+ imb_is_a_dds,
+ NULL,
+ imb_ftype_default,
+ imb_load_dds,
+ NULL,
+ NULL,
+ NULL,
+ 0,
+ IMB_FTYPE_DDS,
+ COLOR_ROLE_DEFAULT_BYTE},
#endif
#ifdef WITH_OPENIMAGEIO
- {NULL, NULL, NULL, imb_is_a_photoshop, imb_ftype_default, NULL, imb_load_photoshop, NULL, NULL, IM_FTYPE_FLOAT, IMB_FTYPE_PSD, COLOR_ROLE_DEFAULT_FLOAT},
+ {NULL,
+ NULL,
+ NULL,
+ imb_is_a_photoshop,
+ imb_ftype_default,
+ NULL,
+ imb_load_photoshop,
+ NULL,
+ NULL,
+ IM_FTYPE_FLOAT,
+ IMB_FTYPE_PSD,
+ COLOR_ROLE_DEFAULT_FLOAT},
#endif
- {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0},
+ {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0},
};
-const ImFileType *IMB_FILE_TYPES_LAST = &IMB_FILE_TYPES[sizeof(IMB_FILE_TYPES) / sizeof(ImFileType) - 1];
+const ImFileType *IMB_FILE_TYPES_LAST =
+ &IMB_FILE_TYPES[sizeof(IMB_FILE_TYPES) / sizeof(ImFileType) - 1];
void imb_filetypes_init(void)
{
- const ImFileType *type;
+ const ImFileType *type;
- for (type = IMB_FILE_TYPES; type < IMB_FILE_TYPES_LAST; type++)
- if (type->init)
- type->init();
+ for (type = IMB_FILE_TYPES; type < IMB_FILE_TYPES_LAST; type++)
+ if (type->init)
+ type->init();
}
void imb_filetypes_exit(void)
{
- const ImFileType *type;
+ const ImFileType *type;
- for (type = IMB_FILE_TYPES; type < IMB_FILE_TYPES_LAST; type++)
- if (type->exit)
- type->exit();
+ for (type = IMB_FILE_TYPES; type < IMB_FILE_TYPES_LAST; type++)
+ if (type->exit)
+ type->exit();
}
diff --git a/source/blender/imbuf/intern/filter.c b/source/blender/imbuf/intern/filter.c
index 673d4aae59f..2d7e90db34e 100644
--- a/source/blender/imbuf/intern/filter.c
+++ b/source/blender/imbuf/intern/filter.c
@@ -35,353 +35,380 @@
static void filtrow(unsigned char *point, int x)
{
- unsigned int c1, c2, c3, error;
-
- if (x > 1) {
- c1 = c2 = *point;
- error = 2;
- for (x--; x > 0; x--) {
- c3 = point[4];
- c1 += (c2 << 1) + c3 + error;
- error = c1 & 3;
- *point = c1 >> 2;
- point += 4;
- c1 = c2;
- c2 = c3;
- }
- *point = (c1 + (c2 << 1) + c2 + error) >> 2;
- }
+ unsigned int c1, c2, c3, error;
+
+ if (x > 1) {
+ c1 = c2 = *point;
+ error = 2;
+ for (x--; x > 0; x--) {
+ c3 = point[4];
+ c1 += (c2 << 1) + c3 + error;
+ error = c1 & 3;
+ *point = c1 >> 2;
+ point += 4;
+ c1 = c2;
+ c2 = c3;
+ }
+ *point = (c1 + (c2 << 1) + c2 + error) >> 2;
+ }
}
static void filtrowf(float *point, int x)
{
- float c1, c2, c3;
-
- if (x > 1) {
- c1 = c2 = *point;
- for (x--; x > 0; x--) {
- c3 = point[4];
- c1 += (c2 * 2) + c3;
- *point = 0.25f * c1;
- point += 4;
- c1 = c2;
- c2 = c3;
- }
- *point = 0.25f * (c1 + (c2 * 2) + c2);
- }
+ float c1, c2, c3;
+
+ if (x > 1) {
+ c1 = c2 = *point;
+ for (x--; x > 0; x--) {
+ c3 = point[4];
+ c1 += (c2 * 2) + c3;
+ *point = 0.25f * c1;
+ point += 4;
+ c1 = c2;
+ c2 = c3;
+ }
+ *point = 0.25f * (c1 + (c2 * 2) + c2);
+ }
}
-
-
static void filtcolum(unsigned char *point, int y, int skip)
{
- unsigned int c1, c2, c3, error;
- unsigned char *point2;
-
- if (y > 1) {
- c1 = c2 = *point;
- point2 = point;
- error = 2;
- for (y--; y > 0; y--) {
- point2 += skip;
- c3 = *point2;
- c1 += (c2 << 1) + c3 + error;
- error = c1 & 3;
- *point = c1 >> 2;
- point = point2;
- c1 = c2;
- c2 = c3;
- }
- *point = (c1 + (c2 << 1) + c2 + error) >> 2;
- }
+ unsigned int c1, c2, c3, error;
+ unsigned char *point2;
+
+ if (y > 1) {
+ c1 = c2 = *point;
+ point2 = point;
+ error = 2;
+ for (y--; y > 0; y--) {
+ point2 += skip;
+ c3 = *point2;
+ c1 += (c2 << 1) + c3 + error;
+ error = c1 & 3;
+ *point = c1 >> 2;
+ point = point2;
+ c1 = c2;
+ c2 = c3;
+ }
+ *point = (c1 + (c2 << 1) + c2 + error) >> 2;
+ }
}
static void filtcolumf(float *point, int y, int skip)
{
- float c1, c2, c3, *point2;
-
- if (y > 1) {
- c1 = c2 = *point;
- point2 = point;
- for (y--; y > 0; y--) {
- point2 += skip;
- c3 = *point2;
- c1 += (c2 * 2) + c3;
- *point = 0.25f * c1;
- point = point2;
- c1 = c2;
- c2 = c3;
- }
- *point = 0.25f * (c1 + (c2 * 2) + c2);
- }
+ float c1, c2, c3, *point2;
+
+ if (y > 1) {
+ c1 = c2 = *point;
+ point2 = point;
+ for (y--; y > 0; y--) {
+ point2 += skip;
+ c3 = *point2;
+ c1 += (c2 * 2) + c3;
+ *point = 0.25f * c1;
+ point = point2;
+ c1 = c2;
+ c2 = c3;
+ }
+ *point = 0.25f * (c1 + (c2 * 2) + c2);
+ }
}
void IMB_filtery(struct ImBuf *ibuf)
{
- unsigned char *point;
- float *pointf;
- int x, y, skip;
-
- point = (unsigned char *)ibuf->rect;
- pointf = ibuf->rect_float;
-
- x = ibuf->x;
- y = ibuf->y;
- skip = x << 2;
-
- for (; x > 0; x--) {
- if (point) {
- if (ibuf->planes > 24) filtcolum(point, y, skip);
- point++;
- filtcolum(point, y, skip);
- point++;
- filtcolum(point, y, skip);
- point++;
- filtcolum(point, y, skip);
- point++;
- }
- if (pointf) {
- if (ibuf->planes > 24) filtcolumf(pointf, y, skip);
- pointf++;
- filtcolumf(pointf, y, skip);
- pointf++;
- filtcolumf(pointf, y, skip);
- pointf++;
- filtcolumf(pointf, y, skip);
- pointf++;
- }
- }
+ unsigned char *point;
+ float *pointf;
+ int x, y, skip;
+
+ point = (unsigned char *)ibuf->rect;
+ pointf = ibuf->rect_float;
+
+ x = ibuf->x;
+ y = ibuf->y;
+ skip = x << 2;
+
+ for (; x > 0; x--) {
+ if (point) {
+ if (ibuf->planes > 24)
+ filtcolum(point, y, skip);
+ point++;
+ filtcolum(point, y, skip);
+ point++;
+ filtcolum(point, y, skip);
+ point++;
+ filtcolum(point, y, skip);
+ point++;
+ }
+ if (pointf) {
+ if (ibuf->planes > 24)
+ filtcolumf(pointf, y, skip);
+ pointf++;
+ filtcolumf(pointf, y, skip);
+ pointf++;
+ filtcolumf(pointf, y, skip);
+ pointf++;
+ filtcolumf(pointf, y, skip);
+ pointf++;
+ }
+ }
}
-
void imb_filterx(struct ImBuf *ibuf)
{
- unsigned char *point;
- float *pointf;
- int x, y, skip;
-
- point = (unsigned char *)ibuf->rect;
- pointf = ibuf->rect_float;
-
- x = ibuf->x;
- y = ibuf->y;
- skip = (x << 2) - 3;
-
- for (; y > 0; y--) {
- if (point) {
- if (ibuf->planes > 24) filtrow(point, x);
- point++;
- filtrow(point, x);
- point++;
- filtrow(point, x);
- point++;
- filtrow(point, x);
- point += skip;
- }
- if (pointf) {
- if (ibuf->planes > 24) filtrowf(pointf, x);
- pointf++;
- filtrowf(pointf, x);
- pointf++;
- filtrowf(pointf, x);
- pointf++;
- filtrowf(pointf, x);
- pointf += skip;
- }
- }
+ unsigned char *point;
+ float *pointf;
+ int x, y, skip;
+
+ point = (unsigned char *)ibuf->rect;
+ pointf = ibuf->rect_float;
+
+ x = ibuf->x;
+ y = ibuf->y;
+ skip = (x << 2) - 3;
+
+ for (; y > 0; y--) {
+ if (point) {
+ if (ibuf->planes > 24)
+ filtrow(point, x);
+ point++;
+ filtrow(point, x);
+ point++;
+ filtrow(point, x);
+ point++;
+ filtrow(point, x);
+ point += skip;
+ }
+ if (pointf) {
+ if (ibuf->planes > 24)
+ filtrowf(pointf, x);
+ pointf++;
+ filtrowf(pointf, x);
+ pointf++;
+ filtrowf(pointf, x);
+ pointf++;
+ filtrowf(pointf, x);
+ pointf += skip;
+ }
+ }
}
static void imb_filterN(ImBuf *out, ImBuf *in)
{
- BLI_assert(out->channels == in->channels);
- BLI_assert(out->x == in->x && out->y == in->y);
-
- const int channels = in->channels;
- const int rowlen = in->x;
-
- if (in->rect && out->rect) {
- for (int y = 0; y < in->y; y++) {
- /* setup rows */
- const char *row2 = (const char *)in->rect + y * channels * rowlen;
- const char *row1 = (y == 0) ? row2 : row2 - channels * rowlen;
- const char *row3 = (y == in->y - 1) ? row2 : row2 + channels * rowlen;
-
- char *cp = (char *)out->rect + y * channels * rowlen;
-
- for (int x = 0; x < rowlen; x++) {
- const char *r11, *r13, *r21, *r23, *r31, *r33;
-
- if (x == 0) {
- r11 = row1;
- r21 = row2;
- r31 = row3;
- }
- else {
- r11 = row1 - channels;
- r21 = row2 - channels;
- r31 = row3 - channels;
- }
-
- if (x == rowlen - 1) {
- r13 = row1;
- r23 = row2;
- r33 = row3;
- }
- else {
- r13 = row1 + channels;
- r23 = row2 + channels;
- r33 = row3 + channels;
- }
-
- cp[0] = (r11[0] + 2 * row1[0] + r13[0] + 2 * r21[0] + 4 * row2[0] + 2 * r23[0] + r31[0] + 2 * row3[0] + r33[0]) >> 4;
- cp[1] = (r11[1] + 2 * row1[1] + r13[1] + 2 * r21[1] + 4 * row2[1] + 2 * r23[1] + r31[1] + 2 * row3[1] + r33[1]) >> 4;
- cp[2] = (r11[2] + 2 * row1[2] + r13[2] + 2 * r21[2] + 4 * row2[2] + 2 * r23[2] + r31[2] + 2 * row3[2] + r33[2]) >> 4;
- cp[3] = (r11[3] + 2 * row1[3] + r13[3] + 2 * r21[3] + 4 * row2[3] + 2 * r23[3] + r31[3] + 2 * row3[3] + r33[3]) >> 4;
- cp += channels; row1 += channels; row2 += channels; row3 += channels;
- }
- }
- }
-
- if (in->rect_float && out->rect_float) {
- for (int y = 0; y < in->y; y++) {
- /* setup rows */
- const float *row2 = (const float *)in->rect_float + y * channels * rowlen;
- const float *row1 = (y == 0) ? row2 : row2 - channels * rowlen;
- const float *row3 = (y == in->y - 1) ? row2 : row2 + channels * rowlen;
-
- float *cp = (float *)out->rect_float + y * channels * rowlen;
-
- for (int x = 0; x < rowlen; x++) {
- const float *r11, *r13, *r21, *r23, *r31, *r33;
-
- if (x == 0) {
- r11 = row1;
- r21 = row2;
- r31 = row3;
- }
- else {
- r11 = row1 - channels;
- r21 = row2 - channels;
- r31 = row3 - channels;
- }
-
- if (x == rowlen - 1) {
- r13 = row1;
- r23 = row2;
- r33 = row3;
- }
- else {
- r13 = row1 + channels;
- r23 = row2 + channels;
- r33 = row3 + channels;
- }
-
- cp[0] = (r11[0] + 2 * row1[0] + r13[0] + 2 * r21[0] + 4 * row2[0] + 2 * r23[0] + r31[0] + 2 * row3[0] + r33[0]) * (1.0f / 16.0f);
- cp[1] = (r11[1] + 2 * row1[1] + r13[1] + 2 * r21[1] + 4 * row2[1] + 2 * r23[1] + r31[1] + 2 * row3[1] + r33[1]) * (1.0f / 16.0f);
- cp[2] = (r11[2] + 2 * row1[2] + r13[2] + 2 * r21[2] + 4 * row2[2] + 2 * r23[2] + r31[2] + 2 * row3[2] + r33[2]) * (1.0f / 16.0f);
- cp[3] = (r11[3] + 2 * row1[3] + r13[3] + 2 * r21[3] + 4 * row2[3] + 2 * r23[3] + r31[3] + 2 * row3[3] + r33[3]) * (1.0f / 16.0f);
- cp += channels; row1 += channels; row2 += channels; row3 += channels;
- }
- }
- }
+ BLI_assert(out->channels == in->channels);
+ BLI_assert(out->x == in->x && out->y == in->y);
+
+ const int channels = in->channels;
+ const int rowlen = in->x;
+
+ if (in->rect && out->rect) {
+ for (int y = 0; y < in->y; y++) {
+ /* setup rows */
+ const char *row2 = (const char *)in->rect + y * channels * rowlen;
+ const char *row1 = (y == 0) ? row2 : row2 - channels * rowlen;
+ const char *row3 = (y == in->y - 1) ? row2 : row2 + channels * rowlen;
+
+ char *cp = (char *)out->rect + y * channels * rowlen;
+
+ for (int x = 0; x < rowlen; x++) {
+ const char *r11, *r13, *r21, *r23, *r31, *r33;
+
+ if (x == 0) {
+ r11 = row1;
+ r21 = row2;
+ r31 = row3;
+ }
+ else {
+ r11 = row1 - channels;
+ r21 = row2 - channels;
+ r31 = row3 - channels;
+ }
+
+ if (x == rowlen - 1) {
+ r13 = row1;
+ r23 = row2;
+ r33 = row3;
+ }
+ else {
+ r13 = row1 + channels;
+ r23 = row2 + channels;
+ r33 = row3 + channels;
+ }
+
+ cp[0] = (r11[0] + 2 * row1[0] + r13[0] + 2 * r21[0] + 4 * row2[0] + 2 * r23[0] + r31[0] +
+ 2 * row3[0] + r33[0]) >>
+ 4;
+ cp[1] = (r11[1] + 2 * row1[1] + r13[1] + 2 * r21[1] + 4 * row2[1] + 2 * r23[1] + r31[1] +
+ 2 * row3[1] + r33[1]) >>
+ 4;
+ cp[2] = (r11[2] + 2 * row1[2] + r13[2] + 2 * r21[2] + 4 * row2[2] + 2 * r23[2] + r31[2] +
+ 2 * row3[2] + r33[2]) >>
+ 4;
+ cp[3] = (r11[3] + 2 * row1[3] + r13[3] + 2 * r21[3] + 4 * row2[3] + 2 * r23[3] + r31[3] +
+ 2 * row3[3] + r33[3]) >>
+ 4;
+ cp += channels;
+ row1 += channels;
+ row2 += channels;
+ row3 += channels;
+ }
+ }
+ }
+
+ if (in->rect_float && out->rect_float) {
+ for (int y = 0; y < in->y; y++) {
+ /* setup rows */
+ const float *row2 = (const float *)in->rect_float + y * channels * rowlen;
+ const float *row1 = (y == 0) ? row2 : row2 - channels * rowlen;
+ const float *row3 = (y == in->y - 1) ? row2 : row2 + channels * rowlen;
+
+ float *cp = (float *)out->rect_float + y * channels * rowlen;
+
+ for (int x = 0; x < rowlen; x++) {
+ const float *r11, *r13, *r21, *r23, *r31, *r33;
+
+ if (x == 0) {
+ r11 = row1;
+ r21 = row2;
+ r31 = row3;
+ }
+ else {
+ r11 = row1 - channels;
+ r21 = row2 - channels;
+ r31 = row3 - channels;
+ }
+
+ if (x == rowlen - 1) {
+ r13 = row1;
+ r23 = row2;
+ r33 = row3;
+ }
+ else {
+ r13 = row1 + channels;
+ r23 = row2 + channels;
+ r33 = row3 + channels;
+ }
+
+ cp[0] = (r11[0] + 2 * row1[0] + r13[0] + 2 * r21[0] + 4 * row2[0] + 2 * r23[0] + r31[0] +
+ 2 * row3[0] + r33[0]) *
+ (1.0f / 16.0f);
+ cp[1] = (r11[1] + 2 * row1[1] + r13[1] + 2 * r21[1] + 4 * row2[1] + 2 * r23[1] + r31[1] +
+ 2 * row3[1] + r33[1]) *
+ (1.0f / 16.0f);
+ cp[2] = (r11[2] + 2 * row1[2] + r13[2] + 2 * r21[2] + 4 * row2[2] + 2 * r23[2] + r31[2] +
+ 2 * row3[2] + r33[2]) *
+ (1.0f / 16.0f);
+ cp[3] = (r11[3] + 2 * row1[3] + r13[3] + 2 * r21[3] + 4 * row2[3] + 2 * r23[3] + r31[3] +
+ 2 * row3[3] + r33[3]) *
+ (1.0f / 16.0f);
+ cp += channels;
+ row1 += channels;
+ row2 += channels;
+ row3 += channels;
+ }
+ }
+ }
}
void IMB_filter(struct ImBuf *ibuf)
{
- IMB_filtery(ibuf);
- imb_filterx(ibuf);
+ IMB_filtery(ibuf);
+ imb_filterx(ibuf);
}
void IMB_mask_filter_extend(char *mask, int width, int height)
{
- const char *row1, *row2, *row3;
- int rowlen, x, y;
- char *temprect;
-
- rowlen = width;
-
- /* make a copy, to prevent flooding */
- temprect = MEM_dupallocN(mask);
-
- for (y = 1; y <= height; y++) {
- /* setup rows */
- row1 = (char *)(temprect + (y - 2) * rowlen);
- row2 = row1 + rowlen;
- row3 = row2 + rowlen;
- if (y == 1)
- row1 = row2;
- else if (y == height)
- row3 = row2;
-
- for (x = 0; x < rowlen; x++) {
- if (mask[((y - 1) * rowlen) + x] == 0) {
- if (*row1 || *row2 || *row3 || *(row1 + 1) || *(row3 + 1) ) {
- mask[((y - 1) * rowlen) + x] = FILTER_MASK_MARGIN;
- }
- else if ((x != rowlen - 1) && (*(row1 + 2) || *(row2 + 2) || *(row3 + 2)) ) {
- mask[((y - 1) * rowlen) + x] = FILTER_MASK_MARGIN;
- }
- }
-
- if (x != 0) {
- row1++; row2++; row3++;
- }
- }
- }
-
- MEM_freeN(temprect);
+ const char *row1, *row2, *row3;
+ int rowlen, x, y;
+ char *temprect;
+
+ rowlen = width;
+
+ /* make a copy, to prevent flooding */
+ temprect = MEM_dupallocN(mask);
+
+ for (y = 1; y <= height; y++) {
+ /* setup rows */
+ row1 = (char *)(temprect + (y - 2) * rowlen);
+ row2 = row1 + rowlen;
+ row3 = row2 + rowlen;
+ if (y == 1)
+ row1 = row2;
+ else if (y == height)
+ row3 = row2;
+
+ for (x = 0; x < rowlen; x++) {
+ if (mask[((y - 1) * rowlen) + x] == 0) {
+ if (*row1 || *row2 || *row3 || *(row1 + 1) || *(row3 + 1)) {
+ mask[((y - 1) * rowlen) + x] = FILTER_MASK_MARGIN;
+ }
+ else if ((x != rowlen - 1) && (*(row1 + 2) || *(row2 + 2) || *(row3 + 2))) {
+ mask[((y - 1) * rowlen) + x] = FILTER_MASK_MARGIN;
+ }
+ }
+
+ if (x != 0) {
+ row1++;
+ row2++;
+ row3++;
+ }
+ }
+ }
+
+ MEM_freeN(temprect);
}
void IMB_mask_clear(ImBuf *ibuf, char *mask, int val)
{
- int x, y;
- if (ibuf->rect_float) {
- for (x = 0; x < ibuf->x; x++) {
- for (y = 0; y < ibuf->y; y++) {
- if (mask[ibuf->x * y + x] == val) {
- float *col = ibuf->rect_float + 4 * (ibuf->x * y + x);
- col[0] = col[1] = col[2] = col[3] = 0.0f;
- }
- }
- }
- }
- else {
- /* char buffer */
- for (x = 0; x < ibuf->x; x++) {
- for (y = 0; y < ibuf->y; y++) {
- if (mask[ibuf->x * y + x] == val) {
- char *col = (char *)(ibuf->rect + ibuf->x * y + x);
- col[0] = col[1] = col[2] = col[3] = 0;
- }
- }
- }
- }
+ int x, y;
+ if (ibuf->rect_float) {
+ for (x = 0; x < ibuf->x; x++) {
+ for (y = 0; y < ibuf->y; y++) {
+ if (mask[ibuf->x * y + x] == val) {
+ float *col = ibuf->rect_float + 4 * (ibuf->x * y + x);
+ col[0] = col[1] = col[2] = col[3] = 0.0f;
+ }
+ }
+ }
+ }
+ else {
+ /* char buffer */
+ for (x = 0; x < ibuf->x; x++) {
+ for (y = 0; y < ibuf->y; y++) {
+ if (mask[ibuf->x * y + x] == val) {
+ char *col = (char *)(ibuf->rect + ibuf->x * y + x);
+ col[0] = col[1] = col[2] = col[3] = 0;
+ }
+ }
+ }
+ }
}
static int filter_make_index(const int x, const int y, const int w, const int h)
{
- if (x < 0 || x >= w || y < 0 || y >= h) return -1; /* return bad index */
- else return y * w + x;
+ if (x < 0 || x >= w || y < 0 || y >= h)
+ return -1; /* return bad index */
+ else
+ return y * w + x;
}
-static int check_pixel_assigned(const void *buffer, const char *mask, const int index, const int depth, const bool is_float)
+static int check_pixel_assigned(
+ const void *buffer, const char *mask, const int index, const int depth, const bool is_float)
{
- int res = 0;
-
- if (index >= 0) {
- const int alpha_index = depth * index + (depth - 1);
-
- if (mask != NULL) {
- res = mask[index] != 0 ? 1 : 0;
- }
- else if ((is_float && ((const float *) buffer)[alpha_index] != 0.0f) ||
- (!is_float && ((const unsigned char *) buffer)[alpha_index] != 0) )
- {
- res = 1;
- }
- }
-
- return res;
+ int res = 0;
+
+ if (index >= 0) {
+ const int alpha_index = depth * index + (depth - 1);
+
+ if (mask != NULL) {
+ res = mask[index] != 0 ? 1 : 0;
+ }
+ else if ((is_float && ((const float *)buffer)[alpha_index] != 0.0f) ||
+ (!is_float && ((const unsigned char *)buffer)[alpha_index] != 0)) {
+ res = 1;
+ }
+ }
+
+ return res;
}
/* if alpha is zero, it checks surrounding pixels and averages color. sets new alphas to 1.0
@@ -390,299 +417,310 @@ static int check_pixel_assigned(const void *buffer, const char *mask, const int
* */
void IMB_filter_extend(struct ImBuf *ibuf, char *mask, int filter)
{
- const int width = ibuf->x;
- const int height = ibuf->y;
- const int depth = 4; /* always 4 channels */
- const int chsize = ibuf->rect_float ? sizeof(float) : sizeof(unsigned char);
- const size_t bsize = ((size_t)width) * height * depth * chsize;
- const bool is_float = (ibuf->rect_float != NULL);
- void *dstbuf = (void *) MEM_dupallocN(ibuf->rect_float ? (void *) ibuf->rect_float : (void *) ibuf->rect);
- char *dstmask = mask == NULL ? NULL : (char *) MEM_dupallocN(mask);
- void *srcbuf = ibuf->rect_float ? (void *) ibuf->rect_float : (void *) ibuf->rect;
- char *srcmask = mask;
- int cannot_early_out = 1, r, n, k, i, j, c;
- float weight[25];
-
- /* build a weights buffer */
- n = 1;
+ const int width = ibuf->x;
+ const int height = ibuf->y;
+ const int depth = 4; /* always 4 channels */
+ const int chsize = ibuf->rect_float ? sizeof(float) : sizeof(unsigned char);
+ const size_t bsize = ((size_t)width) * height * depth * chsize;
+ const bool is_float = (ibuf->rect_float != NULL);
+ void *dstbuf = (void *)MEM_dupallocN(ibuf->rect_float ? (void *)ibuf->rect_float :
+ (void *)ibuf->rect);
+ char *dstmask = mask == NULL ? NULL : (char *)MEM_dupallocN(mask);
+ void *srcbuf = ibuf->rect_float ? (void *)ibuf->rect_float : (void *)ibuf->rect;
+ char *srcmask = mask;
+ int cannot_early_out = 1, r, n, k, i, j, c;
+ float weight[25];
+
+ /* build a weights buffer */
+ n = 1;
#if 0
- k = 0;
- for (i = -n; i <= n; i++)
- for (j = -n; j <= n; j++)
- weight[k++] = sqrt((float) i * i + j * j);
+ k = 0;
+ for (i = -n; i <= n; i++)
+ for (j = -n; j <= n; j++)
+ weight[k++] = sqrt((float) i * i + j * j);
#endif
- weight[0] = 1; weight[1] = 2; weight[2] = 1;
- weight[3] = 2; weight[4] = 0; weight[5] = 2;
- weight[6] = 1; weight[7] = 2; weight[8] = 1;
-
- /* run passes */
- for (r = 0; cannot_early_out == 1 && r < filter; r++) {
- int x, y;
- cannot_early_out = 0;
-
- for (y = 0; y < height; y++) {
- for (x = 0; x < width; x++) {
- const int index = filter_make_index(x, y, width, height);
-
- /* only update unassigned pixels */
- if (!check_pixel_assigned(srcbuf, srcmask, index, depth, is_float)) {
- float tmp[4];
- float wsum = 0;
- float acc[4] = {0, 0, 0, 0};
- k = 0;
-
- if (check_pixel_assigned(srcbuf, srcmask, filter_make_index(x - 1, y, width, height), depth, is_float) ||
- check_pixel_assigned(srcbuf, srcmask, filter_make_index(x + 1, y, width, height), depth, is_float) ||
- check_pixel_assigned(srcbuf, srcmask, filter_make_index(x, y - 1, width, height), depth, is_float) ||
- check_pixel_assigned(srcbuf, srcmask, filter_make_index(x, y + 1, width, height), depth, is_float))
- {
- for (i = -n; i <= n; i++) {
- for (j = -n; j <= n; j++) {
- if (i != 0 || j != 0) {
- const int tmpindex = filter_make_index(x + i, y + j, width, height);
-
- if (check_pixel_assigned(srcbuf, srcmask, tmpindex, depth, is_float)) {
- if (is_float) {
- for (c = 0; c < depth; c++)
- tmp[c] = ((const float *) srcbuf)[depth * tmpindex + c];
- }
- else {
- for (c = 0; c < depth; c++)
- tmp[c] = (float) ((const unsigned char *) srcbuf)[depth * tmpindex + c];
- }
-
- wsum += weight[k];
-
- for (c = 0; c < depth; c++)
- acc[c] += weight[k] * tmp[c];
- }
- }
- k++;
- }
- }
-
- if (wsum != 0) {
- for (c = 0; c < depth; c++)
- acc[c] /= wsum;
-
- if (is_float) {
- for (c = 0; c < depth; c++)
- ((float *) dstbuf)[depth * index + c] = acc[c];
- }
- else {
- for (c = 0; c < depth; c++) {
- ((unsigned char *) dstbuf)[depth * index + c] = acc[c] > 255 ? 255 : (acc[c] < 0 ? 0 : ((unsigned char) (acc[c] + 0.5f)));
- }
- }
-
- if (dstmask != NULL) dstmask[index] = FILTER_MASK_MARGIN; /* assigned */
- cannot_early_out = 1;
- }
- }
- }
- }
- }
-
- /* keep the original buffer up to date. */
- memcpy(srcbuf, dstbuf, bsize);
- if (dstmask != NULL) {
- memcpy(srcmask, dstmask, ((size_t)width) * height);
- }
- }
-
- /* free memory */
- MEM_freeN(dstbuf);
- if (dstmask != NULL) MEM_freeN(dstmask);
+ weight[0] = 1;
+ weight[1] = 2;
+ weight[2] = 1;
+ weight[3] = 2;
+ weight[4] = 0;
+ weight[5] = 2;
+ weight[6] = 1;
+ weight[7] = 2;
+ weight[8] = 1;
+
+ /* run passes */
+ for (r = 0; cannot_early_out == 1 && r < filter; r++) {
+ int x, y;
+ cannot_early_out = 0;
+
+ for (y = 0; y < height; y++) {
+ for (x = 0; x < width; x++) {
+ const int index = filter_make_index(x, y, width, height);
+
+ /* only update unassigned pixels */
+ if (!check_pixel_assigned(srcbuf, srcmask, index, depth, is_float)) {
+ float tmp[4];
+ float wsum = 0;
+ float acc[4] = {0, 0, 0, 0};
+ k = 0;
+
+ if (check_pixel_assigned(
+ srcbuf, srcmask, filter_make_index(x - 1, y, width, height), depth, is_float) ||
+ check_pixel_assigned(
+ srcbuf, srcmask, filter_make_index(x + 1, y, width, height), depth, is_float) ||
+ check_pixel_assigned(
+ srcbuf, srcmask, filter_make_index(x, y - 1, width, height), depth, is_float) ||
+ check_pixel_assigned(
+ srcbuf, srcmask, filter_make_index(x, y + 1, width, height), depth, is_float)) {
+ for (i = -n; i <= n; i++) {
+ for (j = -n; j <= n; j++) {
+ if (i != 0 || j != 0) {
+ const int tmpindex = filter_make_index(x + i, y + j, width, height);
+
+ if (check_pixel_assigned(srcbuf, srcmask, tmpindex, depth, is_float)) {
+ if (is_float) {
+ for (c = 0; c < depth; c++)
+ tmp[c] = ((const float *)srcbuf)[depth * tmpindex + c];
+ }
+ else {
+ for (c = 0; c < depth; c++)
+ tmp[c] = (float)((const unsigned char *)srcbuf)[depth * tmpindex + c];
+ }
+
+ wsum += weight[k];
+
+ for (c = 0; c < depth; c++)
+ acc[c] += weight[k] * tmp[c];
+ }
+ }
+ k++;
+ }
+ }
+
+ if (wsum != 0) {
+ for (c = 0; c < depth; c++)
+ acc[c] /= wsum;
+
+ if (is_float) {
+ for (c = 0; c < depth; c++)
+ ((float *)dstbuf)[depth * index + c] = acc[c];
+ }
+ else {
+ for (c = 0; c < depth; c++) {
+ ((unsigned char *)dstbuf)[depth * index + c] =
+ acc[c] > 255 ? 255 : (acc[c] < 0 ? 0 : ((unsigned char)(acc[c] + 0.5f)));
+ }
+ }
+
+ if (dstmask != NULL)
+ dstmask[index] = FILTER_MASK_MARGIN; /* assigned */
+ cannot_early_out = 1;
+ }
+ }
+ }
+ }
+ }
+
+ /* keep the original buffer up to date. */
+ memcpy(srcbuf, dstbuf, bsize);
+ if (dstmask != NULL) {
+ memcpy(srcmask, dstmask, ((size_t)width) * height);
+ }
+ }
+
+ /* free memory */
+ MEM_freeN(dstbuf);
+ if (dstmask != NULL)
+ MEM_freeN(dstmask);
}
/* threadsafe version, only recreates existing maps */
void IMB_remakemipmap(ImBuf *ibuf, int use_filter)
{
- ImBuf *hbuf = ibuf;
- int curmap = 0;
+ ImBuf *hbuf = ibuf;
+ int curmap = 0;
- ibuf->miptot = 1;
+ ibuf->miptot = 1;
- while (curmap < IMB_MIPMAP_LEVELS) {
+ while (curmap < IMB_MIPMAP_LEVELS) {
- if (ibuf->mipmap[curmap]) {
+ if (ibuf->mipmap[curmap]) {
- if (use_filter) {
- ImBuf *nbuf = IMB_allocImBuf(hbuf->x, hbuf->y, hbuf->planes, hbuf->flags);
- imb_filterN(nbuf, hbuf);
- imb_onehalf_no_alloc(ibuf->mipmap[curmap], nbuf);
- IMB_freeImBuf(nbuf);
- }
- else
- imb_onehalf_no_alloc(ibuf->mipmap[curmap], hbuf);
- }
+ if (use_filter) {
+ ImBuf *nbuf = IMB_allocImBuf(hbuf->x, hbuf->y, hbuf->planes, hbuf->flags);
+ imb_filterN(nbuf, hbuf);
+ imb_onehalf_no_alloc(ibuf->mipmap[curmap], nbuf);
+ IMB_freeImBuf(nbuf);
+ }
+ else
+ imb_onehalf_no_alloc(ibuf->mipmap[curmap], hbuf);
+ }
- ibuf->miptot = curmap + 2;
- hbuf = ibuf->mipmap[curmap];
- if (hbuf)
- hbuf->miplevel = curmap + 1;
+ ibuf->miptot = curmap + 2;
+ hbuf = ibuf->mipmap[curmap];
+ if (hbuf)
+ hbuf->miplevel = curmap + 1;
- if (!hbuf || (hbuf->x <= 2 && hbuf->y <= 2))
- break;
+ if (!hbuf || (hbuf->x <= 2 && hbuf->y <= 2))
+ break;
- curmap++;
- }
+ curmap++;
+ }
}
/* frees too (if there) and recreates new data */
void IMB_makemipmap(ImBuf *ibuf, int use_filter)
{
- ImBuf *hbuf = ibuf;
- int curmap = 0;
+ ImBuf *hbuf = ibuf;
+ int curmap = 0;
- imb_freemipmapImBuf(ibuf);
+ imb_freemipmapImBuf(ibuf);
- /* no mipmap for non RGBA images */
- if (ibuf->rect_float && ibuf->channels < 4)
- return;
+ /* no mipmap for non RGBA images */
+ if (ibuf->rect_float && ibuf->channels < 4)
+ return;
- ibuf->miptot = 1;
+ ibuf->miptot = 1;
- while (curmap < IMB_MIPMAP_LEVELS) {
- if (use_filter) {
- ImBuf *nbuf = IMB_allocImBuf(hbuf->x, hbuf->y, hbuf->planes, hbuf->flags);
- imb_filterN(nbuf, hbuf);
- ibuf->mipmap[curmap] = IMB_onehalf(nbuf);
- IMB_freeImBuf(nbuf);
- }
- else
- ibuf->mipmap[curmap] = IMB_onehalf(hbuf);
+ while (curmap < IMB_MIPMAP_LEVELS) {
+ if (use_filter) {
+ ImBuf *nbuf = IMB_allocImBuf(hbuf->x, hbuf->y, hbuf->planes, hbuf->flags);
+ imb_filterN(nbuf, hbuf);
+ ibuf->mipmap[curmap] = IMB_onehalf(nbuf);
+ IMB_freeImBuf(nbuf);
+ }
+ else
+ ibuf->mipmap[curmap] = IMB_onehalf(hbuf);
- ibuf->miptot = curmap + 2;
- hbuf = ibuf->mipmap[curmap];
- hbuf->miplevel = curmap + 1;
+ ibuf->miptot = curmap + 2;
+ hbuf = ibuf->mipmap[curmap];
+ hbuf->miplevel = curmap + 1;
- if (hbuf->x < 2 && hbuf->y < 2)
- break;
+ if (hbuf->x < 2 && hbuf->y < 2)
+ break;
- curmap++;
- }
+ curmap++;
+ }
}
ImBuf *IMB_getmipmap(ImBuf *ibuf, int level)
{
- CLAMP(level, 0, ibuf->miptot - 1);
- return (level == 0) ? ibuf : ibuf->mipmap[level - 1];
+ CLAMP(level, 0, ibuf->miptot - 1);
+ return (level == 0) ? ibuf : ibuf->mipmap[level - 1];
}
void IMB_premultiply_rect(unsigned int *rect, char planes, int w, int h)
{
- char *cp;
- int x, y, val;
-
- if (planes == 24) { /* put alpha at 255 */
- cp = (char *)(rect);
-
- for (y = 0; y < h; y++)
- for (x = 0; x < w; x++, cp += 4)
- cp[3] = 255;
- }
- else {
- cp = (char *)(rect);
-
- for (y = 0; y < h; y++) {
- for (x = 0; x < w; x++, cp += 4) {
- val = cp[3];
- cp[0] = (cp[0] * val) >> 8;
- cp[1] = (cp[1] * val) >> 8;
- cp[2] = (cp[2] * val) >> 8;
- }
- }
- }
+ char *cp;
+ int x, y, val;
+
+ if (planes == 24) { /* put alpha at 255 */
+ cp = (char *)(rect);
+
+ for (y = 0; y < h; y++)
+ for (x = 0; x < w; x++, cp += 4)
+ cp[3] = 255;
+ }
+ else {
+ cp = (char *)(rect);
+
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < w; x++, cp += 4) {
+ val = cp[3];
+ cp[0] = (cp[0] * val) >> 8;
+ cp[1] = (cp[1] * val) >> 8;
+ cp[2] = (cp[2] * val) >> 8;
+ }
+ }
+ }
}
void IMB_premultiply_rect_float(float *rect_float, int channels, int w, int h)
{
- float val, *cp;
- int x, y;
-
- if (channels == 4) {
- cp = rect_float;
- for (y = 0; y < h; y++) {
- for (x = 0; x < w; x++, cp += 4) {
- val = cp[3];
- cp[0] = cp[0] * val;
- cp[1] = cp[1] * val;
- cp[2] = cp[2] * val;
- }
- }
- }
-
+ float val, *cp;
+ int x, y;
+
+ if (channels == 4) {
+ cp = rect_float;
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < w; x++, cp += 4) {
+ val = cp[3];
+ cp[0] = cp[0] * val;
+ cp[1] = cp[1] * val;
+ cp[2] = cp[2] * val;
+ }
+ }
+ }
}
void IMB_premultiply_alpha(ImBuf *ibuf)
{
- if (ibuf == NULL)
- return;
+ if (ibuf == NULL)
+ return;
- if (ibuf->rect)
- IMB_premultiply_rect(ibuf->rect, ibuf->planes, ibuf->x, ibuf->y);
+ if (ibuf->rect)
+ IMB_premultiply_rect(ibuf->rect, ibuf->planes, ibuf->x, ibuf->y);
- if (ibuf->rect_float)
- IMB_premultiply_rect_float(ibuf->rect_float, ibuf->channels, ibuf->x, ibuf->y);
+ if (ibuf->rect_float)
+ IMB_premultiply_rect_float(ibuf->rect_float, ibuf->channels, ibuf->x, ibuf->y);
}
void IMB_unpremultiply_rect(unsigned int *rect, char planes, int w, int h)
{
- char *cp;
- int x, y;
- float val;
-
- if (planes == 24) { /* put alpha at 255 */
- cp = (char *)(rect);
-
- for (y = 0; y < h; y++)
- for (x = 0; x < w; x++, cp += 4)
- cp[3] = 255;
- }
- else {
- cp = (char *)(rect);
-
- for (y = 0; y < h; y++) {
- for (x = 0; x < w; x++, cp += 4) {
- val = cp[3] != 0 ? 1.0f / (float)cp[3] : 1.0f;
- cp[0] = unit_float_to_uchar_clamp(cp[0] * val);
- cp[1] = unit_float_to_uchar_clamp(cp[1] * val);
- cp[2] = unit_float_to_uchar_clamp(cp[2] * val);
- }
- }
- }
+ char *cp;
+ int x, y;
+ float val;
+
+ if (planes == 24) { /* put alpha at 255 */
+ cp = (char *)(rect);
+
+ for (y = 0; y < h; y++)
+ for (x = 0; x < w; x++, cp += 4)
+ cp[3] = 255;
+ }
+ else {
+ cp = (char *)(rect);
+
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < w; x++, cp += 4) {
+ val = cp[3] != 0 ? 1.0f / (float)cp[3] : 1.0f;
+ cp[0] = unit_float_to_uchar_clamp(cp[0] * val);
+ cp[1] = unit_float_to_uchar_clamp(cp[1] * val);
+ cp[2] = unit_float_to_uchar_clamp(cp[2] * val);
+ }
+ }
+ }
}
void IMB_unpremultiply_rect_float(float *rect_float, int channels, int w, int h)
{
- float val, *fp;
- int x, y;
-
- if (channels == 4) {
- fp = rect_float;
- for (y = 0; y < h; y++) {
- for (x = 0; x < w; x++, fp += 4) {
- val = fp[3] != 0.0f ? 1.0f / fp[3] : 1.0f;
- fp[0] = fp[0] * val;
- fp[1] = fp[1] * val;
- fp[2] = fp[2] * val;
- }
- }
- }
-
+ float val, *fp;
+ int x, y;
+
+ if (channels == 4) {
+ fp = rect_float;
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < w; x++, fp += 4) {
+ val = fp[3] != 0.0f ? 1.0f / fp[3] : 1.0f;
+ fp[0] = fp[0] * val;
+ fp[1] = fp[1] * val;
+ fp[2] = fp[2] * val;
+ }
+ }
+ }
}
void IMB_unpremultiply_alpha(ImBuf *ibuf)
{
- if (ibuf == NULL)
- return;
+ if (ibuf == NULL)
+ return;
- if (ibuf->rect)
- IMB_unpremultiply_rect(ibuf->rect, ibuf->planes, ibuf->x, ibuf->y);
+ if (ibuf->rect)
+ IMB_unpremultiply_rect(ibuf->rect, ibuf->planes, ibuf->x, ibuf->y);
- if (ibuf->rect_float)
- IMB_unpremultiply_rect_float(ibuf->rect_float, ibuf->channels, ibuf->x, ibuf->y);
+ if (ibuf->rect_float)
+ IMB_unpremultiply_rect_float(ibuf->rect_float, ibuf->channels, ibuf->x, ibuf->y);
}
diff --git a/source/blender/imbuf/intern/imageprocess.c b/source/blender/imbuf/intern/imageprocess.c
index 1e48c4fd428..58253bde3e3 100644
--- a/source/blender/imbuf/intern/imageprocess.c
+++ b/source/blender/imbuf/intern/imageprocess.c
@@ -42,86 +42,88 @@
/* Only this one is used liberally here, and in imbuf */
void IMB_convert_rgba_to_abgr(struct ImBuf *ibuf)
{
- size_t size;
- unsigned char rt, *cp = (unsigned char *)ibuf->rect;
- float rtf, *cpf = ibuf->rect_float;
-
- if (ibuf->rect) {
- size = ibuf->x * ibuf->y;
-
- while (size-- > 0) {
- rt = cp[0];
- cp[0] = cp[3];
- cp[3] = rt;
- rt = cp[1];
- cp[1] = cp[2];
- cp[2] = rt;
- cp += 4;
- }
- }
-
- if (ibuf->rect_float) {
- size = ibuf->x * ibuf->y;
-
- while (size-- > 0) {
- rtf = cpf[0];
- cpf[0] = cpf[3];
- cpf[3] = rtf;
- rtf = cpf[1];
- cpf[1] = cpf[2];
- cpf[2] = rtf;
- cpf += 4;
- }
- }
+ size_t size;
+ unsigned char rt, *cp = (unsigned char *)ibuf->rect;
+ float rtf, *cpf = ibuf->rect_float;
+
+ if (ibuf->rect) {
+ size = ibuf->x * ibuf->y;
+
+ while (size-- > 0) {
+ rt = cp[0];
+ cp[0] = cp[3];
+ cp[3] = rt;
+ rt = cp[1];
+ cp[1] = cp[2];
+ cp[2] = rt;
+ cp += 4;
+ }
+ }
+
+ if (ibuf->rect_float) {
+ size = ibuf->x * ibuf->y;
+
+ while (size-- > 0) {
+ rtf = cpf[0];
+ cpf[0] = cpf[3];
+ cpf[3] = rtf;
+ rtf = cpf[1];
+ cpf[1] = cpf[2];
+ cpf[2] = rtf;
+ cpf += 4;
+ }
+ }
}
static void pixel_from_buffer(struct ImBuf *ibuf, unsigned char **outI, float **outF, int x, int y)
{
- size_t offset = ((size_t)ibuf->x) * y * 4 + 4 * x;
+ size_t offset = ((size_t)ibuf->x) * y * 4 + 4 * x;
- if (ibuf->rect)
- *outI = (unsigned char *)ibuf->rect + offset;
+ if (ibuf->rect)
+ *outI = (unsigned char *)ibuf->rect + offset;
- if (ibuf->rect_float)
- *outF = ibuf->rect_float + offset;
+ if (ibuf->rect_float)
+ *outF = ibuf->rect_float + offset;
}
/* BICUBIC Interpolation */
-void bicubic_interpolation_color(struct ImBuf *in, unsigned char outI[4], float outF[4], float u, float v)
+void bicubic_interpolation_color(
+ struct ImBuf *in, unsigned char outI[4], float outF[4], float u, float v)
{
- if (outF) {
- BLI_bicubic_interpolation_fl(in->rect_float, outF, in->x, in->y, 4, u, v);
- }
- else {
- BLI_bicubic_interpolation_char((unsigned char *) in->rect, outI, in->x, in->y, 4, u, v);
- }
+ if (outF) {
+ BLI_bicubic_interpolation_fl(in->rect_float, outF, in->x, in->y, 4, u, v);
+ }
+ else {
+ BLI_bicubic_interpolation_char((unsigned char *)in->rect, outI, in->x, in->y, 4, u, v);
+ }
}
-
void bicubic_interpolation(ImBuf *in, ImBuf *out, float u, float v, int xout, int yout)
{
- unsigned char *outI = NULL;
- float *outF = NULL;
+ unsigned char *outI = NULL;
+ float *outF = NULL;
- if (in == NULL || (in->rect == NULL && in->rect_float == NULL)) {
- return;
- }
+ if (in == NULL || (in->rect == NULL && in->rect_float == NULL)) {
+ return;
+ }
- pixel_from_buffer(out, &outI, &outF, xout, yout); /* gcc warns these could be uninitialized, but its ok */
+ pixel_from_buffer(
+ out, &outI, &outF, xout, yout); /* gcc warns these could be uninitialized, but its ok */
- bicubic_interpolation_color(in, outI, outF, u, v);
+ bicubic_interpolation_color(in, outI, outF, u, v);
}
/* BILINEAR INTERPOLATION */
-void bilinear_interpolation_color(struct ImBuf *in, unsigned char outI[4], float outF[4], float u, float v)
+void bilinear_interpolation_color(
+ struct ImBuf *in, unsigned char outI[4], float outF[4], float u, float v)
{
- if (outF) {
- BLI_bilinear_interpolation_fl(in->rect_float, outF, in->x, in->y, 4, u, v);
- }
- else {
- BLI_bilinear_interpolation_char((unsigned char *) in->rect, outI, in->x, in->y, 4, u, v);
- }
+ if (outF) {
+ BLI_bilinear_interpolation_fl(in->rect_float, outF, in->x, in->y, 4, u, v);
+ }
+ else {
+ BLI_bilinear_interpolation_char((unsigned char *)in->rect, outI, in->x, in->y, 4, u, v);
+ }
}
/* function assumes out to be zero'ed, only does RGBA */
@@ -130,345 +132,356 @@ void bilinear_interpolation_color(struct ImBuf *in, unsigned char outI[4], float
/* Note about wrapping, the u/v still needs to be within the image bounds,
* just the interpolation is wrapped.
* This the same as bilinear_interpolation_color except it wraps rather than using empty and emptyI */
-void bilinear_interpolation_color_wrap(struct ImBuf *in, unsigned char outI[4], float outF[4], float u, float v)
+void bilinear_interpolation_color_wrap(
+ struct ImBuf *in, unsigned char outI[4], float outF[4], float u, float v)
{
- float *row1, *row2, *row3, *row4, a, b;
- unsigned char *row1I, *row2I, *row3I, *row4I;
- float a_b, ma_b, a_mb, ma_mb;
- int y1, y2, x1, x2;
-
-
- /* ImBuf in must have a valid rect or rect_float, assume this is already checked */
-
- x1 = (int)floor(u);
- x2 = (int)ceil(u);
- y1 = (int)floor(v);
- y2 = (int)ceil(v);
-
- /* sample area entirely outside image? */
- if (x2 < 0 || x1 > in->x - 1 || y2 < 0 || y1 > in->y - 1) {
- return;
- }
-
- /* wrap interpolation pixels - main difference from bilinear_interpolation_color */
- if (x1 < 0) x1 = in->x + x1;
- if (y1 < 0) y1 = in->y + y1;
-
- if (x2 >= in->x) x2 = x2 - in->x;
- if (y2 >= in->y) y2 = y2 - in->y;
-
- a = u - floorf(u);
- b = v - floorf(v);
- a_b = a * b; ma_b = (1.0f - a) * b; a_mb = a * (1.0f - b); ma_mb = (1.0f - a) * (1.0f - b);
-
- if (outF) {
- /* sample including outside of edges of image */
- row1 = in->rect_float + ((size_t)in->x) * y1 * 4 + 4 * x1;
- row2 = in->rect_float + ((size_t)in->x) * y2 * 4 + 4 * x1;
- row3 = in->rect_float + ((size_t)in->x) * y1 * 4 + 4 * x2;
- row4 = in->rect_float + ((size_t)in->x) * y2 * 4 + 4 * x2;
-
- outF[0] = ma_mb * row1[0] + a_mb * row3[0] + ma_b * row2[0] + a_b * row4[0];
- outF[1] = ma_mb * row1[1] + a_mb * row3[1] + ma_b * row2[1] + a_b * row4[1];
- outF[2] = ma_mb * row1[2] + a_mb * row3[2] + ma_b * row2[2] + a_b * row4[2];
- outF[3] = ma_mb * row1[3] + a_mb * row3[3] + ma_b * row2[3] + a_b * row4[3];
-
- /* clamp here or else we can easily get off-range */
- CLAMP(outF[0], 0.0f, 1.0f);
- CLAMP(outF[1], 0.0f, 1.0f);
- CLAMP(outF[2], 0.0f, 1.0f);
- CLAMP(outF[3], 0.0f, 1.0f);
- }
- if (outI) {
- /* sample including outside of edges of image */
- row1I = (unsigned char *)in->rect + ((size_t)in->x) * y1 * 4 + 4 * x1;
- row2I = (unsigned char *)in->rect + ((size_t)in->x) * y2 * 4 + 4 * x1;
- row3I = (unsigned char *)in->rect + ((size_t)in->x) * y1 * 4 + 4 * x2;
- row4I = (unsigned char *)in->rect + ((size_t)in->x) * y2 * 4 + 4 * x2;
-
- /* need to add 0.5 to avoid rounding down (causes darken with the smear brush)
- * tested with white images and this should not wrap back to zero */
- outI[0] = (ma_mb * row1I[0] + a_mb * row3I[0] + ma_b * row2I[0] + a_b * row4I[0]) + 0.5f;
- outI[1] = (ma_mb * row1I[1] + a_mb * row3I[1] + ma_b * row2I[1] + a_b * row4I[1]) + 0.5f;
- outI[2] = (ma_mb * row1I[2] + a_mb * row3I[2] + ma_b * row2I[2] + a_b * row4I[2]) + 0.5f;
- outI[3] = (ma_mb * row1I[3] + a_mb * row3I[3] + ma_b * row2I[3] + a_b * row4I[3]) + 0.5f;
- }
+ float *row1, *row2, *row3, *row4, a, b;
+ unsigned char *row1I, *row2I, *row3I, *row4I;
+ float a_b, ma_b, a_mb, ma_mb;
+ int y1, y2, x1, x2;
+
+ /* ImBuf in must have a valid rect or rect_float, assume this is already checked */
+
+ x1 = (int)floor(u);
+ x2 = (int)ceil(u);
+ y1 = (int)floor(v);
+ y2 = (int)ceil(v);
+
+ /* sample area entirely outside image? */
+ if (x2 < 0 || x1 > in->x - 1 || y2 < 0 || y1 > in->y - 1) {
+ return;
+ }
+
+ /* wrap interpolation pixels - main difference from bilinear_interpolation_color */
+ if (x1 < 0)
+ x1 = in->x + x1;
+ if (y1 < 0)
+ y1 = in->y + y1;
+
+ if (x2 >= in->x)
+ x2 = x2 - in->x;
+ if (y2 >= in->y)
+ y2 = y2 - in->y;
+
+ a = u - floorf(u);
+ b = v - floorf(v);
+ a_b = a * b;
+ ma_b = (1.0f - a) * b;
+ a_mb = a * (1.0f - b);
+ ma_mb = (1.0f - a) * (1.0f - b);
+
+ if (outF) {
+ /* sample including outside of edges of image */
+ row1 = in->rect_float + ((size_t)in->x) * y1 * 4 + 4 * x1;
+ row2 = in->rect_float + ((size_t)in->x) * y2 * 4 + 4 * x1;
+ row3 = in->rect_float + ((size_t)in->x) * y1 * 4 + 4 * x2;
+ row4 = in->rect_float + ((size_t)in->x) * y2 * 4 + 4 * x2;
+
+ outF[0] = ma_mb * row1[0] + a_mb * row3[0] + ma_b * row2[0] + a_b * row4[0];
+ outF[1] = ma_mb * row1[1] + a_mb * row3[1] + ma_b * row2[1] + a_b * row4[1];
+ outF[2] = ma_mb * row1[2] + a_mb * row3[2] + ma_b * row2[2] + a_b * row4[2];
+ outF[3] = ma_mb * row1[3] + a_mb * row3[3] + ma_b * row2[3] + a_b * row4[3];
+
+ /* clamp here or else we can easily get off-range */
+ CLAMP(outF[0], 0.0f, 1.0f);
+ CLAMP(outF[1], 0.0f, 1.0f);
+ CLAMP(outF[2], 0.0f, 1.0f);
+ CLAMP(outF[3], 0.0f, 1.0f);
+ }
+ if (outI) {
+ /* sample including outside of edges of image */
+ row1I = (unsigned char *)in->rect + ((size_t)in->x) * y1 * 4 + 4 * x1;
+ row2I = (unsigned char *)in->rect + ((size_t)in->x) * y2 * 4 + 4 * x1;
+ row3I = (unsigned char *)in->rect + ((size_t)in->x) * y1 * 4 + 4 * x2;
+ row4I = (unsigned char *)in->rect + ((size_t)in->x) * y2 * 4 + 4 * x2;
+
+ /* need to add 0.5 to avoid rounding down (causes darken with the smear brush)
+ * tested with white images and this should not wrap back to zero */
+ outI[0] = (ma_mb * row1I[0] + a_mb * row3I[0] + ma_b * row2I[0] + a_b * row4I[0]) + 0.5f;
+ outI[1] = (ma_mb * row1I[1] + a_mb * row3I[1] + ma_b * row2I[1] + a_b * row4I[1]) + 0.5f;
+ outI[2] = (ma_mb * row1I[2] + a_mb * row3I[2] + ma_b * row2I[2] + a_b * row4I[2]) + 0.5f;
+ outI[3] = (ma_mb * row1I[3] + a_mb * row3I[3] + ma_b * row2I[3] + a_b * row4I[3]) + 0.5f;
+ }
}
void bilinear_interpolation(ImBuf *in, ImBuf *out, float u, float v, int xout, int yout)
{
- unsigned char *outI = NULL;
- float *outF = NULL;
+ unsigned char *outI = NULL;
+ float *outF = NULL;
- if (in == NULL || (in->rect == NULL && in->rect_float == NULL)) {
- return;
- }
+ if (in == NULL || (in->rect == NULL && in->rect_float == NULL)) {
+ return;
+ }
- pixel_from_buffer(out, &outI, &outF, xout, yout); /* gcc warns these could be uninitialized, but its ok */
+ pixel_from_buffer(
+ out, &outI, &outF, xout, yout); /* gcc warns these could be uninitialized, but its ok */
- bilinear_interpolation_color(in, outI, outF, u, v);
+ bilinear_interpolation_color(in, outI, outF, u, v);
}
/* function assumes out to be zero'ed, only does RGBA */
/* NEAREST INTERPOLATION */
-void nearest_interpolation_color(struct ImBuf *in, unsigned char outI[4], float outF[4], float u, float v)
+void nearest_interpolation_color(
+ struct ImBuf *in, unsigned char outI[4], float outF[4], float u, float v)
{
- const float *dataF;
- unsigned char *dataI;
- int y1, x1;
-
- /* ImBuf in must have a valid rect or rect_float, assume this is already checked */
-
- x1 = (int)(u);
- y1 = (int)(v);
-
- /* sample area entirely outside image? */
- if (x1 < 0 || x1 > in->x - 1 || y1 < 0 || y1 > in->y - 1) {
- if (outI)
- outI[0] = outI[1] = outI[2] = outI[3] = 0;
- if (outF)
- outF[0] = outF[1] = outF[2] = outF[3] = 0.0f;
- return;
- }
-
- /* sample including outside of edges of image */
- if (x1 < 0 || y1 < 0) {
- if (outI) {
- outI[0] = 0;
- outI[1] = 0;
- outI[2] = 0;
- outI[3] = 0;
- }
- if (outF) {
- outF[0] = 0.0f;
- outF[1] = 0.0f;
- outF[2] = 0.0f;
- outF[3] = 0.0f;
- }
- }
- else {
- dataI = (unsigned char *)in->rect + ((size_t)in->x) * y1 * 4 + 4 * x1;
- if (outI) {
- outI[0] = dataI[0];
- outI[1] = dataI[1];
- outI[2] = dataI[2];
- outI[3] = dataI[3];
- }
- dataF = in->rect_float + ((size_t)in->x) * y1 * 4 + 4 * x1;
- if (outF) {
- outF[0] = dataF[0];
- outF[1] = dataF[1];
- outF[2] = dataF[2];
- outF[3] = dataF[3];
- }
- }
+ const float *dataF;
+ unsigned char *dataI;
+ int y1, x1;
+
+ /* ImBuf in must have a valid rect or rect_float, assume this is already checked */
+
+ x1 = (int)(u);
+ y1 = (int)(v);
+
+ /* sample area entirely outside image? */
+ if (x1 < 0 || x1 > in->x - 1 || y1 < 0 || y1 > in->y - 1) {
+ if (outI)
+ outI[0] = outI[1] = outI[2] = outI[3] = 0;
+ if (outF)
+ outF[0] = outF[1] = outF[2] = outF[3] = 0.0f;
+ return;
+ }
+
+ /* sample including outside of edges of image */
+ if (x1 < 0 || y1 < 0) {
+ if (outI) {
+ outI[0] = 0;
+ outI[1] = 0;
+ outI[2] = 0;
+ outI[3] = 0;
+ }
+ if (outF) {
+ outF[0] = 0.0f;
+ outF[1] = 0.0f;
+ outF[2] = 0.0f;
+ outF[3] = 0.0f;
+ }
+ }
+ else {
+ dataI = (unsigned char *)in->rect + ((size_t)in->x) * y1 * 4 + 4 * x1;
+ if (outI) {
+ outI[0] = dataI[0];
+ outI[1] = dataI[1];
+ outI[2] = dataI[2];
+ outI[3] = dataI[3];
+ }
+ dataF = in->rect_float + ((size_t)in->x) * y1 * 4 + 4 * x1;
+ if (outF) {
+ outF[0] = dataF[0];
+ outF[1] = dataF[1];
+ outF[2] = dataF[2];
+ outF[3] = dataF[3];
+ }
+ }
}
-
-void nearest_interpolation_color_wrap(struct ImBuf *in, unsigned char outI[4], float outF[4], float u, float v)
+void nearest_interpolation_color_wrap(
+ struct ImBuf *in, unsigned char outI[4], float outF[4], float u, float v)
{
- const float *dataF;
- unsigned char *dataI;
- int y, x;
-
- /* ImBuf in must have a valid rect or rect_float, assume this is already checked */
-
- x = (int) floor(u);
- y = (int) floor(v);
-
- x = x % in->x;
- y = y % in->y;
-
- /* wrap interpolation pixels - main difference from nearest_interpolation_color */
- if (x < 0) x += in->x;
- if (y < 0) y += in->y;
-
- dataI = (unsigned char *)in->rect + ((size_t)in->x) * y * 4 + 4 * x;
- if (outI) {
- outI[0] = dataI[0];
- outI[1] = dataI[1];
- outI[2] = dataI[2];
- outI[3] = dataI[3];
- }
- dataF = in->rect_float + ((size_t)in->x) * y * 4 + 4 * x;
- if (outF) {
- outF[0] = dataF[0];
- outF[1] = dataF[1];
- outF[2] = dataF[2];
- outF[3] = dataF[3];
- }
+ const float *dataF;
+ unsigned char *dataI;
+ int y, x;
+
+ /* ImBuf in must have a valid rect or rect_float, assume this is already checked */
+
+ x = (int)floor(u);
+ y = (int)floor(v);
+
+ x = x % in->x;
+ y = y % in->y;
+
+ /* wrap interpolation pixels - main difference from nearest_interpolation_color */
+ if (x < 0)
+ x += in->x;
+ if (y < 0)
+ y += in->y;
+
+ dataI = (unsigned char *)in->rect + ((size_t)in->x) * y * 4 + 4 * x;
+ if (outI) {
+ outI[0] = dataI[0];
+ outI[1] = dataI[1];
+ outI[2] = dataI[2];
+ outI[3] = dataI[3];
+ }
+ dataF = in->rect_float + ((size_t)in->x) * y * 4 + 4 * x;
+ if (outF) {
+ outF[0] = dataF[0];
+ outF[1] = dataF[1];
+ outF[2] = dataF[2];
+ outF[3] = dataF[3];
+ }
}
void nearest_interpolation(ImBuf *in, ImBuf *out, float x, float y, int xout, int yout)
{
- unsigned char *outI = NULL;
- float *outF = NULL;
+ unsigned char *outI = NULL;
+ float *outF = NULL;
- if (in == NULL || (in->rect == NULL && in->rect_float == NULL)) {
- return;
- }
+ if (in == NULL || (in->rect == NULL && in->rect_float == NULL)) {
+ return;
+ }
- pixel_from_buffer(out, &outI, &outF, xout, yout); /* gcc warns these could be uninitialized, but its ok */
+ pixel_from_buffer(
+ out, &outI, &outF, xout, yout); /* gcc warns these could be uninitialized, but its ok */
- nearest_interpolation_color(in, outI, outF, x, y);
+ nearest_interpolation_color(in, outI, outF, x, y);
}
/*********************** Threaded image processing *************************/
-static void processor_apply_func(TaskPool * __restrict pool, void *taskdata, int UNUSED(threadid))
+static void processor_apply_func(TaskPool *__restrict pool, void *taskdata, int UNUSED(threadid))
{
- void (*do_thread) (void *) = (void (*) (void *)) BLI_task_pool_userdata(pool);
- do_thread(taskdata);
+ void (*do_thread)(void *) = (void (*)(void *))BLI_task_pool_userdata(pool);
+ do_thread(taskdata);
}
-void IMB_processor_apply_threaded(int buffer_lines, int handle_size, void *init_customdata,
- void (init_handle) (void *handle, int start_line, int tot_line,
- void *customdata),
- void *(do_thread) (void *))
+void IMB_processor_apply_threaded(
+ int buffer_lines,
+ int handle_size,
+ void *init_customdata,
+ void(init_handle)(void *handle, int start_line, int tot_line, void *customdata),
+ void *(do_thread)(void *))
{
- const int lines_per_task = 64;
+ const int lines_per_task = 64;
- TaskScheduler *task_scheduler = BLI_task_scheduler_get();
- TaskPool *task_pool;
+ TaskScheduler *task_scheduler = BLI_task_scheduler_get();
+ TaskPool *task_pool;
- void *handles;
- int total_tasks = (buffer_lines + lines_per_task - 1) / lines_per_task;
- int i, start_line;
+ void *handles;
+ int total_tasks = (buffer_lines + lines_per_task - 1) / lines_per_task;
+ int i, start_line;
- task_pool = BLI_task_pool_create(task_scheduler, do_thread);
+ task_pool = BLI_task_pool_create(task_scheduler, do_thread);
- handles = MEM_callocN(handle_size * total_tasks, "processor apply threaded handles");
+ handles = MEM_callocN(handle_size * total_tasks, "processor apply threaded handles");
- start_line = 0;
+ start_line = 0;
- for (i = 0; i < total_tasks; i++) {
- int lines_per_current_task;
- void *handle = ((char *) handles) + handle_size * i;
+ for (i = 0; i < total_tasks; i++) {
+ int lines_per_current_task;
+ void *handle = ((char *)handles) + handle_size * i;
- if (i < total_tasks - 1)
- lines_per_current_task = lines_per_task;
- else
- lines_per_current_task = buffer_lines - start_line;
+ if (i < total_tasks - 1)
+ lines_per_current_task = lines_per_task;
+ else
+ lines_per_current_task = buffer_lines - start_line;
- init_handle(handle, start_line, lines_per_current_task, init_customdata);
+ init_handle(handle, start_line, lines_per_current_task, init_customdata);
- BLI_task_pool_push(task_pool, processor_apply_func, handle, false, TASK_PRIORITY_LOW);
+ BLI_task_pool_push(task_pool, processor_apply_func, handle, false, TASK_PRIORITY_LOW);
- start_line += lines_per_task;
- }
+ start_line += lines_per_task;
+ }
- /* work and wait until tasks are done */
- BLI_task_pool_work_and_wait(task_pool);
+ /* work and wait until tasks are done */
+ BLI_task_pool_work_and_wait(task_pool);
- /* Free memory. */
- MEM_freeN(handles);
- BLI_task_pool_free(task_pool);
+ /* Free memory. */
+ MEM_freeN(handles);
+ BLI_task_pool_free(task_pool);
}
typedef struct ScanlineGlobalData {
- void *custom_data;
- ScanlineThreadFunc do_thread;
- int scanlines_per_task;
- int total_scanlines;
+ void *custom_data;
+ ScanlineThreadFunc do_thread;
+ int scanlines_per_task;
+ int total_scanlines;
} ScanlineGlobalData;
typedef struct ScanlineTask {
- int start_scanline;
- int num_scanlines;
+ int start_scanline;
+ int num_scanlines;
} ScanlineTask;
-static void processor_apply_scanline_func(TaskPool * __restrict pool,
+static void processor_apply_scanline_func(TaskPool *__restrict pool,
void *taskdata,
int UNUSED(threadid))
{
- ScanlineGlobalData *data = BLI_task_pool_userdata(pool);
- int start_scanline = POINTER_AS_INT(taskdata);
- int num_scanlines = min_ii(data->scanlines_per_task,
- data->total_scanlines - start_scanline);
- data->do_thread(data->custom_data,
- start_scanline,
- num_scanlines);
+ ScanlineGlobalData *data = BLI_task_pool_userdata(pool);
+ int start_scanline = POINTER_AS_INT(taskdata);
+ int num_scanlines = min_ii(data->scanlines_per_task, data->total_scanlines - start_scanline);
+ data->do_thread(data->custom_data, start_scanline, num_scanlines);
}
void IMB_processor_apply_threaded_scanlines(int total_scanlines,
ScanlineThreadFunc do_thread,
void *custom_data)
{
- const int scanlines_per_task = 64;
- ScanlineGlobalData data;
- data.custom_data = custom_data;
- data.do_thread = do_thread;
- data.scanlines_per_task = scanlines_per_task;
- data.total_scanlines = total_scanlines;
- const int total_tasks = (total_scanlines + scanlines_per_task - 1) / scanlines_per_task;
- TaskScheduler *task_scheduler = BLI_task_scheduler_get();
- TaskPool *task_pool = BLI_task_pool_create(task_scheduler, &data);
- for (int i = 0, start_line = 0; i < total_tasks; i++) {
- BLI_task_pool_push(task_pool,
- processor_apply_scanline_func,
- POINTER_FROM_INT(start_line),
- false,
- TASK_PRIORITY_LOW);
- start_line += scanlines_per_task;
- }
-
- /* work and wait until tasks are done */
- BLI_task_pool_work_and_wait(task_pool);
-
- /* Free memory. */
- BLI_task_pool_free(task_pool);
+ const int scanlines_per_task = 64;
+ ScanlineGlobalData data;
+ data.custom_data = custom_data;
+ data.do_thread = do_thread;
+ data.scanlines_per_task = scanlines_per_task;
+ data.total_scanlines = total_scanlines;
+ const int total_tasks = (total_scanlines + scanlines_per_task - 1) / scanlines_per_task;
+ TaskScheduler *task_scheduler = BLI_task_scheduler_get();
+ TaskPool *task_pool = BLI_task_pool_create(task_scheduler, &data);
+ for (int i = 0, start_line = 0; i < total_tasks; i++) {
+ BLI_task_pool_push(task_pool,
+ processor_apply_scanline_func,
+ POINTER_FROM_INT(start_line),
+ false,
+ TASK_PRIORITY_LOW);
+ start_line += scanlines_per_task;
+ }
+
+ /* work and wait until tasks are done */
+ BLI_task_pool_work_and_wait(task_pool);
+
+ /* Free memory. */
+ BLI_task_pool_free(task_pool);
}
/* Alpha-under */
void IMB_alpha_under_color_float(float *rect_float, int x, int y, float backcol[3])
{
- size_t a = ((size_t)x) * y;
- float *fp = rect_float;
+ size_t a = ((size_t)x) * y;
+ float *fp = rect_float;
- while (a--) {
- if (fp[3] == 0.0f) {
- copy_v3_v3(fp, backcol);
- }
- else {
- float mul = 1.0f - fp[3];
+ while (a--) {
+ if (fp[3] == 0.0f) {
+ copy_v3_v3(fp, backcol);
+ }
+ else {
+ float mul = 1.0f - fp[3];
- fp[0] += mul * backcol[0];
- fp[1] += mul * backcol[1];
- fp[2] += mul * backcol[2];
- }
+ fp[0] += mul * backcol[0];
+ fp[1] += mul * backcol[1];
+ fp[2] += mul * backcol[2];
+ }
- fp[3] = 1.0f;
+ fp[3] = 1.0f;
- fp += 4;
- }
+ fp += 4;
+ }
}
void IMB_alpha_under_color_byte(unsigned char *rect, int x, int y, float backcol[3])
{
- size_t a = ((size_t)x) * y;
- unsigned char *cp = rect;
-
- while (a--) {
- if (cp[3] == 255) {
- /* pass */
- }
- else if (cp[3] == 0) {
- cp[0] = backcol[0] * 255;
- cp[1] = backcol[1] * 255;
- cp[2] = backcol[2] * 255;
- }
- else {
- float alpha = cp[3] / 255.0;
- float mul = 1.0f - alpha;
-
- cp[0] = (cp[0] * alpha) + mul * backcol[0];
- cp[1] = (cp[1] * alpha) + mul * backcol[1];
- cp[2] = (cp[2] * alpha) + mul * backcol[2];
- }
-
- cp[3] = 255;
-
- cp += 4;
- }
+ size_t a = ((size_t)x) * y;
+ unsigned char *cp = rect;
+
+ while (a--) {
+ if (cp[3] == 255) {
+ /* pass */
+ }
+ else if (cp[3] == 0) {
+ cp[0] = backcol[0] * 255;
+ cp[1] = backcol[1] * 255;
+ cp[2] = backcol[2] * 255;
+ }
+ else {
+ float alpha = cp[3] / 255.0;
+ float mul = 1.0f - alpha;
+
+ cp[0] = (cp[0] * alpha) + mul * backcol[0];
+ cp[1] = (cp[1] * alpha) + mul * backcol[1];
+ cp[2] = (cp[2] * alpha) + mul * backcol[2];
+ }
+
+ cp[3] = 255;
+
+ cp += 4;
+ }
}
diff --git a/source/blender/imbuf/intern/imbuf.h b/source/blender/imbuf/intern/imbuf.h
index 1546c2790d7..514b6a24cf0 100644
--- a/source/blender/imbuf/intern/imbuf.h
+++ b/source/blender/imbuf/intern/imbuf.h
@@ -43,7 +43,8 @@
#endif
#define SWAP_SHORT(x) (((x & 0xff) << 8) | ((x >> 8) & 0xff))
-#define SWAP_LONG(x) (((x) << 24) | (((x) & 0xff00) << 8) | (((x) >> 8) & 0xff00) | (((x) >> 24) & 0xff))
+#define SWAP_LONG(x) \
+ (((x) << 24) | (((x)&0xff00) << 8) | (((x) >> 8) & 0xff00) | (((x) >> 24) & 0xff))
#define ENDIAN_NOP(x) (x)
@@ -61,4 +62,4 @@
#define IMB_DPI_DEFAULT 72.0f
-#endif /* __IMBUF_H__ */
+#endif /* __IMBUF_H__ */
diff --git a/source/blender/imbuf/intern/indexer.c b/source/blender/imbuf/intern/indexer.c
index 6de3cabf5bd..106c04f39f6 100644
--- a/source/blender/imbuf/intern/indexer.c
+++ b/source/blender/imbuf/intern/indexer.c
@@ -45,13 +45,11 @@
# include "ffmpeg_compat.h"
#endif
-
static const char magic[] = "BlenMIdx";
static const char temp_ext[] = "_part";
-static const int proxy_sizes[] = { IMB_PROXY_25, IMB_PROXY_50, IMB_PROXY_75,
- IMB_PROXY_100 };
-static const float proxy_fac[] = { 0.25, 0.50, 0.75, 1.00 };
+static const int proxy_sizes[] = {IMB_PROXY_25, IMB_PROXY_50, IMB_PROXY_75, IMB_PROXY_100};
+static const float proxy_fac[] = {0.25, 0.50, 0.75, 1.00};
#ifdef WITH_FFMPEG
static int tc_types[] = {IMB_TC_RECORD_RUN,
@@ -69,362 +67,358 @@ static int tc_types[] = {IMB_TC_RECORD_RUN,
anim_index_builder *IMB_index_builder_create(const char *name)
{
- anim_index_builder *rv = MEM_callocN(sizeof(struct anim_index_builder),
- "index builder");
+ anim_index_builder *rv = MEM_callocN(sizeof(struct anim_index_builder), "index builder");
- fprintf(stderr, "Starting work on index: %s\n", name);
+ fprintf(stderr, "Starting work on index: %s\n", name);
- BLI_strncpy(rv->name, name, sizeof(rv->name));
- BLI_strncpy(rv->temp_name, name, sizeof(rv->temp_name));
+ BLI_strncpy(rv->name, name, sizeof(rv->name));
+ BLI_strncpy(rv->temp_name, name, sizeof(rv->temp_name));
- strcat(rv->temp_name, temp_ext);
+ strcat(rv->temp_name, temp_ext);
- BLI_make_existing_file(rv->temp_name);
+ BLI_make_existing_file(rv->temp_name);
- rv->fp = BLI_fopen(rv->temp_name, "wb");
+ rv->fp = BLI_fopen(rv->temp_name, "wb");
- if (!rv->fp) {
- fprintf(stderr, "Couldn't open index target: %s! "
- "Index build broken!\n", rv->temp_name);
- MEM_freeN(rv);
- return NULL;
- }
+ if (!rv->fp) {
+ fprintf(stderr,
+ "Couldn't open index target: %s! "
+ "Index build broken!\n",
+ rv->temp_name);
+ MEM_freeN(rv);
+ return NULL;
+ }
- fprintf(rv->fp, "%s%c%.3d", magic, (ENDIAN_ORDER == B_ENDIAN) ? 'V' : 'v',
- INDEX_FILE_VERSION);
+ fprintf(rv->fp, "%s%c%.3d", magic, (ENDIAN_ORDER == B_ENDIAN) ? 'V' : 'v', INDEX_FILE_VERSION);
- return rv;
+ return rv;
}
void IMB_index_builder_add_entry(anim_index_builder *fp,
- int frameno, unsigned long long seek_pos,
+ int frameno,
+ unsigned long long seek_pos,
unsigned long long seek_pos_dts,
unsigned long long pts)
{
- fwrite(&frameno, sizeof(int), 1, fp->fp);
- fwrite(&seek_pos, sizeof(unsigned long long), 1, fp->fp);
- fwrite(&seek_pos_dts, sizeof(unsigned long long), 1, fp->fp);
- fwrite(&pts, sizeof(unsigned long long), 1, fp->fp);
+ fwrite(&frameno, sizeof(int), 1, fp->fp);
+ fwrite(&seek_pos, sizeof(unsigned long long), 1, fp->fp);
+ fwrite(&seek_pos_dts, sizeof(unsigned long long), 1, fp->fp);
+ fwrite(&pts, sizeof(unsigned long long), 1, fp->fp);
}
void IMB_index_builder_proc_frame(anim_index_builder *fp,
unsigned char *buffer,
int data_size,
- int frameno, unsigned long long seek_pos,
+ int frameno,
+ unsigned long long seek_pos,
unsigned long long seek_pos_dts,
unsigned long long pts)
{
- if (fp->proc_frame) {
- anim_index_entry e;
- e.frameno = frameno;
- e.seek_pos = seek_pos;
- e.seek_pos_dts = seek_pos_dts;
- e.pts = pts;
-
- fp->proc_frame(fp, buffer, data_size, &e);
- }
- else {
- IMB_index_builder_add_entry(fp, frameno, seek_pos,
- seek_pos_dts, pts);
- }
+ if (fp->proc_frame) {
+ anim_index_entry e;
+ e.frameno = frameno;
+ e.seek_pos = seek_pos;
+ e.seek_pos_dts = seek_pos_dts;
+ e.pts = pts;
+
+ fp->proc_frame(fp, buffer, data_size, &e);
+ }
+ else {
+ IMB_index_builder_add_entry(fp, frameno, seek_pos, seek_pos_dts, pts);
+ }
}
void IMB_index_builder_finish(anim_index_builder *fp, int rollback)
{
- if (fp->delete_priv_data) {
- fp->delete_priv_data(fp);
- }
+ if (fp->delete_priv_data) {
+ fp->delete_priv_data(fp);
+ }
- fclose(fp->fp);
+ fclose(fp->fp);
- if (rollback) {
- unlink(fp->temp_name);
- }
- else {
- unlink(fp->name);
- BLI_rename(fp->temp_name, fp->name);
- }
+ if (rollback) {
+ unlink(fp->temp_name);
+ }
+ else {
+ unlink(fp->name);
+ BLI_rename(fp->temp_name, fp->name);
+ }
- MEM_freeN(fp);
+ MEM_freeN(fp);
}
struct anim_index *IMB_indexer_open(const char *name)
{
- char header[13];
- struct anim_index *idx;
- FILE *fp = BLI_fopen(name, "rb");
- int i;
-
- if (!fp) {
- return NULL;
- }
-
- if (fread(header, 12, 1, fp) != 1) {
- fclose(fp);
- return NULL;
- }
-
- header[12] = 0;
-
- if (memcmp(header, magic, 8) != 0) {
- fclose(fp);
- return NULL;
- }
-
- if (atoi(header + 9) != INDEX_FILE_VERSION) {
- fclose(fp);
- return NULL;
- }
-
- idx = MEM_callocN(sizeof(struct anim_index), "anim_index");
-
- BLI_strncpy(idx->name, name, sizeof(idx->name));
-
- fseek(fp, 0, SEEK_END);
-
- idx->num_entries = (ftell(fp) - 12) /
- (sizeof(int) + /* framepos */
- sizeof(unsigned long long) + /* seek_pos */
- sizeof(unsigned long long) + /* seek_pos_dts */
- sizeof(unsigned long long) /* pts */
- );
-
- fseek(fp, 12, SEEK_SET);
-
- idx->entries = MEM_callocN(sizeof(struct anim_index_entry) *
- idx->num_entries, "anim_index_entries");
-
- for (i = 0; i < idx->num_entries; i++) {
- fread(&idx->entries[i].frameno,
- sizeof(int), 1, fp);
- fread(&idx->entries[i].seek_pos,
- sizeof(unsigned long long), 1, fp);
- fread(&idx->entries[i].seek_pos_dts,
- sizeof(unsigned long long), 1, fp);
- fread(&idx->entries[i].pts,
- sizeof(unsigned long long), 1, fp);
- }
-
- if (((ENDIAN_ORDER == B_ENDIAN) != (header[8] == 'V'))) {
- for (i = 0; i < idx->num_entries; i++) {
- BLI_endian_switch_int32(&idx->entries[i].frameno);
- BLI_endian_switch_int64((int64_t *)&idx->entries[i].seek_pos);
- BLI_endian_switch_int64((int64_t *)&idx->entries[i].seek_pos_dts);
- BLI_endian_switch_int64((int64_t *)&idx->entries[i].pts);
- }
- }
-
- fclose(fp);
-
- return idx;
+ char header[13];
+ struct anim_index *idx;
+ FILE *fp = BLI_fopen(name, "rb");
+ int i;
+
+ if (!fp) {
+ return NULL;
+ }
+
+ if (fread(header, 12, 1, fp) != 1) {
+ fclose(fp);
+ return NULL;
+ }
+
+ header[12] = 0;
+
+ if (memcmp(header, magic, 8) != 0) {
+ fclose(fp);
+ return NULL;
+ }
+
+ if (atoi(header + 9) != INDEX_FILE_VERSION) {
+ fclose(fp);
+ return NULL;
+ }
+
+ idx = MEM_callocN(sizeof(struct anim_index), "anim_index");
+
+ BLI_strncpy(idx->name, name, sizeof(idx->name));
+
+ fseek(fp, 0, SEEK_END);
+
+ idx->num_entries = (ftell(fp) - 12) / (sizeof(int) + /* framepos */
+ sizeof(unsigned long long) + /* seek_pos */
+ sizeof(unsigned long long) + /* seek_pos_dts */
+ sizeof(unsigned long long) /* pts */
+ );
+
+ fseek(fp, 12, SEEK_SET);
+
+ idx->entries = MEM_callocN(sizeof(struct anim_index_entry) * idx->num_entries,
+ "anim_index_entries");
+
+ for (i = 0; i < idx->num_entries; i++) {
+ fread(&idx->entries[i].frameno, sizeof(int), 1, fp);
+ fread(&idx->entries[i].seek_pos, sizeof(unsigned long long), 1, fp);
+ fread(&idx->entries[i].seek_pos_dts, sizeof(unsigned long long), 1, fp);
+ fread(&idx->entries[i].pts, sizeof(unsigned long long), 1, fp);
+ }
+
+ if (((ENDIAN_ORDER == B_ENDIAN) != (header[8] == 'V'))) {
+ for (i = 0; i < idx->num_entries; i++) {
+ BLI_endian_switch_int32(&idx->entries[i].frameno);
+ BLI_endian_switch_int64((int64_t *)&idx->entries[i].seek_pos);
+ BLI_endian_switch_int64((int64_t *)&idx->entries[i].seek_pos_dts);
+ BLI_endian_switch_int64((int64_t *)&idx->entries[i].pts);
+ }
+ }
+
+ fclose(fp);
+
+ return idx;
}
-unsigned long long IMB_indexer_get_seek_pos(
- struct anim_index *idx, int frame_index)
+unsigned long long IMB_indexer_get_seek_pos(struct anim_index *idx, int frame_index)
{
- if (frame_index < 0) {
- frame_index = 0;
- }
- if (frame_index >= idx->num_entries) {
- frame_index = idx->num_entries - 1;
- }
- return idx->entries[frame_index].seek_pos;
+ if (frame_index < 0) {
+ frame_index = 0;
+ }
+ if (frame_index >= idx->num_entries) {
+ frame_index = idx->num_entries - 1;
+ }
+ return idx->entries[frame_index].seek_pos;
}
-unsigned long long IMB_indexer_get_seek_pos_dts(
- struct anim_index *idx, int frame_index)
+unsigned long long IMB_indexer_get_seek_pos_dts(struct anim_index *idx, int frame_index)
{
- if (frame_index < 0) {
- frame_index = 0;
- }
- if (frame_index >= idx->num_entries) {
- frame_index = idx->num_entries - 1;
- }
- return idx->entries[frame_index].seek_pos_dts;
+ if (frame_index < 0) {
+ frame_index = 0;
+ }
+ if (frame_index >= idx->num_entries) {
+ frame_index = idx->num_entries - 1;
+ }
+ return idx->entries[frame_index].seek_pos_dts;
}
int IMB_indexer_get_frame_index(struct anim_index *idx, int frameno)
{
- int len = idx->num_entries;
- int half;
- int middle;
- int first = 0;
-
- /* bsearch (lower bound) the right index */
-
- while (len > 0) {
- half = len >> 1;
- middle = first;
-
- middle += half;
-
- if (idx->entries[middle].frameno < frameno) {
- first = middle;
- first++;
- len = len - half - 1;
- }
- else {
- len = half;
- }
- }
-
- if (first == idx->num_entries) {
- return idx->num_entries - 1;
- }
- else {
- return first;
- }
+ int len = idx->num_entries;
+ int half;
+ int middle;
+ int first = 0;
+
+ /* bsearch (lower bound) the right index */
+
+ while (len > 0) {
+ half = len >> 1;
+ middle = first;
+
+ middle += half;
+
+ if (idx->entries[middle].frameno < frameno) {
+ first = middle;
+ first++;
+ len = len - half - 1;
+ }
+ else {
+ len = half;
+ }
+ }
+
+ if (first == idx->num_entries) {
+ return idx->num_entries - 1;
+ }
+ else {
+ return first;
+ }
}
-unsigned long long IMB_indexer_get_pts(struct anim_index *idx,
- int frame_index)
+unsigned long long IMB_indexer_get_pts(struct anim_index *idx, int frame_index)
{
- if (frame_index < 0) {
- frame_index = 0;
- }
- if (frame_index >= idx->num_entries) {
- frame_index = idx->num_entries - 1;
- }
- return idx->entries[frame_index].pts;
+ if (frame_index < 0) {
+ frame_index = 0;
+ }
+ if (frame_index >= idx->num_entries) {
+ frame_index = idx->num_entries - 1;
+ }
+ return idx->entries[frame_index].pts;
}
int IMB_indexer_get_duration(struct anim_index *idx)
{
- if (idx->num_entries == 0) {
- return 0;
- }
- return idx->entries[idx->num_entries - 1].frameno + 1;
+ if (idx->num_entries == 0) {
+ return 0;
+ }
+ return idx->entries[idx->num_entries - 1].frameno + 1;
}
-int IMB_indexer_can_scan(struct anim_index *idx,
- int old_frame_index, int new_frame_index)
+int IMB_indexer_can_scan(struct anim_index *idx, int old_frame_index, int new_frame_index)
{
- /* makes only sense, if it is the same I-Frame and we are not
- * trying to run backwards in time... */
- return (IMB_indexer_get_seek_pos(idx, old_frame_index) == IMB_indexer_get_seek_pos(idx, new_frame_index) &&
- old_frame_index < new_frame_index);
+ /* makes only sense, if it is the same I-Frame and we are not
+ * trying to run backwards in time... */
+ return (IMB_indexer_get_seek_pos(idx, old_frame_index) ==
+ IMB_indexer_get_seek_pos(idx, new_frame_index) &&
+ old_frame_index < new_frame_index);
}
void IMB_indexer_close(struct anim_index *idx)
{
- MEM_freeN(idx->entries);
- MEM_freeN(idx);
+ MEM_freeN(idx->entries);
+ MEM_freeN(idx);
}
int IMB_proxy_size_to_array_index(IMB_Proxy_Size pr_size)
{
- switch (pr_size) {
- case IMB_PROXY_NONE: /* if we got here, something is broken anyways,
- * so sane defaults... */
- return 0;
- case IMB_PROXY_25:
- return 0;
- case IMB_PROXY_50:
- return 1;
- case IMB_PROXY_75:
- return 2;
- case IMB_PROXY_100:
- return 3;
- default:
- return 0;
- }
+ switch (pr_size) {
+ case IMB_PROXY_NONE: /* if we got here, something is broken anyways,
+ * so sane defaults... */
+ return 0;
+ case IMB_PROXY_25:
+ return 0;
+ case IMB_PROXY_50:
+ return 1;
+ case IMB_PROXY_75:
+ return 2;
+ case IMB_PROXY_100:
+ return 3;
+ default:
+ return 0;
+ }
}
int IMB_timecode_to_array_index(IMB_Timecode_Type tc)
{
- switch (tc) {
- case IMB_TC_NONE: /* if we got here, something is broken anyways,
- * so sane defaults... */
- return 0;
- case IMB_TC_RECORD_RUN:
- return 0;
- case IMB_TC_FREE_RUN:
- return 1;
- case IMB_TC_INTERPOLATED_REC_DATE_FREE_RUN:
- return 2;
- case IMB_TC_RECORD_RUN_NO_GAPS:
- return 3;
- default:
- return 0;
- }
+ switch (tc) {
+ case IMB_TC_NONE: /* if we got here, something is broken anyways,
+ * so sane defaults... */
+ return 0;
+ case IMB_TC_RECORD_RUN:
+ return 0;
+ case IMB_TC_FREE_RUN:
+ return 1;
+ case IMB_TC_INTERPOLATED_REC_DATE_FREE_RUN:
+ return 2;
+ case IMB_TC_RECORD_RUN_NO_GAPS:
+ return 3;
+ default:
+ return 0;
+ }
}
-
/* ----------------------------------------------------------------------
* - rebuild helper functions
* ---------------------------------------------------------------------- */
static void get_index_dir(struct anim *anim, char *index_dir, size_t index_dir_len)
{
- if (!anim->index_dir[0]) {
- char fname[FILE_MAXFILE];
- BLI_split_dirfile(anim->name, index_dir, fname, index_dir_len, sizeof(fname));
- BLI_path_append(index_dir, index_dir_len, "BL_proxy");
- BLI_path_append(index_dir, index_dir_len, fname);
- }
- else {
- BLI_strncpy(index_dir, anim->index_dir, index_dir_len);
- }
+ if (!anim->index_dir[0]) {
+ char fname[FILE_MAXFILE];
+ BLI_split_dirfile(anim->name, index_dir, fname, index_dir_len, sizeof(fname));
+ BLI_path_append(index_dir, index_dir_len, "BL_proxy");
+ BLI_path_append(index_dir, index_dir_len, fname);
+ }
+ else {
+ BLI_strncpy(index_dir, anim->index_dir, index_dir_len);
+ }
}
void IMB_anim_get_fname(struct anim *anim, char *file, int size)
{
- char fname[FILE_MAXFILE];
- BLI_split_dirfile(anim->name, file, fname, size, sizeof(fname));
- BLI_strncpy(file, fname, size);
+ char fname[FILE_MAXFILE];
+ BLI_split_dirfile(anim->name, file, fname, size, sizeof(fname));
+ BLI_strncpy(file, fname, size);
}
-static void get_proxy_filename(struct anim *anim, IMB_Proxy_Size preview_size,
- char *fname, bool temp)
+static void get_proxy_filename(struct anim *anim,
+ IMB_Proxy_Size preview_size,
+ char *fname,
+ bool temp)
{
- char index_dir[FILE_MAXDIR];
- int i = IMB_proxy_size_to_array_index(preview_size);
+ char index_dir[FILE_MAXDIR];
+ int i = IMB_proxy_size_to_array_index(preview_size);
- char proxy_name[256];
- char stream_suffix[20];
- const char *name = (temp) ? "proxy_%d%s_part.avi" : "proxy_%d%s.avi";
+ char proxy_name[256];
+ char stream_suffix[20];
+ const char *name = (temp) ? "proxy_%d%s_part.avi" : "proxy_%d%s.avi";
- stream_suffix[0] = 0;
+ stream_suffix[0] = 0;
- if (anim->streamindex > 0) {
- BLI_snprintf(stream_suffix, sizeof(stream_suffix), "_st%d", anim->streamindex);
- }
+ if (anim->streamindex > 0) {
+ BLI_snprintf(stream_suffix, sizeof(stream_suffix), "_st%d", anim->streamindex);
+ }
- BLI_snprintf(proxy_name, sizeof(proxy_name), name,
- (int) (proxy_fac[i] * 100), stream_suffix, anim->suffix);
+ BLI_snprintf(proxy_name,
+ sizeof(proxy_name),
+ name,
+ (int)(proxy_fac[i] * 100),
+ stream_suffix,
+ anim->suffix);
- get_index_dir(anim, index_dir, sizeof(index_dir));
+ get_index_dir(anim, index_dir, sizeof(index_dir));
- BLI_join_dirfile(fname, FILE_MAXFILE + FILE_MAXDIR, index_dir, proxy_name);
+ BLI_join_dirfile(fname, FILE_MAXFILE + FILE_MAXDIR, index_dir, proxy_name);
}
-static void get_tc_filename(struct anim *anim, IMB_Timecode_Type tc,
- char *fname)
+static void get_tc_filename(struct anim *anim, IMB_Timecode_Type tc, char *fname)
{
- char index_dir[FILE_MAXDIR];
- int i = IMB_timecode_to_array_index(tc);
- const char *index_names[] = {
- "record_run%s%s.blen_tc",
- "free_run%s%s.blen_tc",
- "interp_free_run%s%s.blen_tc",
- "record_run_no_gaps%s%s.blen_tc",
- };
+ char index_dir[FILE_MAXDIR];
+ int i = IMB_timecode_to_array_index(tc);
+ const char *index_names[] = {
+ "record_run%s%s.blen_tc",
+ "free_run%s%s.blen_tc",
+ "interp_free_run%s%s.blen_tc",
+ "record_run_no_gaps%s%s.blen_tc",
+ };
- char stream_suffix[20];
- char index_name[256];
+ char stream_suffix[20];
+ char index_name[256];
- stream_suffix[0] = 0;
+ stream_suffix[0] = 0;
- if (anim->streamindex > 0) {
- BLI_snprintf(stream_suffix, 20, "_st%d", anim->streamindex);
- }
+ if (anim->streamindex > 0) {
+ BLI_snprintf(stream_suffix, 20, "_st%d", anim->streamindex);
+ }
- BLI_snprintf(index_name, 256, index_names[i], stream_suffix, anim->suffix);
+ BLI_snprintf(index_name, 256, index_names[i], stream_suffix, anim->suffix);
- get_index_dir(anim, index_dir, sizeof(index_dir));
+ get_index_dir(anim, index_dir, sizeof(index_dir));
- BLI_join_dirfile(fname, FILE_MAXFILE + FILE_MAXDIR,
- index_dir, index_name);
+ BLI_join_dirfile(fname, FILE_MAXFILE + FILE_MAXDIR, index_dir, index_name);
}
/* ----------------------------------------------------------------------
@@ -432,10 +426,9 @@ static void get_tc_filename(struct anim *anim, IMB_Timecode_Type tc,
* ---------------------------------------------------------------------- */
typedef struct IndexBuildContext {
- int anim_type;
+ int anim_type;
} IndexBuildContext;
-
/* ----------------------------------------------------------------------
* - ffmpeg rebuilder
* ---------------------------------------------------------------------- */
@@ -443,533 +436,527 @@ typedef struct IndexBuildContext {
#ifdef WITH_FFMPEG
struct proxy_output_ctx {
- AVFormatContext *of;
- AVStream *st;
- AVCodecContext *c;
- AVCodec *codec;
- struct SwsContext *sws_ctx;
- AVFrame *frame;
- int cfra;
- int proxy_size;
- int orig_height;
- struct anim *anim;
+ AVFormatContext *of;
+ AVStream *st;
+ AVCodecContext *c;
+ AVCodec *codec;
+ struct SwsContext *sws_ctx;
+ AVFrame *frame;
+ int cfra;
+ int proxy_size;
+ int orig_height;
+ struct anim *anim;
};
// work around stupid swscaler 16 bytes alignment bug...
static int round_up(int x, int mod)
{
- return x + ((mod - (x % mod)) % mod);
+ return x + ((mod - (x % mod)) % mod);
}
static struct proxy_output_ctx *alloc_proxy_output_ffmpeg(
- struct anim *anim,
- AVStream *st, int proxy_size, int width, int height,
- int quality)
+ struct anim *anim, AVStream *st, int proxy_size, int width, int height, int quality)
{
- struct proxy_output_ctx *rv = MEM_callocN(
- sizeof(struct proxy_output_ctx), "alloc_proxy_output");
-
- char fname[FILE_MAX];
- int ffmpeg_quality;
-
- /* JPEG requires this */
- width = round_up(width, 8);
- height = round_up(height, 8);
-
- rv->proxy_size = proxy_size;
- rv->anim = anim;
-
- get_proxy_filename(rv->anim, rv->proxy_size, fname, true);
- BLI_make_existing_file(fname);
-
- rv->of = avformat_alloc_context();
- rv->of->oformat = av_guess_format("avi", NULL, NULL);
-
- BLI_strncpy(rv->of->filename, fname, sizeof(rv->of->filename));
-
- fprintf(stderr, "Starting work on proxy: %s\n", rv->of->filename);
-
- rv->st = avformat_new_stream(rv->of, NULL);
- rv->st->id = 0;
-
- rv->c = rv->st->codec;
- rv->c->codec_type = AVMEDIA_TYPE_VIDEO;
- rv->c->codec_id = AV_CODEC_ID_MJPEG;
- rv->c->width = width;
- rv->c->height = height;
-
- rv->of->oformat->video_codec = rv->c->codec_id;
- rv->codec = avcodec_find_encoder(rv->c->codec_id);
-
- if (!rv->codec) {
- fprintf(stderr, "No ffmpeg MJPEG encoder available? "
- "Proxy not built!\n");
- av_free(rv->of);
- return NULL;
- }
-
- if (rv->codec->pix_fmts) {
- rv->c->pix_fmt = rv->codec->pix_fmts[0];
- }
- else {
- rv->c->pix_fmt = AV_PIX_FMT_YUVJ420P;
- }
-
- rv->c->sample_aspect_ratio =
- rv->st->sample_aspect_ratio =
- st->codec->sample_aspect_ratio;
-
- rv->c->time_base.den = 25;
- rv->c->time_base.num = 1;
- rv->st->time_base = rv->c->time_base;
-
- /* there's no way to set JPEG quality in the same way as in AVI JPEG and image sequence,
- * but this seems to be giving expected quality result */
- ffmpeg_quality = (int)(1.0f + 30.0f * (1.0f - (float)quality / 100.0f) + 0.5f);
- av_opt_set_int(rv->c, "qmin", ffmpeg_quality, 0);
- av_opt_set_int(rv->c, "qmax", ffmpeg_quality, 0);
-
- if (rv->of->flags & AVFMT_GLOBALHEADER) {
- rv->c->flags |= CODEC_FLAG_GLOBAL_HEADER;
- }
-
- if (avio_open(&rv->of->pb, fname, AVIO_FLAG_WRITE) < 0) {
- fprintf(stderr, "Couldn't open outputfile! "
- "Proxy not built!\n");
- av_free(rv->of);
- return 0;
- }
-
- avcodec_open2(rv->c, rv->codec, NULL);
-
- rv->orig_height = av_get_cropped_height_from_codec(st->codec);
-
- if (st->codec->width != width || st->codec->height != height ||
- st->codec->pix_fmt != rv->c->pix_fmt)
- {
- rv->frame = av_frame_alloc();
- avpicture_fill((AVPicture *) rv->frame,
- MEM_mallocN(avpicture_get_size(
- rv->c->pix_fmt,
- round_up(width, 16), height),
- "alloc proxy output frame"),
- rv->c->pix_fmt, round_up(width, 16), height);
-
- rv->sws_ctx = sws_getContext(
- st->codec->width,
- rv->orig_height,
- st->codec->pix_fmt,
- width, height,
- rv->c->pix_fmt,
- SWS_FAST_BILINEAR | SWS_PRINT_INFO,
- NULL, NULL, NULL);
- }
-
- if (avformat_write_header(rv->of, NULL) < 0) {
- fprintf(stderr, "Couldn't set output parameters? "
- "Proxy not built!\n");
- av_free(rv->of);
- return 0;
- }
-
- return rv;
+ struct proxy_output_ctx *rv = MEM_callocN(sizeof(struct proxy_output_ctx), "alloc_proxy_output");
+
+ char fname[FILE_MAX];
+ int ffmpeg_quality;
+
+ /* JPEG requires this */
+ width = round_up(width, 8);
+ height = round_up(height, 8);
+
+ rv->proxy_size = proxy_size;
+ rv->anim = anim;
+
+ get_proxy_filename(rv->anim, rv->proxy_size, fname, true);
+ BLI_make_existing_file(fname);
+
+ rv->of = avformat_alloc_context();
+ rv->of->oformat = av_guess_format("avi", NULL, NULL);
+
+ BLI_strncpy(rv->of->filename, fname, sizeof(rv->of->filename));
+
+ fprintf(stderr, "Starting work on proxy: %s\n", rv->of->filename);
+
+ rv->st = avformat_new_stream(rv->of, NULL);
+ rv->st->id = 0;
+
+ rv->c = rv->st->codec;
+ rv->c->codec_type = AVMEDIA_TYPE_VIDEO;
+ rv->c->codec_id = AV_CODEC_ID_MJPEG;
+ rv->c->width = width;
+ rv->c->height = height;
+
+ rv->of->oformat->video_codec = rv->c->codec_id;
+ rv->codec = avcodec_find_encoder(rv->c->codec_id);
+
+ if (!rv->codec) {
+ fprintf(stderr,
+ "No ffmpeg MJPEG encoder available? "
+ "Proxy not built!\n");
+ av_free(rv->of);
+ return NULL;
+ }
+
+ if (rv->codec->pix_fmts) {
+ rv->c->pix_fmt = rv->codec->pix_fmts[0];
+ }
+ else {
+ rv->c->pix_fmt = AV_PIX_FMT_YUVJ420P;
+ }
+
+ rv->c->sample_aspect_ratio = rv->st->sample_aspect_ratio = st->codec->sample_aspect_ratio;
+
+ rv->c->time_base.den = 25;
+ rv->c->time_base.num = 1;
+ rv->st->time_base = rv->c->time_base;
+
+ /* there's no way to set JPEG quality in the same way as in AVI JPEG and image sequence,
+ * but this seems to be giving expected quality result */
+ ffmpeg_quality = (int)(1.0f + 30.0f * (1.0f - (float)quality / 100.0f) + 0.5f);
+ av_opt_set_int(rv->c, "qmin", ffmpeg_quality, 0);
+ av_opt_set_int(rv->c, "qmax", ffmpeg_quality, 0);
+
+ if (rv->of->flags & AVFMT_GLOBALHEADER) {
+ rv->c->flags |= CODEC_FLAG_GLOBAL_HEADER;
+ }
+
+ if (avio_open(&rv->of->pb, fname, AVIO_FLAG_WRITE) < 0) {
+ fprintf(stderr,
+ "Couldn't open outputfile! "
+ "Proxy not built!\n");
+ av_free(rv->of);
+ return 0;
+ }
+
+ avcodec_open2(rv->c, rv->codec, NULL);
+
+ rv->orig_height = av_get_cropped_height_from_codec(st->codec);
+
+ if (st->codec->width != width || st->codec->height != height ||
+ st->codec->pix_fmt != rv->c->pix_fmt) {
+ rv->frame = av_frame_alloc();
+ avpicture_fill((AVPicture *)rv->frame,
+ MEM_mallocN(avpicture_get_size(rv->c->pix_fmt, round_up(width, 16), height),
+ "alloc proxy output frame"),
+ rv->c->pix_fmt,
+ round_up(width, 16),
+ height);
+
+ rv->sws_ctx = sws_getContext(st->codec->width,
+ rv->orig_height,
+ st->codec->pix_fmt,
+ width,
+ height,
+ rv->c->pix_fmt,
+ SWS_FAST_BILINEAR | SWS_PRINT_INFO,
+ NULL,
+ NULL,
+ NULL);
+ }
+
+ if (avformat_write_header(rv->of, NULL) < 0) {
+ fprintf(stderr,
+ "Couldn't set output parameters? "
+ "Proxy not built!\n");
+ av_free(rv->of);
+ return 0;
+ }
+
+ return rv;
}
-static int add_to_proxy_output_ffmpeg(
- struct proxy_output_ctx *ctx, AVFrame *frame)
+static int add_to_proxy_output_ffmpeg(struct proxy_output_ctx *ctx, AVFrame *frame)
{
- AVPacket packet = { 0 };
- int ret, got_output;
-
- av_init_packet(&packet);
-
- if (!ctx) {
- return 0;
- }
-
- if (ctx->sws_ctx && frame &&
- (frame->data[0] || frame->data[1] ||
- frame->data[2] || frame->data[3]))
- {
- sws_scale(ctx->sws_ctx, (const uint8_t *const *) frame->data,
- frame->linesize, 0, ctx->orig_height,
- ctx->frame->data, ctx->frame->linesize);
- }
-
- frame = ctx->sws_ctx ? (frame ? ctx->frame : 0) : frame;
-
- if (frame) {
- frame->pts = ctx->cfra++;
- }
-
- ret = avcodec_encode_video2(ctx->c, &packet, frame, &got_output);
- if (ret < 0) {
- fprintf(stderr, "Error encoding proxy frame %d for '%s'\n",
- ctx->cfra - 1, ctx->of->filename);
- return 0;
- }
-
- if (got_output) {
- if (packet.pts != AV_NOPTS_VALUE) {
- packet.pts = av_rescale_q(packet.pts,
- ctx->c->time_base,
- ctx->st->time_base);
- }
- if (packet.dts != AV_NOPTS_VALUE) {
- packet.dts = av_rescale_q(packet.dts,
- ctx->c->time_base,
- ctx->st->time_base);
- }
-
- packet.stream_index = ctx->st->index;
-
- if (av_interleaved_write_frame(ctx->of, &packet) != 0) {
- fprintf(stderr, "Error writing proxy frame %d "
- "into '%s'\n", ctx->cfra - 1,
- ctx->of->filename);
- return 0;
- }
-
- return 1;
- }
- else {
- return 0;
- }
+ AVPacket packet = {0};
+ int ret, got_output;
+
+ av_init_packet(&packet);
+
+ if (!ctx) {
+ return 0;
+ }
+
+ if (ctx->sws_ctx && frame &&
+ (frame->data[0] || frame->data[1] || frame->data[2] || frame->data[3])) {
+ sws_scale(ctx->sws_ctx,
+ (const uint8_t *const *)frame->data,
+ frame->linesize,
+ 0,
+ ctx->orig_height,
+ ctx->frame->data,
+ ctx->frame->linesize);
+ }
+
+ frame = ctx->sws_ctx ? (frame ? ctx->frame : 0) : frame;
+
+ if (frame) {
+ frame->pts = ctx->cfra++;
+ }
+
+ ret = avcodec_encode_video2(ctx->c, &packet, frame, &got_output);
+ if (ret < 0) {
+ fprintf(stderr, "Error encoding proxy frame %d for '%s'\n", ctx->cfra - 1, ctx->of->filename);
+ return 0;
+ }
+
+ if (got_output) {
+ if (packet.pts != AV_NOPTS_VALUE) {
+ packet.pts = av_rescale_q(packet.pts, ctx->c->time_base, ctx->st->time_base);
+ }
+ if (packet.dts != AV_NOPTS_VALUE) {
+ packet.dts = av_rescale_q(packet.dts, ctx->c->time_base, ctx->st->time_base);
+ }
+
+ packet.stream_index = ctx->st->index;
+
+ if (av_interleaved_write_frame(ctx->of, &packet) != 0) {
+ fprintf(stderr,
+ "Error writing proxy frame %d "
+ "into '%s'\n",
+ ctx->cfra - 1,
+ ctx->of->filename);
+ return 0;
+ }
+
+ return 1;
+ }
+ else {
+ return 0;
+ }
}
-static void free_proxy_output_ffmpeg(struct proxy_output_ctx *ctx,
- int rollback)
+static void free_proxy_output_ffmpeg(struct proxy_output_ctx *ctx, int rollback)
{
- char fname[FILE_MAX];
- char fname_tmp[FILE_MAX];
+ char fname[FILE_MAX];
+ char fname_tmp[FILE_MAX];
- if (!ctx) {
- return;
- }
+ if (!ctx) {
+ return;
+ }
- if (!rollback) {
- while (add_to_proxy_output_ffmpeg(ctx, NULL)) {}
- }
+ if (!rollback) {
+ while (add_to_proxy_output_ffmpeg(ctx, NULL)) {
+ }
+ }
- avcodec_flush_buffers(ctx->c);
+ avcodec_flush_buffers(ctx->c);
- av_write_trailer(ctx->of);
+ av_write_trailer(ctx->of);
- avcodec_close(ctx->c);
+ avcodec_close(ctx->c);
- if (ctx->of->oformat) {
- if (!(ctx->of->oformat->flags & AVFMT_NOFILE)) {
- avio_close(ctx->of->pb);
- }
- }
- avformat_free_context(ctx->of);
+ if (ctx->of->oformat) {
+ if (!(ctx->of->oformat->flags & AVFMT_NOFILE)) {
+ avio_close(ctx->of->pb);
+ }
+ }
+ avformat_free_context(ctx->of);
- if (ctx->sws_ctx) {
- sws_freeContext(ctx->sws_ctx);
+ if (ctx->sws_ctx) {
+ sws_freeContext(ctx->sws_ctx);
- MEM_freeN(ctx->frame->data[0]);
- av_free(ctx->frame);
- }
+ MEM_freeN(ctx->frame->data[0]);
+ av_free(ctx->frame);
+ }
- get_proxy_filename(ctx->anim, ctx->proxy_size,
- fname_tmp, true);
+ get_proxy_filename(ctx->anim, ctx->proxy_size, fname_tmp, true);
- if (rollback) {
- unlink(fname_tmp);
- }
- else {
- get_proxy_filename(ctx->anim, ctx->proxy_size,
- fname, false);
- unlink(fname);
- BLI_rename(fname_tmp, fname);
- }
+ if (rollback) {
+ unlink(fname_tmp);
+ }
+ else {
+ get_proxy_filename(ctx->anim, ctx->proxy_size, fname, false);
+ unlink(fname);
+ BLI_rename(fname_tmp, fname);
+ }
- MEM_freeN(ctx);
+ MEM_freeN(ctx);
}
typedef struct FFmpegIndexBuilderContext {
- int anim_type;
-
- AVFormatContext *iFormatCtx;
- AVCodecContext *iCodecCtx;
- AVCodec *iCodec;
- AVStream *iStream;
- int videoStream;
-
- int num_proxy_sizes;
- int num_indexers;
-
- struct proxy_output_ctx *proxy_ctx[IMB_PROXY_MAX_SLOT];
- anim_index_builder *indexer[IMB_TC_MAX_SLOT];
-
- IMB_Timecode_Type tcs_in_use;
- IMB_Proxy_Size proxy_sizes_in_use;
-
- unsigned long long seek_pos;
- unsigned long long last_seek_pos;
- unsigned long long seek_pos_dts;
- unsigned long long seek_pos_pts;
- unsigned long long last_seek_pos_dts;
- unsigned long long start_pts;
- double frame_rate;
- double pts_time_base;
- int frameno, frameno_gapless;
- int start_pts_set;
+ int anim_type;
+
+ AVFormatContext *iFormatCtx;
+ AVCodecContext *iCodecCtx;
+ AVCodec *iCodec;
+ AVStream *iStream;
+ int videoStream;
+
+ int num_proxy_sizes;
+ int num_indexers;
+
+ struct proxy_output_ctx *proxy_ctx[IMB_PROXY_MAX_SLOT];
+ anim_index_builder *indexer[IMB_TC_MAX_SLOT];
+
+ IMB_Timecode_Type tcs_in_use;
+ IMB_Proxy_Size proxy_sizes_in_use;
+
+ unsigned long long seek_pos;
+ unsigned long long last_seek_pos;
+ unsigned long long seek_pos_dts;
+ unsigned long long seek_pos_pts;
+ unsigned long long last_seek_pos_dts;
+ unsigned long long start_pts;
+ double frame_rate;
+ double pts_time_base;
+ int frameno, frameno_gapless;
+ int start_pts_set;
} FFmpegIndexBuilderContext;
-static IndexBuildContext *index_ffmpeg_create_context(struct anim *anim, IMB_Timecode_Type tcs_in_use,
- IMB_Proxy_Size proxy_sizes_in_use, int quality)
+static IndexBuildContext *index_ffmpeg_create_context(struct anim *anim,
+ IMB_Timecode_Type tcs_in_use,
+ IMB_Proxy_Size proxy_sizes_in_use,
+ int quality)
{
- FFmpegIndexBuilderContext *context = MEM_callocN(sizeof(FFmpegIndexBuilderContext), "FFmpeg index builder context");
- int num_proxy_sizes = IMB_PROXY_MAX_SLOT;
- int num_indexers = IMB_TC_MAX_SLOT;
- int i, streamcount;
-
- context->tcs_in_use = tcs_in_use;
- context->proxy_sizes_in_use = proxy_sizes_in_use;
- context->num_proxy_sizes = IMB_PROXY_MAX_SLOT;
- context->num_indexers = IMB_TC_MAX_SLOT;
-
- memset(context->proxy_ctx, 0, sizeof(context->proxy_ctx));
- memset(context->indexer, 0, sizeof(context->indexer));
-
- if (avformat_open_input(&context->iFormatCtx, anim->name, NULL, NULL) != 0) {
- MEM_freeN(context);
- return NULL;
- }
-
- if (avformat_find_stream_info(context->iFormatCtx, NULL) < 0) {
- avformat_close_input(&context->iFormatCtx);
- MEM_freeN(context);
- return NULL;
- }
-
- streamcount = anim->streamindex;
-
- /* Find the video stream */
- context->videoStream = -1;
- for (i = 0; i < context->iFormatCtx->nb_streams; i++)
- if (context->iFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
- if (streamcount > 0) {
- streamcount--;
- continue;
- }
- context->videoStream = i;
- break;
- }
-
- if (context->videoStream == -1) {
- avformat_close_input(&context->iFormatCtx);
- MEM_freeN(context);
- return NULL;
- }
-
- context->iStream = context->iFormatCtx->streams[context->videoStream];
- context->iCodecCtx = context->iStream->codec;
-
- context->iCodec = avcodec_find_decoder(context->iCodecCtx->codec_id);
-
- if (context->iCodec == NULL) {
- avformat_close_input(&context->iFormatCtx);
- MEM_freeN(context);
- return NULL;
- }
-
- context->iCodecCtx->workaround_bugs = 1;
-
- if (avcodec_open2(context->iCodecCtx, context->iCodec, NULL) < 0) {
- avformat_close_input(&context->iFormatCtx);
- MEM_freeN(context);
- return NULL;
- }
-
- for (i = 0; i < num_proxy_sizes; i++) {
- if (proxy_sizes_in_use & proxy_sizes[i]) {
- context->proxy_ctx[i] = alloc_proxy_output_ffmpeg(
- anim, context->iStream, proxy_sizes[i],
- context->iCodecCtx->width * proxy_fac[i],
- av_get_cropped_height_from_codec(
- context->iCodecCtx) * proxy_fac[i],
- quality);
- if (!context->proxy_ctx[i]) {
- proxy_sizes_in_use &= ~proxy_sizes[i];
- }
- }
- }
-
- for (i = 0; i < num_indexers; i++) {
- if (tcs_in_use & tc_types[i]) {
- char fname[FILE_MAX];
-
- get_tc_filename(anim, tc_types[i], fname);
-
- context->indexer[i] = IMB_index_builder_create(fname);
- if (!context->indexer[i]) {
- tcs_in_use &= ~tc_types[i];
- }
- }
- }
-
- return (IndexBuildContext *)context;
+ FFmpegIndexBuilderContext *context = MEM_callocN(sizeof(FFmpegIndexBuilderContext),
+ "FFmpeg index builder context");
+ int num_proxy_sizes = IMB_PROXY_MAX_SLOT;
+ int num_indexers = IMB_TC_MAX_SLOT;
+ int i, streamcount;
+
+ context->tcs_in_use = tcs_in_use;
+ context->proxy_sizes_in_use = proxy_sizes_in_use;
+ context->num_proxy_sizes = IMB_PROXY_MAX_SLOT;
+ context->num_indexers = IMB_TC_MAX_SLOT;
+
+ memset(context->proxy_ctx, 0, sizeof(context->proxy_ctx));
+ memset(context->indexer, 0, sizeof(context->indexer));
+
+ if (avformat_open_input(&context->iFormatCtx, anim->name, NULL, NULL) != 0) {
+ MEM_freeN(context);
+ return NULL;
+ }
+
+ if (avformat_find_stream_info(context->iFormatCtx, NULL) < 0) {
+ avformat_close_input(&context->iFormatCtx);
+ MEM_freeN(context);
+ return NULL;
+ }
+
+ streamcount = anim->streamindex;
+
+ /* Find the video stream */
+ context->videoStream = -1;
+ for (i = 0; i < context->iFormatCtx->nb_streams; i++)
+ if (context->iFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
+ if (streamcount > 0) {
+ streamcount--;
+ continue;
+ }
+ context->videoStream = i;
+ break;
+ }
+
+ if (context->videoStream == -1) {
+ avformat_close_input(&context->iFormatCtx);
+ MEM_freeN(context);
+ return NULL;
+ }
+
+ context->iStream = context->iFormatCtx->streams[context->videoStream];
+ context->iCodecCtx = context->iStream->codec;
+
+ context->iCodec = avcodec_find_decoder(context->iCodecCtx->codec_id);
+
+ if (context->iCodec == NULL) {
+ avformat_close_input(&context->iFormatCtx);
+ MEM_freeN(context);
+ return NULL;
+ }
+
+ context->iCodecCtx->workaround_bugs = 1;
+
+ if (avcodec_open2(context->iCodecCtx, context->iCodec, NULL) < 0) {
+ avformat_close_input(&context->iFormatCtx);
+ MEM_freeN(context);
+ return NULL;
+ }
+
+ for (i = 0; i < num_proxy_sizes; i++) {
+ if (proxy_sizes_in_use & proxy_sizes[i]) {
+ context->proxy_ctx[i] = alloc_proxy_output_ffmpeg(
+ anim,
+ context->iStream,
+ proxy_sizes[i],
+ context->iCodecCtx->width * proxy_fac[i],
+ av_get_cropped_height_from_codec(context->iCodecCtx) * proxy_fac[i],
+ quality);
+ if (!context->proxy_ctx[i]) {
+ proxy_sizes_in_use &= ~proxy_sizes[i];
+ }
+ }
+ }
+
+ for (i = 0; i < num_indexers; i++) {
+ if (tcs_in_use & tc_types[i]) {
+ char fname[FILE_MAX];
+
+ get_tc_filename(anim, tc_types[i], fname);
+
+ context->indexer[i] = IMB_index_builder_create(fname);
+ if (!context->indexer[i]) {
+ tcs_in_use &= ~tc_types[i];
+ }
+ }
+ }
+
+ return (IndexBuildContext *)context;
}
static void index_rebuild_ffmpeg_finish(FFmpegIndexBuilderContext *context, int stop)
{
- int i;
+ int i;
- for (i = 0; i < context->num_indexers; i++) {
- if (context->tcs_in_use & tc_types[i]) {
- IMB_index_builder_finish(context->indexer[i], stop);
- }
- }
+ for (i = 0; i < context->num_indexers; i++) {
+ if (context->tcs_in_use & tc_types[i]) {
+ IMB_index_builder_finish(context->indexer[i], stop);
+ }
+ }
- for (i = 0; i < context->num_proxy_sizes; i++) {
- if (context->proxy_sizes_in_use & proxy_sizes[i]) {
- free_proxy_output_ffmpeg(context->proxy_ctx[i], stop);
- }
- }
+ for (i = 0; i < context->num_proxy_sizes; i++) {
+ if (context->proxy_sizes_in_use & proxy_sizes[i]) {
+ free_proxy_output_ffmpeg(context->proxy_ctx[i], stop);
+ }
+ }
- avcodec_close(context->iCodecCtx);
- avformat_close_input(&context->iFormatCtx);
+ avcodec_close(context->iCodecCtx);
+ avformat_close_input(&context->iFormatCtx);
- MEM_freeN(context);
+ MEM_freeN(context);
}
-static void index_rebuild_ffmpeg_proc_decoded_frame(
- FFmpegIndexBuilderContext *context,
- AVPacket *curr_packet,
- AVFrame *in_frame)
+static void index_rebuild_ffmpeg_proc_decoded_frame(FFmpegIndexBuilderContext *context,
+ AVPacket *curr_packet,
+ AVFrame *in_frame)
{
- int i;
- unsigned long long s_pos = context->seek_pos;
- unsigned long long s_dts = context->seek_pos_dts;
- unsigned long long pts = av_get_pts_from_frame(context->iFormatCtx, in_frame);
-
- for (i = 0; i < context->num_proxy_sizes; i++) {
- add_to_proxy_output_ffmpeg(context->proxy_ctx[i], in_frame);
- }
-
- if (!context->start_pts_set) {
- context->start_pts = pts;
- context->start_pts_set = true;
- }
-
- context->frameno = floor((pts - context->start_pts) *
- context->pts_time_base *
- context->frame_rate + 0.5);
-
- /* decoding starts *always* on I-Frames,
- * so: P-Frames won't work, even if all the
- * information is in place, when we seek
- * to the I-Frame presented *after* the P-Frame,
- * but located before the P-Frame within
- * the stream */
-
- if (pts < context->seek_pos_pts) {
- s_pos = context->last_seek_pos;
- s_dts = context->last_seek_pos_dts;
- }
-
- for (i = 0; i < context->num_indexers; i++) {
- if (context->tcs_in_use & tc_types[i]) {
- int tc_frameno = context->frameno;
-
- if (tc_types[i] == IMB_TC_RECORD_RUN_NO_GAPS)
- tc_frameno = context->frameno_gapless;
-
- IMB_index_builder_proc_frame(
- context->indexer[i],
- curr_packet->data,
- curr_packet->size,
- tc_frameno,
- s_pos, s_dts, pts);
- }
- }
-
- context->frameno_gapless++;
+ int i;
+ unsigned long long s_pos = context->seek_pos;
+ unsigned long long s_dts = context->seek_pos_dts;
+ unsigned long long pts = av_get_pts_from_frame(context->iFormatCtx, in_frame);
+
+ for (i = 0; i < context->num_proxy_sizes; i++) {
+ add_to_proxy_output_ffmpeg(context->proxy_ctx[i], in_frame);
+ }
+
+ if (!context->start_pts_set) {
+ context->start_pts = pts;
+ context->start_pts_set = true;
+ }
+
+ context->frameno = floor(
+ (pts - context->start_pts) * context->pts_time_base * context->frame_rate + 0.5);
+
+ /* decoding starts *always* on I-Frames,
+ * so: P-Frames won't work, even if all the
+ * information is in place, when we seek
+ * to the I-Frame presented *after* the P-Frame,
+ * but located before the P-Frame within
+ * the stream */
+
+ if (pts < context->seek_pos_pts) {
+ s_pos = context->last_seek_pos;
+ s_dts = context->last_seek_pos_dts;
+ }
+
+ for (i = 0; i < context->num_indexers; i++) {
+ if (context->tcs_in_use & tc_types[i]) {
+ int tc_frameno = context->frameno;
+
+ if (tc_types[i] == IMB_TC_RECORD_RUN_NO_GAPS)
+ tc_frameno = context->frameno_gapless;
+
+ IMB_index_builder_proc_frame(context->indexer[i],
+ curr_packet->data,
+ curr_packet->size,
+ tc_frameno,
+ s_pos,
+ s_dts,
+ pts);
+ }
+ }
+
+ context->frameno_gapless++;
}
static int index_rebuild_ffmpeg(FFmpegIndexBuilderContext *context,
- short *stop, short *do_update, float *progress)
+ short *stop,
+ short *do_update,
+ float *progress)
{
- AVFrame *in_frame = 0;
- AVPacket next_packet;
- uint64_t stream_size;
-
- memset(&next_packet, 0, sizeof(AVPacket));
-
- in_frame = av_frame_alloc();
-
- stream_size = avio_size(context->iFormatCtx->pb);
-
- context->frame_rate = av_q2d(av_get_r_frame_rate_compat(context->iFormatCtx, context->iStream));
- context->pts_time_base = av_q2d(context->iStream->time_base);
-
- while (av_read_frame(context->iFormatCtx, &next_packet) >= 0) {
- int frame_finished = 0;
- float next_progress = (float)((int)floor(((double) next_packet.pos) * 100 /
- ((double) stream_size) + 0.5)) / 100;
-
- if (*progress != next_progress) {
- *progress = next_progress;
- *do_update = true;
- }
-
- if (*stop) {
- av_free_packet(&next_packet);
- break;
- }
-
- if (next_packet.stream_index == context->videoStream) {
- if (next_packet.flags & AV_PKT_FLAG_KEY) {
- context->last_seek_pos = context->seek_pos;
- context->last_seek_pos_dts = context->seek_pos_dts;
- context->seek_pos = next_packet.pos;
- context->seek_pos_dts = next_packet.dts;
- context->seek_pos_pts = next_packet.pts;
- }
-
- avcodec_decode_video2(
- context->iCodecCtx, in_frame, &frame_finished,
- &next_packet);
- }
-
- if (frame_finished) {
- index_rebuild_ffmpeg_proc_decoded_frame(
- context, &next_packet, in_frame);
- }
- av_free_packet(&next_packet);
- }
-
- /* process pictures still stuck in decoder engine after EOF
- * according to ffmpeg docs using 0-size packets.
- *
- * At least, if we haven't already stopped... */
-
- /* this creates the 0-size packet and prevents a memory leak. */
- av_free_packet(&next_packet);
-
- if (!*stop) {
- int frame_finished;
-
- do {
- frame_finished = 0;
-
- avcodec_decode_video2(
- context->iCodecCtx, in_frame, &frame_finished,
- &next_packet);
-
- if (frame_finished) {
- index_rebuild_ffmpeg_proc_decoded_frame(
- context, &next_packet, in_frame);
- }
- } while (frame_finished);
- }
-
- av_free(in_frame);
-
- return 1;
+ AVFrame *in_frame = 0;
+ AVPacket next_packet;
+ uint64_t stream_size;
+
+ memset(&next_packet, 0, sizeof(AVPacket));
+
+ in_frame = av_frame_alloc();
+
+ stream_size = avio_size(context->iFormatCtx->pb);
+
+ context->frame_rate = av_q2d(av_get_r_frame_rate_compat(context->iFormatCtx, context->iStream));
+ context->pts_time_base = av_q2d(context->iStream->time_base);
+
+ while (av_read_frame(context->iFormatCtx, &next_packet) >= 0) {
+ int frame_finished = 0;
+ float next_progress =
+ (float)((int)floor(((double)next_packet.pos) * 100 / ((double)stream_size) + 0.5)) / 100;
+
+ if (*progress != next_progress) {
+ *progress = next_progress;
+ *do_update = true;
+ }
+
+ if (*stop) {
+ av_free_packet(&next_packet);
+ break;
+ }
+
+ if (next_packet.stream_index == context->videoStream) {
+ if (next_packet.flags & AV_PKT_FLAG_KEY) {
+ context->last_seek_pos = context->seek_pos;
+ context->last_seek_pos_dts = context->seek_pos_dts;
+ context->seek_pos = next_packet.pos;
+ context->seek_pos_dts = next_packet.dts;
+ context->seek_pos_pts = next_packet.pts;
+ }
+
+ avcodec_decode_video2(context->iCodecCtx, in_frame, &frame_finished, &next_packet);
+ }
+
+ if (frame_finished) {
+ index_rebuild_ffmpeg_proc_decoded_frame(context, &next_packet, in_frame);
+ }
+ av_free_packet(&next_packet);
+ }
+
+ /* process pictures still stuck in decoder engine after EOF
+ * according to ffmpeg docs using 0-size packets.
+ *
+ * At least, if we haven't already stopped... */
+
+ /* this creates the 0-size packet and prevents a memory leak. */
+ av_free_packet(&next_packet);
+
+ if (!*stop) {
+ int frame_finished;
+
+ do {
+ frame_finished = 0;
+
+ avcodec_decode_video2(context->iCodecCtx, in_frame, &frame_finished, &next_packet);
+
+ if (frame_finished) {
+ index_rebuild_ffmpeg_proc_decoded_frame(context, &next_packet, in_frame);
+ }
+ } while (frame_finished);
+ }
+
+ av_free(in_frame);
+
+ return 1;
}
#endif
@@ -980,386 +967,386 @@ static int index_rebuild_ffmpeg(FFmpegIndexBuilderContext *context,
#ifdef WITH_AVI
typedef struct FallbackIndexBuilderContext {
- int anim_type;
+ int anim_type;
- struct anim *anim;
- AviMovie *proxy_ctx[IMB_PROXY_MAX_SLOT];
- IMB_Proxy_Size proxy_sizes_in_use;
+ struct anim *anim;
+ AviMovie *proxy_ctx[IMB_PROXY_MAX_SLOT];
+ IMB_Proxy_Size proxy_sizes_in_use;
} FallbackIndexBuilderContext;
static AviMovie *alloc_proxy_output_avi(
- struct anim *anim, char *filename, int width, int height,
- int quality)
+ struct anim *anim, char *filename, int width, int height, int quality)
{
- int x, y;
- AviFormat format;
- double framerate;
- AviMovie *avi;
- short frs_sec = 25; /* it doesn't really matter for proxies,
- * but sane defaults help anyways...*/
- float frs_sec_base = 1.0;
+ int x, y;
+ AviFormat format;
+ double framerate;
+ AviMovie *avi;
+ short frs_sec = 25; /* it doesn't really matter for proxies,
+ * but sane defaults help anyways...*/
+ float frs_sec_base = 1.0;
- IMB_anim_get_fps(anim, &frs_sec, &frs_sec_base, false);
+ IMB_anim_get_fps(anim, &frs_sec, &frs_sec_base, false);
- x = width;
- y = height;
+ x = width;
+ y = height;
- framerate = (double) frs_sec / (double) frs_sec_base;
+ framerate = (double)frs_sec / (double)frs_sec_base;
- avi = MEM_mallocN(sizeof(AviMovie), "avimovie");
+ avi = MEM_mallocN(sizeof(AviMovie), "avimovie");
- format = AVI_FORMAT_MJPEG;
+ format = AVI_FORMAT_MJPEG;
- if (AVI_open_compress(filename, avi, 1, format) != AVI_ERROR_NONE) {
- MEM_freeN(avi);
- return NULL;
- }
+ if (AVI_open_compress(filename, avi, 1, format) != AVI_ERROR_NONE) {
+ MEM_freeN(avi);
+ return NULL;
+ }
- AVI_set_compress_option(avi, AVI_OPTION_TYPE_MAIN, 0, AVI_OPTION_WIDTH, &x);
- AVI_set_compress_option(avi, AVI_OPTION_TYPE_MAIN, 0, AVI_OPTION_HEIGHT, &y);
- AVI_set_compress_option(avi, AVI_OPTION_TYPE_MAIN, 0, AVI_OPTION_QUALITY, &quality);
- AVI_set_compress_option(avi, AVI_OPTION_TYPE_MAIN, 0, AVI_OPTION_FRAMERATE, &framerate);
+ AVI_set_compress_option(avi, AVI_OPTION_TYPE_MAIN, 0, AVI_OPTION_WIDTH, &x);
+ AVI_set_compress_option(avi, AVI_OPTION_TYPE_MAIN, 0, AVI_OPTION_HEIGHT, &y);
+ AVI_set_compress_option(avi, AVI_OPTION_TYPE_MAIN, 0, AVI_OPTION_QUALITY, &quality);
+ AVI_set_compress_option(avi, AVI_OPTION_TYPE_MAIN, 0, AVI_OPTION_FRAMERATE, &framerate);
- avi->interlace = 0;
- avi->odd_fields = 0;
+ avi->interlace = 0;
+ avi->odd_fields = 0;
- return avi;
+ return avi;
}
-static IndexBuildContext *index_fallback_create_context(struct anim *anim, IMB_Timecode_Type UNUSED(tcs_in_use),
- IMB_Proxy_Size proxy_sizes_in_use, int quality)
+static IndexBuildContext *index_fallback_create_context(struct anim *anim,
+ IMB_Timecode_Type UNUSED(tcs_in_use),
+ IMB_Proxy_Size proxy_sizes_in_use,
+ int quality)
{
- FallbackIndexBuilderContext *context;
- int i;
+ FallbackIndexBuilderContext *context;
+ int i;
- /* since timecode indices only work with ffmpeg right now,
- * don't know a sensible fallback here...
- *
- * so no proxies...
- */
- if (proxy_sizes_in_use == IMB_PROXY_NONE) {
- return NULL;
- }
+ /* since timecode indices only work with ffmpeg right now,
+ * don't know a sensible fallback here...
+ *
+ * so no proxies...
+ */
+ if (proxy_sizes_in_use == IMB_PROXY_NONE) {
+ return NULL;
+ }
- context = MEM_callocN(sizeof(FallbackIndexBuilderContext), "fallback index builder context");
+ context = MEM_callocN(sizeof(FallbackIndexBuilderContext), "fallback index builder context");
- context->anim = anim;
- context->proxy_sizes_in_use = proxy_sizes_in_use;
+ context->anim = anim;
+ context->proxy_sizes_in_use = proxy_sizes_in_use;
- memset(context->proxy_ctx, 0, sizeof(context->proxy_ctx));
+ memset(context->proxy_ctx, 0, sizeof(context->proxy_ctx));
- for (i = 0; i < IMB_PROXY_MAX_SLOT; i++) {
- if (context->proxy_sizes_in_use & proxy_sizes[i]) {
- char fname[FILE_MAX];
+ for (i = 0; i < IMB_PROXY_MAX_SLOT; i++) {
+ if (context->proxy_sizes_in_use & proxy_sizes[i]) {
+ char fname[FILE_MAX];
- get_proxy_filename(anim, proxy_sizes[i], fname, true);
- BLI_make_existing_file(fname);
+ get_proxy_filename(anim, proxy_sizes[i], fname, true);
+ BLI_make_existing_file(fname);
- context->proxy_ctx[i] = alloc_proxy_output_avi(anim, fname,
- anim->x * proxy_fac[i], anim->y * proxy_fac[i], quality);
- }
- }
+ context->proxy_ctx[i] = alloc_proxy_output_avi(
+ anim, fname, anim->x * proxy_fac[i], anim->y * proxy_fac[i], quality);
+ }
+ }
- return (IndexBuildContext *)context;
+ return (IndexBuildContext *)context;
}
static void index_rebuild_fallback_finish(FallbackIndexBuilderContext *context, int stop)
{
- struct anim *anim = context->anim;
- char fname[FILE_MAX];
- char fname_tmp[FILE_MAX];
- int i;
-
- for (i = 0; i < IMB_PROXY_MAX_SLOT; i++) {
- if (context->proxy_sizes_in_use & proxy_sizes[i]) {
- AVI_close_compress(context->proxy_ctx[i]);
- MEM_freeN(context->proxy_ctx[i]);
-
- get_proxy_filename(anim, proxy_sizes[i], fname_tmp, true);
- get_proxy_filename(anim, proxy_sizes[i], fname, false);
-
- if (stop) {
- unlink(fname_tmp);
- }
- else {
- unlink(fname);
- rename(fname_tmp, fname);
- }
- }
- }
+ struct anim *anim = context->anim;
+ char fname[FILE_MAX];
+ char fname_tmp[FILE_MAX];
+ int i;
+
+ for (i = 0; i < IMB_PROXY_MAX_SLOT; i++) {
+ if (context->proxy_sizes_in_use & proxy_sizes[i]) {
+ AVI_close_compress(context->proxy_ctx[i]);
+ MEM_freeN(context->proxy_ctx[i]);
+
+ get_proxy_filename(anim, proxy_sizes[i], fname_tmp, true);
+ get_proxy_filename(anim, proxy_sizes[i], fname, false);
+
+ if (stop) {
+ unlink(fname_tmp);
+ }
+ else {
+ unlink(fname);
+ rename(fname_tmp, fname);
+ }
+ }
+ }
}
static void index_rebuild_fallback(FallbackIndexBuilderContext *context,
- short *stop, short *do_update, float *progress)
+ short *stop,
+ short *do_update,
+ float *progress)
{
- int cnt = IMB_anim_get_duration(context->anim, IMB_TC_NONE);
- int i, pos;
- struct anim *anim = context->anim;
+ int cnt = IMB_anim_get_duration(context->anim, IMB_TC_NONE);
+ int i, pos;
+ struct anim *anim = context->anim;
- for (pos = 0; pos < cnt; pos++) {
- struct ImBuf *ibuf = IMB_anim_absolute(anim, pos, IMB_TC_NONE, IMB_PROXY_NONE);
- struct ImBuf *tmp_ibuf = IMB_dupImBuf(ibuf);
- float next_progress = (float) pos / (float) cnt;
+ for (pos = 0; pos < cnt; pos++) {
+ struct ImBuf *ibuf = IMB_anim_absolute(anim, pos, IMB_TC_NONE, IMB_PROXY_NONE);
+ struct ImBuf *tmp_ibuf = IMB_dupImBuf(ibuf);
+ float next_progress = (float)pos / (float)cnt;
- if (*progress != next_progress) {
- *progress = next_progress;
- *do_update = true;
- }
+ if (*progress != next_progress) {
+ *progress = next_progress;
+ *do_update = true;
+ }
- if (*stop) {
- break;
- }
+ if (*stop) {
+ break;
+ }
- IMB_flipy(tmp_ibuf);
+ IMB_flipy(tmp_ibuf);
- for (i = 0; i < IMB_PROXY_MAX_SLOT; i++) {
- if (context->proxy_sizes_in_use & proxy_sizes[i]) {
- int x = anim->x * proxy_fac[i];
- int y = anim->y * proxy_fac[i];
+ for (i = 0; i < IMB_PROXY_MAX_SLOT; i++) {
+ if (context->proxy_sizes_in_use & proxy_sizes[i]) {
+ int x = anim->x * proxy_fac[i];
+ int y = anim->y * proxy_fac[i];
- struct ImBuf *s_ibuf = IMB_dupImBuf(tmp_ibuf);
+ struct ImBuf *s_ibuf = IMB_dupImBuf(tmp_ibuf);
- IMB_scalefastImBuf(s_ibuf, x, y);
+ IMB_scalefastImBuf(s_ibuf, x, y);
- IMB_convert_rgba_to_abgr(s_ibuf);
+ IMB_convert_rgba_to_abgr(s_ibuf);
- AVI_write_frame(context->proxy_ctx[i], pos,
- AVI_FORMAT_RGB32,
- s_ibuf->rect, x * y * 4);
+ AVI_write_frame(context->proxy_ctx[i], pos, AVI_FORMAT_RGB32, s_ibuf->rect, x * y * 4);
- /* note that libavi free's the buffer... */
- s_ibuf->rect = NULL;
+ /* note that libavi free's the buffer... */
+ s_ibuf->rect = NULL;
- IMB_freeImBuf(s_ibuf);
- }
- }
+ IMB_freeImBuf(s_ibuf);
+ }
+ }
- IMB_freeImBuf(tmp_ibuf);
- IMB_freeImBuf(ibuf);
- }
+ IMB_freeImBuf(tmp_ibuf);
+ IMB_freeImBuf(ibuf);
+ }
}
-#endif /* WITH_AVI */
+#endif /* WITH_AVI */
/* ----------------------------------------------------------------------
* - public API
* ---------------------------------------------------------------------- */
-IndexBuildContext *IMB_anim_index_rebuild_context(struct anim *anim, IMB_Timecode_Type tcs_in_use,
- IMB_Proxy_Size proxy_sizes_in_use, int quality,
- const bool overwrite, GSet *file_list)
+IndexBuildContext *IMB_anim_index_rebuild_context(struct anim *anim,
+ IMB_Timecode_Type tcs_in_use,
+ IMB_Proxy_Size proxy_sizes_in_use,
+ int quality,
+ const bool overwrite,
+ GSet *file_list)
{
- IndexBuildContext *context = NULL;
- IMB_Proxy_Size proxy_sizes_to_build = proxy_sizes_in_use;
- int i;
-
- /* Don't generate the same file twice! */
- if (file_list) {
- for (i = 0; i < IMB_PROXY_MAX_SLOT; ++i) {
- IMB_Proxy_Size proxy_size = proxy_sizes[i];
- if (proxy_size & proxy_sizes_to_build) {
- char filename[FILE_MAX];
- get_proxy_filename(anim, proxy_size, filename, false);
-
- void **filename_key_p;
- if (!BLI_gset_ensure_p_ex(file_list, filename, &filename_key_p)) {
- *filename_key_p = BLI_strdup(filename);
- }
- else {
- proxy_sizes_to_build &= ~proxy_size;
- printf("Proxy: %s already registered for generation, skipping\n", filename);
- }
- }
- }
- }
-
- if (!overwrite) {
- IMB_Proxy_Size built_proxies = IMB_anim_proxy_get_existing(anim);
- if (built_proxies != 0) {
-
- for (i = 0; i < IMB_PROXY_MAX_SLOT; ++i) {
- IMB_Proxy_Size proxy_size = proxy_sizes[i];
- if (proxy_size & built_proxies) {
- char filename[FILE_MAX];
- get_proxy_filename(anim, proxy_size, filename, false);
- printf("Skipping proxy: %s\n", filename);
- }
- }
- }
- proxy_sizes_to_build &= ~built_proxies;
- }
-
- fflush(stdout);
-
- if (proxy_sizes_to_build == 0) {
- return NULL;
- }
-
-
- switch (anim->curtype) {
+ IndexBuildContext *context = NULL;
+ IMB_Proxy_Size proxy_sizes_to_build = proxy_sizes_in_use;
+ int i;
+
+ /* Don't generate the same file twice! */
+ if (file_list) {
+ for (i = 0; i < IMB_PROXY_MAX_SLOT; ++i) {
+ IMB_Proxy_Size proxy_size = proxy_sizes[i];
+ if (proxy_size & proxy_sizes_to_build) {
+ char filename[FILE_MAX];
+ get_proxy_filename(anim, proxy_size, filename, false);
+
+ void **filename_key_p;
+ if (!BLI_gset_ensure_p_ex(file_list, filename, &filename_key_p)) {
+ *filename_key_p = BLI_strdup(filename);
+ }
+ else {
+ proxy_sizes_to_build &= ~proxy_size;
+ printf("Proxy: %s already registered for generation, skipping\n", filename);
+ }
+ }
+ }
+ }
+
+ if (!overwrite) {
+ IMB_Proxy_Size built_proxies = IMB_anim_proxy_get_existing(anim);
+ if (built_proxies != 0) {
+
+ for (i = 0; i < IMB_PROXY_MAX_SLOT; ++i) {
+ IMB_Proxy_Size proxy_size = proxy_sizes[i];
+ if (proxy_size & built_proxies) {
+ char filename[FILE_MAX];
+ get_proxy_filename(anim, proxy_size, filename, false);
+ printf("Skipping proxy: %s\n", filename);
+ }
+ }
+ }
+ proxy_sizes_to_build &= ~built_proxies;
+ }
+
+ fflush(stdout);
+
+ if (proxy_sizes_to_build == 0) {
+ return NULL;
+ }
+
+ switch (anim->curtype) {
#ifdef WITH_FFMPEG
- case ANIM_FFMPEG:
- context = index_ffmpeg_create_context(anim, tcs_in_use, proxy_sizes_to_build, quality);
- break;
+ case ANIM_FFMPEG:
+ context = index_ffmpeg_create_context(anim, tcs_in_use, proxy_sizes_to_build, quality);
+ break;
#endif
#ifdef WITH_AVI
- default:
- context = index_fallback_create_context(anim, tcs_in_use, proxy_sizes_to_build, quality);
- break;
+ default:
+ context = index_fallback_create_context(anim, tcs_in_use, proxy_sizes_to_build, quality);
+ break;
#endif
- }
+ }
- if (context)
- context->anim_type = anim->curtype;
+ if (context)
+ context->anim_type = anim->curtype;
- return context;
+ return context;
- UNUSED_VARS(tcs_in_use, proxy_sizes_in_use, quality);
+ UNUSED_VARS(tcs_in_use, proxy_sizes_in_use, quality);
}
void IMB_anim_index_rebuild(struct IndexBuildContext *context,
- short *stop, short *do_update, float *progress)
+ short *stop,
+ short *do_update,
+ float *progress)
{
- switch (context->anim_type) {
+ switch (context->anim_type) {
#ifdef WITH_FFMPEG
- case ANIM_FFMPEG:
- index_rebuild_ffmpeg((FFmpegIndexBuilderContext *)context, stop, do_update, progress);
- break;
+ case ANIM_FFMPEG:
+ index_rebuild_ffmpeg((FFmpegIndexBuilderContext *)context, stop, do_update, progress);
+ break;
#endif
#ifdef WITH_AVI
- default:
- index_rebuild_fallback((FallbackIndexBuilderContext *)context, stop, do_update, progress);
- break;
+ default:
+ index_rebuild_fallback((FallbackIndexBuilderContext *)context, stop, do_update, progress);
+ break;
#endif
- }
+ }
- UNUSED_VARS(stop, do_update, progress);
+ UNUSED_VARS(stop, do_update, progress);
}
void IMB_anim_index_rebuild_finish(IndexBuildContext *context, short stop)
{
- switch (context->anim_type) {
+ switch (context->anim_type) {
#ifdef WITH_FFMPEG
- case ANIM_FFMPEG:
- index_rebuild_ffmpeg_finish((FFmpegIndexBuilderContext *)context, stop);
- break;
+ case ANIM_FFMPEG:
+ index_rebuild_ffmpeg_finish((FFmpegIndexBuilderContext *)context, stop);
+ break;
#endif
#ifdef WITH_AVI
- default:
- index_rebuild_fallback_finish((FallbackIndexBuilderContext *)context, stop);
- break;
+ default:
+ index_rebuild_fallback_finish((FallbackIndexBuilderContext *)context, stop);
+ break;
#endif
- }
+ }
- /* static defined at top of the file */
- UNUSED_VARS(stop, proxy_sizes);
+ /* static defined at top of the file */
+ UNUSED_VARS(stop, proxy_sizes);
}
-
void IMB_free_indices(struct anim *anim)
{
- int i;
-
- for (i = 0; i < IMB_PROXY_MAX_SLOT; i++) {
- if (anim->proxy_anim[i]) {
- IMB_close_anim(anim->proxy_anim[i]);
- anim->proxy_anim[i] = NULL;
- }
- }
-
- for (i = 0; i < IMB_TC_MAX_SLOT; i++) {
- if (anim->curr_idx[i]) {
- IMB_indexer_close(anim->curr_idx[i]);
- anim->curr_idx[i] = NULL;
- }
- }
-
-
- anim->proxies_tried = 0;
- anim->indices_tried = 0;
+ int i;
+
+ for (i = 0; i < IMB_PROXY_MAX_SLOT; i++) {
+ if (anim->proxy_anim[i]) {
+ IMB_close_anim(anim->proxy_anim[i]);
+ anim->proxy_anim[i] = NULL;
+ }
+ }
+
+ for (i = 0; i < IMB_TC_MAX_SLOT; i++) {
+ if (anim->curr_idx[i]) {
+ IMB_indexer_close(anim->curr_idx[i]);
+ anim->curr_idx[i] = NULL;
+ }
+ }
+
+ anim->proxies_tried = 0;
+ anim->indices_tried = 0;
}
void IMB_anim_set_index_dir(struct anim *anim, const char *dir)
{
- if (STREQ(anim->index_dir, dir)) {
- return;
- }
- BLI_strncpy(anim->index_dir, dir, sizeof(anim->index_dir));
+ if (STREQ(anim->index_dir, dir)) {
+ return;
+ }
+ BLI_strncpy(anim->index_dir, dir, sizeof(anim->index_dir));
- IMB_free_indices(anim);
+ IMB_free_indices(anim);
}
-struct anim *IMB_anim_open_proxy(
- struct anim *anim, IMB_Proxy_Size preview_size)
+struct anim *IMB_anim_open_proxy(struct anim *anim, IMB_Proxy_Size preview_size)
{
- char fname[FILE_MAX];
- int i = IMB_proxy_size_to_array_index(preview_size);
+ char fname[FILE_MAX];
+ int i = IMB_proxy_size_to_array_index(preview_size);
- if (anim->proxy_anim[i]) {
- return anim->proxy_anim[i];
- }
+ if (anim->proxy_anim[i]) {
+ return anim->proxy_anim[i];
+ }
- if (anim->proxies_tried & preview_size) {
- return NULL;
- }
+ if (anim->proxies_tried & preview_size) {
+ return NULL;
+ }
- get_proxy_filename(anim, preview_size, fname, false);
+ get_proxy_filename(anim, preview_size, fname, false);
- /* proxies are generated in the same color space as animation itself */
- anim->proxy_anim[i] = IMB_open_anim(fname, 0, 0, anim->colorspace);
+ /* proxies are generated in the same color space as animation itself */
+ anim->proxy_anim[i] = IMB_open_anim(fname, 0, 0, anim->colorspace);
- anim->proxies_tried |= preview_size;
+ anim->proxies_tried |= preview_size;
- return anim->proxy_anim[i];
+ return anim->proxy_anim[i];
}
-struct anim_index *IMB_anim_open_index(
- struct anim *anim, IMB_Timecode_Type tc)
+struct anim_index *IMB_anim_open_index(struct anim *anim, IMB_Timecode_Type tc)
{
- char fname[FILE_MAX];
- int i = IMB_timecode_to_array_index(tc);
+ char fname[FILE_MAX];
+ int i = IMB_timecode_to_array_index(tc);
- if (anim->curr_idx[i]) {
- return anim->curr_idx[i];
- }
+ if (anim->curr_idx[i]) {
+ return anim->curr_idx[i];
+ }
- if (anim->indices_tried & tc) {
- return NULL;
- }
+ if (anim->indices_tried & tc) {
+ return NULL;
+ }
- get_tc_filename(anim, tc, fname);
+ get_tc_filename(anim, tc, fname);
- anim->curr_idx[i] = IMB_indexer_open(fname);
+ anim->curr_idx[i] = IMB_indexer_open(fname);
- anim->indices_tried |= tc;
+ anim->indices_tried |= tc;
- return anim->curr_idx[i];
+ return anim->curr_idx[i];
}
-int IMB_anim_index_get_frame_index(struct anim *anim, IMB_Timecode_Type tc,
- int position)
+int IMB_anim_index_get_frame_index(struct anim *anim, IMB_Timecode_Type tc, int position)
{
- struct anim_index *idx = IMB_anim_open_index(anim, tc);
+ struct anim_index *idx = IMB_anim_open_index(anim, tc);
- if (!idx) {
- return position;
- }
+ if (!idx) {
+ return position;
+ }
- return IMB_indexer_get_frame_index(idx, position);
+ return IMB_indexer_get_frame_index(idx, position);
}
IMB_Proxy_Size IMB_anim_proxy_get_existing(struct anim *anim)
{
- const int num_proxy_sizes = IMB_PROXY_MAX_SLOT;
- IMB_Proxy_Size existing = 0;
- int i;
- for (i = 0; i < num_proxy_sizes; ++i) {
- IMB_Proxy_Size proxy_size = proxy_sizes[i];
- char filename[FILE_MAX];
- get_proxy_filename(anim, proxy_size, filename, false);
- if (BLI_exists(filename)) {
- existing |= proxy_size;
- }
- }
- return existing;
+ const int num_proxy_sizes = IMB_PROXY_MAX_SLOT;
+ IMB_Proxy_Size existing = 0;
+ int i;
+ for (i = 0; i < num_proxy_sizes; ++i) {
+ IMB_Proxy_Size proxy_size = proxy_sizes[i];
+ char filename[FILE_MAX];
+ get_proxy_filename(anim, proxy_size, filename, false);
+ if (BLI_exists(filename)) {
+ existing |= proxy_size;
+ }
+ }
+ return existing;
}
diff --git a/source/blender/imbuf/intern/iris.c b/source/blender/imbuf/intern/iris.c
index 5bed5b28b14..ee1a6b57c26 100644
--- a/source/blender/imbuf/intern/iris.c
+++ b/source/blender/imbuf/intern/iris.c
@@ -21,7 +21,6 @@
* \ingroup imbuf
*/
-
#include <string.h>
#include "BLI_utildefines.h"
@@ -40,18 +39,18 @@
#define IMAGIC 0732
typedef struct {
- ushort imagic; /* stuff saved on disk . . */
- ushort type;
- ushort dim;
- ushort xsize;
- ushort ysize;
- ushort zsize;
- uint min;
- uint max;
- uchar _pad1[4];
- char name[80];
- uint colormap;
- uchar _pad2[404];
+ ushort imagic; /* stuff saved on disk . . */
+ ushort type;
+ ushort dim;
+ ushort xsize;
+ ushort ysize;
+ ushort zsize;
+ uint min;
+ uint max;
+ uchar _pad1[4];
+ char name[80];
+ uint colormap;
+ uchar _pad2[404];
} IMAGE;
#define HEADER_SIZE 512
@@ -62,36 +61,44 @@ BLI_STATIC_ASSERT(sizeof(IMAGE) == HEADER_SIZE, "Invalid header size");
#define GINTLUM (156)
#define BINTLUM (21)
-#define ILUM(r, g, b) ((int)(RINTLUM * (r) + GINTLUM * (g) + BINTLUM * (b)) >> 8)
+#define ILUM(r, g, b) ((int)(RINTLUM * (r) + GINTLUM * (g) + BINTLUM * (b)) >> 8)
-#define OFFSET_R 0 /* this is byte order dependent */
-#define OFFSET_G 1
-#define OFFSET_B 2
+#define OFFSET_R 0 /* this is byte order dependent */
+#define OFFSET_G 1
+#define OFFSET_B 2
// #define OFFSET_A 3
-#define CHANOFFSET(z) (3 - (z)) /* this is byte order dependent */
+#define CHANOFFSET(z) (3 - (z)) /* this is byte order dependent */
// #define TYPEMASK 0xff00
-#define BPPMASK 0x00ff
+#define BPPMASK 0x00ff
// #define ITYPE_VERBATIM 0x0000 // UNUSED
-#define ITYPE_RLE 0x0100
-#define ISRLE(type) (((type) & 0xff00) == ITYPE_RLE)
+#define ITYPE_RLE 0x0100
+#define ISRLE(type) (((type)&0xff00) == ITYPE_RLE)
// #define ISVERBATIM(type) (((type) & 0xff00) == ITYPE_VERBATIM)
-#define BPP(type) ((type) & BPPMASK)
-#define RLE(bpp) (ITYPE_RLE | (bpp))
+#define BPP(type) ((type)&BPPMASK)
+#define RLE(bpp) (ITYPE_RLE | (bpp))
// #define VERBATIM(bpp) (ITYPE_VERBATIM | (bpp)) // UNUSED
// #define IBUFSIZE(pixels) ((pixels + (pixels >> 6)) << 2) // UNUSED
// #define RLE_NOP 0x00
/* local struct for mem access */
typedef struct MFileOffset {
- const uchar *_file_data;
- uint _file_offset;
+ const uchar *_file_data;
+ uint _file_offset;
} MFileOffset;
#define MFILE_DATA(inf) ((void)0, ((inf)->_file_data + (inf)->_file_offset))
-#define MFILE_STEP(inf, step) { (inf)->_file_offset += step; } ((void)0)
-#define MFILE_SEEK(inf, pos) { (inf)->_file_offset = pos; } ((void)0)
+#define MFILE_STEP(inf, step) \
+ { \
+ (inf)->_file_offset += step; \
+ } \
+ ((void)0)
+#define MFILE_SEEK(inf, pos) \
+ { \
+ (inf)->_file_offset = pos; \
+ } \
+ ((void)0)
/* error flags */
#define DIRTY_FLAG_EOF (1 << 0)
@@ -108,8 +115,10 @@ static int putlong(FILE *outf, uint val);
static int writetab(FILE *outf, uint *tab, int len);
static void readtab(MFileOffset *inf, uint *tab, int len);
-static int expandrow(uchar *optr, const uchar *optr_end, const uchar *iptr, const uchar *iptr_end, int z);
-static int expandrow2(float *optr, const float *optr_end, const uchar *iptr, const uchar *iptr_end, int z);
+static int expandrow(
+ uchar *optr, const uchar *optr_end, const uchar *iptr, const uchar *iptr_end, int z);
+static int expandrow2(
+ float *optr, const float *optr_end, const uchar *iptr, const uchar *iptr_end, int z);
static void interleaverow(uchar *lptr, const uchar *cptr, int z, int n);
static void interleaverow2(float *lptr, const uchar *cptr, int z, int n);
static int compressrow(uchar *lbuf, uchar *rlebuf, int z, int cnt);
@@ -121,107 +130,109 @@ static void lumrow(uchar *rgbptr, uchar *lumptr, int n);
static ushort getshort(MFileOffset *inf)
{
- const uchar *buf;
+ const uchar *buf;
- buf = MFILE_DATA(inf);
- MFILE_STEP(inf, 2);
+ buf = MFILE_DATA(inf);
+ MFILE_STEP(inf, 2);
- return ((ushort)buf[0] << 8) + ((ushort)buf[1] << 0);
+ return ((ushort)buf[0] << 8) + ((ushort)buf[1] << 0);
}
static uint getlong(MFileOffset *mofs)
{
- const uchar *buf;
+ const uchar *buf;
- buf = MFILE_DATA(mofs);
- MFILE_STEP(mofs, 4);
+ buf = MFILE_DATA(mofs);
+ MFILE_STEP(mofs, 4);
- return ((uint)buf[0] << 24) + ((uint)buf[1] << 16) + ((uint)buf[2] << 8) + ((uint)buf[3] << 0);
+ return ((uint)buf[0] << 24) + ((uint)buf[1] << 16) + ((uint)buf[2] << 8) + ((uint)buf[3] << 0);
}
static void putshort(FILE *outf, ushort val)
{
- uchar buf[2];
+ uchar buf[2];
- buf[0] = (val >> 8);
- buf[1] = (val >> 0);
- fwrite(buf, 2, 1, outf);
+ buf[0] = (val >> 8);
+ buf[1] = (val >> 0);
+ fwrite(buf, 2, 1, outf);
}
static int putlong(FILE *outf, uint val)
{
- uchar buf[4];
+ uchar buf[4];
- buf[0] = (val >> 24);
- buf[1] = (val >> 16);
- buf[2] = (val >> 8);
- buf[3] = (val >> 0);
- return fwrite(buf, 4, 1, outf);
+ buf[0] = (val >> 24);
+ buf[1] = (val >> 16);
+ buf[2] = (val >> 8);
+ buf[3] = (val >> 0);
+ return fwrite(buf, 4, 1, outf);
}
static void readheader(MFileOffset *inf, IMAGE *image)
{
- memset(image, 0, sizeof(IMAGE));
- image->imagic = getshort(inf);
- image->type = getshort(inf);
- image->dim = getshort(inf);
- image->xsize = getshort(inf);
- image->ysize = getshort(inf);
- image->zsize = getshort(inf);
+ memset(image, 0, sizeof(IMAGE));
+ image->imagic = getshort(inf);
+ image->type = getshort(inf);
+ image->dim = getshort(inf);
+ image->xsize = getshort(inf);
+ image->ysize = getshort(inf);
+ image->zsize = getshort(inf);
}
static int writeheader(FILE *outf, IMAGE *image)
{
- IMAGE t = {0};
-
- fwrite(&t, sizeof(IMAGE), 1, outf);
- fseek(outf, 0, SEEK_SET);
- putshort(outf, image->imagic);
- putshort(outf, image->type);
- putshort(outf, image->dim);
- putshort(outf, image->xsize);
- putshort(outf, image->ysize);
- putshort(outf, image->zsize);
- putlong(outf, image->min);
- putlong(outf, image->max);
- putlong(outf, 0);
- return fwrite("no name", 8, 1, outf);
+ IMAGE t = {0};
+
+ fwrite(&t, sizeof(IMAGE), 1, outf);
+ fseek(outf, 0, SEEK_SET);
+ putshort(outf, image->imagic);
+ putshort(outf, image->type);
+ putshort(outf, image->dim);
+ putshort(outf, image->xsize);
+ putshort(outf, image->ysize);
+ putshort(outf, image->zsize);
+ putlong(outf, image->min);
+ putlong(outf, image->max);
+ putlong(outf, 0);
+ return fwrite("no name", 8, 1, outf);
}
static int writetab(FILE *outf, uint *tab, int len)
{
- int r = 0;
+ int r = 0;
- while (len) {
- r = putlong(outf, *tab++);
- len -= 4;
- }
- return r;
+ while (len) {
+ r = putlong(outf, *tab++);
+ len -= 4;
+ }
+ return r;
}
static void readtab(MFileOffset *inf, uint *tab, int len)
{
- while (len) {
- *tab++ = getlong(inf);
- len -= 4;
- }
+ while (len) {
+ *tab++ = getlong(inf);
+ len -= 4;
+ }
}
static void test_endian_zbuf(struct ImBuf *ibuf)
{
- int len;
- int *zval;
+ int len;
+ int *zval;
- if (BIG_LONG(1) == 1) return;
- if (ibuf->zbuf == NULL) return;
+ if (BIG_LONG(1) == 1)
+ return;
+ if (ibuf->zbuf == NULL)
+ return;
- len = ibuf->x * ibuf->y;
- zval = ibuf->zbuf;
+ len = ibuf->x * ibuf->y;
+ zval = ibuf->zbuf;
- while (len--) {
- zval[0] = BIG_LONG(zval[0]);
- zval++;
- }
+ while (len--) {
+ zval[0] = BIG_LONG(zval[0]);
+ zval++;
+ }
}
/* from misc_util: flip the bytes from x */
@@ -232,7 +243,7 @@ static void test_endian_zbuf(struct ImBuf *ibuf)
int imb_is_a_iris(const uchar *mem)
{
- return ((GS(mem) == IMAGIC) || (GSS(mem) == IMAGIC));
+ return ((GS(mem) == IMAGIC) || (GSS(mem) == IMAGIC));
}
/*
@@ -243,516 +254,535 @@ int imb_is_a_iris(const uchar *mem)
struct ImBuf *imb_loadiris(const uchar *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE])
{
- uint *base, *lptr = NULL;
- float *fbase, *fptr = NULL;
- uint *zbase, *zptr;
- const uchar *rledat;
- const uchar *mem_end = mem + size;
- MFileOffset _inf_data = {mem, 0}, *inf = &_inf_data;
- IMAGE image;
- int bpp, rle, cur, badorder;
- ImBuf *ibuf = NULL;
- uchar dirty_flag = 0;
-
- if (size < HEADER_SIZE) {
- return NULL;
- }
-
- if (!imb_is_a_iris(mem)) {
- return NULL;
- }
-
- /* OCIO_TODO: only tested with 1 byte per pixel, not sure how to test with other settings */
- colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE);
-
- readheader(inf, &image);
- if (image.imagic != IMAGIC) {
- fprintf(stderr, "longimagedata: bad magic number in image file\n");
- return(NULL);
- }
-
- rle = ISRLE(image.type);
- bpp = BPP(image.type);
- if (bpp != 1 && bpp != 2) {
- fprintf(stderr, "longimagedata: image must have 1 or 2 byte per pix chan\n");
- return(NULL);
- }
- if ((uint)image.zsize > 8) {
- fprintf(stderr, "longimagedata: channels over 8 not supported\n");
- return(NULL);
- }
-
- const int xsize = image.xsize;
- const int ysize = image.ysize;
- const int zsize = image.zsize;
-
- if (flags & IB_test) {
- ibuf = IMB_allocImBuf(image.xsize, image.ysize, 8 * image.zsize, 0);
- if (ibuf) ibuf->ftype = IMB_FTYPE_IMAGIC;
- return(ibuf);
- }
-
- if (rle) {
- size_t tablen = (size_t)ysize * (size_t)zsize * sizeof(int);
- MFILE_SEEK(inf, HEADER_SIZE);
-
- uint *starttab = MEM_mallocN(tablen, "iris starttab");
- uint *lengthtab = MEM_mallocN(tablen, "iris endtab");
+ uint *base, *lptr = NULL;
+ float *fbase, *fptr = NULL;
+ uint *zbase, *zptr;
+ const uchar *rledat;
+ const uchar *mem_end = mem + size;
+ MFileOffset _inf_data = {mem, 0}, *inf = &_inf_data;
+ IMAGE image;
+ int bpp, rle, cur, badorder;
+ ImBuf *ibuf = NULL;
+ uchar dirty_flag = 0;
+
+ if (size < HEADER_SIZE) {
+ return NULL;
+ }
+
+ if (!imb_is_a_iris(mem)) {
+ return NULL;
+ }
+
+ /* OCIO_TODO: only tested with 1 byte per pixel, not sure how to test with other settings */
+ colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE);
+
+ readheader(inf, &image);
+ if (image.imagic != IMAGIC) {
+ fprintf(stderr, "longimagedata: bad magic number in image file\n");
+ return (NULL);
+ }
+
+ rle = ISRLE(image.type);
+ bpp = BPP(image.type);
+ if (bpp != 1 && bpp != 2) {
+ fprintf(stderr, "longimagedata: image must have 1 or 2 byte per pix chan\n");
+ return (NULL);
+ }
+ if ((uint)image.zsize > 8) {
+ fprintf(stderr, "longimagedata: channels over 8 not supported\n");
+ return (NULL);
+ }
+
+ const int xsize = image.xsize;
+ const int ysize = image.ysize;
+ const int zsize = image.zsize;
+
+ if (flags & IB_test) {
+ ibuf = IMB_allocImBuf(image.xsize, image.ysize, 8 * image.zsize, 0);
+ if (ibuf)
+ ibuf->ftype = IMB_FTYPE_IMAGIC;
+ return (ibuf);
+ }
+
+ if (rle) {
+ size_t tablen = (size_t)ysize * (size_t)zsize * sizeof(int);
+ MFILE_SEEK(inf, HEADER_SIZE);
+
+ uint *starttab = MEM_mallocN(tablen, "iris starttab");
+ uint *lengthtab = MEM_mallocN(tablen, "iris endtab");
#define MFILE_CAPACITY_AT_PTR_OK_OR_FAIL(p) \
- if (UNLIKELY((p) > mem_end)) { dirty_flag |= DIRTY_FLAG_EOF; goto fail_rle; } ((void)0)
-
- MFILE_CAPACITY_AT_PTR_OK_OR_FAIL(MFILE_DATA(inf) + ((4 * 2) * tablen));
-
- readtab(inf, starttab, tablen);
- readtab(inf, lengthtab, tablen);
-
- /* check data order */
- cur = 0;
- badorder = 0;
- for (size_t y = 0; y < ysize; y++) {
- for (size_t z = 0; z < zsize; z++) {
- if (starttab[y + z * ysize] < cur) {
- badorder = 1;
- break;
- }
- cur = starttab[y + z * ysize];
- }
- if (badorder)
- break;
- }
-
- if (bpp == 1) {
-
- ibuf = IMB_allocImBuf(xsize, ysize, 8 * zsize, IB_rect);
- if (!ibuf) {
- goto fail_rle;
- }
- if (ibuf->planes > 32) ibuf->planes = 32;
- base = ibuf->rect;
- zbase = (uint *)ibuf->zbuf;
-
- if (badorder) {
- for (size_t z = 0; z < zsize; z++) {
- lptr = base;
- for (size_t y = 0; y < ysize; y++) {
- MFILE_SEEK(inf, starttab[y + z * ysize]);
- rledat = MFILE_DATA(inf);
- MFILE_STEP(inf, lengthtab[y + z * ysize]);
- const uchar *rledat_next = MFILE_DATA(inf);
- uint *lptr_next = lptr + xsize;
- MFILE_CAPACITY_AT_PTR_OK_OR_FAIL(rledat_next);
- dirty_flag |= expandrow((uchar *)lptr, (uchar *)lptr_next, rledat, rledat_next, 3 - z);
- lptr = lptr_next;
- }
- }
- }
- else {
- lptr = base;
- zptr = zbase;
- for (size_t y = 0; y < ysize; y++) {
-
- uint *lptr_next = lptr + xsize;
- uint *zptr_next = zptr + xsize;
-
- for (size_t z = 0; z < zsize; z++) {
- MFILE_SEEK(inf, starttab[y + z * ysize]);
- rledat = MFILE_DATA(inf);
- MFILE_STEP(inf, lengthtab[y + z * ysize]);
- const uchar *rledat_next = MFILE_DATA(inf);
- MFILE_CAPACITY_AT_PTR_OK_OR_FAIL(rledat_next);
- if (z < 4) {
- dirty_flag |= expandrow((uchar *)lptr, (uchar *)lptr_next, rledat, rledat_next, 3 - z);
- }
- else if (z < 8) {
- dirty_flag |= expandrow((uchar *)zptr, (uchar *)zptr_next, rledat, rledat_next, 7 - z);
- }
- }
- lptr = lptr_next;
- zptr = zptr_next;
- }
- }
-
-
- }
- else { /* bpp == 2 */
-
- ibuf = IMB_allocImBuf(xsize, ysize, 32, (flags & IB_rect) | IB_rectfloat);
- if (!ibuf) {
- goto fail_rle;
- }
-
- fbase = ibuf->rect_float;
-
- if (badorder) {
- for (size_t z = 0; z < zsize; z++) {
- fptr = fbase;
- for (size_t y = 0; y < ysize; y++) {
- MFILE_SEEK(inf, starttab[y + z * ysize]);
- rledat = MFILE_DATA(inf);
- MFILE_STEP(inf, lengthtab[y + z * ysize]);
- const uchar *rledat_next = MFILE_DATA(inf);
- MFILE_CAPACITY_AT_PTR_OK_OR_FAIL(rledat_next);
- float *fptr_next = fptr + (xsize * 4);
- dirty_flag |= expandrow2(fptr, fptr_next, rledat, rledat_next, 3 - z);
- fptr = fptr_next;
- }
- }
- }
- else {
- fptr = fbase;
- float *fptr_next = fptr + (xsize * 4);
-
- for (size_t y = 0; y < ysize; y++) {
-
- for (size_t z = 0; z < zsize; z++) {
- MFILE_SEEK(inf, starttab[y + z * ysize]);
- rledat = MFILE_DATA(inf);
- MFILE_STEP(inf, lengthtab[y + z * ysize]);
- const uchar *rledat_next = MFILE_DATA(inf);
- MFILE_CAPACITY_AT_PTR_OK_OR_FAIL(rledat_next);
- dirty_flag |= expandrow2(fptr, fptr_next, rledat, rledat_next, 3 - z);
- }
- fptr = fptr_next;
- }
- }
- }
+ if (UNLIKELY((p) > mem_end)) { \
+ dirty_flag |= DIRTY_FLAG_EOF; \
+ goto fail_rle; \
+ } \
+ ((void)0)
+
+ MFILE_CAPACITY_AT_PTR_OK_OR_FAIL(MFILE_DATA(inf) + ((4 * 2) * tablen));
+
+ readtab(inf, starttab, tablen);
+ readtab(inf, lengthtab, tablen);
+
+ /* check data order */
+ cur = 0;
+ badorder = 0;
+ for (size_t y = 0; y < ysize; y++) {
+ for (size_t z = 0; z < zsize; z++) {
+ if (starttab[y + z * ysize] < cur) {
+ badorder = 1;
+ break;
+ }
+ cur = starttab[y + z * ysize];
+ }
+ if (badorder)
+ break;
+ }
+
+ if (bpp == 1) {
+
+ ibuf = IMB_allocImBuf(xsize, ysize, 8 * zsize, IB_rect);
+ if (!ibuf) {
+ goto fail_rle;
+ }
+ if (ibuf->planes > 32)
+ ibuf->planes = 32;
+ base = ibuf->rect;
+ zbase = (uint *)ibuf->zbuf;
+
+ if (badorder) {
+ for (size_t z = 0; z < zsize; z++) {
+ lptr = base;
+ for (size_t y = 0; y < ysize; y++) {
+ MFILE_SEEK(inf, starttab[y + z * ysize]);
+ rledat = MFILE_DATA(inf);
+ MFILE_STEP(inf, lengthtab[y + z * ysize]);
+ const uchar *rledat_next = MFILE_DATA(inf);
+ uint *lptr_next = lptr + xsize;
+ MFILE_CAPACITY_AT_PTR_OK_OR_FAIL(rledat_next);
+ dirty_flag |= expandrow((uchar *)lptr, (uchar *)lptr_next, rledat, rledat_next, 3 - z);
+ lptr = lptr_next;
+ }
+ }
+ }
+ else {
+ lptr = base;
+ zptr = zbase;
+ for (size_t y = 0; y < ysize; y++) {
+
+ uint *lptr_next = lptr + xsize;
+ uint *zptr_next = zptr + xsize;
+
+ for (size_t z = 0; z < zsize; z++) {
+ MFILE_SEEK(inf, starttab[y + z * ysize]);
+ rledat = MFILE_DATA(inf);
+ MFILE_STEP(inf, lengthtab[y + z * ysize]);
+ const uchar *rledat_next = MFILE_DATA(inf);
+ MFILE_CAPACITY_AT_PTR_OK_OR_FAIL(rledat_next);
+ if (z < 4) {
+ dirty_flag |= expandrow(
+ (uchar *)lptr, (uchar *)lptr_next, rledat, rledat_next, 3 - z);
+ }
+ else if (z < 8) {
+ dirty_flag |= expandrow(
+ (uchar *)zptr, (uchar *)zptr_next, rledat, rledat_next, 7 - z);
+ }
+ }
+ lptr = lptr_next;
+ zptr = zptr_next;
+ }
+ }
+ }
+ else { /* bpp == 2 */
+
+ ibuf = IMB_allocImBuf(xsize, ysize, 32, (flags & IB_rect) | IB_rectfloat);
+ if (!ibuf) {
+ goto fail_rle;
+ }
+
+ fbase = ibuf->rect_float;
+
+ if (badorder) {
+ for (size_t z = 0; z < zsize; z++) {
+ fptr = fbase;
+ for (size_t y = 0; y < ysize; y++) {
+ MFILE_SEEK(inf, starttab[y + z * ysize]);
+ rledat = MFILE_DATA(inf);
+ MFILE_STEP(inf, lengthtab[y + z * ysize]);
+ const uchar *rledat_next = MFILE_DATA(inf);
+ MFILE_CAPACITY_AT_PTR_OK_OR_FAIL(rledat_next);
+ float *fptr_next = fptr + (xsize * 4);
+ dirty_flag |= expandrow2(fptr, fptr_next, rledat, rledat_next, 3 - z);
+ fptr = fptr_next;
+ }
+ }
+ }
+ else {
+ fptr = fbase;
+ float *fptr_next = fptr + (xsize * 4);
+
+ for (size_t y = 0; y < ysize; y++) {
+
+ for (size_t z = 0; z < zsize; z++) {
+ MFILE_SEEK(inf, starttab[y + z * ysize]);
+ rledat = MFILE_DATA(inf);
+ MFILE_STEP(inf, lengthtab[y + z * ysize]);
+ const uchar *rledat_next = MFILE_DATA(inf);
+ MFILE_CAPACITY_AT_PTR_OK_OR_FAIL(rledat_next);
+ dirty_flag |= expandrow2(fptr, fptr_next, rledat, rledat_next, 3 - z);
+ }
+ fptr = fptr_next;
+ }
+ }
+ }
#undef MFILE_CAPACITY_AT_PTR_OK_OR_FAIL
-fail_rle:
- MEM_freeN(starttab);
- MEM_freeN(lengthtab);
+ fail_rle:
+ MEM_freeN(starttab);
+ MEM_freeN(lengthtab);
- if (!ibuf) {
- return NULL;
- }
- }
- else {
+ if (!ibuf) {
+ return NULL;
+ }
+ }
+ else {
#define MFILE_CAPACITY_AT_PTR_OK_OR_FAIL(p) \
- if (UNLIKELY((p) > mem_end)) { dirty_flag |= DIRTY_FLAG_EOF; goto fail_uncompressed; } ((void)0)
-
- if (bpp == 1) {
-
- ibuf = IMB_allocImBuf(xsize, ysize, 8 * zsize, IB_rect);
- if (!ibuf) {
- goto fail_uncompressed;
- }
- if (ibuf->planes > 32) ibuf->planes = 32;
-
- base = ibuf->rect;
- zbase = (uint *)ibuf->zbuf;
-
- MFILE_SEEK(inf, HEADER_SIZE);
- rledat = MFILE_DATA(inf);
-
- for (size_t z = 0; z < zsize; z++) {
-
- if (z < 4) lptr = base;
- else if (z < 8) lptr = zbase;
-
- for (size_t y = 0; y < ysize; y++) {
- const uchar *rledat_next = rledat + xsize;
- const int z_ofs = 3 - z;
- MFILE_CAPACITY_AT_PTR_OK_OR_FAIL(rledat_next + z_ofs);
- interleaverow((uchar *)lptr, rledat, z_ofs, xsize);
- rledat = rledat_next;
- lptr += xsize;
- }
- }
-
- }
- else { /* bpp == 2 */
-
- ibuf = IMB_allocImBuf(xsize, ysize, 32, (flags & IB_rect) | IB_rectfloat);
- if (!ibuf) {
- goto fail_uncompressed;
- }
-
- fbase = ibuf->rect_float;
-
- MFILE_SEEK(inf, HEADER_SIZE);
- rledat = MFILE_DATA(inf);
-
- for (size_t z = 0; z < zsize; z++) {
-
- fptr = fbase;
-
- for (size_t y = 0; y < ysize; y++) {
- const uchar *rledat_next = rledat + xsize * 2;
- const int z_ofs = 3 - z;
- MFILE_CAPACITY_AT_PTR_OK_OR_FAIL(rledat_next + z_ofs);
- interleaverow2(fptr, rledat, z_ofs, xsize);
- rledat = rledat_next;
- fptr += xsize * 4;
- }
- }
-
- }
+ if (UNLIKELY((p) > mem_end)) { \
+ dirty_flag |= DIRTY_FLAG_EOF; \
+ goto fail_uncompressed; \
+ } \
+ ((void)0)
+
+ if (bpp == 1) {
+
+ ibuf = IMB_allocImBuf(xsize, ysize, 8 * zsize, IB_rect);
+ if (!ibuf) {
+ goto fail_uncompressed;
+ }
+ if (ibuf->planes > 32)
+ ibuf->planes = 32;
+
+ base = ibuf->rect;
+ zbase = (uint *)ibuf->zbuf;
+
+ MFILE_SEEK(inf, HEADER_SIZE);
+ rledat = MFILE_DATA(inf);
+
+ for (size_t z = 0; z < zsize; z++) {
+
+ if (z < 4)
+ lptr = base;
+ else if (z < 8)
+ lptr = zbase;
+
+ for (size_t y = 0; y < ysize; y++) {
+ const uchar *rledat_next = rledat + xsize;
+ const int z_ofs = 3 - z;
+ MFILE_CAPACITY_AT_PTR_OK_OR_FAIL(rledat_next + z_ofs);
+ interleaverow((uchar *)lptr, rledat, z_ofs, xsize);
+ rledat = rledat_next;
+ lptr += xsize;
+ }
+ }
+ }
+ else { /* bpp == 2 */
+
+ ibuf = IMB_allocImBuf(xsize, ysize, 32, (flags & IB_rect) | IB_rectfloat);
+ if (!ibuf) {
+ goto fail_uncompressed;
+ }
+
+ fbase = ibuf->rect_float;
+
+ MFILE_SEEK(inf, HEADER_SIZE);
+ rledat = MFILE_DATA(inf);
+
+ for (size_t z = 0; z < zsize; z++) {
+
+ fptr = fbase;
+
+ for (size_t y = 0; y < ysize; y++) {
+ const uchar *rledat_next = rledat + xsize * 2;
+ const int z_ofs = 3 - z;
+ MFILE_CAPACITY_AT_PTR_OK_OR_FAIL(rledat_next + z_ofs);
+ interleaverow2(fptr, rledat, z_ofs, xsize);
+ rledat = rledat_next;
+ fptr += xsize * 4;
+ }
+ }
+ }
#undef MFILE_CAPACITY_AT_PTR_OK_OR_FAIL
-fail_uncompressed:
- if (!ibuf) {
- return NULL;
- }
- }
-
- if (bpp == 1) {
- uchar *rect;
-
- if (image.zsize == 1) {
- rect = (uchar *) ibuf->rect;
- for (size_t x = (size_t)ibuf->x * (size_t)ibuf->y; x > 0; x--) {
- rect[0] = 255;
- rect[1] = rect[2] = rect[3];
- rect += 4;
- }
- }
- else if (image.zsize == 2) {
- /* grayscale with alpha */
- rect = (uchar *) ibuf->rect;
- for (size_t x = (size_t)ibuf->x * (size_t)ibuf->y; x > 0; x--) {
- rect[0] = rect[2];
- rect[1] = rect[2] = rect[3];
- rect += 4;
- }
- }
- else if (image.zsize == 3) {
- /* add alpha */
- rect = (uchar *) ibuf->rect;
- for (size_t x = (size_t)ibuf->x * (size_t)ibuf->y; x > 0; x--) {
- rect[0] = 255;
- rect += 4;
- }
- }
-
- }
- else { /* bpp == 2 */
-
- if (image.zsize == 1) {
- fbase = ibuf->rect_float;
- for (size_t x = (size_t)ibuf->x * (size_t)ibuf->y; x > 0; x--) {
- fbase[0] = 1;
- fbase[1] = fbase[2] = fbase[3];
- fbase += 4;
- }
- }
- else if (image.zsize == 2) {
- /* grayscale with alpha */
- fbase = ibuf->rect_float;
- for (size_t x = (size_t)ibuf->x * (size_t)ibuf->y; x > 0; x--) {
- fbase[0] = fbase[2];
- fbase[1] = fbase[2] = fbase[3];
- fbase += 4;
- }
- }
- else if (image.zsize == 3) {
- /* add alpha */
- fbase = ibuf->rect_float;
- for (size_t x = (size_t)ibuf->x * (size_t)ibuf->y; x > 0; x--) {
- fbase[0] = 1;
- fbase += 4;
- }
- }
-
- if (flags & IB_rect) {
- IMB_rect_from_float(ibuf);
- }
-
- }
-
- if (dirty_flag) {
- fprintf(stderr, "longimagedata: corrupt file content (%d)\n", dirty_flag);
- }
- ibuf->ftype = IMB_FTYPE_IMAGIC;
-
- test_endian_zbuf(ibuf);
-
- if (ibuf->rect) {
- IMB_convert_rgba_to_abgr(ibuf);
- }
-
- return(ibuf);
+ fail_uncompressed:
+ if (!ibuf) {
+ return NULL;
+ }
+ }
+
+ if (bpp == 1) {
+ uchar *rect;
+
+ if (image.zsize == 1) {
+ rect = (uchar *)ibuf->rect;
+ for (size_t x = (size_t)ibuf->x * (size_t)ibuf->y; x > 0; x--) {
+ rect[0] = 255;
+ rect[1] = rect[2] = rect[3];
+ rect += 4;
+ }
+ }
+ else if (image.zsize == 2) {
+ /* grayscale with alpha */
+ rect = (uchar *)ibuf->rect;
+ for (size_t x = (size_t)ibuf->x * (size_t)ibuf->y; x > 0; x--) {
+ rect[0] = rect[2];
+ rect[1] = rect[2] = rect[3];
+ rect += 4;
+ }
+ }
+ else if (image.zsize == 3) {
+ /* add alpha */
+ rect = (uchar *)ibuf->rect;
+ for (size_t x = (size_t)ibuf->x * (size_t)ibuf->y; x > 0; x--) {
+ rect[0] = 255;
+ rect += 4;
+ }
+ }
+ }
+ else { /* bpp == 2 */
+
+ if (image.zsize == 1) {
+ fbase = ibuf->rect_float;
+ for (size_t x = (size_t)ibuf->x * (size_t)ibuf->y; x > 0; x--) {
+ fbase[0] = 1;
+ fbase[1] = fbase[2] = fbase[3];
+ fbase += 4;
+ }
+ }
+ else if (image.zsize == 2) {
+ /* grayscale with alpha */
+ fbase = ibuf->rect_float;
+ for (size_t x = (size_t)ibuf->x * (size_t)ibuf->y; x > 0; x--) {
+ fbase[0] = fbase[2];
+ fbase[1] = fbase[2] = fbase[3];
+ fbase += 4;
+ }
+ }
+ else if (image.zsize == 3) {
+ /* add alpha */
+ fbase = ibuf->rect_float;
+ for (size_t x = (size_t)ibuf->x * (size_t)ibuf->y; x > 0; x--) {
+ fbase[0] = 1;
+ fbase += 4;
+ }
+ }
+
+ if (flags & IB_rect) {
+ IMB_rect_from_float(ibuf);
+ }
+ }
+
+ if (dirty_flag) {
+ fprintf(stderr, "longimagedata: corrupt file content (%d)\n", dirty_flag);
+ }
+ ibuf->ftype = IMB_FTYPE_IMAGIC;
+
+ test_endian_zbuf(ibuf);
+
+ if (ibuf->rect) {
+ IMB_convert_rgba_to_abgr(ibuf);
+ }
+
+ return (ibuf);
}
/* static utility functions for longimagedata */
static void interleaverow(uchar *lptr, const uchar *cptr, int z, int n)
{
- lptr += z;
- while (n--) {
- *lptr = *cptr++;
- lptr += 4;
- }
+ lptr += z;
+ while (n--) {
+ *lptr = *cptr++;
+ lptr += 4;
+ }
}
static void interleaverow2(float *lptr, const uchar *cptr, int z, int n)
{
- lptr += z;
- while (n--) {
- *lptr = ((cptr[0] << 8) | (cptr[1] << 0)) / (float)0xFFFF;
- cptr += 2;
- lptr += 4;
- }
+ lptr += z;
+ while (n--) {
+ *lptr = ((cptr[0] << 8) | (cptr[1] << 0)) / (float)0xFFFF;
+ cptr += 2;
+ lptr += 4;
+ }
}
static int expandrow2(
- float *optr, const float *optr_end,
- const uchar *iptr, const uchar *iptr_end, int z)
+ float *optr, const float *optr_end, const uchar *iptr, const uchar *iptr_end, int z)
{
- ushort pixel, count;
- float pixel_f;
+ ushort pixel, count;
+ float pixel_f;
#define EXPAND_CAPACITY_AT_INPUT_OK_OR_FAIL(iptr_next) \
- if (UNLIKELY(iptr_next > iptr_end)) { goto fail; } ((void)0)
+ if (UNLIKELY(iptr_next > iptr_end)) { \
+ goto fail; \
+ } \
+ ((void)0)
#define EXPAND_CAPACITY_AT_OUTPUT_OK_OR_FAIL(optr_next) \
- if (UNLIKELY(optr_next > optr_end)) { goto fail; } ((void)0)
-
- optr += z;
- optr_end += z;
- while (1) {
- const uchar *iptr_next = iptr + 2;
- EXPAND_CAPACITY_AT_INPUT_OK_OR_FAIL(iptr_next);
- pixel = (iptr[0] << 8) | (iptr[1] << 0);
- iptr = iptr_next;
-
- if (!(count = (pixel & 0x7f)) )
- return false;
- const float *optr_next = optr + count;
- EXPAND_CAPACITY_AT_OUTPUT_OK_OR_FAIL(optr_next);
- if (pixel & 0x80) {
- iptr_next = iptr + (count * 2);
- EXPAND_CAPACITY_AT_INPUT_OK_OR_FAIL(iptr_next);
- while (count >= 8) {
- optr[0 * 4] = ((iptr[0] << 8) | (iptr[1] << 0)) / (float)0xFFFF;
- optr[1 * 4] = ((iptr[2] << 8) | (iptr[3] << 0)) / (float)0xFFFF;
- optr[2 * 4] = ((iptr[4] << 8) | (iptr[5] << 0)) / (float)0xFFFF;
- optr[3 * 4] = ((iptr[6] << 8) | (iptr[7] << 0)) / (float)0xFFFF;
- optr[4 * 4] = ((iptr[8] << 8) | (iptr[9] << 0)) / (float)0xFFFF;
- optr[5 * 4] = ((iptr[10] << 8) | (iptr[11] << 0)) / (float)0xFFFF;
- optr[6 * 4] = ((iptr[12] << 8) | (iptr[13] << 0)) / (float)0xFFFF;
- optr[7 * 4] = ((iptr[14] << 8) | (iptr[15] << 0)) / (float)0xFFFF;
- optr += 8 * 4;
- iptr += 8 * 2;
- count -= 8;
- }
- while (count--) {
- *optr = ((iptr[0] << 8) | (iptr[1] << 0)) / (float)0xFFFF;
- iptr += 2;
- optr += 4;
- }
- BLI_assert(iptr == iptr_next);
- }
- else {
- iptr_next = iptr + 2;
- EXPAND_CAPACITY_AT_INPUT_OK_OR_FAIL(iptr_next);
- pixel_f = ((iptr[0] << 8) | (iptr[1] << 0)) / (float)0xFFFF;
- iptr = iptr_next;
-
- while (count >= 8) {
- optr[0 * 4] = pixel_f;
- optr[1 * 4] = pixel_f;
- optr[2 * 4] = pixel_f;
- optr[3 * 4] = pixel_f;
- optr[4 * 4] = pixel_f;
- optr[5 * 4] = pixel_f;
- optr[6 * 4] = pixel_f;
- optr[7 * 4] = pixel_f;
- optr += 8 * 4;
- count -= 8;
- }
- while (count--) {
- *optr = pixel_f;
- optr += 4;
- }
- BLI_assert(iptr == iptr_next);
- }
- BLI_assert(optr == optr_next);
- }
- return false;
+ if (UNLIKELY(optr_next > optr_end)) { \
+ goto fail; \
+ } \
+ ((void)0)
+
+ optr += z;
+ optr_end += z;
+ while (1) {
+ const uchar *iptr_next = iptr + 2;
+ EXPAND_CAPACITY_AT_INPUT_OK_OR_FAIL(iptr_next);
+ pixel = (iptr[0] << 8) | (iptr[1] << 0);
+ iptr = iptr_next;
+
+ if (!(count = (pixel & 0x7f)))
+ return false;
+ const float *optr_next = optr + count;
+ EXPAND_CAPACITY_AT_OUTPUT_OK_OR_FAIL(optr_next);
+ if (pixel & 0x80) {
+ iptr_next = iptr + (count * 2);
+ EXPAND_CAPACITY_AT_INPUT_OK_OR_FAIL(iptr_next);
+ while (count >= 8) {
+ optr[0 * 4] = ((iptr[0] << 8) | (iptr[1] << 0)) / (float)0xFFFF;
+ optr[1 * 4] = ((iptr[2] << 8) | (iptr[3] << 0)) / (float)0xFFFF;
+ optr[2 * 4] = ((iptr[4] << 8) | (iptr[5] << 0)) / (float)0xFFFF;
+ optr[3 * 4] = ((iptr[6] << 8) | (iptr[7] << 0)) / (float)0xFFFF;
+ optr[4 * 4] = ((iptr[8] << 8) | (iptr[9] << 0)) / (float)0xFFFF;
+ optr[5 * 4] = ((iptr[10] << 8) | (iptr[11] << 0)) / (float)0xFFFF;
+ optr[6 * 4] = ((iptr[12] << 8) | (iptr[13] << 0)) / (float)0xFFFF;
+ optr[7 * 4] = ((iptr[14] << 8) | (iptr[15] << 0)) / (float)0xFFFF;
+ optr += 8 * 4;
+ iptr += 8 * 2;
+ count -= 8;
+ }
+ while (count--) {
+ *optr = ((iptr[0] << 8) | (iptr[1] << 0)) / (float)0xFFFF;
+ iptr += 2;
+ optr += 4;
+ }
+ BLI_assert(iptr == iptr_next);
+ }
+ else {
+ iptr_next = iptr + 2;
+ EXPAND_CAPACITY_AT_INPUT_OK_OR_FAIL(iptr_next);
+ pixel_f = ((iptr[0] << 8) | (iptr[1] << 0)) / (float)0xFFFF;
+ iptr = iptr_next;
+
+ while (count >= 8) {
+ optr[0 * 4] = pixel_f;
+ optr[1 * 4] = pixel_f;
+ optr[2 * 4] = pixel_f;
+ optr[3 * 4] = pixel_f;
+ optr[4 * 4] = pixel_f;
+ optr[5 * 4] = pixel_f;
+ optr[6 * 4] = pixel_f;
+ optr[7 * 4] = pixel_f;
+ optr += 8 * 4;
+ count -= 8;
+ }
+ while (count--) {
+ *optr = pixel_f;
+ optr += 4;
+ }
+ BLI_assert(iptr == iptr_next);
+ }
+ BLI_assert(optr == optr_next);
+ }
+ return false;
#undef EXPAND_CAPACITY_AT_INPUT_OK_OR_FAIL
#undef EXPAND_CAPACITY_AT_OUTPUT_OK_OR_FAIL
fail:
- return DIRTY_FLAG_ENCODING;
+ return DIRTY_FLAG_ENCODING;
}
static int expandrow(
- uchar *optr, const uchar *optr_end,
- const uchar *iptr, const uchar *iptr_end, int z)
+ uchar *optr, const uchar *optr_end, const uchar *iptr, const uchar *iptr_end, int z)
{
- uchar pixel, count;
+ uchar pixel, count;
#define EXPAND_CAPACITY_AT_INPUT_OK_OR_FAIL(iptr_next) \
- if (UNLIKELY(iptr_next > iptr_end)) { goto fail; } ((void)0)
+ if (UNLIKELY(iptr_next > iptr_end)) { \
+ goto fail; \
+ } \
+ ((void)0)
#define EXPAND_CAPACITY_AT_OUTPUT_OK_OR_FAIL(optr_next) \
- if (UNLIKELY(optr_next > optr_end)) { goto fail; } ((void)0)
-
- optr += z;
- optr_end += z;
- while (1) {
- const uchar *iptr_next = iptr + 1;
- EXPAND_CAPACITY_AT_INPUT_OK_OR_FAIL(iptr_next);
- pixel = *iptr;
- iptr = iptr_next;
- if (!(count = (pixel & 0x7f)) )
- return false;
- const uchar *optr_next = optr + ((int)count * 4);
- EXPAND_CAPACITY_AT_OUTPUT_OK_OR_FAIL(optr_next);
-
- if (pixel & 0x80) {
- iptr_next = iptr + count;
- EXPAND_CAPACITY_AT_INPUT_OK_OR_FAIL(iptr_next);
- while (count >= 8) {
- optr[0 * 4] = iptr[0];
- optr[1 * 4] = iptr[1];
- optr[2 * 4] = iptr[2];
- optr[3 * 4] = iptr[3];
- optr[4 * 4] = iptr[4];
- optr[5 * 4] = iptr[5];
- optr[6 * 4] = iptr[6];
- optr[7 * 4] = iptr[7];
- optr += 8 * 4;
- iptr += 8;
- count -= 8;
- }
- while (count--) {
- *optr = *iptr++;
- optr += 4;
- }
- BLI_assert(iptr == iptr_next);
- }
- else {
- iptr_next = iptr + 1;
- EXPAND_CAPACITY_AT_INPUT_OK_OR_FAIL(iptr_next);
- pixel = *iptr++;
- while (count >= 8) {
- optr[0 * 4] = pixel;
- optr[1 * 4] = pixel;
- optr[2 * 4] = pixel;
- optr[3 * 4] = pixel;
- optr[4 * 4] = pixel;
- optr[5 * 4] = pixel;
- optr[6 * 4] = pixel;
- optr[7 * 4] = pixel;
- optr += 8 * 4;
- count -= 8;
- }
- while (count--) {
- *optr = pixel;
- optr += 4;
- }
- BLI_assert(iptr == iptr_next);
- }
- BLI_assert(optr == optr_next);
- }
-
- return false;
+ if (UNLIKELY(optr_next > optr_end)) { \
+ goto fail; \
+ } \
+ ((void)0)
+
+ optr += z;
+ optr_end += z;
+ while (1) {
+ const uchar *iptr_next = iptr + 1;
+ EXPAND_CAPACITY_AT_INPUT_OK_OR_FAIL(iptr_next);
+ pixel = *iptr;
+ iptr = iptr_next;
+ if (!(count = (pixel & 0x7f)))
+ return false;
+ const uchar *optr_next = optr + ((int)count * 4);
+ EXPAND_CAPACITY_AT_OUTPUT_OK_OR_FAIL(optr_next);
+
+ if (pixel & 0x80) {
+ iptr_next = iptr + count;
+ EXPAND_CAPACITY_AT_INPUT_OK_OR_FAIL(iptr_next);
+ while (count >= 8) {
+ optr[0 * 4] = iptr[0];
+ optr[1 * 4] = iptr[1];
+ optr[2 * 4] = iptr[2];
+ optr[3 * 4] = iptr[3];
+ optr[4 * 4] = iptr[4];
+ optr[5 * 4] = iptr[5];
+ optr[6 * 4] = iptr[6];
+ optr[7 * 4] = iptr[7];
+ optr += 8 * 4;
+ iptr += 8;
+ count -= 8;
+ }
+ while (count--) {
+ *optr = *iptr++;
+ optr += 4;
+ }
+ BLI_assert(iptr == iptr_next);
+ }
+ else {
+ iptr_next = iptr + 1;
+ EXPAND_CAPACITY_AT_INPUT_OK_OR_FAIL(iptr_next);
+ pixel = *iptr++;
+ while (count >= 8) {
+ optr[0 * 4] = pixel;
+ optr[1 * 4] = pixel;
+ optr[2 * 4] = pixel;
+ optr[3 * 4] = pixel;
+ optr[4 * 4] = pixel;
+ optr[5 * 4] = pixel;
+ optr[6 * 4] = pixel;
+ optr[7 * 4] = pixel;
+ optr += 8 * 4;
+ count -= 8;
+ }
+ while (count--) {
+ *optr = pixel;
+ optr += 4;
+ }
+ BLI_assert(iptr == iptr_next);
+ }
+ BLI_assert(optr == optr_next);
+ }
+
+ return false;
#undef EXPAND_CAPACITY_AT_INPUT_OK_OR_FAIL
#undef EXPAND_CAPACITY_AT_OUTPUT_OK_OR_FAIL
fail:
- return DIRTY_FLAG_ENCODING;
+ return DIRTY_FLAG_ENCODING;
}
/**
@@ -769,174 +799,177 @@ fail:
static int output_iris(uint *lptr, int xsize, int ysize, int zsize, const char *name, int *zptr)
{
- FILE *outf;
- IMAGE *image;
- int tablen, y, z, pos, len = 0;
- uint *starttab, *lengthtab;
- uchar *rlebuf;
- uint *lumbuf;
- int rlebuflen, goodwrite;
-
- goodwrite = 1;
- outf = BLI_fopen(name, "wb");
- if (!outf) return 0;
-
- tablen = ysize * zsize * sizeof(int);
-
- image = (IMAGE *)MEM_mallocN(sizeof(IMAGE), "iris image");
- starttab = (uint *)MEM_mallocN(tablen, "iris starttab");
- lengthtab = (uint *)MEM_mallocN(tablen, "iris lengthtab");
- rlebuflen = 1.05 * xsize + 10;
- rlebuf = (uchar *)MEM_mallocN(rlebuflen, "iris rlebuf");
- lumbuf = (uint *)MEM_mallocN(xsize * sizeof(int), "iris lumbuf");
-
- memset(image, 0, sizeof(IMAGE));
- image->imagic = IMAGIC;
- image->type = RLE(1);
- if (zsize > 1)
- image->dim = 3;
- else
- image->dim = 2;
- image->xsize = xsize;
- image->ysize = ysize;
- image->zsize = zsize;
- image->min = 0;
- image->max = 255;
- goodwrite *= writeheader(outf, image);
- fseek(outf, HEADER_SIZE + (2 * tablen), SEEK_SET);
- pos = HEADER_SIZE + (2 * tablen);
-
- for (y = 0; y < ysize; y++) {
- for (z = 0; z < zsize; z++) {
-
- if (zsize == 1) {
- lumrow((uchar *)lptr, (uchar *)lumbuf, xsize);
- len = compressrow((uchar *)lumbuf, rlebuf, CHANOFFSET(z), xsize);
- }
- else {
- if (z < 4) {
- len = compressrow((uchar *)lptr, rlebuf, CHANOFFSET(z), xsize);
- }
- else if (z < 8 && zptr) {
- len = compressrow((uchar *)zptr, rlebuf, CHANOFFSET(z - 4), xsize);
- }
- }
- if (len > rlebuflen) {
- fprintf(stderr, "output_iris: rlebuf is too small - bad poop\n");
- exit(1);
- }
- goodwrite *= fwrite(rlebuf, len, 1, outf);
- starttab[y + z * ysize] = pos;
- lengthtab[y + z * ysize] = len;
- pos += len;
- }
- lptr += xsize;
- if (zptr) zptr += xsize;
- }
-
- fseek(outf, HEADER_SIZE, SEEK_SET);
- goodwrite *= writetab(outf, starttab, tablen);
- goodwrite *= writetab(outf, lengthtab, tablen);
- MEM_freeN(image);
- MEM_freeN(starttab);
- MEM_freeN(lengthtab);
- MEM_freeN(rlebuf);
- MEM_freeN(lumbuf);
- fclose(outf);
- if (goodwrite)
- return 1;
- else {
- fprintf(stderr, "output_iris: not enough space for image!!\n");
- return 0;
- }
+ FILE *outf;
+ IMAGE *image;
+ int tablen, y, z, pos, len = 0;
+ uint *starttab, *lengthtab;
+ uchar *rlebuf;
+ uint *lumbuf;
+ int rlebuflen, goodwrite;
+
+ goodwrite = 1;
+ outf = BLI_fopen(name, "wb");
+ if (!outf)
+ return 0;
+
+ tablen = ysize * zsize * sizeof(int);
+
+ image = (IMAGE *)MEM_mallocN(sizeof(IMAGE), "iris image");
+ starttab = (uint *)MEM_mallocN(tablen, "iris starttab");
+ lengthtab = (uint *)MEM_mallocN(tablen, "iris lengthtab");
+ rlebuflen = 1.05 * xsize + 10;
+ rlebuf = (uchar *)MEM_mallocN(rlebuflen, "iris rlebuf");
+ lumbuf = (uint *)MEM_mallocN(xsize * sizeof(int), "iris lumbuf");
+
+ memset(image, 0, sizeof(IMAGE));
+ image->imagic = IMAGIC;
+ image->type = RLE(1);
+ if (zsize > 1)
+ image->dim = 3;
+ else
+ image->dim = 2;
+ image->xsize = xsize;
+ image->ysize = ysize;
+ image->zsize = zsize;
+ image->min = 0;
+ image->max = 255;
+ goodwrite *= writeheader(outf, image);
+ fseek(outf, HEADER_SIZE + (2 * tablen), SEEK_SET);
+ pos = HEADER_SIZE + (2 * tablen);
+
+ for (y = 0; y < ysize; y++) {
+ for (z = 0; z < zsize; z++) {
+
+ if (zsize == 1) {
+ lumrow((uchar *)lptr, (uchar *)lumbuf, xsize);
+ len = compressrow((uchar *)lumbuf, rlebuf, CHANOFFSET(z), xsize);
+ }
+ else {
+ if (z < 4) {
+ len = compressrow((uchar *)lptr, rlebuf, CHANOFFSET(z), xsize);
+ }
+ else if (z < 8 && zptr) {
+ len = compressrow((uchar *)zptr, rlebuf, CHANOFFSET(z - 4), xsize);
+ }
+ }
+ if (len > rlebuflen) {
+ fprintf(stderr, "output_iris: rlebuf is too small - bad poop\n");
+ exit(1);
+ }
+ goodwrite *= fwrite(rlebuf, len, 1, outf);
+ starttab[y + z * ysize] = pos;
+ lengthtab[y + z * ysize] = len;
+ pos += len;
+ }
+ lptr += xsize;
+ if (zptr)
+ zptr += xsize;
+ }
+
+ fseek(outf, HEADER_SIZE, SEEK_SET);
+ goodwrite *= writetab(outf, starttab, tablen);
+ goodwrite *= writetab(outf, lengthtab, tablen);
+ MEM_freeN(image);
+ MEM_freeN(starttab);
+ MEM_freeN(lengthtab);
+ MEM_freeN(rlebuf);
+ MEM_freeN(lumbuf);
+ fclose(outf);
+ if (goodwrite)
+ return 1;
+ else {
+ fprintf(stderr, "output_iris: not enough space for image!!\n");
+ return 0;
+ }
}
/* static utility functions for output_iris */
static void lumrow(uchar *rgbptr, uchar *lumptr, int n)
{
- lumptr += CHANOFFSET(0);
- while (n--) {
- *lumptr = ILUM(rgbptr[OFFSET_R], rgbptr[OFFSET_G], rgbptr[OFFSET_B]);
- lumptr += 4;
- rgbptr += 4;
- }
+ lumptr += CHANOFFSET(0);
+ while (n--) {
+ *lumptr = ILUM(rgbptr[OFFSET_R], rgbptr[OFFSET_G], rgbptr[OFFSET_B]);
+ lumptr += 4;
+ rgbptr += 4;
+ }
}
static int compressrow(uchar *lbuf, uchar *rlebuf, int z, int cnt)
{
- uchar *iptr, *ibufend, *sptr, *optr;
- short todo, cc;
- int count;
-
- lbuf += z;
- iptr = lbuf;
- ibufend = iptr + cnt * 4;
- optr = rlebuf;
-
- while (iptr < ibufend) {
- sptr = iptr;
- iptr += 8;
- while ((iptr < ibufend) && ((iptr[-8] != iptr[-4]) || (iptr[-4] != iptr[0])))
- iptr += 4;
- iptr -= 8;
- count = (iptr - sptr) / 4;
- while (count) {
- todo = count > 126 ? 126 : count;
- count -= todo;
- *optr++ = 0x80 | todo;
- while (todo > 8) {
- optr[0] = sptr[0 * 4];
- optr[1] = sptr[1 * 4];
- optr[2] = sptr[2 * 4];
- optr[3] = sptr[3 * 4];
- optr[4] = sptr[4 * 4];
- optr[5] = sptr[5 * 4];
- optr[6] = sptr[6 * 4];
- optr[7] = sptr[7 * 4];
-
- optr += 8;
- sptr += 8 * 4;
- todo -= 8;
- }
- while (todo--) {
- *optr++ = *sptr;
- sptr += 4;
- }
- }
- sptr = iptr;
- cc = *iptr;
- iptr += 4;
- while ( (iptr < ibufend) && (*iptr == cc) )
- iptr += 4;
- count = (iptr - sptr) / 4;
- while (count) {
- todo = count > 126 ? 126 : count;
- count -= todo;
- *optr++ = todo;
- *optr++ = cc;
- }
- }
- *optr++ = 0;
- return optr - (uchar *)rlebuf;
+ uchar *iptr, *ibufend, *sptr, *optr;
+ short todo, cc;
+ int count;
+
+ lbuf += z;
+ iptr = lbuf;
+ ibufend = iptr + cnt * 4;
+ optr = rlebuf;
+
+ while (iptr < ibufend) {
+ sptr = iptr;
+ iptr += 8;
+ while ((iptr < ibufend) && ((iptr[-8] != iptr[-4]) || (iptr[-4] != iptr[0])))
+ iptr += 4;
+ iptr -= 8;
+ count = (iptr - sptr) / 4;
+ while (count) {
+ todo = count > 126 ? 126 : count;
+ count -= todo;
+ *optr++ = 0x80 | todo;
+ while (todo > 8) {
+ optr[0] = sptr[0 * 4];
+ optr[1] = sptr[1 * 4];
+ optr[2] = sptr[2 * 4];
+ optr[3] = sptr[3 * 4];
+ optr[4] = sptr[4 * 4];
+ optr[5] = sptr[5 * 4];
+ optr[6] = sptr[6 * 4];
+ optr[7] = sptr[7 * 4];
+
+ optr += 8;
+ sptr += 8 * 4;
+ todo -= 8;
+ }
+ while (todo--) {
+ *optr++ = *sptr;
+ sptr += 4;
+ }
+ }
+ sptr = iptr;
+ cc = *iptr;
+ iptr += 4;
+ while ((iptr < ibufend) && (*iptr == cc))
+ iptr += 4;
+ count = (iptr - sptr) / 4;
+ while (count) {
+ todo = count > 126 ? 126 : count;
+ count -= todo;
+ *optr++ = todo;
+ *optr++ = cc;
+ }
+ }
+ *optr++ = 0;
+ return optr - (uchar *)rlebuf;
}
int imb_saveiris(struct ImBuf *ibuf, const char *name, int flags)
{
- short zsize;
- int ret;
+ short zsize;
+ int ret;
- zsize = (ibuf->planes + 7) >> 3;
- if (flags & IB_zbuf && ibuf->zbuf != NULL) zsize = 8;
+ zsize = (ibuf->planes + 7) >> 3;
+ if (flags & IB_zbuf && ibuf->zbuf != NULL)
+ zsize = 8;
- IMB_convert_rgba_to_abgr(ibuf);
- test_endian_zbuf(ibuf);
+ IMB_convert_rgba_to_abgr(ibuf);
+ test_endian_zbuf(ibuf);
- ret = output_iris(ibuf->rect, ibuf->x, ibuf->y, zsize, name, ibuf->zbuf);
+ ret = output_iris(ibuf->rect, ibuf->x, ibuf->y, zsize, name, ibuf->zbuf);
- /* restore! Quite clumsy, 2 times a switch... maybe better a malloc ? */
- IMB_convert_rgba_to_abgr(ibuf);
- test_endian_zbuf(ibuf);
+ /* restore! Quite clumsy, 2 times a switch... maybe better a malloc ? */
+ IMB_convert_rgba_to_abgr(ibuf);
+ test_endian_zbuf(ibuf);
- return(ret);
+ return (ret);
}
diff --git a/source/blender/imbuf/intern/jp2.c b/source/blender/imbuf/intern/jp2.c
index aaeb4e4c2ad..4863da8ab18 100644
--- a/source/blender/imbuf/intern/jp2.c
+++ b/source/blender/imbuf/intern/jp2.c
@@ -34,55 +34,56 @@
#define JP2_FILEHEADER_SIZE 12
-static const char JP2_HEAD[] = {0x0, 0x0, 0x0, 0x0C, 0x6A, 0x50, 0x20, 0x20, 0x0D, 0x0A, 0x87, 0x0A};
+static const char JP2_HEAD[] = {
+ 0x0, 0x0, 0x0, 0x0C, 0x6A, 0x50, 0x20, 0x20, 0x0D, 0x0A, 0x87, 0x0A};
static const char J2K_HEAD[] = {0xFF, 0x4F, 0xFF, 0x51, 0x00};
/* We only need this because of how the presets are set */
/* this typedef is copied from 'openjpeg-1.5.0/applications/codec/image_to_j2k.c' */
typedef struct img_folder {
- /** The directory path of the folder containing input images*/
- char *imgdirpath;
- /** Output format*/
- char *out_format;
- /** Enable option*/
- char set_imgdir;
- /** Enable Cod Format for output*/
- char set_out_format;
- /** User specified rate stored in case of cinema option*/
- float *rates;
+ /** The directory path of the folder containing input images*/
+ char *imgdirpath;
+ /** Output format*/
+ char *out_format;
+ /** Enable option*/
+ char set_imgdir;
+ /** Enable Cod Format for output*/
+ char set_out_format;
+ /** User specified rate stored in case of cinema option*/
+ float *rates;
} img_fol_t;
enum {
- DCP_CINEMA2K = 3,
- DCP_CINEMA4K = 4,
+ DCP_CINEMA2K = 3,
+ DCP_CINEMA4K = 4,
};
static bool check_jp2(const unsigned char *mem) /* J2K_CFMT */
{
- return memcmp(JP2_HEAD, mem, sizeof(JP2_HEAD)) ? 0 : 1;
+ return memcmp(JP2_HEAD, mem, sizeof(JP2_HEAD)) ? 0 : 1;
}
static bool check_j2k(const unsigned char *mem) /* J2K_CFMT */
{
- return memcmp(J2K_HEAD, mem, sizeof(J2K_HEAD)) ? 0 : 1;
+ return memcmp(J2K_HEAD, mem, sizeof(J2K_HEAD)) ? 0 : 1;
}
static OPJ_CODEC_FORMAT format_from_header(const unsigned char mem[JP2_FILEHEADER_SIZE])
{
- if (check_jp2(mem)) {
- return OPJ_CODEC_JP2;
- }
- else if (check_j2k(mem)) {
- return OPJ_CODEC_J2K;
- }
- else {
- return OPJ_CODEC_UNKNOWN;
- }
+ if (check_jp2(mem)) {
+ return OPJ_CODEC_JP2;
+ }
+ else if (check_j2k(mem)) {
+ return OPJ_CODEC_J2K;
+ }
+ else {
+ return OPJ_CODEC_UNKNOWN;
+ }
}
int imb_is_a_jp2(const unsigned char *buf)
{
- return check_jp2(buf);
+ return check_jp2(buf);
}
/**
@@ -90,16 +91,16 @@ int imb_is_a_jp2(const unsigned char *buf)
*/
static void error_callback(const char *msg, void *client_data)
{
- FILE *stream = (FILE *)client_data;
- fprintf(stream, "[ERROR] %s", msg);
+ FILE *stream = (FILE *)client_data;
+ fprintf(stream, "[ERROR] %s", msg);
}
/**
* sample warning callback expecting a FILE* client object
*/
static void warning_callback(const char *msg, void *client_data)
{
- FILE *stream = (FILE *)client_data;
- fprintf(stream, "[WARNING] %s", msg);
+ FILE *stream = (FILE *)client_data;
+ fprintf(stream, "[WARNING] %s", msg);
}
#ifdef DEBUG
@@ -108,92 +109,86 @@ static void warning_callback(const char *msg, void *client_data)
*/
static void info_callback(const char *msg, void *client_data)
{
- FILE *stream = (FILE *)client_data;
- fprintf(stream, "[INFO] %s", msg);
+ FILE *stream = (FILE *)client_data;
+ fprintf(stream, "[INFO] %s", msg);
}
#endif
-#define PIXEL_LOOPER_BEGIN(_rect) \
- for (y = h - 1; y != (unsigned int)(-1); y--) { \
- for (i = y * w, i_next = (y + 1) * w; \
- i < i_next; \
- i++, _rect += 4) \
- { \
+#define PIXEL_LOOPER_BEGIN(_rect) \
+ for (y = h - 1; y != (unsigned int)(-1); y--) { \
+ for (i = y * w, i_next = (y + 1) * w; i < i_next; i++, _rect += 4) {
-#define PIXEL_LOOPER_BEGIN_CHANNELS(_rect, _channels) \
- for (y = h - 1; y != (unsigned int)(-1); y--) { \
- for (i = y * w, i_next = (y + 1) * w; \
- i < i_next; \
- i++, _rect += _channels) \
- { \
+#define PIXEL_LOOPER_BEGIN_CHANNELS(_rect, _channels) \
+ for (y = h - 1; y != (unsigned int)(-1); y--) { \
+ for (i = y * w, i_next = (y + 1) * w; i < i_next; i++, _rect += _channels) {
#define PIXEL_LOOPER_END \
- } \
-} (void)0 \
-
+ } \
+ } \
+ (void)0
/** \name Buffer Stream
* \{ */
struct BufInfo {
- const unsigned char *buf;
- const unsigned char *cur;
- OPJ_OFF_T len;
+ const unsigned char *buf;
+ const unsigned char *cur;
+ OPJ_OFF_T len;
};
static void opj_read_from_buffer_free(void *UNUSED(p_user_data))
{
- /* nop */
+ /* nop */
}
static OPJ_SIZE_T opj_read_from_buffer(void *p_buffer, OPJ_SIZE_T p_nb_bytes, void *p_user_data)
{
- struct BufInfo *p_file = p_user_data;
- OPJ_UINT32 l_nb_read;
-
- if (p_file->cur + p_nb_bytes < p_file->buf + p_file->len ) {
- l_nb_read = p_nb_bytes;
- }
- else {
- l_nb_read = (OPJ_UINT32)(p_file->buf + p_file->len - p_file->cur);
- }
- memcpy(p_buffer, p_file->cur, l_nb_read);
- p_file->cur += l_nb_read;
-
- return l_nb_read ? l_nb_read : ((OPJ_SIZE_T)-1);
+ struct BufInfo *p_file = p_user_data;
+ OPJ_UINT32 l_nb_read;
+
+ if (p_file->cur + p_nb_bytes < p_file->buf + p_file->len) {
+ l_nb_read = p_nb_bytes;
+ }
+ else {
+ l_nb_read = (OPJ_UINT32)(p_file->buf + p_file->len - p_file->cur);
+ }
+ memcpy(p_buffer, p_file->cur, l_nb_read);
+ p_file->cur += l_nb_read;
+
+ return l_nb_read ? l_nb_read : ((OPJ_SIZE_T)-1);
}
#if 0
static OPJ_SIZE_T opj_write_from_buffer(void *p_buffer, OPJ_SIZE_T p_nb_bytes, void *p_user_data)
{
- struct BufInfo *p_file = p_user_data;
- memcpy(p_file->cur, p_buffer, p_nb_bytes);
- p_file->cur += p_nb_bytes;
- p_file->len += p_nb_bytes;
- return p_nb_bytes;
+ struct BufInfo *p_file = p_user_data;
+ memcpy(p_file->cur, p_buffer, p_nb_bytes);
+ p_file->cur += p_nb_bytes;
+ p_file->len += p_nb_bytes;
+ return p_nb_bytes;
}
#endif
static OPJ_OFF_T opj_skip_from_buffer(OPJ_OFF_T p_nb_bytes, void *p_user_data)
{
- struct BufInfo *p_file = p_user_data;
- if (p_file->cur + p_nb_bytes < p_file->buf + p_file->len) {
- p_file->cur += p_nb_bytes;
- return p_nb_bytes;
- }
- p_file->cur = p_file->buf + p_file->len;
- return (OPJ_OFF_T)-1;
+ struct BufInfo *p_file = p_user_data;
+ if (p_file->cur + p_nb_bytes < p_file->buf + p_file->len) {
+ p_file->cur += p_nb_bytes;
+ return p_nb_bytes;
+ }
+ p_file->cur = p_file->buf + p_file->len;
+ return (OPJ_OFF_T)-1;
}
static OPJ_BOOL opj_seek_from_buffer(OPJ_OFF_T p_nb_bytes, void *p_user_data)
{
- struct BufInfo *p_file = p_user_data;
- if (p_nb_bytes < p_file->len) {
- p_file->cur = p_file->buf + p_nb_bytes;
- return OPJ_TRUE;
- }
- p_file->cur = p_file->buf + p_file->len;
- return OPJ_FALSE;
+ struct BufInfo *p_file = p_user_data;
+ if (p_nb_bytes < p_file->len) {
+ p_file->cur = p_file->buf + p_nb_bytes;
+ return OPJ_TRUE;
+ }
+ p_file->cur = p_file->buf + p_file->len;
+ return OPJ_FALSE;
}
/**
@@ -201,79 +196,78 @@ static OPJ_BOOL opj_seek_from_buffer(OPJ_OFF_T p_nb_bytes, void *p_user_data)
* (would be nice if this was supported by the API).
*/
-static opj_stream_t *opj_stream_create_from_buffer(
- struct BufInfo *p_file, OPJ_UINT32 p_size,
- OPJ_BOOL p_is_read_stream)
+static opj_stream_t *opj_stream_create_from_buffer(struct BufInfo *p_file,
+ OPJ_UINT32 p_size,
+ OPJ_BOOL p_is_read_stream)
{
- opj_stream_t *l_stream = opj_stream_create(p_size, p_is_read_stream);
- if (l_stream == NULL) {
- return NULL;
- }
- opj_stream_set_user_data(l_stream, p_file, opj_read_from_buffer_free);
- opj_stream_set_user_data_length(l_stream, p_file->len);
- opj_stream_set_read_function(l_stream, opj_read_from_buffer);
-#if 0 /* UNUSED */
- opj_stream_set_write_function(l_stream, opj_write_from_buffer);
+ opj_stream_t *l_stream = opj_stream_create(p_size, p_is_read_stream);
+ if (l_stream == NULL) {
+ return NULL;
+ }
+ opj_stream_set_user_data(l_stream, p_file, opj_read_from_buffer_free);
+ opj_stream_set_user_data_length(l_stream, p_file->len);
+ opj_stream_set_read_function(l_stream, opj_read_from_buffer);
+#if 0 /* UNUSED */
+ opj_stream_set_write_function(l_stream, opj_write_from_buffer);
#endif
- opj_stream_set_skip_function(l_stream, opj_skip_from_buffer);
- opj_stream_set_seek_function(l_stream, opj_seek_from_buffer);
+ opj_stream_set_skip_function(l_stream, opj_skip_from_buffer);
+ opj_stream_set_seek_function(l_stream, opj_seek_from_buffer);
- return l_stream;
+ return l_stream;
}
/** \} */
-
/** \name File Stream
* \{ */
static void opj_free_from_file(void *p_user_data)
{
- FILE *f = p_user_data;
- fclose(f);
+ FILE *f = p_user_data;
+ fclose(f);
}
-static OPJ_UINT64 opj_get_data_length_from_file (void *p_user_data)
+static OPJ_UINT64 opj_get_data_length_from_file(void *p_user_data)
{
- FILE *p_file = p_user_data;
- OPJ_OFF_T file_length = 0;
+ FILE *p_file = p_user_data;
+ OPJ_OFF_T file_length = 0;
- fseek(p_file, 0, SEEK_END);
- file_length = ftell(p_file);
- fseek(p_file, 0, SEEK_SET);
+ fseek(p_file, 0, SEEK_END);
+ file_length = ftell(p_file);
+ fseek(p_file, 0, SEEK_SET);
- return (OPJ_UINT64)file_length;
+ return (OPJ_UINT64)file_length;
}
static OPJ_SIZE_T opj_read_from_file(void *p_buffer, OPJ_SIZE_T p_nb_bytes, void *p_user_data)
{
- FILE *p_file = p_user_data;
- OPJ_SIZE_T l_nb_read = fread(p_buffer, 1, p_nb_bytes, p_file);
- return l_nb_read ? l_nb_read : (OPJ_SIZE_T)-1;
+ FILE *p_file = p_user_data;
+ OPJ_SIZE_T l_nb_read = fread(p_buffer, 1, p_nb_bytes, p_file);
+ return l_nb_read ? l_nb_read : (OPJ_SIZE_T)-1;
}
static OPJ_SIZE_T opj_write_from_file(void *p_buffer, OPJ_SIZE_T p_nb_bytes, void *p_user_data)
{
- FILE *p_file = p_user_data;
- return fwrite(p_buffer, 1, p_nb_bytes, p_file);
+ FILE *p_file = p_user_data;
+ return fwrite(p_buffer, 1, p_nb_bytes, p_file);
}
static OPJ_OFF_T opj_skip_from_file(OPJ_OFF_T p_nb_bytes, void *p_user_data)
{
- FILE *p_file = p_user_data;
- if (fseek(p_file, p_nb_bytes, SEEK_CUR)) {
- return -1;
- }
- return p_nb_bytes;
+ FILE *p_file = p_user_data;
+ if (fseek(p_file, p_nb_bytes, SEEK_CUR)) {
+ return -1;
+ }
+ return p_nb_bytes;
}
static OPJ_BOOL opj_seek_from_file(OPJ_OFF_T p_nb_bytes, void *p_user_data)
{
- FILE *p_file = p_user_data;
- if (fseek(p_file, p_nb_bytes, SEEK_SET)) {
- return OPJ_FALSE;
- }
- return OPJ_TRUE;
+ FILE *p_file = p_user_data;
+ if (fseek(p_file, p_nb_bytes, SEEK_SET)) {
+ return OPJ_FALSE;
+ }
+ return OPJ_TRUE;
}
/**
@@ -281,304 +275,317 @@ static OPJ_BOOL opj_seek_from_file(OPJ_OFF_T p_nb_bytes, void *p_user_data)
* (would be nice if this was supported by the API).
*/
-static opj_stream_t *opj_stream_create_from_file(
- const char *filepath, OPJ_UINT32 p_size, OPJ_BOOL p_is_read_stream,
- FILE **r_file)
+static opj_stream_t *opj_stream_create_from_file(const char *filepath,
+ OPJ_UINT32 p_size,
+ OPJ_BOOL p_is_read_stream,
+ FILE **r_file)
{
- FILE *p_file = BLI_fopen(filepath, p_is_read_stream ? "rb" : "wb");
- if (p_file == NULL) {
- return NULL;
- }
-
- opj_stream_t *l_stream = opj_stream_create(p_size, p_is_read_stream);
- if (l_stream == NULL) {
- fclose(p_file);
- return NULL;
- }
-
- opj_stream_set_user_data(l_stream, p_file, opj_free_from_file);
- opj_stream_set_user_data_length(l_stream, opj_get_data_length_from_file(p_file));
- opj_stream_set_write_function(l_stream, opj_write_from_file);
- opj_stream_set_read_function(l_stream, opj_read_from_file);
- opj_stream_set_skip_function(l_stream, opj_skip_from_file);
- opj_stream_set_seek_function(l_stream, opj_seek_from_file);
-
- if (r_file) {
- *r_file = p_file;
- }
- return l_stream;
+ FILE *p_file = BLI_fopen(filepath, p_is_read_stream ? "rb" : "wb");
+ if (p_file == NULL) {
+ return NULL;
+ }
+
+ opj_stream_t *l_stream = opj_stream_create(p_size, p_is_read_stream);
+ if (l_stream == NULL) {
+ fclose(p_file);
+ return NULL;
+ }
+
+ opj_stream_set_user_data(l_stream, p_file, opj_free_from_file);
+ opj_stream_set_user_data_length(l_stream, opj_get_data_length_from_file(p_file));
+ opj_stream_set_write_function(l_stream, opj_write_from_file);
+ opj_stream_set_read_function(l_stream, opj_read_from_file);
+ opj_stream_set_skip_function(l_stream, opj_skip_from_file);
+ opj_stream_set_seek_function(l_stream, opj_seek_from_file);
+
+ if (r_file) {
+ *r_file = p_file;
+ }
+ return l_stream;
}
/** \} */
-static ImBuf *imb_load_jp2_stream(
- opj_stream_t *stream, OPJ_CODEC_FORMAT p_format,
- int flags, char colorspace[IM_MAX_SPACE]);
+static ImBuf *imb_load_jp2_stream(opj_stream_t *stream,
+ OPJ_CODEC_FORMAT p_format,
+ int flags,
+ char colorspace[IM_MAX_SPACE]);
-ImBuf *imb_load_jp2(const unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE])
+ImBuf *imb_load_jp2(const unsigned char *mem,
+ size_t size,
+ int flags,
+ char colorspace[IM_MAX_SPACE])
{
- const OPJ_CODEC_FORMAT format = (size > JP2_FILEHEADER_SIZE) ? format_from_header(mem) : OPJ_CODEC_UNKNOWN;
- struct BufInfo buf_wrapper = { .buf = mem, .cur = mem, .len = size, };
- opj_stream_t *stream = opj_stream_create_from_buffer(&buf_wrapper, OPJ_J2K_STREAM_CHUNK_SIZE, true);
- ImBuf *ibuf = imb_load_jp2_stream(stream, format, flags, colorspace);
- opj_stream_destroy(stream);
- return ibuf;
+ const OPJ_CODEC_FORMAT format = (size > JP2_FILEHEADER_SIZE) ? format_from_header(mem) :
+ OPJ_CODEC_UNKNOWN;
+ struct BufInfo buf_wrapper = {
+ .buf = mem,
+ .cur = mem,
+ .len = size,
+ };
+ opj_stream_t *stream = opj_stream_create_from_buffer(
+ &buf_wrapper, OPJ_J2K_STREAM_CHUNK_SIZE, true);
+ ImBuf *ibuf = imb_load_jp2_stream(stream, format, flags, colorspace);
+ opj_stream_destroy(stream);
+ return ibuf;
}
ImBuf *imb_load_jp2_filepath(const char *filepath, int flags, char colorspace[IM_MAX_SPACE])
{
- FILE *p_file = NULL;
- unsigned char mem[JP2_FILEHEADER_SIZE];
- opj_stream_t *stream = opj_stream_create_from_file(filepath, OPJ_J2K_STREAM_CHUNK_SIZE, true, &p_file);
- if (stream) {
- return NULL;
- }
- else {
- if (fread(mem, sizeof(mem), 1, p_file) != sizeof(mem)) {
- opj_stream_destroy(stream);
- return NULL;
- }
- else {
- fseek(p_file, 0, SEEK_SET);
- }
- }
-
- const OPJ_CODEC_FORMAT format = format_from_header(mem);
- ImBuf *ibuf = imb_load_jp2_stream(stream, format, flags, colorspace);
- opj_stream_destroy(stream);
- return ibuf;
+ FILE *p_file = NULL;
+ unsigned char mem[JP2_FILEHEADER_SIZE];
+ opj_stream_t *stream = opj_stream_create_from_file(
+ filepath, OPJ_J2K_STREAM_CHUNK_SIZE, true, &p_file);
+ if (stream) {
+ return NULL;
+ }
+ else {
+ if (fread(mem, sizeof(mem), 1, p_file) != sizeof(mem)) {
+ opj_stream_destroy(stream);
+ return NULL;
+ }
+ else {
+ fseek(p_file, 0, SEEK_SET);
+ }
+ }
+
+ const OPJ_CODEC_FORMAT format = format_from_header(mem);
+ ImBuf *ibuf = imb_load_jp2_stream(stream, format, flags, colorspace);
+ opj_stream_destroy(stream);
+ return ibuf;
}
-
-static ImBuf *imb_load_jp2_stream(
- opj_stream_t *stream, const OPJ_CODEC_FORMAT format,
- int flags, char colorspace[IM_MAX_SPACE])
+static ImBuf *imb_load_jp2_stream(opj_stream_t *stream,
+ const OPJ_CODEC_FORMAT format,
+ int flags,
+ char colorspace[IM_MAX_SPACE])
{
- if (format == OPJ_CODEC_UNKNOWN) {
- return NULL;
- }
+ if (format == OPJ_CODEC_UNKNOWN) {
+ return NULL;
+ }
- struct ImBuf *ibuf = NULL;
- bool use_float = false; /* for precision higher then 8 use float */
- bool use_alpha = false;
+ struct ImBuf *ibuf = NULL;
+ bool use_float = false; /* for precision higher then 8 use float */
+ bool use_alpha = false;
- long signed_offsets[4] = {0, 0, 0, 0};
- int float_divs[4] = {1, 1, 1, 1};
+ long signed_offsets[4] = {0, 0, 0, 0};
+ int float_divs[4] = {1, 1, 1, 1};
- unsigned int i, i_next, w, h, planes;
- unsigned int y;
- int *r, *g, *b, *a; /* matching 'opj_image_comp.data' type */
+ unsigned int i, i_next, w, h, planes;
+ unsigned int y;
+ int *r, *g, *b, *a; /* matching 'opj_image_comp.data' type */
- opj_dparameters_t parameters; /* decompression parameters */
+ opj_dparameters_t parameters; /* decompression parameters */
- opj_image_t *image = NULL;
- opj_codec_t *codec = NULL; /* handle to a decompressor */
+ opj_image_t *image = NULL;
+ opj_codec_t *codec = NULL; /* handle to a decompressor */
- /* both 8, 12 and 16 bit JP2Ks are default to standard byte colorspace */
- colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE);
+ /* both 8, 12 and 16 bit JP2Ks are default to standard byte colorspace */
+ colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE);
- /* set decoding parameters to default values */
- opj_set_default_decoder_parameters(&parameters);
+ /* set decoding parameters to default values */
+ opj_set_default_decoder_parameters(&parameters);
- /* JPEG 2000 compressed image data */
+ /* JPEG 2000 compressed image data */
- /* get a decoder handle */
- codec = opj_create_decompress(format);
+ /* get a decoder handle */
+ codec = opj_create_decompress(format);
- /* configure the event callbacks (not required) */
- opj_set_error_handler(codec, error_callback, stderr);
- opj_set_warning_handler(codec, warning_callback, stderr);
-#ifdef DEBUG /* too noisy */
- opj_set_info_handler(codec, info_callback, stderr);
+ /* configure the event callbacks (not required) */
+ opj_set_error_handler(codec, error_callback, stderr);
+ opj_set_warning_handler(codec, warning_callback, stderr);
+#ifdef DEBUG /* too noisy */
+ opj_set_info_handler(codec, info_callback, stderr);
#endif
- /* setup the decoder decoding parameters using the current image and user parameters */
- if (opj_setup_decoder(codec, &parameters) == false) {
- goto finally;
- }
-
- if (opj_read_header(stream, codec, &image) == false) {
- printf("OpenJPEG error: failed to read the header\n");
- goto finally;
- }
-
- /* decode the stream and fill the image structure */
- if (opj_decode(codec, stream, image) == false) {
- fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n");
- goto finally;
- }
-
- if ((image->numcomps * image->x1 * image->y1) == 0) {
- fprintf(stderr, "\nError: invalid raw image parameters\n");
- goto finally;
- }
-
- w = image->comps[0].w;
- h = image->comps[0].h;
-
- switch (image->numcomps) {
- case 1: /* Grayscale */
- case 3: /* Color */
- planes = 24;
- use_alpha = false;
- break;
- default: /* 2 or 4 - Grayscale or Color + alpha */
- planes = 32; /* grayscale + alpha */
- use_alpha = true;
- break;
- }
-
-
- i = image->numcomps;
- if (i > 4) i = 4;
-
- while (i) {
- i--;
-
- if (image->comps[i].prec > 8)
- use_float = true;
-
- if (image->comps[i].sgnd)
- signed_offsets[i] = 1 << (image->comps[i].prec - 1);
-
- /* only needed for float images but dosnt hurt to calc this */
- float_divs[i] = (1 << image->comps[i].prec) - 1;
- }
-
- ibuf = IMB_allocImBuf(w, h, planes, use_float ? IB_rectfloat : IB_rect);
-
- if (ibuf == NULL) {
- goto finally;
- }
-
- ibuf->ftype = IMB_FTYPE_JP2;
- if (1 /* is_jp2 */ ) {
- ibuf->foptions.flag |= JP2_JP2;
- }
- else {
- ibuf->foptions.flag |= JP2_J2K;
- }
-
- if (use_float) {
- float *rect_float = ibuf->rect_float;
-
- if (image->numcomps < 3) {
- r = image->comps[0].data;
- a = (use_alpha) ? image->comps[1].data : NULL;
-
- /* grayscale 12bits+ */
- if (use_alpha) {
- a = image->comps[1].data;
- PIXEL_LOOPER_BEGIN(rect_float) {
- rect_float[0] = rect_float[1] = rect_float[2] = (float)(r[i] + signed_offsets[0]) / float_divs[0];
- rect_float[3] = (a[i] + signed_offsets[1]) / float_divs[1];
- }
- PIXEL_LOOPER_END;
- }
- else {
- PIXEL_LOOPER_BEGIN(rect_float) {
- rect_float[0] = rect_float[1] = rect_float[2] = (float)(r[i] + signed_offsets[0]) / float_divs[0];
- rect_float[3] = 1.0f;
- }
- PIXEL_LOOPER_END;
- }
- }
- else {
- r = image->comps[0].data;
- g = image->comps[1].data;
- b = image->comps[2].data;
-
- /* rgb or rgba 12bits+ */
- if (use_alpha) {
- a = image->comps[3].data;
- PIXEL_LOOPER_BEGIN(rect_float) {
- rect_float[0] = (float)(r[i] + signed_offsets[0]) / float_divs[0];
- rect_float[1] = (float)(g[i] + signed_offsets[1]) / float_divs[1];
- rect_float[2] = (float)(b[i] + signed_offsets[2]) / float_divs[2];
- rect_float[3] = (float)(a[i] + signed_offsets[3]) / float_divs[3];
- }
- PIXEL_LOOPER_END;
- }
- else {
- PIXEL_LOOPER_BEGIN(rect_float) {
- rect_float[0] = (float)(r[i] + signed_offsets[0]) / float_divs[0];
- rect_float[1] = (float)(g[i] + signed_offsets[1]) / float_divs[1];
- rect_float[2] = (float)(b[i] + signed_offsets[2]) / float_divs[2];
- rect_float[3] = 1.0f;
- }
- PIXEL_LOOPER_END;
- }
- }
-
- }
- else {
- unsigned char *rect_uchar = (unsigned char *)ibuf->rect;
-
- if (image->numcomps < 3) {
- r = image->comps[0].data;
- a = (use_alpha) ? image->comps[1].data : NULL;
-
- /* grayscale */
- if (use_alpha) {
- a = image->comps[3].data;
- PIXEL_LOOPER_BEGIN(rect_uchar) {
- rect_uchar[0] = rect_uchar[1] = rect_uchar[2] = (r[i] + signed_offsets[0]);
- rect_uchar[3] = a[i] + signed_offsets[1];
- }
- PIXEL_LOOPER_END;
- }
- else {
- PIXEL_LOOPER_BEGIN(rect_uchar) {
- rect_uchar[0] = rect_uchar[1] = rect_uchar[2] = (r[i] + signed_offsets[0]);
- rect_uchar[3] = 255;
- }
- PIXEL_LOOPER_END;
- }
- }
- else {
- r = image->comps[0].data;
- g = image->comps[1].data;
- b = image->comps[2].data;
-
- /* 8bit rgb or rgba */
- if (use_alpha) {
- a = image->comps[3].data;
- PIXEL_LOOPER_BEGIN(rect_uchar) {
- rect_uchar[0] = r[i] + signed_offsets[0];
- rect_uchar[1] = g[i] + signed_offsets[1];
- rect_uchar[2] = b[i] + signed_offsets[2];
- rect_uchar[3] = a[i] + signed_offsets[3];
- }
- PIXEL_LOOPER_END;
- }
- else {
- PIXEL_LOOPER_BEGIN(rect_uchar) {
- rect_uchar[0] = r[i] + signed_offsets[0];
- rect_uchar[1] = g[i] + signed_offsets[1];
- rect_uchar[2] = b[i] + signed_offsets[2];
- rect_uchar[3] = 255;
- }
- PIXEL_LOOPER_END;
- }
- }
- }
-
- if (flags & IB_rect) {
- IMB_rect_from_float(ibuf);
- }
+ /* setup the decoder decoding parameters using the current image and user parameters */
+ if (opj_setup_decoder(codec, &parameters) == false) {
+ goto finally;
+ }
+
+ if (opj_read_header(stream, codec, &image) == false) {
+ printf("OpenJPEG error: failed to read the header\n");
+ goto finally;
+ }
+
+ /* decode the stream and fill the image structure */
+ if (opj_decode(codec, stream, image) == false) {
+ fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n");
+ goto finally;
+ }
+
+ if ((image->numcomps * image->x1 * image->y1) == 0) {
+ fprintf(stderr, "\nError: invalid raw image parameters\n");
+ goto finally;
+ }
+
+ w = image->comps[0].w;
+ h = image->comps[0].h;
+
+ switch (image->numcomps) {
+ case 1: /* Grayscale */
+ case 3: /* Color */
+ planes = 24;
+ use_alpha = false;
+ break;
+ default: /* 2 or 4 - Grayscale or Color + alpha */
+ planes = 32; /* grayscale + alpha */
+ use_alpha = true;
+ break;
+ }
+
+ i = image->numcomps;
+ if (i > 4)
+ i = 4;
+
+ while (i) {
+ i--;
+
+ if (image->comps[i].prec > 8)
+ use_float = true;
+
+ if (image->comps[i].sgnd)
+ signed_offsets[i] = 1 << (image->comps[i].prec - 1);
+
+ /* only needed for float images but dosnt hurt to calc this */
+ float_divs[i] = (1 << image->comps[i].prec) - 1;
+ }
+
+ ibuf = IMB_allocImBuf(w, h, planes, use_float ? IB_rectfloat : IB_rect);
+
+ if (ibuf == NULL) {
+ goto finally;
+ }
+
+ ibuf->ftype = IMB_FTYPE_JP2;
+ if (1 /* is_jp2 */) {
+ ibuf->foptions.flag |= JP2_JP2;
+ }
+ else {
+ ibuf->foptions.flag |= JP2_J2K;
+ }
+
+ if (use_float) {
+ float *rect_float = ibuf->rect_float;
+
+ if (image->numcomps < 3) {
+ r = image->comps[0].data;
+ a = (use_alpha) ? image->comps[1].data : NULL;
+
+ /* grayscale 12bits+ */
+ if (use_alpha) {
+ a = image->comps[1].data;
+ PIXEL_LOOPER_BEGIN (rect_float) {
+ rect_float[0] = rect_float[1] = rect_float[2] = (float)(r[i] + signed_offsets[0]) /
+ float_divs[0];
+ rect_float[3] = (a[i] + signed_offsets[1]) / float_divs[1];
+ }
+ PIXEL_LOOPER_END;
+ }
+ else {
+ PIXEL_LOOPER_BEGIN (rect_float) {
+ rect_float[0] = rect_float[1] = rect_float[2] = (float)(r[i] + signed_offsets[0]) /
+ float_divs[0];
+ rect_float[3] = 1.0f;
+ }
+ PIXEL_LOOPER_END;
+ }
+ }
+ else {
+ r = image->comps[0].data;
+ g = image->comps[1].data;
+ b = image->comps[2].data;
+
+ /* rgb or rgba 12bits+ */
+ if (use_alpha) {
+ a = image->comps[3].data;
+ PIXEL_LOOPER_BEGIN (rect_float) {
+ rect_float[0] = (float)(r[i] + signed_offsets[0]) / float_divs[0];
+ rect_float[1] = (float)(g[i] + signed_offsets[1]) / float_divs[1];
+ rect_float[2] = (float)(b[i] + signed_offsets[2]) / float_divs[2];
+ rect_float[3] = (float)(a[i] + signed_offsets[3]) / float_divs[3];
+ }
+ PIXEL_LOOPER_END;
+ }
+ else {
+ PIXEL_LOOPER_BEGIN (rect_float) {
+ rect_float[0] = (float)(r[i] + signed_offsets[0]) / float_divs[0];
+ rect_float[1] = (float)(g[i] + signed_offsets[1]) / float_divs[1];
+ rect_float[2] = (float)(b[i] + signed_offsets[2]) / float_divs[2];
+ rect_float[3] = 1.0f;
+ }
+ PIXEL_LOOPER_END;
+ }
+ }
+ }
+ else {
+ unsigned char *rect_uchar = (unsigned char *)ibuf->rect;
+
+ if (image->numcomps < 3) {
+ r = image->comps[0].data;
+ a = (use_alpha) ? image->comps[1].data : NULL;
+
+ /* grayscale */
+ if (use_alpha) {
+ a = image->comps[3].data;
+ PIXEL_LOOPER_BEGIN (rect_uchar) {
+ rect_uchar[0] = rect_uchar[1] = rect_uchar[2] = (r[i] + signed_offsets[0]);
+ rect_uchar[3] = a[i] + signed_offsets[1];
+ }
+ PIXEL_LOOPER_END;
+ }
+ else {
+ PIXEL_LOOPER_BEGIN (rect_uchar) {
+ rect_uchar[0] = rect_uchar[1] = rect_uchar[2] = (r[i] + signed_offsets[0]);
+ rect_uchar[3] = 255;
+ }
+ PIXEL_LOOPER_END;
+ }
+ }
+ else {
+ r = image->comps[0].data;
+ g = image->comps[1].data;
+ b = image->comps[2].data;
+
+ /* 8bit rgb or rgba */
+ if (use_alpha) {
+ a = image->comps[3].data;
+ PIXEL_LOOPER_BEGIN (rect_uchar) {
+ rect_uchar[0] = r[i] + signed_offsets[0];
+ rect_uchar[1] = g[i] + signed_offsets[1];
+ rect_uchar[2] = b[i] + signed_offsets[2];
+ rect_uchar[3] = a[i] + signed_offsets[3];
+ }
+ PIXEL_LOOPER_END;
+ }
+ else {
+ PIXEL_LOOPER_BEGIN (rect_uchar) {
+ rect_uchar[0] = r[i] + signed_offsets[0];
+ rect_uchar[1] = g[i] + signed_offsets[1];
+ rect_uchar[2] = b[i] + signed_offsets[2];
+ rect_uchar[3] = 255;
+ }
+ PIXEL_LOOPER_END;
+ }
+ }
+ }
+
+ if (flags & IB_rect) {
+ IMB_rect_from_float(ibuf);
+ }
finally:
- /* free remaining structures */
- if (codec) {
- opj_destroy_codec(codec);
- }
+ /* free remaining structures */
+ if (codec) {
+ opj_destroy_codec(codec);
+ }
- if (image) {
- opj_image_destroy(image);
- }
+ if (image) {
+ opj_image_destroy(image);
+ }
- return ibuf;
+ return ibuf;
}
//static opj_image_t* rawtoimage(const char *filename, opj_cparameters_t *parameters, raw_cparameters_t *raw_cp)
@@ -586,34 +593,37 @@ finally:
/* use inline because the float passed can be a function call that would end up being called many times */
#if 0
-#define UPSAMPLE_8_TO_12(_val) ((_val << 4) | (_val & ((1 << 4) - 1)))
-#define UPSAMPLE_8_TO_16(_val) ((_val << 8) + _val)
-
-#define DOWNSAMPLE_FLOAT_TO_8BIT(_val) (_val) <= 0.0f ? 0 : ((_val) >= 1.0f ? 255 : (int)(255.0f * (_val)))
-#define DOWNSAMPLE_FLOAT_TO_12BIT(_val) (_val) <= 0.0f ? 0 : ((_val) >= 1.0f ? 4095 : (int)(4095.0f * (_val)))
-#define DOWNSAMPLE_FLOAT_TO_16BIT(_val) (_val) <= 0.0f ? 0 : ((_val) >= 1.0f ? 65535 : (int)(65535.0f * (_val)))
+# define UPSAMPLE_8_TO_12(_val) ((_val << 4) | (_val & ((1 << 4) - 1)))
+# define UPSAMPLE_8_TO_16(_val) ((_val << 8) + _val)
+
+# define DOWNSAMPLE_FLOAT_TO_8BIT(_val) \
+ (_val) <= 0.0f ? 0 : ((_val) >= 1.0f ? 255 : (int)(255.0f * (_val)))
+# define DOWNSAMPLE_FLOAT_TO_12BIT(_val) \
+ (_val) <= 0.0f ? 0 : ((_val) >= 1.0f ? 4095 : (int)(4095.0f * (_val)))
+# define DOWNSAMPLE_FLOAT_TO_16BIT(_val) \
+ (_val) <= 0.0f ? 0 : ((_val) >= 1.0f ? 65535 : (int)(65535.0f * (_val)))
#else
BLI_INLINE int UPSAMPLE_8_TO_12(const unsigned char _val)
{
- return (_val << 4) | (_val & ((1 << 4) - 1));
+ return (_val << 4) | (_val & ((1 << 4) - 1));
}
BLI_INLINE int UPSAMPLE_8_TO_16(const unsigned char _val)
{
- return (_val << 8) + _val;
+ return (_val << 8) + _val;
}
BLI_INLINE int DOWNSAMPLE_FLOAT_TO_8BIT(const float _val)
{
- return (_val) <= 0.0f ? 0 : ((_val) >= 1.0f ? 255 : (int)(255.0f * (_val)));
+ return (_val) <= 0.0f ? 0 : ((_val) >= 1.0f ? 255 : (int)(255.0f * (_val)));
}
BLI_INLINE int DOWNSAMPLE_FLOAT_TO_12BIT(const float _val)
{
- return (_val) <= 0.0f ? 0 : ((_val) >= 1.0f ? 4095 : (int)(4095.0f * (_val)));
+ return (_val) <= 0.0f ? 0 : ((_val) >= 1.0f ? 4095 : (int)(4095.0f * (_val)));
}
BLI_INLINE int DOWNSAMPLE_FLOAT_TO_16BIT(const float _val)
{
- return (_val) <= 0.0f ? 0 : ((_val) >= 1.0f ? 65535 : (int)(65535.0f * (_val)));
+ return (_val) <= 0.0f ? 0 : ((_val) >= 1.0f ? 65535 : (int)(65535.0f * (_val)));
}
#endif
@@ -627,645 +637,651 @@ BLI_INLINE int DOWNSAMPLE_FLOAT_TO_16BIT(const float _val)
/* ****************************** COPIED FROM image_to_j2k.c */
/* ----------------------------------------------------------------------- */
-#define CINEMA_24_CS 1302083 /*Codestream length for 24fps*/
-#define CINEMA_48_CS 651041 /*Codestream length for 48fps*/
-#define COMP_24_CS 1041666 /*Maximum size per color component for 2K & 4K @ 24fps*/
-#define COMP_48_CS 520833 /*Maximum size per color component for 2K @ 48fps*/
-
+#define CINEMA_24_CS 1302083 /*Codestream length for 24fps*/
+#define CINEMA_48_CS 651041 /*Codestream length for 48fps*/
+#define COMP_24_CS 1041666 /*Maximum size per color component for 2K & 4K @ 24fps*/
+#define COMP_48_CS 520833 /*Maximum size per color component for 2K @ 48fps*/
static int initialise_4K_poc(opj_poc_t *POC, int numres)
{
- POC[0].tile = 1;
- POC[0].resno0 = 0;
- POC[0].compno0 = 0;
- POC[0].layno1 = 1;
- POC[0].resno1 = numres - 1;
- POC[0].compno1 = 3;
- POC[0].prg1 = OPJ_CPRL;
- POC[1].tile = 1;
- POC[1].resno0 = numres - 1;
- POC[1].compno0 = 0;
- POC[1].layno1 = 1;
- POC[1].resno1 = numres;
- POC[1].compno1 = 3;
- POC[1].prg1 = OPJ_CPRL;
- return 2;
+ POC[0].tile = 1;
+ POC[0].resno0 = 0;
+ POC[0].compno0 = 0;
+ POC[0].layno1 = 1;
+ POC[0].resno1 = numres - 1;
+ POC[0].compno1 = 3;
+ POC[0].prg1 = OPJ_CPRL;
+ POC[1].tile = 1;
+ POC[1].resno0 = numres - 1;
+ POC[1].compno0 = 0;
+ POC[1].layno1 = 1;
+ POC[1].resno1 = numres;
+ POC[1].compno1 = 3;
+ POC[1].prg1 = OPJ_CPRL;
+ return 2;
}
static void cinema_parameters(opj_cparameters_t *parameters)
{
- parameters->tile_size_on = 0; /* false */
- parameters->cp_tdx = 1;
- parameters->cp_tdy = 1;
+ parameters->tile_size_on = 0; /* false */
+ parameters->cp_tdx = 1;
+ parameters->cp_tdy = 1;
- /*Tile part*/
- parameters->tp_flag = 'C';
- parameters->tp_on = 1;
+ /*Tile part*/
+ parameters->tp_flag = 'C';
+ parameters->tp_on = 1;
- /*Tile and Image shall be at (0, 0)*/
- parameters->cp_tx0 = 0;
- parameters->cp_ty0 = 0;
- parameters->image_offset_x0 = 0;
- parameters->image_offset_y0 = 0;
+ /*Tile and Image shall be at (0, 0)*/
+ parameters->cp_tx0 = 0;
+ parameters->cp_ty0 = 0;
+ parameters->image_offset_x0 = 0;
+ parameters->image_offset_y0 = 0;
- /*Codeblock size = 32 * 32*/
- parameters->cblockw_init = 32;
- parameters->cblockh_init = 32;
- parameters->csty |= 0x01;
+ /*Codeblock size = 32 * 32*/
+ parameters->cblockw_init = 32;
+ parameters->cblockh_init = 32;
+ parameters->csty |= 0x01;
- /*The progression order shall be CPRL*/
- parameters->prog_order = OPJ_CPRL;
+ /*The progression order shall be CPRL*/
+ parameters->prog_order = OPJ_CPRL;
- /* No ROI */
- parameters->roi_compno = -1;
+ /* No ROI */
+ parameters->roi_compno = -1;
- parameters->subsampling_dx = 1; parameters->subsampling_dy = 1;
+ parameters->subsampling_dx = 1;
+ parameters->subsampling_dy = 1;
- /* 9-7 transform */
- parameters->irreversible = 1;
+ /* 9-7 transform */
+ parameters->irreversible = 1;
}
-static void cinema_setup_encoder(opj_cparameters_t *parameters, opj_image_t *image, img_fol_t *img_fol)
+static void cinema_setup_encoder(opj_cparameters_t *parameters,
+ opj_image_t *image,
+ img_fol_t *img_fol)
{
- int i;
- float temp_rate;
-
- switch (parameters->cp_cinema) {
- case OPJ_CINEMA2K_24:
- case OPJ_CINEMA2K_48:
- if (parameters->numresolution > 6) {
- parameters->numresolution = 6;
- }
- if (!((image->comps[0].w == 2048) || (image->comps[0].h == 1080))) {
- fprintf(stdout, "Image coordinates %u x %u is not 2K compliant.\nJPEG Digital Cinema Profile-3 "
- "(2K profile) compliance requires that at least one of coordinates match 2048 x 1080\n",
- image->comps[0].w, image->comps[0].h);
- parameters->cp_rsiz = OPJ_STD_RSIZ;
- }
- else {
- parameters->cp_rsiz = DCP_CINEMA2K;
- }
- break;
-
- case OPJ_CINEMA4K_24:
- if (parameters->numresolution < 1) {
- parameters->numresolution = 1;
- }
- else if (parameters->numresolution > 7) {
- parameters->numresolution = 7;
- }
- if (!((image->comps[0].w == 4096) || (image->comps[0].h == 2160))) {
- fprintf(stdout, "Image coordinates %u x %u is not 4K compliant.\nJPEG Digital Cinema Profile-4"
- "(4K profile) compliance requires that at least one of coordinates match 4096 x 2160\n",
- image->comps[0].w, image->comps[0].h);
- parameters->cp_rsiz = OPJ_STD_RSIZ;
- }
- else {
- parameters->cp_rsiz = DCP_CINEMA2K;
- }
- parameters->numpocs = initialise_4K_poc(parameters->POC, parameters->numresolution);
- break;
- case OPJ_OFF:
- /* do nothing */
- break;
- }
-
- switch (parameters->cp_cinema) {
- case OPJ_CINEMA2K_24:
- case OPJ_CINEMA4K_24:
- for (i = 0; i < parameters->tcp_numlayers; i++) {
- temp_rate = 0;
- if (img_fol->rates[i] == 0) {
- parameters->tcp_rates[0] = ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec)) /
- (CINEMA_24_CS * 8 * image->comps[0].dx * image->comps[0].dy);
- }
- else {
- temp_rate = ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec)) /
- (img_fol->rates[i] * 8 * image->comps[0].dx * image->comps[0].dy);
- if (temp_rate > CINEMA_24_CS) {
- parameters->tcp_rates[i] = ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec)) /
- (CINEMA_24_CS * 8 * image->comps[0].dx * image->comps[0].dy);
- }
- else {
- parameters->tcp_rates[i] = img_fol->rates[i];
- }
- }
- }
- parameters->max_comp_size = COMP_24_CS;
- break;
-
- case OPJ_CINEMA2K_48:
- for (i = 0; i < parameters->tcp_numlayers; i++) {
- temp_rate = 0;
- if (img_fol->rates[i] == 0) {
- parameters->tcp_rates[0] = ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec)) /
- (CINEMA_48_CS * 8 * image->comps[0].dx * image->comps[0].dy);
- }
- else {
- temp_rate = ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec)) /
- (img_fol->rates[i] * 8 * image->comps[0].dx * image->comps[0].dy);
- if (temp_rate > CINEMA_48_CS) {
- parameters->tcp_rates[0] = ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec)) /
- (CINEMA_48_CS * 8 * image->comps[0].dx * image->comps[0].dy);
- }
- else {
- parameters->tcp_rates[i] = img_fol->rates[i];
- }
- }
- }
- parameters->max_comp_size = COMP_48_CS;
- break;
- case OPJ_OFF:
- /* do nothing */
- break;
- }
- parameters->cp_disto_alloc = 1;
+ int i;
+ float temp_rate;
+
+ switch (parameters->cp_cinema) {
+ case OPJ_CINEMA2K_24:
+ case OPJ_CINEMA2K_48:
+ if (parameters->numresolution > 6) {
+ parameters->numresolution = 6;
+ }
+ if (!((image->comps[0].w == 2048) || (image->comps[0].h == 1080))) {
+ fprintf(stdout,
+ "Image coordinates %u x %u is not 2K compliant.\nJPEG Digital Cinema Profile-3 "
+ "(2K profile) compliance requires that at least one of coordinates match 2048 x "
+ "1080\n",
+ image->comps[0].w,
+ image->comps[0].h);
+ parameters->cp_rsiz = OPJ_STD_RSIZ;
+ }
+ else {
+ parameters->cp_rsiz = DCP_CINEMA2K;
+ }
+ break;
+
+ case OPJ_CINEMA4K_24:
+ if (parameters->numresolution < 1) {
+ parameters->numresolution = 1;
+ }
+ else if (parameters->numresolution > 7) {
+ parameters->numresolution = 7;
+ }
+ if (!((image->comps[0].w == 4096) || (image->comps[0].h == 2160))) {
+ fprintf(stdout,
+ "Image coordinates %u x %u is not 4K compliant.\nJPEG Digital Cinema Profile-4"
+ "(4K profile) compliance requires that at least one of coordinates match 4096 x "
+ "2160\n",
+ image->comps[0].w,
+ image->comps[0].h);
+ parameters->cp_rsiz = OPJ_STD_RSIZ;
+ }
+ else {
+ parameters->cp_rsiz = DCP_CINEMA2K;
+ }
+ parameters->numpocs = initialise_4K_poc(parameters->POC, parameters->numresolution);
+ break;
+ case OPJ_OFF:
+ /* do nothing */
+ break;
+ }
+
+ switch (parameters->cp_cinema) {
+ case OPJ_CINEMA2K_24:
+ case OPJ_CINEMA4K_24:
+ for (i = 0; i < parameters->tcp_numlayers; i++) {
+ temp_rate = 0;
+ if (img_fol->rates[i] == 0) {
+ parameters->tcp_rates[0] = ((float)(image->numcomps * image->comps[0].w *
+ image->comps[0].h * image->comps[0].prec)) /
+ (CINEMA_24_CS * 8 * image->comps[0].dx * image->comps[0].dy);
+ }
+ else {
+ temp_rate = ((float)(image->numcomps * image->comps[0].w * image->comps[0].h *
+ image->comps[0].prec)) /
+ (img_fol->rates[i] * 8 * image->comps[0].dx * image->comps[0].dy);
+ if (temp_rate > CINEMA_24_CS) {
+ parameters->tcp_rates[i] = ((float)(image->numcomps * image->comps[0].w *
+ image->comps[0].h * image->comps[0].prec)) /
+ (CINEMA_24_CS * 8 * image->comps[0].dx *
+ image->comps[0].dy);
+ }
+ else {
+ parameters->tcp_rates[i] = img_fol->rates[i];
+ }
+ }
+ }
+ parameters->max_comp_size = COMP_24_CS;
+ break;
+
+ case OPJ_CINEMA2K_48:
+ for (i = 0; i < parameters->tcp_numlayers; i++) {
+ temp_rate = 0;
+ if (img_fol->rates[i] == 0) {
+ parameters->tcp_rates[0] = ((float)(image->numcomps * image->comps[0].w *
+ image->comps[0].h * image->comps[0].prec)) /
+ (CINEMA_48_CS * 8 * image->comps[0].dx * image->comps[0].dy);
+ }
+ else {
+ temp_rate = ((float)(image->numcomps * image->comps[0].w * image->comps[0].h *
+ image->comps[0].prec)) /
+ (img_fol->rates[i] * 8 * image->comps[0].dx * image->comps[0].dy);
+ if (temp_rate > CINEMA_48_CS) {
+ parameters->tcp_rates[0] = ((float)(image->numcomps * image->comps[0].w *
+ image->comps[0].h * image->comps[0].prec)) /
+ (CINEMA_48_CS * 8 * image->comps[0].dx *
+ image->comps[0].dy);
+ }
+ else {
+ parameters->tcp_rates[i] = img_fol->rates[i];
+ }
+ }
+ }
+ parameters->max_comp_size = COMP_48_CS;
+ break;
+ case OPJ_OFF:
+ /* do nothing */
+ break;
+ }
+ parameters->cp_disto_alloc = 1;
}
static float channel_colormanage_noop(float value)
{
- return value;
+ return value;
}
static opj_image_t *ibuftoimage(ImBuf *ibuf, opj_cparameters_t *parameters)
{
- unsigned char *rect_uchar;
- float *rect_float, from_straight[4];
-
- unsigned int subsampling_dx = parameters->subsampling_dx;
- unsigned int subsampling_dy = parameters->subsampling_dy;
-
- unsigned int i, i_next, numcomps, w, h, prec;
- unsigned int y;
- int *r, *g, *b, *a; /* matching 'opj_image_comp.data' type */
- OPJ_COLOR_SPACE color_space;
- opj_image_cmptparm_t cmptparm[4]; /* maximum of 4 components */
- opj_image_t *image = NULL;
-
- float (*chanel_colormanage_cb)(float);
-
- img_fol_t img_fol; /* only needed for cinema presets */
- memset(&img_fol, 0, sizeof(img_fol_t));
-
- if (ibuf->float_colorspace || (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA)) {
- /* float buffer was managed already, no need in color space conversion */
- chanel_colormanage_cb = channel_colormanage_noop;
- }
- else {
- /* standard linear-to-srgb conversion if float buffer wasn't managed */
- chanel_colormanage_cb = linearrgb_to_srgb;
- }
-
- if (ibuf->foptions.flag & JP2_CINE) {
-
- if (ibuf->x == 4096 || ibuf->y == 2160)
- parameters->cp_cinema = OPJ_CINEMA4K_24;
- else {
- if (ibuf->foptions.flag & JP2_CINE_48FPS) {
- parameters->cp_cinema = OPJ_CINEMA2K_48;
- }
- else {
- parameters->cp_cinema = OPJ_CINEMA2K_24;
- }
- }
- if (parameters->cp_cinema) {
- img_fol.rates = (float *)MEM_mallocN(parameters->tcp_numlayers * sizeof(float), "jp2_rates");
- for (i = 0; i < parameters->tcp_numlayers; i++) {
- img_fol.rates[i] = parameters->tcp_rates[i];
- }
- cinema_parameters(parameters);
- }
-
- color_space = (ibuf->foptions.flag & JP2_YCC) ? OPJ_CLRSPC_SYCC : OPJ_CLRSPC_SRGB;
- prec = 12;
- numcomps = 3;
- }
- else {
- /* Get settings from the imbuf */
- color_space = (ibuf->foptions.flag & JP2_YCC) ? OPJ_CLRSPC_SYCC : OPJ_CLRSPC_SRGB;
-
- if (ibuf->foptions.flag & JP2_16BIT) prec = 16;
- else if (ibuf->foptions.flag & JP2_12BIT) prec = 12;
- else prec = 8;
-
- /* 32bit images == alpha channel */
- /* grayscale not supported yet */
- numcomps = (ibuf->planes == 32) ? 4 : 3;
- }
-
- w = ibuf->x;
- h = ibuf->y;
-
-
- /* initialize image components */
- memset(&cmptparm, 0, 4 * sizeof(opj_image_cmptparm_t));
- for (i = 0; i < numcomps; i++) {
- cmptparm[i].prec = prec;
- cmptparm[i].bpp = prec;
- cmptparm[i].sgnd = 0;
- cmptparm[i].dx = subsampling_dx;
- cmptparm[i].dy = subsampling_dy;
- cmptparm[i].w = w;
- cmptparm[i].h = h;
- }
- /* create the image */
- image = opj_image_create(numcomps, &cmptparm[0], color_space);
- if (!image) {
- printf("Error: opj_image_create() failed\n");
- return NULL;
- }
-
- /* set image offset and reference grid */
- image->x0 = parameters->image_offset_x0;
- image->y0 = parameters->image_offset_y0;
- image->x1 = image->x0 + (w - 1) * subsampling_dx + 1 + image->x0;
- image->y1 = image->y0 + (h - 1) * subsampling_dy + 1 + image->y0;
-
- /* set image data */
- rect_uchar = (unsigned char *) ibuf->rect;
- rect_float = ibuf->rect_float;
-
- /* set the destination channels */
- r = image->comps[0].data;
- g = image->comps[1].data;
- b = image->comps[2].data;
- a = (numcomps == 4) ? image->comps[3].data : NULL;
-
- if (rect_float && rect_uchar && prec == 8) {
- /* No need to use the floating point buffer, just write the 8 bits from the char buffer */
- rect_float = NULL;
- }
-
- if (rect_float) {
- int channels_in_float = ibuf->channels ? ibuf->channels : 4;
-
- switch (prec) {
- case 8: /* Convert blenders float color channels to 8, 12 or 16bit ints */
- if (numcomps == 4) {
- if (channels_in_float == 4) {
- PIXEL_LOOPER_BEGIN(rect_float)
- {
- premul_to_straight_v4_v4(from_straight, rect_float);
- r[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(from_straight[0]));
- g[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(from_straight[1]));
- b[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(from_straight[2]));
- a[i] = DOWNSAMPLE_FLOAT_TO_8BIT(from_straight[3]);
- }
- PIXEL_LOOPER_END;
- }
- else if (channels_in_float == 3) {
- PIXEL_LOOPER_BEGIN_CHANNELS(rect_float, 3)
- {
- r[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(rect_float[0]));
- g[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(rect_float[1]));
- b[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(rect_float[2]));
- a[i] = 255;
- }
- PIXEL_LOOPER_END;
- }
- else {
- PIXEL_LOOPER_BEGIN_CHANNELS(rect_float, 1)
- {
- r[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(rect_float[0]));
- g[i] = b[i] = r[i];
- a[i] = 255;
- }
- PIXEL_LOOPER_END;
- }
- }
- else {
- if (channels_in_float == 4) {
- PIXEL_LOOPER_BEGIN(rect_float)
- {
- premul_to_straight_v4_v4(from_straight, rect_float);
- r[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(from_straight[0]));
- g[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(from_straight[1]));
- b[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(from_straight[2]));
- }
- PIXEL_LOOPER_END;
- }
- else if (channels_in_float == 3) {
- PIXEL_LOOPER_BEGIN_CHANNELS(rect_float, 3)
- {
- r[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(rect_float[0]));
- g[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(rect_float[1]));
- b[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(rect_float[2]));
- }
- PIXEL_LOOPER_END;
- }
- else {
- PIXEL_LOOPER_BEGIN_CHANNELS(rect_float, 1)
- {
- r[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(rect_float[0]));
- g[i] = b[i] = r[i];
- }
- PIXEL_LOOPER_END;
- }
- }
- break;
-
- case 12:
- if (numcomps == 4) {
- if (channels_in_float == 4) {
- PIXEL_LOOPER_BEGIN(rect_float)
- {
- premul_to_straight_v4_v4(from_straight, rect_float);
- r[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(from_straight[0]));
- g[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(from_straight[1]));
- b[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(from_straight[2]));
- a[i] = DOWNSAMPLE_FLOAT_TO_12BIT(from_straight[3]);
- }
- PIXEL_LOOPER_END;
- }
- else if (channels_in_float == 3) {
- PIXEL_LOOPER_BEGIN_CHANNELS(rect_float, 3)
- {
- r[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(rect_float[0]));
- g[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(rect_float[1]));
- b[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(rect_float[2]));
- a[i] = 4095;
- }
- PIXEL_LOOPER_END;
- }
- else {
- PIXEL_LOOPER_BEGIN_CHANNELS(rect_float, 1)
- {
- r[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(rect_float[0]));
- g[i] = b[i] = r[i];
- a[i] = 4095;
- }
- PIXEL_LOOPER_END;
- }
- }
- else {
- if (channels_in_float == 4) {
- PIXEL_LOOPER_BEGIN(rect_float)
- {
- premul_to_straight_v4_v4(from_straight, rect_float);
- r[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(from_straight[0]));
- g[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(from_straight[1]));
- b[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(from_straight[2]));
- }
- PIXEL_LOOPER_END;
- }
- else if (channels_in_float == 3) {
- PIXEL_LOOPER_BEGIN_CHANNELS(rect_float, 3)
- {
- r[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(rect_float[0]));
- g[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(rect_float[1]));
- b[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(rect_float[2]));
- }
- PIXEL_LOOPER_END;
- }
- else {
- PIXEL_LOOPER_BEGIN_CHANNELS(rect_float, 1)
- {
- r[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(rect_float[0]));
- g[i] = b[i] = r[i];
- }
- PIXEL_LOOPER_END;
- }
- }
- break;
-
- case 16:
- if (numcomps == 4) {
- if (channels_in_float == 4) {
- PIXEL_LOOPER_BEGIN(rect_float)
- {
- premul_to_straight_v4_v4(from_straight, rect_float);
- r[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(from_straight[0]));
- g[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(from_straight[1]));
- b[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(from_straight[2]));
- a[i] = DOWNSAMPLE_FLOAT_TO_16BIT(from_straight[3]);
- }
- PIXEL_LOOPER_END;
- }
- else if (channels_in_float == 3) {
- PIXEL_LOOPER_BEGIN_CHANNELS(rect_float, 3)
- {
- r[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(rect_float[0]));
- g[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(rect_float[1]));
- b[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(rect_float[2]));
- a[i] = 65535;
- }
- PIXEL_LOOPER_END;
- }
- else {
- PIXEL_LOOPER_BEGIN_CHANNELS(rect_float, 1)
- {
- r[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(rect_float[0]));
- g[i] = b[i] = r[i];
- a[i] = 65535;
- }
- PIXEL_LOOPER_END;
- }
- }
- else {
- if (channels_in_float == 4) {
- PIXEL_LOOPER_BEGIN(rect_float)
- {
- premul_to_straight_v4_v4(from_straight, rect_float);
- r[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(from_straight[0]));
- g[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(from_straight[1]));
- b[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(from_straight[2]));
- }
- PIXEL_LOOPER_END;
- }
- else if (channels_in_float == 3) {
- PIXEL_LOOPER_BEGIN_CHANNELS(rect_float, 3)
- {
- r[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(rect_float[0]));
- g[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(rect_float[1]));
- b[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(rect_float[2]));
- }
- PIXEL_LOOPER_END;
- }
- else {
- PIXEL_LOOPER_BEGIN_CHANNELS(rect_float, 1)
- {
- r[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(rect_float[0]));
- g[i] = b[i] = r[i];
- }
- PIXEL_LOOPER_END;
- }
- }
- break;
- }
- }
- else {
- /* just use rect*/
- switch (prec) {
- case 8:
- if (numcomps == 4) {
- PIXEL_LOOPER_BEGIN(rect_uchar)
- {
- r[i] = rect_uchar[0];
- g[i] = rect_uchar[1];
- b[i] = rect_uchar[2];
- a[i] = rect_uchar[3];
- }
- PIXEL_LOOPER_END;
- }
- else {
- PIXEL_LOOPER_BEGIN(rect_uchar)
- {
- r[i] = rect_uchar[0];
- g[i] = rect_uchar[1];
- b[i] = rect_uchar[2];
- }
- PIXEL_LOOPER_END;
- }
- break;
-
- case 12: /* Up Sampling, a bit pointless but best write the bit depth requested */
- if (numcomps == 4) {
- PIXEL_LOOPER_BEGIN(rect_uchar)
- {
- r[i] = UPSAMPLE_8_TO_12(rect_uchar[0]);
- g[i] = UPSAMPLE_8_TO_12(rect_uchar[1]);
- b[i] = UPSAMPLE_8_TO_12(rect_uchar[2]);
- a[i] = UPSAMPLE_8_TO_12(rect_uchar[3]);
- }
- PIXEL_LOOPER_END;
- }
- else {
- PIXEL_LOOPER_BEGIN(rect_uchar)
- {
- r[i] = UPSAMPLE_8_TO_12(rect_uchar[0]);
- g[i] = UPSAMPLE_8_TO_12(rect_uchar[1]);
- b[i] = UPSAMPLE_8_TO_12(rect_uchar[2]);
- }
- PIXEL_LOOPER_END;
- }
- break;
-
- case 16:
- if (numcomps == 4) {
- PIXEL_LOOPER_BEGIN(rect_uchar)
- {
- r[i] = UPSAMPLE_8_TO_16(rect_uchar[0]);
- g[i] = UPSAMPLE_8_TO_16(rect_uchar[1]);
- b[i] = UPSAMPLE_8_TO_16(rect_uchar[2]);
- a[i] = UPSAMPLE_8_TO_16(rect_uchar[3]);
- }
- PIXEL_LOOPER_END;
- }
- else {
- PIXEL_LOOPER_BEGIN(rect_uchar)
- {
- r[i] = UPSAMPLE_8_TO_16(rect_uchar[0]);
- g[i] = UPSAMPLE_8_TO_16(rect_uchar[1]);
- b[i] = UPSAMPLE_8_TO_16(rect_uchar[2]);
- }
- PIXEL_LOOPER_END;
- }
- break;
- }
- }
-
- /* Decide if MCT should be used */
- parameters->tcp_mct = image->numcomps == 3 ? 1 : 0;
-
- if (parameters->cp_cinema) {
- cinema_setup_encoder(parameters, image, &img_fol);
- }
-
- if (img_fol.rates)
- MEM_freeN(img_fol.rates);
-
- return image;
+ unsigned char *rect_uchar;
+ float *rect_float, from_straight[4];
+
+ unsigned int subsampling_dx = parameters->subsampling_dx;
+ unsigned int subsampling_dy = parameters->subsampling_dy;
+
+ unsigned int i, i_next, numcomps, w, h, prec;
+ unsigned int y;
+ int *r, *g, *b, *a; /* matching 'opj_image_comp.data' type */
+ OPJ_COLOR_SPACE color_space;
+ opj_image_cmptparm_t cmptparm[4]; /* maximum of 4 components */
+ opj_image_t *image = NULL;
+
+ float (*chanel_colormanage_cb)(float);
+
+ img_fol_t img_fol; /* only needed for cinema presets */
+ memset(&img_fol, 0, sizeof(img_fol_t));
+
+ if (ibuf->float_colorspace || (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA)) {
+ /* float buffer was managed already, no need in color space conversion */
+ chanel_colormanage_cb = channel_colormanage_noop;
+ }
+ else {
+ /* standard linear-to-srgb conversion if float buffer wasn't managed */
+ chanel_colormanage_cb = linearrgb_to_srgb;
+ }
+
+ if (ibuf->foptions.flag & JP2_CINE) {
+
+ if (ibuf->x == 4096 || ibuf->y == 2160)
+ parameters->cp_cinema = OPJ_CINEMA4K_24;
+ else {
+ if (ibuf->foptions.flag & JP2_CINE_48FPS) {
+ parameters->cp_cinema = OPJ_CINEMA2K_48;
+ }
+ else {
+ parameters->cp_cinema = OPJ_CINEMA2K_24;
+ }
+ }
+ if (parameters->cp_cinema) {
+ img_fol.rates = (float *)MEM_mallocN(parameters->tcp_numlayers * sizeof(float), "jp2_rates");
+ for (i = 0; i < parameters->tcp_numlayers; i++) {
+ img_fol.rates[i] = parameters->tcp_rates[i];
+ }
+ cinema_parameters(parameters);
+ }
+
+ color_space = (ibuf->foptions.flag & JP2_YCC) ? OPJ_CLRSPC_SYCC : OPJ_CLRSPC_SRGB;
+ prec = 12;
+ numcomps = 3;
+ }
+ else {
+ /* Get settings from the imbuf */
+ color_space = (ibuf->foptions.flag & JP2_YCC) ? OPJ_CLRSPC_SYCC : OPJ_CLRSPC_SRGB;
+
+ if (ibuf->foptions.flag & JP2_16BIT)
+ prec = 16;
+ else if (ibuf->foptions.flag & JP2_12BIT)
+ prec = 12;
+ else
+ prec = 8;
+
+ /* 32bit images == alpha channel */
+ /* grayscale not supported yet */
+ numcomps = (ibuf->planes == 32) ? 4 : 3;
+ }
+
+ w = ibuf->x;
+ h = ibuf->y;
+
+ /* initialize image components */
+ memset(&cmptparm, 0, 4 * sizeof(opj_image_cmptparm_t));
+ for (i = 0; i < numcomps; i++) {
+ cmptparm[i].prec = prec;
+ cmptparm[i].bpp = prec;
+ cmptparm[i].sgnd = 0;
+ cmptparm[i].dx = subsampling_dx;
+ cmptparm[i].dy = subsampling_dy;
+ cmptparm[i].w = w;
+ cmptparm[i].h = h;
+ }
+ /* create the image */
+ image = opj_image_create(numcomps, &cmptparm[0], color_space);
+ if (!image) {
+ printf("Error: opj_image_create() failed\n");
+ return NULL;
+ }
+
+ /* set image offset and reference grid */
+ image->x0 = parameters->image_offset_x0;
+ image->y0 = parameters->image_offset_y0;
+ image->x1 = image->x0 + (w - 1) * subsampling_dx + 1 + image->x0;
+ image->y1 = image->y0 + (h - 1) * subsampling_dy + 1 + image->y0;
+
+ /* set image data */
+ rect_uchar = (unsigned char *)ibuf->rect;
+ rect_float = ibuf->rect_float;
+
+ /* set the destination channels */
+ r = image->comps[0].data;
+ g = image->comps[1].data;
+ b = image->comps[2].data;
+ a = (numcomps == 4) ? image->comps[3].data : NULL;
+
+ if (rect_float && rect_uchar && prec == 8) {
+ /* No need to use the floating point buffer, just write the 8 bits from the char buffer */
+ rect_float = NULL;
+ }
+
+ if (rect_float) {
+ int channels_in_float = ibuf->channels ? ibuf->channels : 4;
+
+ switch (prec) {
+ case 8: /* Convert blenders float color channels to 8, 12 or 16bit ints */
+ if (numcomps == 4) {
+ if (channels_in_float == 4) {
+ PIXEL_LOOPER_BEGIN (rect_float) {
+ premul_to_straight_v4_v4(from_straight, rect_float);
+ r[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(from_straight[0]));
+ g[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(from_straight[1]));
+ b[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(from_straight[2]));
+ a[i] = DOWNSAMPLE_FLOAT_TO_8BIT(from_straight[3]);
+ }
+ PIXEL_LOOPER_END;
+ }
+ else if (channels_in_float == 3) {
+ PIXEL_LOOPER_BEGIN_CHANNELS(rect_float, 3)
+ {
+ r[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(rect_float[0]));
+ g[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(rect_float[1]));
+ b[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(rect_float[2]));
+ a[i] = 255;
+ }
+ PIXEL_LOOPER_END;
+ }
+ else {
+ PIXEL_LOOPER_BEGIN_CHANNELS(rect_float, 1)
+ {
+ r[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(rect_float[0]));
+ g[i] = b[i] = r[i];
+ a[i] = 255;
+ }
+ PIXEL_LOOPER_END;
+ }
+ }
+ else {
+ if (channels_in_float == 4) {
+ PIXEL_LOOPER_BEGIN (rect_float) {
+ premul_to_straight_v4_v4(from_straight, rect_float);
+ r[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(from_straight[0]));
+ g[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(from_straight[1]));
+ b[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(from_straight[2]));
+ }
+ PIXEL_LOOPER_END;
+ }
+ else if (channels_in_float == 3) {
+ PIXEL_LOOPER_BEGIN_CHANNELS(rect_float, 3)
+ {
+ r[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(rect_float[0]));
+ g[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(rect_float[1]));
+ b[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(rect_float[2]));
+ }
+ PIXEL_LOOPER_END;
+ }
+ else {
+ PIXEL_LOOPER_BEGIN_CHANNELS(rect_float, 1)
+ {
+ r[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(rect_float[0]));
+ g[i] = b[i] = r[i];
+ }
+ PIXEL_LOOPER_END;
+ }
+ }
+ break;
+
+ case 12:
+ if (numcomps == 4) {
+ if (channels_in_float == 4) {
+ PIXEL_LOOPER_BEGIN (rect_float) {
+ premul_to_straight_v4_v4(from_straight, rect_float);
+ r[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(from_straight[0]));
+ g[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(from_straight[1]));
+ b[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(from_straight[2]));
+ a[i] = DOWNSAMPLE_FLOAT_TO_12BIT(from_straight[3]);
+ }
+ PIXEL_LOOPER_END;
+ }
+ else if (channels_in_float == 3) {
+ PIXEL_LOOPER_BEGIN_CHANNELS(rect_float, 3)
+ {
+ r[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(rect_float[0]));
+ g[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(rect_float[1]));
+ b[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(rect_float[2]));
+ a[i] = 4095;
+ }
+ PIXEL_LOOPER_END;
+ }
+ else {
+ PIXEL_LOOPER_BEGIN_CHANNELS(rect_float, 1)
+ {
+ r[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(rect_float[0]));
+ g[i] = b[i] = r[i];
+ a[i] = 4095;
+ }
+ PIXEL_LOOPER_END;
+ }
+ }
+ else {
+ if (channels_in_float == 4) {
+ PIXEL_LOOPER_BEGIN (rect_float) {
+ premul_to_straight_v4_v4(from_straight, rect_float);
+ r[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(from_straight[0]));
+ g[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(from_straight[1]));
+ b[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(from_straight[2]));
+ }
+ PIXEL_LOOPER_END;
+ }
+ else if (channels_in_float == 3) {
+ PIXEL_LOOPER_BEGIN_CHANNELS(rect_float, 3)
+ {
+ r[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(rect_float[0]));
+ g[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(rect_float[1]));
+ b[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(rect_float[2]));
+ }
+ PIXEL_LOOPER_END;
+ }
+ else {
+ PIXEL_LOOPER_BEGIN_CHANNELS(rect_float, 1)
+ {
+ r[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(rect_float[0]));
+ g[i] = b[i] = r[i];
+ }
+ PIXEL_LOOPER_END;
+ }
+ }
+ break;
+
+ case 16:
+ if (numcomps == 4) {
+ if (channels_in_float == 4) {
+ PIXEL_LOOPER_BEGIN (rect_float) {
+ premul_to_straight_v4_v4(from_straight, rect_float);
+ r[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(from_straight[0]));
+ g[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(from_straight[1]));
+ b[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(from_straight[2]));
+ a[i] = DOWNSAMPLE_FLOAT_TO_16BIT(from_straight[3]);
+ }
+ PIXEL_LOOPER_END;
+ }
+ else if (channels_in_float == 3) {
+ PIXEL_LOOPER_BEGIN_CHANNELS(rect_float, 3)
+ {
+ r[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(rect_float[0]));
+ g[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(rect_float[1]));
+ b[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(rect_float[2]));
+ a[i] = 65535;
+ }
+ PIXEL_LOOPER_END;
+ }
+ else {
+ PIXEL_LOOPER_BEGIN_CHANNELS(rect_float, 1)
+ {
+ r[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(rect_float[0]));
+ g[i] = b[i] = r[i];
+ a[i] = 65535;
+ }
+ PIXEL_LOOPER_END;
+ }
+ }
+ else {
+ if (channels_in_float == 4) {
+ PIXEL_LOOPER_BEGIN (rect_float) {
+ premul_to_straight_v4_v4(from_straight, rect_float);
+ r[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(from_straight[0]));
+ g[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(from_straight[1]));
+ b[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(from_straight[2]));
+ }
+ PIXEL_LOOPER_END;
+ }
+ else if (channels_in_float == 3) {
+ PIXEL_LOOPER_BEGIN_CHANNELS(rect_float, 3)
+ {
+ r[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(rect_float[0]));
+ g[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(rect_float[1]));
+ b[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(rect_float[2]));
+ }
+ PIXEL_LOOPER_END;
+ }
+ else {
+ PIXEL_LOOPER_BEGIN_CHANNELS(rect_float, 1)
+ {
+ r[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(rect_float[0]));
+ g[i] = b[i] = r[i];
+ }
+ PIXEL_LOOPER_END;
+ }
+ }
+ break;
+ }
+ }
+ else {
+ /* just use rect*/
+ switch (prec) {
+ case 8:
+ if (numcomps == 4) {
+ PIXEL_LOOPER_BEGIN (rect_uchar) {
+ r[i] = rect_uchar[0];
+ g[i] = rect_uchar[1];
+ b[i] = rect_uchar[2];
+ a[i] = rect_uchar[3];
+ }
+ PIXEL_LOOPER_END;
+ }
+ else {
+ PIXEL_LOOPER_BEGIN (rect_uchar) {
+ r[i] = rect_uchar[0];
+ g[i] = rect_uchar[1];
+ b[i] = rect_uchar[2];
+ }
+ PIXEL_LOOPER_END;
+ }
+ break;
+
+ case 12: /* Up Sampling, a bit pointless but best write the bit depth requested */
+ if (numcomps == 4) {
+ PIXEL_LOOPER_BEGIN (rect_uchar) {
+ r[i] = UPSAMPLE_8_TO_12(rect_uchar[0]);
+ g[i] = UPSAMPLE_8_TO_12(rect_uchar[1]);
+ b[i] = UPSAMPLE_8_TO_12(rect_uchar[2]);
+ a[i] = UPSAMPLE_8_TO_12(rect_uchar[3]);
+ }
+ PIXEL_LOOPER_END;
+ }
+ else {
+ PIXEL_LOOPER_BEGIN (rect_uchar) {
+ r[i] = UPSAMPLE_8_TO_12(rect_uchar[0]);
+ g[i] = UPSAMPLE_8_TO_12(rect_uchar[1]);
+ b[i] = UPSAMPLE_8_TO_12(rect_uchar[2]);
+ }
+ PIXEL_LOOPER_END;
+ }
+ break;
+
+ case 16:
+ if (numcomps == 4) {
+ PIXEL_LOOPER_BEGIN (rect_uchar) {
+ r[i] = UPSAMPLE_8_TO_16(rect_uchar[0]);
+ g[i] = UPSAMPLE_8_TO_16(rect_uchar[1]);
+ b[i] = UPSAMPLE_8_TO_16(rect_uchar[2]);
+ a[i] = UPSAMPLE_8_TO_16(rect_uchar[3]);
+ }
+ PIXEL_LOOPER_END;
+ }
+ else {
+ PIXEL_LOOPER_BEGIN (rect_uchar) {
+ r[i] = UPSAMPLE_8_TO_16(rect_uchar[0]);
+ g[i] = UPSAMPLE_8_TO_16(rect_uchar[1]);
+ b[i] = UPSAMPLE_8_TO_16(rect_uchar[2]);
+ }
+ PIXEL_LOOPER_END;
+ }
+ break;
+ }
+ }
+
+ /* Decide if MCT should be used */
+ parameters->tcp_mct = image->numcomps == 3 ? 1 : 0;
+
+ if (parameters->cp_cinema) {
+ cinema_setup_encoder(parameters, image, &img_fol);
+ }
+
+ if (img_fol.rates)
+ MEM_freeN(img_fol.rates);
+
+ return image;
}
int imb_save_jp2_stream(struct ImBuf *ibuf, opj_stream_t *stream, int flags);
int imb_save_jp2(struct ImBuf *ibuf, const char *filepath, int flags)
{
- opj_stream_t *stream = opj_stream_create_from_file(filepath, OPJ_J2K_STREAM_CHUNK_SIZE, false, NULL);
- if (stream == NULL) {
- return 0;
- }
- int ret = imb_save_jp2_stream(ibuf, stream, flags);
- opj_stream_destroy(stream);
- return ret;
+ opj_stream_t *stream = opj_stream_create_from_file(
+ filepath, OPJ_J2K_STREAM_CHUNK_SIZE, false, NULL);
+ if (stream == NULL) {
+ return 0;
+ }
+ int ret = imb_save_jp2_stream(ibuf, stream, flags);
+ opj_stream_destroy(stream);
+ return ret;
}
/* Found write info at http://users.ece.gatech.edu/~slabaugh/personal/c/bitmapUnix.c */
int imb_save_jp2_stream(struct ImBuf *ibuf, opj_stream_t *stream, int UNUSED(flags))
{
- int quality = ibuf->foptions.quality;
-
- opj_cparameters_t parameters; /* compression parameters */
- opj_image_t *image = NULL;
-
- /* set encoding parameters to default values */
- opj_set_default_encoder_parameters(&parameters);
-
- /* compression ratio */
- /* invert range, from 10-100, 100-1
- * where jpeg see's 1 and highest quality (lossless) and 100 is very low quality*/
- parameters.tcp_rates[0] = ((100 - quality) / 90.0f * 99.0f) + 1;
-
-
- parameters.tcp_numlayers = 1; /* only one resolution */
- parameters.cp_disto_alloc = 1;
-
- image = ibuftoimage(ibuf, &parameters);
-
- opj_codec_t *codec = NULL;
- int ok = false;
- /* JP2 format output */
- {
- /* get a JP2 compressor handle */
- OPJ_CODEC_FORMAT format = OPJ_CODEC_JP2;
- if (ibuf->foptions.flag & JP2_J2K) {
- format = OPJ_CODEC_J2K;
- }
- else if (ibuf->foptions.flag & JP2_JP2) {
- format = OPJ_CODEC_JP2;
- }
-
- codec = opj_create_compress(format);
-
- /* configure the event callbacks (not required) */
- opj_set_error_handler(codec, error_callback, stderr);
- opj_set_warning_handler(codec, warning_callback, stderr);
-#ifdef DEBUG /* too noisy */
- opj_set_info_handler(codec, info_callback, stderr);
+ int quality = ibuf->foptions.quality;
+
+ opj_cparameters_t parameters; /* compression parameters */
+ opj_image_t *image = NULL;
+
+ /* set encoding parameters to default values */
+ opj_set_default_encoder_parameters(&parameters);
+
+ /* compression ratio */
+ /* invert range, from 10-100, 100-1
+ * where jpeg see's 1 and highest quality (lossless) and 100 is very low quality*/
+ parameters.tcp_rates[0] = ((100 - quality) / 90.0f * 99.0f) + 1;
+
+ parameters.tcp_numlayers = 1; /* only one resolution */
+ parameters.cp_disto_alloc = 1;
+
+ image = ibuftoimage(ibuf, &parameters);
+
+ opj_codec_t *codec = NULL;
+ int ok = false;
+ /* JP2 format output */
+ {
+ /* get a JP2 compressor handle */
+ OPJ_CODEC_FORMAT format = OPJ_CODEC_JP2;
+ if (ibuf->foptions.flag & JP2_J2K) {
+ format = OPJ_CODEC_J2K;
+ }
+ else if (ibuf->foptions.flag & JP2_JP2) {
+ format = OPJ_CODEC_JP2;
+ }
+
+ codec = opj_create_compress(format);
+
+ /* configure the event callbacks (not required) */
+ opj_set_error_handler(codec, error_callback, stderr);
+ opj_set_warning_handler(codec, warning_callback, stderr);
+#ifdef DEBUG /* too noisy */
+ opj_set_info_handler(codec, info_callback, stderr);
#endif
- /* setup the encoder parameters using the current image and using user parameters */
- if (opj_setup_encoder(codec, &parameters, image) == false) {
- goto finally;
- }
+ /* setup the encoder parameters using the current image and using user parameters */
+ if (opj_setup_encoder(codec, &parameters, image) == false) {
+ goto finally;
+ }
- if (opj_start_compress(codec, image, stream) == false) {
- goto finally;
- }
- if (opj_encode(codec, stream) == false) {
- goto finally;
- }
- if (opj_end_compress(codec, stream) == false) {
- goto finally;
- }
- }
+ if (opj_start_compress(codec, image, stream) == false) {
+ goto finally;
+ }
+ if (opj_encode(codec, stream) == false) {
+ goto finally;
+ }
+ if (opj_end_compress(codec, stream) == false) {
+ goto finally;
+ }
+ }
- ok = true;
+ ok = true;
finally:
- /* free remaining compression structures */
- if (codec) {
- opj_destroy_codec(codec);
- }
+ /* free remaining compression structures */
+ if (codec) {
+ opj_destroy_codec(codec);
+ }
- /* free image data */
- if (image) {
- opj_image_destroy(image);
- }
+ /* free image data */
+ if (image) {
+ opj_image_destroy(image);
+ }
- if (ok == false) {
- fprintf(stderr, "failed to encode image\n");
- }
+ if (ok == false) {
+ fprintf(stderr, "failed to encode image\n");
+ }
- return ok;
+ return ok;
}
diff --git a/source/blender/imbuf/intern/jpeg.c b/source/blender/imbuf/intern/jpeg.c
index 25b23d9a19d..6743fe536b1 100644
--- a/source/blender/imbuf/intern/jpeg.c
+++ b/source/blender/imbuf/intern/jpeg.c
@@ -21,8 +21,6 @@
* \ingroup imbuf
*/
-
-
/* This little block needed for linking to Blender... */
#include <stdio.h>
#include <setjmp.h>
@@ -61,8 +59,9 @@ static uchar ibuf_quality;
int imb_is_a_jpeg(const unsigned char *mem)
{
- if ((mem[0] == 0xFF) && (mem[1] == 0xD8)) return 1;
- return 0;
+ if ((mem[0] == 0xFF) && (mem[1] == 0xD8))
+ return 1;
+ return 0;
}
/*----------------------------------------------------------
@@ -70,25 +69,25 @@ int imb_is_a_jpeg(const unsigned char *mem)
*---------------------------------------------------------- */
typedef struct my_error_mgr {
- struct jpeg_error_mgr pub; /* "public" fields */
+ struct jpeg_error_mgr pub; /* "public" fields */
- jmp_buf setjmp_buffer; /* for return to caller */
+ jmp_buf setjmp_buffer; /* for return to caller */
} my_error_mgr;
typedef my_error_mgr *my_error_ptr;
static void jpeg_error(j_common_ptr cinfo)
{
- my_error_ptr err = (my_error_ptr)cinfo->err;
+ my_error_ptr err = (my_error_ptr)cinfo->err;
- /* Always display the message */
- (*cinfo->err->output_message)(cinfo);
+ /* Always display the message */
+ (*cinfo->err->output_message)(cinfo);
- /* Let the memory manager delete any temp files before we die */
- jpeg_destroy(cinfo);
+ /* Let the memory manager delete any temp files before we die */
+ jpeg_destroy(cinfo);
- /* return control to the setjmp point */
- longjmp(err->setjmp_buffer, 1);
+ /* return control to the setjmp point */
+ longjmp(err->setjmp_buffer, 1);
}
/*----------------------------------------------------------
@@ -97,547 +96,545 @@ static void jpeg_error(j_common_ptr cinfo)
#if 0
typedef struct {
- unsigned char *buffer;
- int filled;
+ unsigned char *buffer;
+ int filled;
} buffer_struct;
#endif
typedef struct {
- struct jpeg_source_mgr pub; /* public fields */
+ struct jpeg_source_mgr pub; /* public fields */
- const unsigned char *buffer;
- int size;
- JOCTET terminal[2];
+ const unsigned char *buffer;
+ int size;
+ JOCTET terminal[2];
} my_source_mgr;
typedef my_source_mgr *my_src_ptr;
static void init_source(j_decompress_ptr cinfo)
{
- (void)cinfo; /* unused */
+ (void)cinfo; /* unused */
}
-
static boolean fill_input_buffer(j_decompress_ptr cinfo)
{
- my_src_ptr src = (my_src_ptr) cinfo->src;
+ my_src_ptr src = (my_src_ptr)cinfo->src;
- /* Since we have given all we have got already
- * we simply fake an end of file
- */
+ /* Since we have given all we have got already
+ * we simply fake an end of file
+ */
- src->pub.next_input_byte = src->terminal;
- src->pub.bytes_in_buffer = 2;
- src->terminal[0] = (JOCTET) 0xFF;
- src->terminal[1] = (JOCTET) JPEG_EOI;
+ src->pub.next_input_byte = src->terminal;
+ src->pub.bytes_in_buffer = 2;
+ src->terminal[0] = (JOCTET)0xFF;
+ src->terminal[1] = (JOCTET)JPEG_EOI;
- return true;
+ return true;
}
-
static void skip_input_data(j_decompress_ptr cinfo, long num_bytes)
{
- my_src_ptr src = (my_src_ptr) cinfo->src;
+ my_src_ptr src = (my_src_ptr)cinfo->src;
- if (num_bytes > 0) {
- /* prevent skipping over file end */
- size_t skip_size = (size_t)num_bytes <= src->pub.bytes_in_buffer ? num_bytes : src->pub.bytes_in_buffer;
+ if (num_bytes > 0) {
+ /* prevent skipping over file end */
+ size_t skip_size = (size_t)num_bytes <= src->pub.bytes_in_buffer ? num_bytes :
+ src->pub.bytes_in_buffer;
- src->pub.next_input_byte = src->pub.next_input_byte + skip_size;
- src->pub.bytes_in_buffer = src->pub.bytes_in_buffer - skip_size;
- }
+ src->pub.next_input_byte = src->pub.next_input_byte + skip_size;
+ src->pub.bytes_in_buffer = src->pub.bytes_in_buffer - skip_size;
+ }
}
-
static void term_source(j_decompress_ptr cinfo)
{
- (void)cinfo; /* unused */
+ (void)cinfo; /* unused */
}
static void memory_source(j_decompress_ptr cinfo, const unsigned char *buffer, size_t size)
{
- my_src_ptr src;
+ my_src_ptr src;
- if (cinfo->src == NULL) { /* first time for this JPEG object? */
- cinfo->src = (struct jpeg_source_mgr *)(*cinfo->mem->alloc_small)
- ((j_common_ptr) cinfo, JPOOL_PERMANENT, sizeof(my_source_mgr));
- }
+ if (cinfo->src == NULL) { /* first time for this JPEG object? */
+ cinfo->src = (struct jpeg_source_mgr *)(*cinfo->mem->alloc_small)(
+ (j_common_ptr)cinfo, JPOOL_PERMANENT, sizeof(my_source_mgr));
+ }
- src = (my_src_ptr) cinfo->src;
- src->pub.init_source = init_source;
- src->pub.fill_input_buffer = fill_input_buffer;
- src->pub.skip_input_data = skip_input_data;
- src->pub.resync_to_restart = jpeg_resync_to_restart;
- src->pub.term_source = term_source;
+ src = (my_src_ptr)cinfo->src;
+ src->pub.init_source = init_source;
+ src->pub.fill_input_buffer = fill_input_buffer;
+ src->pub.skip_input_data = skip_input_data;
+ src->pub.resync_to_restart = jpeg_resync_to_restart;
+ src->pub.term_source = term_source;
- src->pub.bytes_in_buffer = size;
- src->pub.next_input_byte = buffer;
+ src->pub.bytes_in_buffer = size;
+ src->pub.next_input_byte = buffer;
- src->buffer = buffer;
- src->size = size;
+ src->buffer = buffer;
+ src->size = size;
}
+#define MAKESTMT(stuff) \
+ do { \
+ stuff \
+ } while (0)
-#define MAKESTMT(stuff) do { stuff } while (0)
-
-#define INPUT_VARS(cinfo) \
- struct jpeg_source_mgr *datasrc = (cinfo)->src; \
- const JOCTET * next_input_byte = datasrc->next_input_byte; \
- size_t bytes_in_buffer = datasrc->bytes_in_buffer
+#define INPUT_VARS(cinfo) \
+ struct jpeg_source_mgr *datasrc = (cinfo)->src; \
+ const JOCTET *next_input_byte = datasrc->next_input_byte; \
+ size_t bytes_in_buffer = datasrc->bytes_in_buffer
/* Unload the local copies --- do this only at a restart boundary */
-#define INPUT_SYNC(cinfo) \
- ( datasrc->next_input_byte = next_input_byte, \
- datasrc->bytes_in_buffer = bytes_in_buffer )
+#define INPUT_SYNC(cinfo) \
+ (datasrc->next_input_byte = next_input_byte, datasrc->bytes_in_buffer = bytes_in_buffer)
/* Reload the local copies --- seldom used except in MAKE_BYTE_AVAIL */
-#define INPUT_RELOAD(cinfo) \
- ( next_input_byte = datasrc->next_input_byte, \
- bytes_in_buffer = datasrc->bytes_in_buffer )
+#define INPUT_RELOAD(cinfo) \
+ (next_input_byte = datasrc->next_input_byte, bytes_in_buffer = datasrc->bytes_in_buffer)
/* Internal macro for INPUT_BYTE and INPUT_2BYTES: make a byte available.
* Note we do *not* do INPUT_SYNC before calling fill_input_buffer,
* but we must reload the local copies after a successful fill.
*/
-#define MAKE_BYTE_AVAIL(cinfo, action) \
- if (bytes_in_buffer == 0) { \
- if (! (*datasrc->fill_input_buffer) (cinfo)) \
- { action; } \
- INPUT_RELOAD(cinfo); \
- } (void)0
-
+#define MAKE_BYTE_AVAIL(cinfo, action) \
+ if (bytes_in_buffer == 0) { \
+ if (!(*datasrc->fill_input_buffer)(cinfo)) { \
+ action; \
+ } \
+ INPUT_RELOAD(cinfo); \
+ } \
+ (void)0
/* Read a byte into variable V.
* If must suspend, take the specified action (typically "return false").
*/
-#define INPUT_BYTE(cinfo, V, action) \
- MAKESTMT(MAKE_BYTE_AVAIL(cinfo, action); \
- bytes_in_buffer--; \
- V = GETJOCTET(*next_input_byte++); )
+#define INPUT_BYTE(cinfo, V, action) \
+ MAKESTMT(MAKE_BYTE_AVAIL(cinfo, action); bytes_in_buffer--; V = GETJOCTET(*next_input_byte++);)
/* As above, but read two bytes interpreted as an unsigned 16-bit integer.
* V should be declared unsigned int or perhaps INT32.
*/
-#define INPUT_2BYTES(cinfo, V, action) \
- MAKESTMT(MAKE_BYTE_AVAIL(cinfo, action); \
- bytes_in_buffer--; \
- V = ((unsigned int) GETJOCTET(*next_input_byte++)) << 8; \
- MAKE_BYTE_AVAIL(cinfo, action); \
- bytes_in_buffer--; \
- V += GETJOCTET(*next_input_byte++); )
+#define INPUT_2BYTES(cinfo, V, action) \
+ MAKESTMT(MAKE_BYTE_AVAIL(cinfo, action); bytes_in_buffer--; \
+ V = ((unsigned int)GETJOCTET(*next_input_byte++)) << 8; \
+ MAKE_BYTE_AVAIL(cinfo, action); \
+ bytes_in_buffer--; \
+ V += GETJOCTET(*next_input_byte++);)
struct NeoGeo_Word {
- uchar pad1;
- uchar pad2;
- uchar pad3;
- uchar quality;
-} ;
+ uchar pad1;
+ uchar pad2;
+ uchar pad3;
+ uchar quality;
+};
BLI_STATIC_ASSERT(sizeof(struct NeoGeo_Word) == 4, "Must be 4 bytes");
static boolean handle_app1(j_decompress_ptr cinfo)
{
- INT32 length; /* initialized by the macro */
- INT32 i;
- char neogeo[128];
-
- INPUT_VARS(cinfo);
-
- INPUT_2BYTES(cinfo, length, return false);
- length -= 2;
-
- if (length < 16) {
- for (i = 0; i < length; i++) {
- INPUT_BYTE(cinfo, neogeo[i], return false);
- }
- length = 0;
- if (STREQLEN(neogeo, "NeoGeo", 6)) {
- struct NeoGeo_Word *neogeo_word = (struct NeoGeo_Word *)(neogeo + 6);
- ibuf_quality = neogeo_word->quality;
- }
- }
- INPUT_SYNC(cinfo); /* do before skip_input_data */
- if (length > 0) {
- (*cinfo->src->skip_input_data)(cinfo, length);
- }
- return true;
+ INT32 length; /* initialized by the macro */
+ INT32 i;
+ char neogeo[128];
+
+ INPUT_VARS(cinfo);
+
+ INPUT_2BYTES(cinfo, length, return false);
+ length -= 2;
+
+ if (length < 16) {
+ for (i = 0; i < length; i++) {
+ INPUT_BYTE(cinfo, neogeo[i], return false);
+ }
+ length = 0;
+ if (STREQLEN(neogeo, "NeoGeo", 6)) {
+ struct NeoGeo_Word *neogeo_word = (struct NeoGeo_Word *)(neogeo + 6);
+ ibuf_quality = neogeo_word->quality;
+ }
+ }
+ INPUT_SYNC(cinfo); /* do before skip_input_data */
+ if (length > 0) {
+ (*cinfo->src->skip_input_data)(cinfo, length);
+ }
+ return true;
}
-
static ImBuf *ibJpegImageFromCinfo(struct jpeg_decompress_struct *cinfo, int flags)
{
- JSAMPARRAY row_pointer;
- JSAMPLE *buffer = NULL;
- int row_stride;
- int x, y, depth, r, g, b, k;
- struct ImBuf *ibuf = NULL;
- uchar *rect;
- jpeg_saved_marker_ptr marker;
- char *str, *key, *value;
-
- /* install own app1 handler */
- ibuf_quality = jpeg_default_quality;
- jpeg_set_marker_processor(cinfo, 0xe1, handle_app1);
- cinfo->dct_method = JDCT_FLOAT;
- jpeg_save_markers(cinfo, JPEG_COM, 0xffff);
-
- if (jpeg_read_header(cinfo, false) == JPEG_HEADER_OK) {
- x = cinfo->image_width;
- y = cinfo->image_height;
- depth = cinfo->num_components;
-
- if (cinfo->jpeg_color_space == JCS_YCCK) cinfo->out_color_space = JCS_CMYK;
-
- jpeg_start_decompress(cinfo);
-
- if (flags & IB_test) {
- jpeg_abort_decompress(cinfo);
- ibuf = IMB_allocImBuf(x, y, 8 * depth, 0);
- }
- else if ((ibuf = IMB_allocImBuf(x, y, 8 * depth, IB_rect)) == NULL) {
- jpeg_abort_decompress(cinfo);
- }
- else {
- row_stride = cinfo->output_width * depth;
-
- row_pointer = (*cinfo->mem->alloc_sarray)((j_common_ptr) cinfo, JPOOL_IMAGE, row_stride, 1);
-
- for (y = ibuf->y - 1; y >= 0; y--) {
- jpeg_read_scanlines(cinfo, row_pointer, 1);
- rect = (uchar *) (ibuf->rect + y * ibuf->x);
- buffer = row_pointer[0];
-
- switch (depth) {
- case 1:
- for (x = ibuf->x; x > 0; x--) {
- rect[3] = 255;
- rect[0] = rect[1] = rect[2] = *buffer++;
- rect += 4;
- }
- break;
- case 3:
- for (x = ibuf->x; x > 0; x--) {
- rect[3] = 255;
- rect[0] = *buffer++;
- rect[1] = *buffer++;
- rect[2] = *buffer++;
- rect += 4;
- }
- break;
- case 4:
- for (x = ibuf->x; x > 0; x--) {
- r = *buffer++;
- g = *buffer++;
- b = *buffer++;
- k = *buffer++;
-
- r = (r * k) / 255;
- g = (g * k) / 255;
- b = (b * k) / 255;
-
- rect[3] = 255;
- rect[2] = b;
- rect[1] = g;
- rect[0] = r;
- rect += 4;
- }
- break;
- }
- }
-
- marker = cinfo->marker_list;
- while (marker) {
- if (marker->marker != JPEG_COM)
- goto next_stamp_marker;
-
- /*
- * JPEG marker strings are not null-terminated,
- * create a null-terminated copy before going further
- */
- str = BLI_strdupn((char *)marker->data, marker->data_length);
-
- /*
- * Because JPEG format don't support the
- * pair "key/value" like PNG, we store the
- * stampinfo in a single "encode" string:
- * "Blender:key:value"
- *
- * That is why we need split it to the
- * common key/value here.
- */
- if (!STREQLEN(str, "Blender", 7)) {
- /*
- * Maybe the file have text that
- * we don't know "what it's", in that
- * case we keep the text (with a
- * key "None").
- * This is only for don't "lose"
- * the information when we write
- * it back to disk.
- */
- IMB_metadata_ensure(&ibuf->metadata);
- IMB_metadata_set_field(ibuf->metadata, "None", str);
- ibuf->flags |= IB_metadata;
- MEM_freeN(str);
- goto next_stamp_marker;
- }
-
- key = strchr(str, ':');
- /*
- * A little paranoid, but the file maybe
- * is broken... and a "extra" check is better
- * then segfault ;)
- */
- if (!key) {
- MEM_freeN(str);
- goto next_stamp_marker;
- }
-
- key++;
- value = strchr(key, ':');
- if (!value) {
- MEM_freeN(str);
- goto next_stamp_marker;
- }
-
- *value = '\0'; /* need finish the key string */
- value++;
- IMB_metadata_ensure(&ibuf->metadata);
- IMB_metadata_set_field(ibuf->metadata, key, value);
- ibuf->flags |= IB_metadata;
- MEM_freeN(str);
-next_stamp_marker:
- marker = marker->next;
- }
-
- jpeg_finish_decompress(cinfo);
- }
-
- jpeg_destroy((j_common_ptr) cinfo);
- if (ibuf) {
- ibuf->ftype = IMB_FTYPE_JPG;
- ibuf->foptions.quality = MIN2(ibuf_quality, 100);
- }
- }
-
- return(ibuf);
+ JSAMPARRAY row_pointer;
+ JSAMPLE *buffer = NULL;
+ int row_stride;
+ int x, y, depth, r, g, b, k;
+ struct ImBuf *ibuf = NULL;
+ uchar *rect;
+ jpeg_saved_marker_ptr marker;
+ char *str, *key, *value;
+
+ /* install own app1 handler */
+ ibuf_quality = jpeg_default_quality;
+ jpeg_set_marker_processor(cinfo, 0xe1, handle_app1);
+ cinfo->dct_method = JDCT_FLOAT;
+ jpeg_save_markers(cinfo, JPEG_COM, 0xffff);
+
+ if (jpeg_read_header(cinfo, false) == JPEG_HEADER_OK) {
+ x = cinfo->image_width;
+ y = cinfo->image_height;
+ depth = cinfo->num_components;
+
+ if (cinfo->jpeg_color_space == JCS_YCCK)
+ cinfo->out_color_space = JCS_CMYK;
+
+ jpeg_start_decompress(cinfo);
+
+ if (flags & IB_test) {
+ jpeg_abort_decompress(cinfo);
+ ibuf = IMB_allocImBuf(x, y, 8 * depth, 0);
+ }
+ else if ((ibuf = IMB_allocImBuf(x, y, 8 * depth, IB_rect)) == NULL) {
+ jpeg_abort_decompress(cinfo);
+ }
+ else {
+ row_stride = cinfo->output_width * depth;
+
+ row_pointer = (*cinfo->mem->alloc_sarray)((j_common_ptr)cinfo, JPOOL_IMAGE, row_stride, 1);
+
+ for (y = ibuf->y - 1; y >= 0; y--) {
+ jpeg_read_scanlines(cinfo, row_pointer, 1);
+ rect = (uchar *)(ibuf->rect + y * ibuf->x);
+ buffer = row_pointer[0];
+
+ switch (depth) {
+ case 1:
+ for (x = ibuf->x; x > 0; x--) {
+ rect[3] = 255;
+ rect[0] = rect[1] = rect[2] = *buffer++;
+ rect += 4;
+ }
+ break;
+ case 3:
+ for (x = ibuf->x; x > 0; x--) {
+ rect[3] = 255;
+ rect[0] = *buffer++;
+ rect[1] = *buffer++;
+ rect[2] = *buffer++;
+ rect += 4;
+ }
+ break;
+ case 4:
+ for (x = ibuf->x; x > 0; x--) {
+ r = *buffer++;
+ g = *buffer++;
+ b = *buffer++;
+ k = *buffer++;
+
+ r = (r * k) / 255;
+ g = (g * k) / 255;
+ b = (b * k) / 255;
+
+ rect[3] = 255;
+ rect[2] = b;
+ rect[1] = g;
+ rect[0] = r;
+ rect += 4;
+ }
+ break;
+ }
+ }
+
+ marker = cinfo->marker_list;
+ while (marker) {
+ if (marker->marker != JPEG_COM)
+ goto next_stamp_marker;
+
+ /*
+ * JPEG marker strings are not null-terminated,
+ * create a null-terminated copy before going further
+ */
+ str = BLI_strdupn((char *)marker->data, marker->data_length);
+
+ /*
+ * Because JPEG format don't support the
+ * pair "key/value" like PNG, we store the
+ * stampinfo in a single "encode" string:
+ * "Blender:key:value"
+ *
+ * That is why we need split it to the
+ * common key/value here.
+ */
+ if (!STREQLEN(str, "Blender", 7)) {
+ /*
+ * Maybe the file have text that
+ * we don't know "what it's", in that
+ * case we keep the text (with a
+ * key "None").
+ * This is only for don't "lose"
+ * the information when we write
+ * it back to disk.
+ */
+ IMB_metadata_ensure(&ibuf->metadata);
+ IMB_metadata_set_field(ibuf->metadata, "None", str);
+ ibuf->flags |= IB_metadata;
+ MEM_freeN(str);
+ goto next_stamp_marker;
+ }
+
+ key = strchr(str, ':');
+ /*
+ * A little paranoid, but the file maybe
+ * is broken... and a "extra" check is better
+ * then segfault ;)
+ */
+ if (!key) {
+ MEM_freeN(str);
+ goto next_stamp_marker;
+ }
+
+ key++;
+ value = strchr(key, ':');
+ if (!value) {
+ MEM_freeN(str);
+ goto next_stamp_marker;
+ }
+
+ *value = '\0'; /* need finish the key string */
+ value++;
+ IMB_metadata_ensure(&ibuf->metadata);
+ IMB_metadata_set_field(ibuf->metadata, key, value);
+ ibuf->flags |= IB_metadata;
+ MEM_freeN(str);
+ next_stamp_marker:
+ marker = marker->next;
+ }
+
+ jpeg_finish_decompress(cinfo);
+ }
+
+ jpeg_destroy((j_common_ptr)cinfo);
+ if (ibuf) {
+ ibuf->ftype = IMB_FTYPE_JPG;
+ ibuf->foptions.quality = MIN2(ibuf_quality, 100);
+ }
+ }
+
+ return (ibuf);
}
-ImBuf *imb_load_jpeg(const unsigned char *buffer, size_t size, int flags, char colorspace[IM_MAX_SPACE])
+ImBuf *imb_load_jpeg(const unsigned char *buffer,
+ size_t size,
+ int flags,
+ char colorspace[IM_MAX_SPACE])
{
- struct jpeg_decompress_struct _cinfo, *cinfo = &_cinfo;
- struct my_error_mgr jerr;
- ImBuf *ibuf;
+ struct jpeg_decompress_struct _cinfo, *cinfo = &_cinfo;
+ struct my_error_mgr jerr;
+ ImBuf *ibuf;
- if (!imb_is_a_jpeg(buffer)) return NULL;
+ if (!imb_is_a_jpeg(buffer))
+ return NULL;
- colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE);
+ colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE);
- cinfo->err = jpeg_std_error(&jerr.pub);
- jerr.pub.error_exit = jpeg_error;
+ cinfo->err = jpeg_std_error(&jerr.pub);
+ jerr.pub.error_exit = jpeg_error;
- /* Establish the setjmp return context for my_error_exit to use. */
- if (setjmp(jerr.setjmp_buffer)) {
- /* If we get here, the JPEG code has signaled an error.
- * We need to clean up the JPEG object, close the input file, and return.
- */
- jpeg_destroy_decompress(cinfo);
- return NULL;
- }
+ /* Establish the setjmp return context for my_error_exit to use. */
+ if (setjmp(jerr.setjmp_buffer)) {
+ /* If we get here, the JPEG code has signaled an error.
+ * We need to clean up the JPEG object, close the input file, and return.
+ */
+ jpeg_destroy_decompress(cinfo);
+ return NULL;
+ }
- jpeg_create_decompress(cinfo);
- memory_source(cinfo, buffer, size);
+ jpeg_create_decompress(cinfo);
+ memory_source(cinfo, buffer, size);
- ibuf = ibJpegImageFromCinfo(cinfo, flags);
+ ibuf = ibJpegImageFromCinfo(cinfo, flags);
- return(ibuf);
+ return (ibuf);
}
-
static void write_jpeg(struct jpeg_compress_struct *cinfo, struct ImBuf *ibuf)
{
- JSAMPLE *buffer = NULL;
- JSAMPROW row_pointer[1];
- uchar *rect;
- int x, y;
- char neogeo[128];
- struct NeoGeo_Word *neogeo_word;
-
- jpeg_start_compress(cinfo, true);
-
- strcpy(neogeo, "NeoGeo");
- neogeo_word = (struct NeoGeo_Word *)(neogeo + 6);
- memset(neogeo_word, 0, sizeof(*neogeo_word));
- neogeo_word->quality = ibuf->foptions.quality;
- jpeg_write_marker(cinfo, 0xe1, (JOCTET *) neogeo, 10);
- if (ibuf->metadata) {
- IDProperty *prop;
- /* Static storage array for the short metadata. */
- char static_text[1024];
- const int static_text_size = ARRAY_SIZE(static_text);
- for (prop = ibuf->metadata->data.group.first; prop; prop = prop->next) {
- if (prop->type == IDP_STRING) {
- int text_len;
- if (!strcmp(prop->name, "None")) {
- jpeg_write_marker(cinfo, JPEG_COM, (JOCTET *) IDP_String(prop), prop->len + 1);
- }
-
- char *text = static_text;
- int text_size = static_text_size;
- /* 7 is for Blender, 2 colon separators, length of property
- * name and property value, followed by the NULL-terminator. */
- const int text_length_required = 7 + 2 + strlen(prop->name) + strlen(IDP_String(prop)) + 1;
- if (text_length_required <= static_text_size) {
- text = MEM_mallocN(text_length_required, "jpeg metadata field");
- text_size = text_length_required;
- }
-
- /*
- * The JPEG format don't support a pair "key/value"
- * like PNG, so we "encode" the stamp in a
- * single string:
- * "Blender:key:value"
- *
- * The first "Blender" is a simple identify to help
- * in the read process.
- */
- text_len = BLI_snprintf(text, text_size, "Blender:%s:%s", prop->name, IDP_String(prop));
- jpeg_write_marker(cinfo, JPEG_COM, (JOCTET *) text, text_len + 1);
-
- /* TODO(sergey): Ideally we will try to re-use allocation as
- * much as possible. In practice, such long fields don't happen
- * often. */
- if (text != static_text) {
- MEM_freeN(text);
- }
- }
- }
- }
-
- row_pointer[0] =
- MEM_mallocN(sizeof(JSAMPLE) *
- cinfo->input_components *
- cinfo->image_width, "jpeg row_pointer");
-
- for (y = ibuf->y - 1; y >= 0; y--) {
- rect = (uchar *) (ibuf->rect + y * ibuf->x);
- buffer = row_pointer[0];
-
- switch (cinfo->in_color_space) {
- case JCS_RGB:
- for (x = 0; x < ibuf->x; x++) {
- *buffer++ = rect[0];
- *buffer++ = rect[1];
- *buffer++ = rect[2];
- rect += 4;
- }
- break;
- case JCS_GRAYSCALE:
- for (x = 0; x < ibuf->x; x++) {
- *buffer++ = rect[0];
- rect += 4;
- }
- break;
- case JCS_UNKNOWN:
- memcpy(buffer, rect, 4 * ibuf->x);
- break;
- /* default was missing... intentional ? */
- default:
- /* do nothing */
- break;
- }
-
- jpeg_write_scanlines(cinfo, row_pointer, 1);
- }
-
- jpeg_finish_compress(cinfo);
- MEM_freeN(row_pointer[0]);
+ JSAMPLE *buffer = NULL;
+ JSAMPROW row_pointer[1];
+ uchar *rect;
+ int x, y;
+ char neogeo[128];
+ struct NeoGeo_Word *neogeo_word;
+
+ jpeg_start_compress(cinfo, true);
+
+ strcpy(neogeo, "NeoGeo");
+ neogeo_word = (struct NeoGeo_Word *)(neogeo + 6);
+ memset(neogeo_word, 0, sizeof(*neogeo_word));
+ neogeo_word->quality = ibuf->foptions.quality;
+ jpeg_write_marker(cinfo, 0xe1, (JOCTET *)neogeo, 10);
+ if (ibuf->metadata) {
+ IDProperty *prop;
+ /* Static storage array for the short metadata. */
+ char static_text[1024];
+ const int static_text_size = ARRAY_SIZE(static_text);
+ for (prop = ibuf->metadata->data.group.first; prop; prop = prop->next) {
+ if (prop->type == IDP_STRING) {
+ int text_len;
+ if (!strcmp(prop->name, "None")) {
+ jpeg_write_marker(cinfo, JPEG_COM, (JOCTET *)IDP_String(prop), prop->len + 1);
+ }
+
+ char *text = static_text;
+ int text_size = static_text_size;
+ /* 7 is for Blender, 2 colon separators, length of property
+ * name and property value, followed by the NULL-terminator. */
+ const int text_length_required = 7 + 2 + strlen(prop->name) + strlen(IDP_String(prop)) + 1;
+ if (text_length_required <= static_text_size) {
+ text = MEM_mallocN(text_length_required, "jpeg metadata field");
+ text_size = text_length_required;
+ }
+
+ /*
+ * The JPEG format don't support a pair "key/value"
+ * like PNG, so we "encode" the stamp in a
+ * single string:
+ * "Blender:key:value"
+ *
+ * The first "Blender" is a simple identify to help
+ * in the read process.
+ */
+ text_len = BLI_snprintf(text, text_size, "Blender:%s:%s", prop->name, IDP_String(prop));
+ jpeg_write_marker(cinfo, JPEG_COM, (JOCTET *)text, text_len + 1);
+
+ /* TODO(sergey): Ideally we will try to re-use allocation as
+ * much as possible. In practice, such long fields don't happen
+ * often. */
+ if (text != static_text) {
+ MEM_freeN(text);
+ }
+ }
+ }
+ }
+
+ row_pointer[0] = MEM_mallocN(sizeof(JSAMPLE) * cinfo->input_components * cinfo->image_width,
+ "jpeg row_pointer");
+
+ for (y = ibuf->y - 1; y >= 0; y--) {
+ rect = (uchar *)(ibuf->rect + y * ibuf->x);
+ buffer = row_pointer[0];
+
+ switch (cinfo->in_color_space) {
+ case JCS_RGB:
+ for (x = 0; x < ibuf->x; x++) {
+ *buffer++ = rect[0];
+ *buffer++ = rect[1];
+ *buffer++ = rect[2];
+ rect += 4;
+ }
+ break;
+ case JCS_GRAYSCALE:
+ for (x = 0; x < ibuf->x; x++) {
+ *buffer++ = rect[0];
+ rect += 4;
+ }
+ break;
+ case JCS_UNKNOWN:
+ memcpy(buffer, rect, 4 * ibuf->x);
+ break;
+ /* default was missing... intentional ? */
+ default:
+ /* do nothing */
+ break;
+ }
+
+ jpeg_write_scanlines(cinfo, row_pointer, 1);
+ }
+
+ jpeg_finish_compress(cinfo);
+ MEM_freeN(row_pointer[0]);
}
-
static int init_jpeg(FILE *outfile, struct jpeg_compress_struct *cinfo, struct ImBuf *ibuf)
{
- int quality;
+ int quality;
- quality = ibuf->foptions.quality;
- if (quality <= 0) quality = jpeg_default_quality;
- if (quality > 100) quality = 100;
+ quality = ibuf->foptions.quality;
+ if (quality <= 0)
+ quality = jpeg_default_quality;
+ if (quality > 100)
+ quality = 100;
- jpeg_create_compress(cinfo);
- jpeg_stdio_dest(cinfo, outfile);
+ jpeg_create_compress(cinfo);
+ jpeg_stdio_dest(cinfo, outfile);
- cinfo->image_width = ibuf->x;
- cinfo->image_height = ibuf->y;
+ cinfo->image_width = ibuf->x;
+ cinfo->image_height = ibuf->y;
- cinfo->in_color_space = JCS_RGB;
- if (ibuf->planes == 8) cinfo->in_color_space = JCS_GRAYSCALE;
+ cinfo->in_color_space = JCS_RGB;
+ if (ibuf->planes == 8)
+ cinfo->in_color_space = JCS_GRAYSCALE;
#if 0
- /* just write RGBA as RGB,
- * unsupported feature only confuses other s/w */
+ /* just write RGBA as RGB,
+ * unsupported feature only confuses other s/w */
- if (ibuf->planes == 32) cinfo->in_color_space = JCS_UNKNOWN;
+ if (ibuf->planes == 32) cinfo->in_color_space = JCS_UNKNOWN;
#endif
- switch (cinfo->in_color_space) {
- case JCS_RGB:
- cinfo->input_components = 3;
- break;
- case JCS_GRAYSCALE:
- cinfo->input_components = 1;
- break;
- case JCS_UNKNOWN:
- cinfo->input_components = 4;
- break;
- /* default was missing... intentional ? */
- default:
- /* do nothing */
- break;
- }
- jpeg_set_defaults(cinfo);
-
- /* own settings */
-
- cinfo->dct_method = JDCT_FLOAT;
- jpeg_set_quality(cinfo, quality, true);
-
- return(0);
+ switch (cinfo->in_color_space) {
+ case JCS_RGB:
+ cinfo->input_components = 3;
+ break;
+ case JCS_GRAYSCALE:
+ cinfo->input_components = 1;
+ break;
+ case JCS_UNKNOWN:
+ cinfo->input_components = 4;
+ break;
+ /* default was missing... intentional ? */
+ default:
+ /* do nothing */
+ break;
+ }
+ jpeg_set_defaults(cinfo);
+
+ /* own settings */
+
+ cinfo->dct_method = JDCT_FLOAT;
+ jpeg_set_quality(cinfo, quality, true);
+
+ return (0);
}
-
static int save_stdjpeg(const char *name, struct ImBuf *ibuf)
{
- FILE *outfile;
- struct jpeg_compress_struct _cinfo, *cinfo = &_cinfo;
- struct my_error_mgr jerr;
+ FILE *outfile;
+ struct jpeg_compress_struct _cinfo, *cinfo = &_cinfo;
+ struct my_error_mgr jerr;
- if ((outfile = BLI_fopen(name, "wb")) == NULL)
- return 0;
+ if ((outfile = BLI_fopen(name, "wb")) == NULL)
+ return 0;
- cinfo->err = jpeg_std_error(&jerr.pub);
- jerr.pub.error_exit = jpeg_error;
+ cinfo->err = jpeg_std_error(&jerr.pub);
+ jerr.pub.error_exit = jpeg_error;
- /* Establish the setjmp return context for jpeg_error to use. */
- if (setjmp(jerr.setjmp_buffer)) {
- /* If we get here, the JPEG code has signaled an error.
- * We need to clean up the JPEG object, close the input file, and return.
- */
- jpeg_destroy_compress(cinfo);
- fclose(outfile);
- remove(name);
- return 0;
- }
+ /* Establish the setjmp return context for jpeg_error to use. */
+ if (setjmp(jerr.setjmp_buffer)) {
+ /* If we get here, the JPEG code has signaled an error.
+ * We need to clean up the JPEG object, close the input file, and return.
+ */
+ jpeg_destroy_compress(cinfo);
+ fclose(outfile);
+ remove(name);
+ return 0;
+ }
- init_jpeg(outfile, cinfo, ibuf);
+ init_jpeg(outfile, cinfo, ibuf);
- write_jpeg(cinfo, ibuf);
+ write_jpeg(cinfo, ibuf);
- fclose(outfile);
- jpeg_destroy_compress(cinfo);
+ fclose(outfile);
+ jpeg_destroy_compress(cinfo);
- return 1;
+ return 1;
}
int imb_savejpeg(struct ImBuf *ibuf, const char *name, int flags)
{
- ibuf->flags = flags;
- return save_stdjpeg(name, ibuf);
+ ibuf->flags = flags;
+ return save_stdjpeg(name, ibuf);
}
diff --git a/source/blender/imbuf/intern/metadata.c b/source/blender/imbuf/intern/metadata.c
index cc4c2661ef2..ed3b214047a 100644
--- a/source/blender/imbuf/intern/metadata.c
+++ b/source/blender/imbuf/intern/metadata.c
@@ -21,7 +21,6 @@
* \ingroup imbuf
*/
-
#include <stdlib.h>
#include <string.h>
@@ -39,77 +38,79 @@
#define METADATA_MAX_VALUE_LENGTH 1024
-
void IMB_metadata_ensure(struct IDProperty **metadata)
{
- if (*metadata != NULL) {
- return;
- }
+ if (*metadata != NULL) {
+ return;
+ }
- IDPropertyTemplate val;
- *metadata = IDP_New(IDP_GROUP, &val, "metadata");
+ IDPropertyTemplate val;
+ *metadata = IDP_New(IDP_GROUP, &val, "metadata");
}
void IMB_metadata_free(struct IDProperty *metadata)
{
- if (metadata == NULL) {
- return;
- }
+ if (metadata == NULL) {
+ return;
+ }
- IDP_FreeProperty(metadata);
- MEM_freeN(metadata);
+ IDP_FreeProperty(metadata);
+ MEM_freeN(metadata);
}
-bool IMB_metadata_get_field(struct IDProperty *metadata, const char *key, char *field, const size_t len)
+bool IMB_metadata_get_field(struct IDProperty *metadata,
+ const char *key,
+ char *field,
+ const size_t len)
{
- IDProperty *prop;
+ IDProperty *prop;
- if (metadata == NULL) {
- return false;
- }
+ if (metadata == NULL) {
+ return false;
+ }
- prop = IDP_GetPropertyFromGroup(metadata, key);
+ prop = IDP_GetPropertyFromGroup(metadata, key);
- if (prop && prop->type == IDP_STRING) {
- BLI_strncpy(field, IDP_String(prop), len);
- return true;
- }
- return false;
+ if (prop && prop->type == IDP_STRING) {
+ BLI_strncpy(field, IDP_String(prop), len);
+ return true;
+ }
+ return false;
}
void IMB_metadata_copy(struct ImBuf *dimb, struct ImBuf *simb)
{
- BLI_assert(dimb != simb);
- if (simb->metadata) {
- IMB_metadata_free(dimb->metadata);
- dimb->metadata = IDP_CopyProperty(simb->metadata);
- }
+ BLI_assert(dimb != simb);
+ if (simb->metadata) {
+ IMB_metadata_free(dimb->metadata);
+ dimb->metadata = IDP_CopyProperty(simb->metadata);
+ }
}
void IMB_metadata_set_field(struct IDProperty *metadata, const char *key, const char *value)
{
- BLI_assert(metadata);
- IDProperty *prop = IDP_GetPropertyFromGroup(metadata, key);
+ BLI_assert(metadata);
+ IDProperty *prop = IDP_GetPropertyFromGroup(metadata, key);
- if (prop != NULL && prop->type != IDP_STRING) {
- IDP_FreeFromGroup(metadata, prop);
- prop = NULL;
- }
+ if (prop != NULL && prop->type != IDP_STRING) {
+ IDP_FreeFromGroup(metadata, prop);
+ prop = NULL;
+ }
- if (prop == NULL) {
- prop = IDP_NewString(value, key, METADATA_MAX_VALUE_LENGTH);
- IDP_AddToGroup(metadata, prop);
- }
+ if (prop == NULL) {
+ prop = IDP_NewString(value, key, METADATA_MAX_VALUE_LENGTH);
+ IDP_AddToGroup(metadata, prop);
+ }
- IDP_AssignString(prop, value, METADATA_MAX_VALUE_LENGTH);
+ IDP_AssignString(prop, value, METADATA_MAX_VALUE_LENGTH);
}
void IMB_metadata_foreach(struct ImBuf *ibuf, IMBMetadataForeachCb callback, void *userdata)
{
- if (ibuf->metadata == NULL) {
- return;
- }
- for (IDProperty *prop = ibuf->metadata->data.group.first; prop != NULL; prop = prop->next) {
- callback(prop->name, IDP_String(prop), userdata);
- }
+ if (ibuf->metadata == NULL) {
+ return;
+ }
+ for (IDProperty *prop = ibuf->metadata->data.group.first; prop != NULL; prop = prop->next) {
+ callback(prop->name, IDP_String(prop), userdata);
+ }
}
diff --git a/source/blender/imbuf/intern/module.c b/source/blender/imbuf/intern/module.c
index c22ac2c9bfc..dc3d4cfbb62 100644
--- a/source/blender/imbuf/intern/module.c
+++ b/source/blender/imbuf/intern/module.c
@@ -18,7 +18,6 @@
* \ingroup imbuf
*/
-
#include <stddef.h>
#include "BLI_utildefines.h"
@@ -30,18 +29,18 @@
void IMB_init(void)
{
- imb_refcounter_lock_init();
- imb_mmap_lock_init();
- imb_filetypes_init();
- imb_tile_cache_init();
- colormanagement_init();
+ imb_refcounter_lock_init();
+ imb_mmap_lock_init();
+ imb_filetypes_init();
+ imb_tile_cache_init();
+ colormanagement_init();
}
void IMB_exit(void)
{
- imb_tile_cache_exit();
- imb_filetypes_exit();
- colormanagement_exit();
- imb_mmap_lock_exit();
- imb_refcounter_lock_exit();
+ imb_tile_cache_exit();
+ imb_filetypes_exit();
+ colormanagement_exit();
+ imb_mmap_lock_exit();
+ imb_refcounter_lock_exit();
}
diff --git a/source/blender/imbuf/intern/moviecache.c b/source/blender/imbuf/intern/moviecache.c
index 78a45d29775..fe6909b0f3f 100644
--- a/source/blender/imbuf/intern/moviecache.c
+++ b/source/blender/imbuf/intern/moviecache.c
@@ -42,7 +42,7 @@
#ifdef DEBUG_MESSAGES
# if defined __GNUC__
-# define PRINT(format, args ...) printf(format, ##args)
+# define PRINT(format, args...) printf(format, ##args)
# else
# define PRINT(format, ...) printf(__VA_ARGS__)
# endif
@@ -54,552 +54,562 @@ static MEM_CacheLimiterC *limitor = NULL;
static pthread_mutex_t limitor_lock = BLI_MUTEX_INITIALIZER;
typedef struct MovieCache {
- char name[64];
+ char name[64];
- GHash *hash;
- GHashHashFP hashfp;
- GHashCmpFP cmpfp;
- MovieCacheGetKeyDataFP getdatafp;
+ GHash *hash;
+ GHashHashFP hashfp;
+ GHashCmpFP cmpfp;
+ MovieCacheGetKeyDataFP getdatafp;
- MovieCacheGetPriorityDataFP getprioritydatafp;
- MovieCacheGetItemPriorityFP getitempriorityfp;
- MovieCachePriorityDeleterFP prioritydeleterfp;
+ MovieCacheGetPriorityDataFP getprioritydatafp;
+ MovieCacheGetItemPriorityFP getitempriorityfp;
+ MovieCachePriorityDeleterFP prioritydeleterfp;
- struct BLI_mempool *keys_pool;
- struct BLI_mempool *items_pool;
- struct BLI_mempool *userkeys_pool;
+ struct BLI_mempool *keys_pool;
+ struct BLI_mempool *items_pool;
+ struct BLI_mempool *userkeys_pool;
- int keysize;
+ int keysize;
- void *last_userkey;
+ void *last_userkey;
- int totseg, *points, proxy, render_flags; /* for visual statistics optimization */
- int pad;
+ int totseg, *points, proxy, render_flags; /* for visual statistics optimization */
+ int pad;
} MovieCache;
typedef struct MovieCacheKey {
- MovieCache *cache_owner;
- void *userkey;
+ MovieCache *cache_owner;
+ void *userkey;
} MovieCacheKey;
typedef struct MovieCacheItem {
- MovieCache *cache_owner;
- ImBuf *ibuf;
- MEM_CacheLimiterHandleC *c_handle;
- void *priority_data;
+ MovieCache *cache_owner;
+ ImBuf *ibuf;
+ MEM_CacheLimiterHandleC *c_handle;
+ void *priority_data;
} MovieCacheItem;
static unsigned int moviecache_hashhash(const void *keyv)
{
- const MovieCacheKey *key = keyv;
+ const MovieCacheKey *key = keyv;
- return key->cache_owner->hashfp(key->userkey);
+ return key->cache_owner->hashfp(key->userkey);
}
static bool moviecache_hashcmp(const void *av, const void *bv)
{
- const MovieCacheKey *a = av;
- const MovieCacheKey *b = bv;
+ const MovieCacheKey *a = av;
+ const MovieCacheKey *b = bv;
- return a->cache_owner->cmpfp(a->userkey, b->userkey);
+ return a->cache_owner->cmpfp(a->userkey, b->userkey);
}
static void moviecache_keyfree(void *val)
{
- MovieCacheKey *key = val;
+ MovieCacheKey *key = val;
- BLI_mempool_free(key->cache_owner->userkeys_pool, key->userkey);
+ BLI_mempool_free(key->cache_owner->userkeys_pool, key->userkey);
- BLI_mempool_free(key->cache_owner->keys_pool, key);
+ BLI_mempool_free(key->cache_owner->keys_pool, key);
}
static void moviecache_valfree(void *val)
{
- MovieCacheItem *item = (MovieCacheItem *)val;
- MovieCache *cache = item->cache_owner;
+ MovieCacheItem *item = (MovieCacheItem *)val;
+ MovieCache *cache = item->cache_owner;
- PRINT("%s: cache '%s' free item %p buffer %p\n", __func__, cache->name, item, item->ibuf);
+ PRINT("%s: cache '%s' free item %p buffer %p\n", __func__, cache->name, item, item->ibuf);
- if (item->ibuf) {
- MEM_CacheLimiter_unmanage(item->c_handle);
- IMB_freeImBuf(item->ibuf);
- }
+ if (item->ibuf) {
+ MEM_CacheLimiter_unmanage(item->c_handle);
+ IMB_freeImBuf(item->ibuf);
+ }
- if (item->priority_data && cache->prioritydeleterfp) {
- cache->prioritydeleterfp(item->priority_data);
- }
+ if (item->priority_data && cache->prioritydeleterfp) {
+ cache->prioritydeleterfp(item->priority_data);
+ }
- BLI_mempool_free(item->cache_owner->items_pool, item);
+ BLI_mempool_free(item->cache_owner->items_pool, item);
}
static void check_unused_keys(MovieCache *cache)
{
- GHashIterator gh_iter;
+ GHashIterator gh_iter;
- BLI_ghashIterator_init(&gh_iter, cache->hash);
+ BLI_ghashIterator_init(&gh_iter, cache->hash);
- while (!BLI_ghashIterator_done(&gh_iter)) {
- const MovieCacheKey *key = BLI_ghashIterator_getKey(&gh_iter);
- const MovieCacheItem *item = BLI_ghashIterator_getValue(&gh_iter);
- bool remove;
+ while (!BLI_ghashIterator_done(&gh_iter)) {
+ const MovieCacheKey *key = BLI_ghashIterator_getKey(&gh_iter);
+ const MovieCacheItem *item = BLI_ghashIterator_getValue(&gh_iter);
+ bool remove;
- BLI_ghashIterator_step(&gh_iter);
+ BLI_ghashIterator_step(&gh_iter);
- remove = !item->ibuf;
+ remove = !item->ibuf;
- if (remove) {
- PRINT("%s: cache '%s' remove item %p without buffer\n", __func__, cache->name, item);
- }
+ if (remove) {
+ PRINT("%s: cache '%s' remove item %p without buffer\n", __func__, cache->name, item);
+ }
- if (remove)
- BLI_ghash_remove(cache->hash, key, moviecache_keyfree, moviecache_valfree);
- }
+ if (remove)
+ BLI_ghash_remove(cache->hash, key, moviecache_keyfree, moviecache_valfree);
+ }
}
static int compare_int(const void *av, const void *bv)
{
- const int *a = av;
- const int *b = bv;
- return *a - *b;
+ const int *a = av;
+ const int *b = bv;
+ return *a - *b;
}
static void IMB_moviecache_destructor(void *p)
{
- MovieCacheItem *item = (MovieCacheItem *)p;
+ MovieCacheItem *item = (MovieCacheItem *)p;
- if (item && item->ibuf) {
- MovieCache *cache = item->cache_owner;
+ if (item && item->ibuf) {
+ MovieCache *cache = item->cache_owner;
- PRINT("%s: cache '%s' destroy item %p buffer %p\n", __func__, cache->name, item, item->ibuf);
+ PRINT("%s: cache '%s' destroy item %p buffer %p\n", __func__, cache->name, item, item->ibuf);
- IMB_freeImBuf(item->ibuf);
+ IMB_freeImBuf(item->ibuf);
- item->ibuf = NULL;
- item->c_handle = NULL;
+ item->ibuf = NULL;
+ item->c_handle = NULL;
- /* force cached segments to be updated */
- if (cache->points) {
- MEM_freeN(cache->points);
- cache->points = NULL;
- }
- }
+ /* force cached segments to be updated */
+ if (cache->points) {
+ MEM_freeN(cache->points);
+ cache->points = NULL;
+ }
+ }
}
/* approximate size of ImBuf in memory */
static size_t IMB_get_size_in_memory(ImBuf *ibuf)
{
- int a;
- size_t size = 0, channel_size = 0;
-
- /* Persistent images should have no affect on how "normal"
- * images are cached.
- *
- * This is a bit arbitrary, but would make it so only movies
- * and sequences are memory limited, keeping textures in the
- * memory in order to avoid constant file reload on viewport
- * update.
- */
- if (ibuf->userflags & IB_PERSISTENT) {
- return 0;
- }
-
- size += sizeof(ImBuf);
-
- if (ibuf->rect)
- channel_size += sizeof(char);
-
- if (ibuf->rect_float)
- channel_size += sizeof(float);
-
- size += channel_size * ibuf->x * ibuf->y * ibuf->channels;
-
- if (ibuf->miptot) {
- for (a = 0; a < ibuf->miptot; a++) {
- if (ibuf->mipmap[a])
- size += IMB_get_size_in_memory(ibuf->mipmap[a]);
- }
- }
-
- if (ibuf->tiles) {
- size += sizeof(unsigned int) * ibuf->ytiles * ibuf->xtiles;
- }
-
- return size;
+ int a;
+ size_t size = 0, channel_size = 0;
+
+ /* Persistent images should have no affect on how "normal"
+ * images are cached.
+ *
+ * This is a bit arbitrary, but would make it so only movies
+ * and sequences are memory limited, keeping textures in the
+ * memory in order to avoid constant file reload on viewport
+ * update.
+ */
+ if (ibuf->userflags & IB_PERSISTENT) {
+ return 0;
+ }
+
+ size += sizeof(ImBuf);
+
+ if (ibuf->rect)
+ channel_size += sizeof(char);
+
+ if (ibuf->rect_float)
+ channel_size += sizeof(float);
+
+ size += channel_size * ibuf->x * ibuf->y * ibuf->channels;
+
+ if (ibuf->miptot) {
+ for (a = 0; a < ibuf->miptot; a++) {
+ if (ibuf->mipmap[a])
+ size += IMB_get_size_in_memory(ibuf->mipmap[a]);
+ }
+ }
+
+ if (ibuf->tiles) {
+ size += sizeof(unsigned int) * ibuf->ytiles * ibuf->xtiles;
+ }
+
+ return size;
}
static size_t get_item_size(void *p)
{
- size_t size = sizeof(MovieCacheItem);
- MovieCacheItem *item = (MovieCacheItem *) p;
+ size_t size = sizeof(MovieCacheItem);
+ MovieCacheItem *item = (MovieCacheItem *)p;
- if (item->ibuf)
- size += IMB_get_size_in_memory(item->ibuf);
+ if (item->ibuf)
+ size += IMB_get_size_in_memory(item->ibuf);
- return size;
+ return size;
}
static int get_item_priority(void *item_v, int default_priority)
{
- MovieCacheItem *item = (MovieCacheItem *) item_v;
- MovieCache *cache = item->cache_owner;
- int priority;
+ MovieCacheItem *item = (MovieCacheItem *)item_v;
+ MovieCache *cache = item->cache_owner;
+ int priority;
- if (!cache->getitempriorityfp) {
- PRINT("%s: cache '%s' item %p use default priority %d\n", __func__, cache-> name, item, default_priority);
+ if (!cache->getitempriorityfp) {
+ PRINT("%s: cache '%s' item %p use default priority %d\n",
+ __func__,
+ cache->name,
+ item,
+ default_priority);
- return default_priority;
- }
+ return default_priority;
+ }
- priority = cache->getitempriorityfp(cache->last_userkey, item->priority_data);
+ priority = cache->getitempriorityfp(cache->last_userkey, item->priority_data);
- PRINT("%s: cache '%s' item %p priority %d\n", __func__, cache-> name, item, priority);
+ PRINT("%s: cache '%s' item %p priority %d\n", __func__, cache->name, item, priority);
- return priority;
+ return priority;
}
static bool get_item_destroyable(void *item_v)
{
- MovieCacheItem *item = (MovieCacheItem *) item_v;
- /* IB_BITMAPDIRTY means image was modified from inside blender and
- * changes are not saved to disk.
- *
- * Such buffers are never to be freed.
- */
- if ((item->ibuf->userflags & IB_BITMAPDIRTY) ||
- (item->ibuf->userflags & IB_PERSISTENT))
- {
- return false;
- }
- return true;
+ MovieCacheItem *item = (MovieCacheItem *)item_v;
+ /* IB_BITMAPDIRTY means image was modified from inside blender and
+ * changes are not saved to disk.
+ *
+ * Such buffers are never to be freed.
+ */
+ if ((item->ibuf->userflags & IB_BITMAPDIRTY) || (item->ibuf->userflags & IB_PERSISTENT)) {
+ return false;
+ }
+ return true;
}
void IMB_moviecache_init(void)
{
- limitor = new_MEM_CacheLimiter(IMB_moviecache_destructor, get_item_size);
+ limitor = new_MEM_CacheLimiter(IMB_moviecache_destructor, get_item_size);
- MEM_CacheLimiter_ItemPriority_Func_set(limitor, get_item_priority);
- MEM_CacheLimiter_ItemDestroyable_Func_set(limitor, get_item_destroyable);
+ MEM_CacheLimiter_ItemPriority_Func_set(limitor, get_item_priority);
+ MEM_CacheLimiter_ItemDestroyable_Func_set(limitor, get_item_destroyable);
}
void IMB_moviecache_destruct(void)
{
- if (limitor)
- delete_MEM_CacheLimiter(limitor);
+ if (limitor)
+ delete_MEM_CacheLimiter(limitor);
}
-MovieCache *IMB_moviecache_create(const char *name, int keysize, GHashHashFP hashfp, GHashCmpFP cmpfp)
+MovieCache *IMB_moviecache_create(const char *name,
+ int keysize,
+ GHashHashFP hashfp,
+ GHashCmpFP cmpfp)
{
- MovieCache *cache;
+ MovieCache *cache;
- PRINT("%s: cache '%s' create\n", __func__, name);
+ PRINT("%s: cache '%s' create\n", __func__, name);
- cache = MEM_callocN(sizeof(MovieCache), "MovieCache");
+ cache = MEM_callocN(sizeof(MovieCache), "MovieCache");
- BLI_strncpy(cache->name, name, sizeof(cache->name));
+ BLI_strncpy(cache->name, name, sizeof(cache->name));
- cache->keys_pool = BLI_mempool_create(sizeof(MovieCacheKey), 0, 64, BLI_MEMPOOL_NOP);
- cache->items_pool = BLI_mempool_create(sizeof(MovieCacheItem), 0, 64, BLI_MEMPOOL_NOP);
- cache->userkeys_pool = BLI_mempool_create(keysize, 0, 64, BLI_MEMPOOL_NOP);
- cache->hash = BLI_ghash_new(moviecache_hashhash, moviecache_hashcmp, "MovieClip ImBuf cache hash");
+ cache->keys_pool = BLI_mempool_create(sizeof(MovieCacheKey), 0, 64, BLI_MEMPOOL_NOP);
+ cache->items_pool = BLI_mempool_create(sizeof(MovieCacheItem), 0, 64, BLI_MEMPOOL_NOP);
+ cache->userkeys_pool = BLI_mempool_create(keysize, 0, 64, BLI_MEMPOOL_NOP);
+ cache->hash = BLI_ghash_new(
+ moviecache_hashhash, moviecache_hashcmp, "MovieClip ImBuf cache hash");
- cache->keysize = keysize;
- cache->hashfp = hashfp;
- cache->cmpfp = cmpfp;
- cache->proxy = -1;
+ cache->keysize = keysize;
+ cache->hashfp = hashfp;
+ cache->cmpfp = cmpfp;
+ cache->proxy = -1;
- return cache;
+ return cache;
}
void IMB_moviecache_set_getdata_callback(MovieCache *cache, MovieCacheGetKeyDataFP getdatafp)
{
- cache->getdatafp = getdatafp;
+ cache->getdatafp = getdatafp;
}
-void IMB_moviecache_set_priority_callback(struct MovieCache *cache, MovieCacheGetPriorityDataFP getprioritydatafp,
+void IMB_moviecache_set_priority_callback(struct MovieCache *cache,
+ MovieCacheGetPriorityDataFP getprioritydatafp,
MovieCacheGetItemPriorityFP getitempriorityfp,
MovieCachePriorityDeleterFP prioritydeleterfp)
{
- cache->last_userkey = MEM_mallocN(cache->keysize, "movie cache last user key");
+ cache->last_userkey = MEM_mallocN(cache->keysize, "movie cache last user key");
- cache->getprioritydatafp = getprioritydatafp;
- cache->getitempriorityfp = getitempriorityfp;
- cache->prioritydeleterfp = prioritydeleterfp;
+ cache->getprioritydatafp = getprioritydatafp;
+ cache->getitempriorityfp = getitempriorityfp;
+ cache->prioritydeleterfp = prioritydeleterfp;
}
static void do_moviecache_put(MovieCache *cache, void *userkey, ImBuf *ibuf, bool need_lock)
{
- MovieCacheKey *key;
- MovieCacheItem *item;
+ MovieCacheKey *key;
+ MovieCacheItem *item;
- if (!limitor)
- IMB_moviecache_init();
+ if (!limitor)
+ IMB_moviecache_init();
- IMB_refImBuf(ibuf);
+ IMB_refImBuf(ibuf);
- key = BLI_mempool_alloc(cache->keys_pool);
- key->cache_owner = cache;
- key->userkey = BLI_mempool_alloc(cache->userkeys_pool);
- memcpy(key->userkey, userkey, cache->keysize);
+ key = BLI_mempool_alloc(cache->keys_pool);
+ key->cache_owner = cache;
+ key->userkey = BLI_mempool_alloc(cache->userkeys_pool);
+ memcpy(key->userkey, userkey, cache->keysize);
- item = BLI_mempool_alloc(cache->items_pool);
+ item = BLI_mempool_alloc(cache->items_pool);
- PRINT("%s: cache '%s' put %p, item %p\n", __func__, cache-> name, ibuf, item);
+ PRINT("%s: cache '%s' put %p, item %p\n", __func__, cache->name, ibuf, item);
- item->ibuf = ibuf;
- item->cache_owner = cache;
- item->c_handle = NULL;
- item->priority_data = NULL;
+ item->ibuf = ibuf;
+ item->cache_owner = cache;
+ item->c_handle = NULL;
+ item->priority_data = NULL;
- if (cache->getprioritydatafp) {
- item->priority_data = cache->getprioritydatafp(userkey);
- }
+ if (cache->getprioritydatafp) {
+ item->priority_data = cache->getprioritydatafp(userkey);
+ }
- BLI_ghash_reinsert(cache->hash, key, item, moviecache_keyfree, moviecache_valfree);
+ BLI_ghash_reinsert(cache->hash, key, item, moviecache_keyfree, moviecache_valfree);
- if (cache->last_userkey) {
- memcpy(cache->last_userkey, userkey, cache->keysize);
- }
+ if (cache->last_userkey) {
+ memcpy(cache->last_userkey, userkey, cache->keysize);
+ }
- if (need_lock)
- BLI_mutex_lock(&limitor_lock);
+ if (need_lock)
+ BLI_mutex_lock(&limitor_lock);
- item->c_handle = MEM_CacheLimiter_insert(limitor, item);
+ item->c_handle = MEM_CacheLimiter_insert(limitor, item);
- MEM_CacheLimiter_ref(item->c_handle);
- MEM_CacheLimiter_enforce_limits(limitor);
- MEM_CacheLimiter_unref(item->c_handle);
+ MEM_CacheLimiter_ref(item->c_handle);
+ MEM_CacheLimiter_enforce_limits(limitor);
+ MEM_CacheLimiter_unref(item->c_handle);
- if (need_lock)
- BLI_mutex_unlock(&limitor_lock);
+ if (need_lock)
+ BLI_mutex_unlock(&limitor_lock);
- /* cache limiter can't remove unused keys which points to destroyed values */
- check_unused_keys(cache);
+ /* cache limiter can't remove unused keys which points to destroyed values */
+ check_unused_keys(cache);
- if (cache->points) {
- MEM_freeN(cache->points);
- cache->points = NULL;
- }
+ if (cache->points) {
+ MEM_freeN(cache->points);
+ cache->points = NULL;
+ }
}
void IMB_moviecache_put(MovieCache *cache, void *userkey, ImBuf *ibuf)
{
- do_moviecache_put(cache, userkey, ibuf, true);
+ do_moviecache_put(cache, userkey, ibuf, true);
}
bool IMB_moviecache_put_if_possible(MovieCache *cache, void *userkey, ImBuf *ibuf)
{
- size_t mem_in_use, mem_limit, elem_size;
- bool result = false;
+ size_t mem_in_use, mem_limit, elem_size;
+ bool result = false;
- elem_size = IMB_get_size_in_memory(ibuf);
- mem_limit = MEM_CacheLimiter_get_maximum();
+ elem_size = IMB_get_size_in_memory(ibuf);
+ mem_limit = MEM_CacheLimiter_get_maximum();
- BLI_mutex_lock(&limitor_lock);
- mem_in_use = MEM_CacheLimiter_get_memory_in_use(limitor);
+ BLI_mutex_lock(&limitor_lock);
+ mem_in_use = MEM_CacheLimiter_get_memory_in_use(limitor);
- if (mem_in_use + elem_size <= mem_limit) {
- do_moviecache_put(cache, userkey, ibuf, false);
- result = true;
- }
+ if (mem_in_use + elem_size <= mem_limit) {
+ do_moviecache_put(cache, userkey, ibuf, false);
+ result = true;
+ }
- BLI_mutex_unlock(&limitor_lock);
+ BLI_mutex_unlock(&limitor_lock);
- return result;
+ return result;
}
ImBuf *IMB_moviecache_get(MovieCache *cache, void *userkey)
{
- MovieCacheKey key;
- MovieCacheItem *item;
+ MovieCacheKey key;
+ MovieCacheItem *item;
- key.cache_owner = cache;
- key.userkey = userkey;
- item = (MovieCacheItem *)BLI_ghash_lookup(cache->hash, &key);
+ key.cache_owner = cache;
+ key.userkey = userkey;
+ item = (MovieCacheItem *)BLI_ghash_lookup(cache->hash, &key);
- if (item) {
- if (item->ibuf) {
- BLI_mutex_lock(&limitor_lock);
- MEM_CacheLimiter_touch(item->c_handle);
- BLI_mutex_unlock(&limitor_lock);
+ if (item) {
+ if (item->ibuf) {
+ BLI_mutex_lock(&limitor_lock);
+ MEM_CacheLimiter_touch(item->c_handle);
+ BLI_mutex_unlock(&limitor_lock);
- IMB_refImBuf(item->ibuf);
+ IMB_refImBuf(item->ibuf);
- return item->ibuf;
- }
- }
+ return item->ibuf;
+ }
+ }
- return NULL;
+ return NULL;
}
bool IMB_moviecache_has_frame(MovieCache *cache, void *userkey)
{
- MovieCacheKey key;
- MovieCacheItem *item;
+ MovieCacheKey key;
+ MovieCacheItem *item;
- key.cache_owner = cache;
- key.userkey = userkey;
- item = (MovieCacheItem *)BLI_ghash_lookup(cache->hash, &key);
+ key.cache_owner = cache;
+ key.userkey = userkey;
+ item = (MovieCacheItem *)BLI_ghash_lookup(cache->hash, &key);
- return item != NULL;
+ return item != NULL;
}
void IMB_moviecache_free(MovieCache *cache)
{
- PRINT("%s: cache '%s' free\n", __func__, cache->name);
+ PRINT("%s: cache '%s' free\n", __func__, cache->name);
- BLI_ghash_free(cache->hash, moviecache_keyfree, moviecache_valfree);
+ BLI_ghash_free(cache->hash, moviecache_keyfree, moviecache_valfree);
- BLI_mempool_destroy(cache->keys_pool);
- BLI_mempool_destroy(cache->items_pool);
- BLI_mempool_destroy(cache->userkeys_pool);
+ BLI_mempool_destroy(cache->keys_pool);
+ BLI_mempool_destroy(cache->items_pool);
+ BLI_mempool_destroy(cache->userkeys_pool);
- if (cache->points)
- MEM_freeN(cache->points);
+ if (cache->points)
+ MEM_freeN(cache->points);
- if (cache->last_userkey)
- MEM_freeN(cache->last_userkey);
+ if (cache->last_userkey)
+ MEM_freeN(cache->last_userkey);
- MEM_freeN(cache);
+ MEM_freeN(cache);
}
-void IMB_moviecache_cleanup(MovieCache *cache, bool (cleanup_check_cb) (ImBuf *ibuf, void *userkey, void *userdata), void *userdata)
+void IMB_moviecache_cleanup(MovieCache *cache,
+ bool(cleanup_check_cb)(ImBuf *ibuf, void *userkey, void *userdata),
+ void *userdata)
{
- GHashIterator gh_iter;
+ GHashIterator gh_iter;
- check_unused_keys(cache);
+ check_unused_keys(cache);
- BLI_ghashIterator_init(&gh_iter, cache->hash);
+ BLI_ghashIterator_init(&gh_iter, cache->hash);
- while (!BLI_ghashIterator_done(&gh_iter)) {
- MovieCacheKey *key = BLI_ghashIterator_getKey(&gh_iter);
- MovieCacheItem *item = BLI_ghashIterator_getValue(&gh_iter);
+ while (!BLI_ghashIterator_done(&gh_iter)) {
+ MovieCacheKey *key = BLI_ghashIterator_getKey(&gh_iter);
+ MovieCacheItem *item = BLI_ghashIterator_getValue(&gh_iter);
- BLI_ghashIterator_step(&gh_iter);
+ BLI_ghashIterator_step(&gh_iter);
- if (cleanup_check_cb(item->ibuf, key->userkey, userdata)) {
- PRINT("%s: cache '%s' remove item %p\n", __func__, cache->name, item);
+ if (cleanup_check_cb(item->ibuf, key->userkey, userdata)) {
+ PRINT("%s: cache '%s' remove item %p\n", __func__, cache->name, item);
- BLI_ghash_remove(cache->hash, key, moviecache_keyfree, moviecache_valfree);
- }
- }
+ BLI_ghash_remove(cache->hash, key, moviecache_keyfree, moviecache_valfree);
+ }
+ }
}
/* get segments of cached frames. useful for debugging cache policies */
-void IMB_moviecache_get_cache_segments(MovieCache *cache, int proxy, int render_flags, int *totseg_r, int **points_r)
+void IMB_moviecache_get_cache_segments(
+ MovieCache *cache, int proxy, int render_flags, int *totseg_r, int **points_r)
{
- *totseg_r = 0;
- *points_r = NULL;
-
- if (!cache->getdatafp)
- return;
-
- if (cache->proxy != proxy || cache->render_flags != render_flags) {
- if (cache->points)
- MEM_freeN(cache->points);
-
- cache->points = NULL;
- }
-
- if (cache->points) {
- *totseg_r = cache->totseg;
- *points_r = cache->points;
- }
- else {
- int totframe = BLI_ghash_len(cache->hash);
- int *frames = MEM_callocN(totframe * sizeof(int), "movieclip cache frames");
- int a, totseg = 0;
- GHashIterator gh_iter;
-
- a = 0;
- GHASH_ITER(gh_iter, cache->hash) {
- MovieCacheKey *key = BLI_ghashIterator_getKey(&gh_iter);
- MovieCacheItem *item = BLI_ghashIterator_getValue(&gh_iter);
- int framenr, curproxy, curflags;
-
- if (item->ibuf) {
- cache->getdatafp(key->userkey, &framenr, &curproxy, &curflags);
-
- if (curproxy == proxy && curflags == render_flags)
- frames[a++] = framenr;
- }
- }
-
- qsort(frames, totframe, sizeof(int), compare_int);
-
- /* count */
- for (a = 0; a < totframe; a++) {
- if (a && frames[a] - frames[a - 1] != 1)
- totseg++;
-
- if (a == totframe - 1)
- totseg++;
- }
-
- if (totseg) {
- int b, *points;
-
- points = MEM_callocN(2 * sizeof(int) * totseg, "movieclip cache segments");
-
- /* fill */
- for (a = 0, b = 0; a < totframe; a++) {
- if (a == 0)
- points[b++] = frames[a];
-
- if (a && frames[a] - frames[a - 1] != 1) {
- points[b++] = frames[a - 1];
- points[b++] = frames[a];
- }
-
- if (a == totframe - 1)
- points[b++] = frames[a];
- }
-
- *totseg_r = totseg;
- *points_r = points;
-
- cache->totseg = totseg;
- cache->points = points;
- cache->proxy = proxy;
- cache->render_flags = render_flags;
- }
-
- MEM_freeN(frames);
- }
+ *totseg_r = 0;
+ *points_r = NULL;
+
+ if (!cache->getdatafp)
+ return;
+
+ if (cache->proxy != proxy || cache->render_flags != render_flags) {
+ if (cache->points)
+ MEM_freeN(cache->points);
+
+ cache->points = NULL;
+ }
+
+ if (cache->points) {
+ *totseg_r = cache->totseg;
+ *points_r = cache->points;
+ }
+ else {
+ int totframe = BLI_ghash_len(cache->hash);
+ int *frames = MEM_callocN(totframe * sizeof(int), "movieclip cache frames");
+ int a, totseg = 0;
+ GHashIterator gh_iter;
+
+ a = 0;
+ GHASH_ITER (gh_iter, cache->hash) {
+ MovieCacheKey *key = BLI_ghashIterator_getKey(&gh_iter);
+ MovieCacheItem *item = BLI_ghashIterator_getValue(&gh_iter);
+ int framenr, curproxy, curflags;
+
+ if (item->ibuf) {
+ cache->getdatafp(key->userkey, &framenr, &curproxy, &curflags);
+
+ if (curproxy == proxy && curflags == render_flags)
+ frames[a++] = framenr;
+ }
+ }
+
+ qsort(frames, totframe, sizeof(int), compare_int);
+
+ /* count */
+ for (a = 0; a < totframe; a++) {
+ if (a && frames[a] - frames[a - 1] != 1)
+ totseg++;
+
+ if (a == totframe - 1)
+ totseg++;
+ }
+
+ if (totseg) {
+ int b, *points;
+
+ points = MEM_callocN(2 * sizeof(int) * totseg, "movieclip cache segments");
+
+ /* fill */
+ for (a = 0, b = 0; a < totframe; a++) {
+ if (a == 0)
+ points[b++] = frames[a];
+
+ if (a && frames[a] - frames[a - 1] != 1) {
+ points[b++] = frames[a - 1];
+ points[b++] = frames[a];
+ }
+
+ if (a == totframe - 1)
+ points[b++] = frames[a];
+ }
+
+ *totseg_r = totseg;
+ *points_r = points;
+
+ cache->totseg = totseg;
+ cache->points = points;
+ cache->proxy = proxy;
+ cache->render_flags = render_flags;
+ }
+
+ MEM_freeN(frames);
+ }
}
struct MovieCacheIter *IMB_moviecacheIter_new(MovieCache *cache)
{
- GHashIterator *iter;
+ GHashIterator *iter;
- check_unused_keys(cache);
- iter = BLI_ghashIterator_new(cache->hash);
+ check_unused_keys(cache);
+ iter = BLI_ghashIterator_new(cache->hash);
- return (struct MovieCacheIter *) iter;
+ return (struct MovieCacheIter *)iter;
}
void IMB_moviecacheIter_free(struct MovieCacheIter *iter)
{
- BLI_ghashIterator_free((GHashIterator *) iter);
+ BLI_ghashIterator_free((GHashIterator *)iter);
}
bool IMB_moviecacheIter_done(struct MovieCacheIter *iter)
{
- return BLI_ghashIterator_done((GHashIterator *) iter);
+ return BLI_ghashIterator_done((GHashIterator *)iter);
}
void IMB_moviecacheIter_step(struct MovieCacheIter *iter)
{
- BLI_ghashIterator_step((GHashIterator *) iter);
+ BLI_ghashIterator_step((GHashIterator *)iter);
}
ImBuf *IMB_moviecacheIter_getImBuf(struct MovieCacheIter *iter)
{
- MovieCacheItem *item = BLI_ghashIterator_getValue((GHashIterator *) iter);
- return item->ibuf;
+ MovieCacheItem *item = BLI_ghashIterator_getValue((GHashIterator *)iter);
+ return item->ibuf;
}
void *IMB_moviecacheIter_getUserKey(struct MovieCacheIter *iter)
{
- MovieCacheKey *key = BLI_ghashIterator_getKey((GHashIterator *) iter);
- return key->userkey;
+ MovieCacheKey *key = BLI_ghashIterator_getKey((GHashIterator *)iter);
+ return key->userkey;
}
diff --git a/source/blender/imbuf/intern/oiio/CMakeLists.txt b/source/blender/imbuf/intern/oiio/CMakeLists.txt
index 3311d3fd9b4..984e62bc75a 100644
--- a/source/blender/imbuf/intern/oiio/CMakeLists.txt
+++ b/source/blender/imbuf/intern/oiio/CMakeLists.txt
@@ -19,14 +19,14 @@
# ***** END GPL LICENSE BLOCK *****
set(INC
- .
- ..
- ../..
- ../../../blenkernel
- ../../../blenlib
- ../../../makesdna
- ../../../../../intern/guardedalloc
- ../../../../../intern/utfconv
+ .
+ ..
+ ../..
+ ../../../blenkernel
+ ../../../blenlib
+ ../../../makesdna
+ ../../../../../intern/guardedalloc
+ ../../../../../intern/utfconv
)
set(INC_SYS
@@ -34,25 +34,25 @@ set(INC_SYS
)
set(SRC
- openimageio_api.h
+ openimageio_api.h
- openimageio_api.cpp
+ openimageio_api.cpp
)
set(LIB
)
if(WITH_OPENIMAGEIO)
- list(APPEND INC_SYS
- ${OPENIMAGEIO_INCLUDE_DIRS}
- ${BOOST_INCLUDE_DIR}
- )
- if(WITH_IMAGE_OPENEXR)
- list(APPEND INC_SYS
- ${OPENEXR_INCLUDE_DIRS}
- )
- endif()
- add_definitions(-DWITH_OPENIMAGEIO)
+ list(APPEND INC_SYS
+ ${OPENIMAGEIO_INCLUDE_DIRS}
+ ${BOOST_INCLUDE_DIR}
+ )
+ if(WITH_IMAGE_OPENEXR)
+ list(APPEND INC_SYS
+ ${OPENEXR_INCLUDE_DIRS}
+ )
+ endif()
+ add_definitions(-DWITH_OPENIMAGEIO)
endif()
blender_add_lib(bf_imbuf_openimageio "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/source/blender/imbuf/intern/oiio/openimageio_api.cpp b/source/blender/imbuf/intern/oiio/openimageio_api.cpp
index 4a21478de13..7b14678ed62 100644
--- a/source/blender/imbuf/intern/oiio/openimageio_api.cpp
+++ b/source/blender/imbuf/intern/oiio/openimageio_api.cpp
@@ -24,7 +24,7 @@
#include <set>
#if defined(WIN32)
-#include "utfconv.h"
+# include "utfconv.h"
#endif
// NOTE: Keep first, BLI_path_util conflicts with OIIO's format.
@@ -32,8 +32,7 @@
#include <openimageio_api.h>
#include <OpenImageIO/imageio.h>
-extern "C"
-{
+extern "C" {
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
@@ -52,232 +51,227 @@ using std::unique_ptr;
typedef unsigned char uchar;
-template <class T, class Q>
+template<class T, class Q>
static void fill_all_channels(T *pixels, int width, int height, int components, Q alpha)
{
- if (components == 2) {
- for (int i = width * height - 1; i >= 0; i--) {
- pixels[i * 4 + 3] = pixels[i * 2 + 1];
- pixels[i * 4 + 2] = pixels[i * 2 + 0];
- pixels[i * 4 + 1] = pixels[i * 2 + 0];
- pixels[i * 4 + 0] = pixels[i * 2 + 0];
- }
- }
- else if (components == 3) {
- for (int i = width * height - 1; i >= 0; i--) {
- pixels[i * 4 + 3] = alpha;
- pixels[i * 4 + 2] = pixels[i * 3 + 2];
- pixels[i * 4 + 1] = pixels[i * 3 + 1];
- pixels[i * 4 + 0] = pixels[i * 3 + 0];
-
- }
- }
- else if (components == 1) {
- for (int i = width * height - 1; i >= 0; i--) {
- pixels[i * 4 + 3] = alpha;
- pixels[i * 4 + 2] = pixels[i];
- pixels[i * 4 + 1] = pixels[i];
- pixels[i * 4 + 0] = pixels[i];
- }
- }
-
+ if (components == 2) {
+ for (int i = width * height - 1; i >= 0; i--) {
+ pixels[i * 4 + 3] = pixels[i * 2 + 1];
+ pixels[i * 4 + 2] = pixels[i * 2 + 0];
+ pixels[i * 4 + 1] = pixels[i * 2 + 0];
+ pixels[i * 4 + 0] = pixels[i * 2 + 0];
+ }
+ }
+ else if (components == 3) {
+ for (int i = width * height - 1; i >= 0; i--) {
+ pixels[i * 4 + 3] = alpha;
+ pixels[i * 4 + 2] = pixels[i * 3 + 2];
+ pixels[i * 4 + 1] = pixels[i * 3 + 1];
+ pixels[i * 4 + 0] = pixels[i * 3 + 0];
+ }
+ }
+ else if (components == 1) {
+ for (int i = width * height - 1; i >= 0; i--) {
+ pixels[i * 4 + 3] = alpha;
+ pixels[i * 4 + 2] = pixels[i];
+ pixels[i * 4 + 1] = pixels[i];
+ pixels[i * 4 + 0] = pixels[i];
+ }
+ }
}
-static ImBuf *imb_oiio_load_image(ImageInput *in, int width, int height, int components, int flags, bool is_alpha)
+static ImBuf *imb_oiio_load_image(
+ ImageInput *in, int width, int height, int components, int flags, bool is_alpha)
{
- ImBuf *ibuf;
- int scanlinesize = width * components * sizeof(uchar);
-
- /* allocate the memory for the image */
- ibuf = IMB_allocImBuf(width, height, is_alpha ? 32 : 24, flags | IB_rect);
-
- try
- {
- if (!in->read_image(TypeDesc::UINT8,
- (uchar *)ibuf->rect + (height - 1) * scanlinesize,
- AutoStride,
- -scanlinesize,
- AutoStride))
- {
- std::cerr << __func__ << ": ImageInput::read_image() failed:" << std::endl
- << in->geterror() << std::endl;
-
- if (ibuf)
- IMB_freeImBuf(ibuf);
-
- return NULL;
- }
- }
- catch (const std::exception &exc)
- {
- std::cerr << exc.what() << std::endl;
- if (ibuf) IMB_freeImBuf(ibuf);
-
- return NULL;
- }
-
- /* ImBuf always needs 4 channels */
- fill_all_channels((uchar *)ibuf->rect, width, height, components, 0xFF);
-
- return ibuf;
+ ImBuf *ibuf;
+ int scanlinesize = width * components * sizeof(uchar);
+
+ /* allocate the memory for the image */
+ ibuf = IMB_allocImBuf(width, height, is_alpha ? 32 : 24, flags | IB_rect);
+
+ try {
+ if (!in->read_image(TypeDesc::UINT8,
+ (uchar *)ibuf->rect + (height - 1) * scanlinesize,
+ AutoStride,
+ -scanlinesize,
+ AutoStride)) {
+ std::cerr << __func__ << ": ImageInput::read_image() failed:" << std::endl
+ << in->geterror() << std::endl;
+
+ if (ibuf)
+ IMB_freeImBuf(ibuf);
+
+ return NULL;
+ }
+ }
+ catch (const std::exception &exc) {
+ std::cerr << exc.what() << std::endl;
+ if (ibuf)
+ IMB_freeImBuf(ibuf);
+
+ return NULL;
+ }
+
+ /* ImBuf always needs 4 channels */
+ fill_all_channels((uchar *)ibuf->rect, width, height, components, 0xFF);
+
+ return ibuf;
}
-static ImBuf *imb_oiio_load_image_float(ImageInput *in, int width, int height, int components, int flags, bool is_alpha)
+static ImBuf *imb_oiio_load_image_float(
+ ImageInput *in, int width, int height, int components, int flags, bool is_alpha)
{
- ImBuf *ibuf;
- int scanlinesize = width * components * sizeof(float);
-
- /* allocate the memory for the image */
- ibuf = IMB_allocImBuf(width, height, is_alpha ? 32 : 24, flags | IB_rectfloat);
-
- try
- {
- if (!in->read_image(TypeDesc::FLOAT,
- (uchar *)ibuf->rect_float + (height - 1) * scanlinesize,
- AutoStride,
- -scanlinesize,
- AutoStride))
- {
- std::cerr << __func__ << ": ImageInput::read_image() failed:" << std::endl
- << in->geterror() << std::endl;
-
- if (ibuf)
- IMB_freeImBuf(ibuf);
-
- return NULL;
- }
- }
- catch (const std::exception &exc)
- {
- std::cerr << exc.what() << std::endl;
- if (ibuf) IMB_freeImBuf(ibuf);
-
- return NULL;
- }
-
- /* ImBuf always needs 4 channels */
- fill_all_channels((float *)ibuf->rect_float, width, height, components, 1.0f);
-
- /* note: Photoshop 16 bit files never has alpha with it, so no need to handle associated/unassociated alpha */
- return ibuf;
+ ImBuf *ibuf;
+ int scanlinesize = width * components * sizeof(float);
+
+ /* allocate the memory for the image */
+ ibuf = IMB_allocImBuf(width, height, is_alpha ? 32 : 24, flags | IB_rectfloat);
+
+ try {
+ if (!in->read_image(TypeDesc::FLOAT,
+ (uchar *)ibuf->rect_float + (height - 1) * scanlinesize,
+ AutoStride,
+ -scanlinesize,
+ AutoStride)) {
+ std::cerr << __func__ << ": ImageInput::read_image() failed:" << std::endl
+ << in->geterror() << std::endl;
+
+ if (ibuf)
+ IMB_freeImBuf(ibuf);
+
+ return NULL;
+ }
+ }
+ catch (const std::exception &exc) {
+ std::cerr << exc.what() << std::endl;
+ if (ibuf)
+ IMB_freeImBuf(ibuf);
+
+ return NULL;
+ }
+
+ /* ImBuf always needs 4 channels */
+ fill_all_channels((float *)ibuf->rect_float, width, height, components, 1.0f);
+
+ /* note: Photoshop 16 bit files never has alpha with it, so no need to handle associated/unassociated alpha */
+ return ibuf;
}
-extern "C"
-{
+extern "C" {
int imb_is_a_photoshop(const char *filename)
{
- const char *photoshop_extension[] = {
- ".psd",
- ".pdd",
- ".psb",
- NULL,
- };
-
- return BLI_path_extension_check_array(filename, photoshop_extension);
+ const char *photoshop_extension[] = {
+ ".psd",
+ ".pdd",
+ ".psb",
+ NULL,
+ };
+
+ return BLI_path_extension_check_array(filename, photoshop_extension);
}
int imb_save_photoshop(struct ImBuf *ibuf, const char * /*name*/, int flags)
{
- if (flags & IB_mem) {
- std::cerr << __func__ << ": Photoshop PSD-save: Create PSD in memory"
- << " currently not supported" << std::endl;
- imb_addencodedbufferImBuf(ibuf);
- ibuf->encodedsize = 0;
- return(0);
- }
-
- return(0);
+ if (flags & IB_mem) {
+ std::cerr << __func__ << ": Photoshop PSD-save: Create PSD in memory"
+ << " currently not supported" << std::endl;
+ imb_addencodedbufferImBuf(ibuf);
+ ibuf->encodedsize = 0;
+ return (0);
+ }
+
+ return (0);
}
struct ImBuf *imb_load_photoshop(const char *filename, int flags, char colorspace[IM_MAX_SPACE])
{
- struct ImBuf *ibuf = NULL;
- int width, height, components;
- bool is_float, is_alpha;
- int basesize;
- char file_colorspace[IM_MAX_SPACE];
-
- /* load image from file through OIIO */
- if (imb_is_a_photoshop(filename) == 0) return (NULL);
-
- colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE);
-
- unique_ptr<ImageInput> in(ImageInput::create(filename));
- if (!in) {
- std::cerr << __func__ << ": ImageInput::create() failed:" << std::endl
- << OIIO_NAMESPACE::geterror() << std::endl;
- return NULL;
- }
-
- ImageSpec spec, config;
- config.attribute("oiio:UnassociatedAlpha", (int) 1);
-
- if (!in->open(filename, spec, config)) {
- std::cerr << __func__ << ": ImageInput::open() failed:" << std::endl
- << in->geterror() << std::endl;
- return NULL;
- }
-
- string ics = spec.get_string_attribute("oiio:ColorSpace");
- BLI_strncpy(file_colorspace, ics.c_str(), IM_MAX_SPACE);
-
- /* only use colorspaces exis */
- if (colormanage_colorspace_get_named(file_colorspace))
- strcpy(colorspace, file_colorspace);
- else
- std::cerr << __func__ << ": The embed colorspace (\"" << file_colorspace
- << "\") not supported in existent OCIO configuration file. Fallback "
- << "to system default colorspace (\"" << colorspace << "\")." << std::endl;
-
- width = spec.width;
- height = spec.height;
- components = spec.nchannels;
- is_alpha = spec.alpha_channel != -1;
- basesize = spec.format.basesize();
- is_float = basesize > 1;
-
- /* we only handle certain number of components */
- if (!(components >= 1 && components <= 4)) {
- if (in) {
- in->close();
- }
- return NULL;
- }
-
- if (is_float)
- ibuf = imb_oiio_load_image_float(in.get(), width, height, components, flags, is_alpha);
- else
- ibuf = imb_oiio_load_image(in.get(), width, height, components, flags, is_alpha);
-
- if (in) {
- in->close();
- }
-
- if (!ibuf)
- return NULL;
-
- /* ImBuf always needs 4 channels */
- ibuf->ftype = IMB_FTYPE_PSD;
- ibuf->channels = 4;
- ibuf->planes = (3 + (is_alpha ? 1 : 0)) * 4 << basesize;
-
- try
- {
- return ibuf;
- }
- catch (const std::exception &exc)
- {
- std::cerr << exc.what() << std::endl;
- if (ibuf) IMB_freeImBuf(ibuf);
-
- return NULL;
- }
+ struct ImBuf *ibuf = NULL;
+ int width, height, components;
+ bool is_float, is_alpha;
+ int basesize;
+ char file_colorspace[IM_MAX_SPACE];
+
+ /* load image from file through OIIO */
+ if (imb_is_a_photoshop(filename) == 0)
+ return (NULL);
+
+ colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE);
+
+ unique_ptr<ImageInput> in(ImageInput::create(filename));
+ if (!in) {
+ std::cerr << __func__ << ": ImageInput::create() failed:" << std::endl
+ << OIIO_NAMESPACE::geterror() << std::endl;
+ return NULL;
+ }
+
+ ImageSpec spec, config;
+ config.attribute("oiio:UnassociatedAlpha", (int)1);
+
+ if (!in->open(filename, spec, config)) {
+ std::cerr << __func__ << ": ImageInput::open() failed:" << std::endl
+ << in->geterror() << std::endl;
+ return NULL;
+ }
+
+ string ics = spec.get_string_attribute("oiio:ColorSpace");
+ BLI_strncpy(file_colorspace, ics.c_str(), IM_MAX_SPACE);
+
+ /* only use colorspaces exis */
+ if (colormanage_colorspace_get_named(file_colorspace))
+ strcpy(colorspace, file_colorspace);
+ else
+ std::cerr << __func__ << ": The embed colorspace (\"" << file_colorspace
+ << "\") not supported in existent OCIO configuration file. Fallback "
+ << "to system default colorspace (\"" << colorspace << "\")." << std::endl;
+
+ width = spec.width;
+ height = spec.height;
+ components = spec.nchannels;
+ is_alpha = spec.alpha_channel != -1;
+ basesize = spec.format.basesize();
+ is_float = basesize > 1;
+
+ /* we only handle certain number of components */
+ if (!(components >= 1 && components <= 4)) {
+ if (in) {
+ in->close();
+ }
+ return NULL;
+ }
+
+ if (is_float)
+ ibuf = imb_oiio_load_image_float(in.get(), width, height, components, flags, is_alpha);
+ else
+ ibuf = imb_oiio_load_image(in.get(), width, height, components, flags, is_alpha);
+
+ if (in) {
+ in->close();
+ }
+
+ if (!ibuf)
+ return NULL;
+
+ /* ImBuf always needs 4 channels */
+ ibuf->ftype = IMB_FTYPE_PSD;
+ ibuf->channels = 4;
+ ibuf->planes = (3 + (is_alpha ? 1 : 0)) * 4 << basesize;
+
+ try {
+ return ibuf;
+ }
+ catch (const std::exception &exc) {
+ std::cerr << exc.what() << std::endl;
+ if (ibuf)
+ IMB_freeImBuf(ibuf);
+
+ return NULL;
+ }
}
int OIIO_getVersionHex(void)
{
- return openimageio_version();
+ return openimageio_version();
}
-} // export "C"
+} // export "C"
diff --git a/source/blender/imbuf/intern/oiio/openimageio_api.h b/source/blender/imbuf/intern/oiio/openimageio_api.h
index d6249af2a0a..520ad0c5da5 100644
--- a/source/blender/imbuf/intern/oiio/openimageio_api.h
+++ b/source/blender/imbuf/intern/oiio/openimageio_api.h
@@ -21,7 +21,6 @@
* \ingroup openimageio
*/
-
#ifndef __OPENIMAGEIO_API_H__
#define __OPENIMAGEIO_API_H__
@@ -33,11 +32,11 @@ extern "C" {
struct ImBuf;
-int imb_is_a_photoshop (const char *name);
+int imb_is_a_photoshop(const char *name);
-int imb_save_photoshop (struct ImBuf *ibuf, const char *name, int flags);
+int imb_save_photoshop(struct ImBuf *ibuf, const char *name, int flags);
-struct ImBuf *imb_load_photoshop (const char *name, int flags, char *colorspace);
+struct ImBuf *imb_load_photoshop(const char *name, int flags, char *colorspace);
int OIIO_getVersionHex(void);
@@ -46,4 +45,4 @@ int OIIO_getVersionHex(void);
#endif
-#endif /* __OPENIMAGEIO_API_H__ */
+#endif /* __OPENIMAGEIO_API_H__ */
diff --git a/source/blender/imbuf/intern/openexr/CMakeLists.txt b/source/blender/imbuf/intern/openexr/CMakeLists.txt
index c9ede9ff07f..fc584ace81e 100644
--- a/source/blender/imbuf/intern/openexr/CMakeLists.txt
+++ b/source/blender/imbuf/intern/openexr/CMakeLists.txt
@@ -19,14 +19,14 @@
# ***** END GPL LICENSE BLOCK *****
set(INC
- .
- ..
- ../..
- ../../../blenkernel
- ../../../blenlib
- ../../../makesdna
- ../../../../../intern/guardedalloc
- ../../../../../intern/utfconv
+ .
+ ..
+ ../..
+ ../../../blenkernel
+ ../../../blenlib
+ ../../../makesdna
+ ../../../../../intern/guardedalloc
+ ../../../../../intern/utfconv
)
set(INC_SYS
@@ -34,20 +34,20 @@ set(INC_SYS
)
set(SRC
- openexr_api.h
- openexr_multi.h
+ openexr_api.h
+ openexr_multi.h
- openexr_api.cpp
+ openexr_api.cpp
)
set(LIB
)
if(WITH_IMAGE_OPENEXR)
- list(APPEND INC_SYS
- ${OPENEXR_INCLUDE_DIRS}
- )
- add_definitions(-DWITH_OPENEXR)
+ list(APPEND INC_SYS
+ ${OPENEXR_INCLUDE_DIRS}
+ )
+ add_definitions(-DWITH_OPENEXR)
endif()
blender_add_lib(bf_imbuf_openexr "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp
index 155f971c5eb..d0f550feb0d 100644
--- a/source/blender/imbuf/intern/openexr/openexr_api.cpp
+++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp
@@ -61,12 +61,11 @@
#include <openexr_api.h>
-#if defined (WIN32)
-#include "utfconv.h"
+#if defined(WIN32)
+# include "utfconv.h"
#endif
-extern "C"
-{
+extern "C" {
// The following prevents a linking error in debug mode for MSVC using the libs in CVS
#if defined(WITH_OPENEXR) && defined(_WIN32) && defined(DEBUG) && _MSC_VER < 1900
@@ -100,63 +99,62 @@ extern "C" {
using namespace Imf;
using namespace Imath;
-extern "C"
-{
+extern "C" {
/* prototype */
static struct ExrPass *imb_exr_get_pass(ListBase *lb, char *passname);
-static bool exr_has_multiview(MultiPartInputFile& file);
-static bool exr_has_multipart_file(MultiPartInputFile& file);
-static bool exr_has_alpha(MultiPartInputFile& file);
-static bool exr_has_zbuffer(MultiPartInputFile& file);
+static bool exr_has_multiview(MultiPartInputFile &file);
+static bool exr_has_multipart_file(MultiPartInputFile &file);
+static bool exr_has_alpha(MultiPartInputFile &file);
+static bool exr_has_zbuffer(MultiPartInputFile &file);
static void exr_printf(const char *__restrict format, ...);
-static void imb_exr_type_by_channels(ChannelList& channels, StringVector& views,
- bool *r_singlelayer, bool *r_multilayer, bool *r_multiview);
+static void imb_exr_type_by_channels(ChannelList &channels,
+ StringVector &views,
+ bool *r_singlelayer,
+ bool *r_multilayer,
+ bool *r_multiview);
}
/* Memory Input Stream */
-class Mem_IStream : public Imf::IStream
-{
-public:
-
- Mem_IStream(unsigned char *exrbuf, size_t exrsize) :
- IStream("dummy"), _exrpos(0), _exrsize(exrsize)
- {
- _exrbuf = exrbuf;
- }
-
- virtual bool read(char c[], int n);
- virtual Int64 tellg();
- virtual void seekg(Int64 pos);
- virtual void clear();
- //virtual ~Mem_IStream() {}; // unused
-
-private:
-
- Int64 _exrpos;
- Int64 _exrsize;
- unsigned char *_exrbuf;
+class Mem_IStream : public Imf::IStream {
+ public:
+ Mem_IStream(unsigned char *exrbuf, size_t exrsize)
+ : IStream("dummy"), _exrpos(0), _exrsize(exrsize)
+ {
+ _exrbuf = exrbuf;
+ }
+
+ virtual bool read(char c[], int n);
+ virtual Int64 tellg();
+ virtual void seekg(Int64 pos);
+ virtual void clear();
+ //virtual ~Mem_IStream() {}; // unused
+
+ private:
+ Int64 _exrpos;
+ Int64 _exrsize;
+ unsigned char *_exrbuf;
};
bool Mem_IStream::read(char c[], int n)
{
- if (n + _exrpos <= _exrsize) {
- memcpy(c, (void *)(&_exrbuf[_exrpos]), n);
- _exrpos += n;
- return true;
- }
- else
- return false;
+ if (n + _exrpos <= _exrsize) {
+ memcpy(c, (void *)(&_exrbuf[_exrpos]), n);
+ _exrpos += n;
+ return true;
+ }
+ else
+ return false;
}
Int64 Mem_IStream::tellg()
{
- return _exrpos;
+ return _exrpos;
}
void Mem_IStream::seekg(Int64 pos)
{
- _exrpos = pos;
+ _exrpos = pos;
}
void Mem_IStream::clear()
@@ -165,132 +163,127 @@ void Mem_IStream::clear()
/* File Input Stream */
-class IFileStream : public Imf::IStream
-{
-public:
- IFileStream(const char *filename)
- : IStream(filename)
- {
- /* utf-8 file path support on windows */
-#if defined (WIN32)
- wchar_t *wfilename = alloc_utf16_from_8(filename, 0);
- ifs.open(wfilename, std::ios_base::binary);
- free(wfilename);
+class IFileStream : public Imf::IStream {
+ public:
+ IFileStream(const char *filename) : IStream(filename)
+ {
+ /* utf-8 file path support on windows */
+#if defined(WIN32)
+ wchar_t *wfilename = alloc_utf16_from_8(filename, 0);
+ ifs.open(wfilename, std::ios_base::binary);
+ free(wfilename);
#else
- ifs.open(filename, std::ios_base::binary);
+ ifs.open(filename, std::ios_base::binary);
#endif
- if (!ifs)
- Iex::throwErrnoExc();
- }
-
- virtual bool read(char c[], int n)
- {
- if (!ifs)
- throw Iex::InputExc("Unexpected end of file.");
-
- errno = 0;
- ifs.read(c, n);
- return check_error();
- }
-
- virtual Int64 tellg()
- {
- return std::streamoff(ifs.tellg());
- }
-
- virtual void seekg(Int64 pos)
- {
- ifs.seekg(pos);
- check_error();
- }
-
- virtual void clear()
- {
- ifs.clear();
- }
-
-private:
- bool check_error()
- {
- if (!ifs) {
- if (errno)
- Iex::throwErrnoExc();
-
- return false;
- }
-
- return true;
- }
-
- std::ifstream ifs;
+ if (!ifs)
+ Iex::throwErrnoExc();
+ }
+
+ virtual bool read(char c[], int n)
+ {
+ if (!ifs)
+ throw Iex::InputExc("Unexpected end of file.");
+
+ errno = 0;
+ ifs.read(c, n);
+ return check_error();
+ }
+
+ virtual Int64 tellg()
+ {
+ return std::streamoff(ifs.tellg());
+ }
+
+ virtual void seekg(Int64 pos)
+ {
+ ifs.seekg(pos);
+ check_error();
+ }
+
+ virtual void clear()
+ {
+ ifs.clear();
+ }
+
+ private:
+ bool check_error()
+ {
+ if (!ifs) {
+ if (errno)
+ Iex::throwErrnoExc();
+
+ return false;
+ }
+
+ return true;
+ }
+
+ std::ifstream ifs;
};
/* File Output Stream */
-class OFileStream : public OStream
-{
-public:
- OFileStream(const char *filename)
- : OStream(filename)
- {
- /* utf-8 file path support on windows */
-#if defined (WIN32)
- wchar_t *wfilename = alloc_utf16_from_8(filename, 0);
- ofs.open(wfilename, std::ios_base::binary);
- free(wfilename);
+class OFileStream : public OStream {
+ public:
+ OFileStream(const char *filename) : OStream(filename)
+ {
+ /* utf-8 file path support on windows */
+#if defined(WIN32)
+ wchar_t *wfilename = alloc_utf16_from_8(filename, 0);
+ ofs.open(wfilename, std::ios_base::binary);
+ free(wfilename);
#else
- ofs.open(filename, std::ios_base::binary);
+ ofs.open(filename, std::ios_base::binary);
#endif
- if (!ofs)
- Iex::throwErrnoExc();
- }
-
- virtual void write(const char c[], int n)
- {
- errno = 0;
- ofs.write(c, n);
- check_error();
- }
-
- virtual Int64 tellp()
- {
- return std::streamoff(ofs.tellp());
- }
-
- virtual void seekp(Int64 pos)
- {
- ofs.seekp(pos);
- check_error();
- }
-
-private:
- void check_error()
- {
- if (!ofs) {
- if (errno)
- Iex::throwErrnoExc();
-
- throw Iex::ErrnoExc("File output failed.");
- }
- }
-
- std::ofstream ofs;
+ if (!ofs)
+ Iex::throwErrnoExc();
+ }
+
+ virtual void write(const char c[], int n)
+ {
+ errno = 0;
+ ofs.write(c, n);
+ check_error();
+ }
+
+ virtual Int64 tellp()
+ {
+ return std::streamoff(ofs.tellp());
+ }
+
+ virtual void seekp(Int64 pos)
+ {
+ ofs.seekp(pos);
+ check_error();
+ }
+
+ private:
+ void check_error()
+ {
+ if (!ofs) {
+ if (errno)
+ Iex::throwErrnoExc();
+
+ throw Iex::ErrnoExc("File output failed.");
+ }
+ }
+
+ std::ofstream ofs;
};
struct _RGBAZ {
- half r;
- half g;
- half b;
- half a;
- half z;
+ half r;
+ half g;
+ half b;
+ half a;
+ half z;
};
typedef struct _RGBAZ RGBAZ;
-extern "C"
-{
+extern "C" {
/**
* Test presence of OpenEXR file.
@@ -298,249 +291,255 @@ extern "C"
*/
int imb_is_a_openexr(const unsigned char *mem)
{
- return Imf::isImfMagic((const char *)mem);
+ return Imf::isImfMagic((const char *)mem);
}
static void openexr_header_compression(Header *header, int compression)
{
- switch (compression) {
- case R_IMF_EXR_CODEC_NONE:
- header->compression() = NO_COMPRESSION;
- break;
- case R_IMF_EXR_CODEC_PXR24:
- header->compression() = PXR24_COMPRESSION;
- break;
- case R_IMF_EXR_CODEC_ZIP:
- header->compression() = ZIP_COMPRESSION;
- break;
- case R_IMF_EXR_CODEC_PIZ:
- header->compression() = PIZ_COMPRESSION;
- break;
- case R_IMF_EXR_CODEC_RLE:
- header->compression() = RLE_COMPRESSION;
- break;
- case R_IMF_EXR_CODEC_ZIPS:
- header->compression() = ZIPS_COMPRESSION;
- break;
- case R_IMF_EXR_CODEC_B44:
- header->compression() = B44_COMPRESSION;
- break;
- case R_IMF_EXR_CODEC_B44A:
- header->compression() = B44A_COMPRESSION;
- break;
+ switch (compression) {
+ case R_IMF_EXR_CODEC_NONE:
+ header->compression() = NO_COMPRESSION;
+ break;
+ case R_IMF_EXR_CODEC_PXR24:
+ header->compression() = PXR24_COMPRESSION;
+ break;
+ case R_IMF_EXR_CODEC_ZIP:
+ header->compression() = ZIP_COMPRESSION;
+ break;
+ case R_IMF_EXR_CODEC_PIZ:
+ header->compression() = PIZ_COMPRESSION;
+ break;
+ case R_IMF_EXR_CODEC_RLE:
+ header->compression() = RLE_COMPRESSION;
+ break;
+ case R_IMF_EXR_CODEC_ZIPS:
+ header->compression() = ZIPS_COMPRESSION;
+ break;
+ case R_IMF_EXR_CODEC_B44:
+ header->compression() = B44_COMPRESSION;
+ break;
+ case R_IMF_EXR_CODEC_B44A:
+ header->compression() = B44A_COMPRESSION;
+ break;
#if OPENEXR_VERSION_MAJOR >= 2 && OPENEXR_VERSION_MINOR >= 2
- case R_IMF_EXR_CODEC_DWAA:
- header->compression() = DWAA_COMPRESSION;
- break;
- case R_IMF_EXR_CODEC_DWAB:
- header->compression() = DWAB_COMPRESSION;
- break;
+ case R_IMF_EXR_CODEC_DWAA:
+ header->compression() = DWAA_COMPRESSION;
+ break;
+ case R_IMF_EXR_CODEC_DWAB:
+ header->compression() = DWAB_COMPRESSION;
+ break;
#endif
- default:
- header->compression() = ZIP_COMPRESSION;
- break;
- }
+ default:
+ header->compression() = ZIP_COMPRESSION;
+ break;
+ }
}
static void openexr_header_metadata(Header *header, struct ImBuf *ibuf)
{
- if (ibuf->metadata) {
- IDProperty *prop;
-
- for (prop = (IDProperty *)ibuf->metadata->data.group.first; prop; prop = prop->next) {
- if (prop->type == IDP_STRING) {
- header->insert(prop->name, StringAttribute(IDP_String(prop)));
- }
- }
- }
-
- if (ibuf->ppm[0] > 0.0)
- addXDensity(*header, ibuf->ppm[0] / 39.3700787); /* 1 meter = 39.3700787 inches */
+ if (ibuf->metadata) {
+ IDProperty *prop;
+
+ for (prop = (IDProperty *)ibuf->metadata->data.group.first; prop; prop = prop->next) {
+ if (prop->type == IDP_STRING) {
+ header->insert(prop->name, StringAttribute(IDP_String(prop)));
+ }
+ }
+ }
+
+ if (ibuf->ppm[0] > 0.0)
+ addXDensity(*header, ibuf->ppm[0] / 39.3700787); /* 1 meter = 39.3700787 inches */
}
-static void openexr_header_metadata_callback(void *data, const char *propname, char *prop, int UNUSED(len))
+static void openexr_header_metadata_callback(void *data,
+ const char *propname,
+ char *prop,
+ int UNUSED(len))
{
- Header *header = (Header *)data;
- header->insert(propname, StringAttribute(prop));
+ Header *header = (Header *)data;
+ header->insert(propname, StringAttribute(prop));
}
-
-static bool imb_save_openexr_half(
- ImBuf *ibuf, const char *name, const int flags)
+static bool imb_save_openexr_half(ImBuf *ibuf, const char *name, const int flags)
{
- const int channels = ibuf->channels;
- const bool is_alpha = (channels >= 4) && (ibuf->planes == 32);
- const bool is_zbuf = (flags & IB_zbuffloat) && ibuf->zbuf_float != NULL; /* summarize */
- const int width = ibuf->x;
- const int height = ibuf->y;
-
- try
- {
- Header header(width, height);
-
- openexr_header_compression(&header, ibuf->foptions.flag & OPENEXR_COMPRESS);
- openexr_header_metadata(&header, ibuf);
-
- /* create channels */
- header.channels().insert("R", Channel(HALF));
- header.channels().insert("G", Channel(HALF));
- header.channels().insert("B", Channel(HALF));
- if (is_alpha)
- header.channels().insert("A", Channel(HALF));
- if (is_zbuf) // z we do as float always
- header.channels().insert("Z", Channel(Imf::FLOAT));
-
- FrameBuffer frameBuffer;
-
- /* manually create ofstream, so we can handle utf-8 filepaths on windows */
- OFileStream file_stream(name);
- OutputFile file(file_stream, header);
-
- /* we store first everything in half array */
- std::vector<RGBAZ> pixels(height * width);
- RGBAZ *to = &pixels[0];
- int xstride = sizeof(RGBAZ);
- int ystride = xstride * width;
-
- /* indicate used buffers */
- frameBuffer.insert("R", Slice(HALF, (char *) &to->r, xstride, ystride));
- frameBuffer.insert("G", Slice(HALF, (char *) &to->g, xstride, ystride));
- frameBuffer.insert("B", Slice(HALF, (char *) &to->b, xstride, ystride));
- if (is_alpha) {
- frameBuffer.insert("A", Slice(HALF, (char *) &to->a, xstride, ystride));
- }
- if (is_zbuf) {
- frameBuffer.insert("Z", Slice(Imf::FLOAT, (char *)(ibuf->zbuf_float + (height - 1) * width),
- sizeof(float), sizeof(float) * -width));
- }
- if (ibuf->rect_float) {
- float *from;
-
- for (int i = ibuf->y - 1; i >= 0; i--) {
- from = ibuf->rect_float + channels * i * width;
-
- for (int j = ibuf->x; j > 0; j--) {
- to->r = from[0];
- to->g = (channels >= 2) ? from[1] : from[0];
- to->b = (channels >= 3) ? from[2] : from[0];
- to->a = (channels >= 4) ? from[3] : 1.0f;
- to++; from += channels;
- }
- }
- }
- else {
- unsigned char *from;
-
- for (int i = ibuf->y - 1; i >= 0; i--) {
- from = (unsigned char *)ibuf->rect + 4 * i * width;
-
- for (int j = ibuf->x; j > 0; j--) {
- to->r = srgb_to_linearrgb((float)from[0] / 255.0f);
- to->g = srgb_to_linearrgb((float)from[1] / 255.0f);
- to->b = srgb_to_linearrgb((float)from[2] / 255.0f);
- to->a = channels >= 4 ? (float)from[3] / 255.0f : 1.0f;
- to++; from += 4;
- }
- }
- }
-
- exr_printf("OpenEXR-save: Writing OpenEXR file of height %d.\n", height);
-
- file.setFrameBuffer(frameBuffer);
- file.writePixels(height);
- }
- catch (const std::exception& exc)
- {
- printf("OpenEXR-save: ERROR: %s\n", exc.what());
-
- return false;
- }
-
- return true;
+ const int channels = ibuf->channels;
+ const bool is_alpha = (channels >= 4) && (ibuf->planes == 32);
+ const bool is_zbuf = (flags & IB_zbuffloat) && ibuf->zbuf_float != NULL; /* summarize */
+ const int width = ibuf->x;
+ const int height = ibuf->y;
+
+ try {
+ Header header(width, height);
+
+ openexr_header_compression(&header, ibuf->foptions.flag & OPENEXR_COMPRESS);
+ openexr_header_metadata(&header, ibuf);
+
+ /* create channels */
+ header.channels().insert("R", Channel(HALF));
+ header.channels().insert("G", Channel(HALF));
+ header.channels().insert("B", Channel(HALF));
+ if (is_alpha)
+ header.channels().insert("A", Channel(HALF));
+ if (is_zbuf) // z we do as float always
+ header.channels().insert("Z", Channel(Imf::FLOAT));
+
+ FrameBuffer frameBuffer;
+
+ /* manually create ofstream, so we can handle utf-8 filepaths on windows */
+ OFileStream file_stream(name);
+ OutputFile file(file_stream, header);
+
+ /* we store first everything in half array */
+ std::vector<RGBAZ> pixels(height * width);
+ RGBAZ *to = &pixels[0];
+ int xstride = sizeof(RGBAZ);
+ int ystride = xstride * width;
+
+ /* indicate used buffers */
+ frameBuffer.insert("R", Slice(HALF, (char *)&to->r, xstride, ystride));
+ frameBuffer.insert("G", Slice(HALF, (char *)&to->g, xstride, ystride));
+ frameBuffer.insert("B", Slice(HALF, (char *)&to->b, xstride, ystride));
+ if (is_alpha) {
+ frameBuffer.insert("A", Slice(HALF, (char *)&to->a, xstride, ystride));
+ }
+ if (is_zbuf) {
+ frameBuffer.insert("Z",
+ Slice(Imf::FLOAT,
+ (char *)(ibuf->zbuf_float + (height - 1) * width),
+ sizeof(float),
+ sizeof(float) * -width));
+ }
+ if (ibuf->rect_float) {
+ float *from;
+
+ for (int i = ibuf->y - 1; i >= 0; i--) {
+ from = ibuf->rect_float + channels * i * width;
+
+ for (int j = ibuf->x; j > 0; j--) {
+ to->r = from[0];
+ to->g = (channels >= 2) ? from[1] : from[0];
+ to->b = (channels >= 3) ? from[2] : from[0];
+ to->a = (channels >= 4) ? from[3] : 1.0f;
+ to++;
+ from += channels;
+ }
+ }
+ }
+ else {
+ unsigned char *from;
+
+ for (int i = ibuf->y - 1; i >= 0; i--) {
+ from = (unsigned char *)ibuf->rect + 4 * i * width;
+
+ for (int j = ibuf->x; j > 0; j--) {
+ to->r = srgb_to_linearrgb((float)from[0] / 255.0f);
+ to->g = srgb_to_linearrgb((float)from[1] / 255.0f);
+ to->b = srgb_to_linearrgb((float)from[2] / 255.0f);
+ to->a = channels >= 4 ? (float)from[3] / 255.0f : 1.0f;
+ to++;
+ from += 4;
+ }
+ }
+ }
+
+ exr_printf("OpenEXR-save: Writing OpenEXR file of height %d.\n", height);
+
+ file.setFrameBuffer(frameBuffer);
+ file.writePixels(height);
+ }
+ catch (const std::exception &exc) {
+ printf("OpenEXR-save: ERROR: %s\n", exc.what());
+
+ return false;
+ }
+
+ return true;
}
-static bool imb_save_openexr_float(
- ImBuf *ibuf, const char *name, const int flags)
+static bool imb_save_openexr_float(ImBuf *ibuf, const char *name, const int flags)
{
- const int channels = ibuf->channels;
- const bool is_alpha = (channels >= 4) && (ibuf->planes == 32);
- const bool is_zbuf = (flags & IB_zbuffloat) && ibuf->zbuf_float != NULL; /* summarize */
- const int width = ibuf->x;
- const int height = ibuf->y;
-
- try
- {
- Header header(width, height);
-
- openexr_header_compression(&header, ibuf->foptions.flag & OPENEXR_COMPRESS);
- openexr_header_metadata(&header, ibuf);
-
- /* create channels */
- header.channels().insert("R", Channel(Imf::FLOAT));
- header.channels().insert("G", Channel(Imf::FLOAT));
- header.channels().insert("B", Channel(Imf::FLOAT));
- if (is_alpha)
- header.channels().insert("A", Channel(Imf::FLOAT));
- if (is_zbuf)
- header.channels().insert("Z", Channel(Imf::FLOAT));
-
- FrameBuffer frameBuffer;
-
- /* manually create ofstream, so we can handle utf-8 filepaths on windows */
- OFileStream file_stream(name);
- OutputFile file(file_stream, header);
-
- int xstride = sizeof(float) * channels;
- int ystride = -xstride * width;
-
- /* last scanline, stride negative */
- float *rect[4] = {NULL, NULL, NULL, NULL};
- rect[0] = ibuf->rect_float + channels * (height - 1) * width;
- rect[1] = (channels >= 2) ? rect[0] + 1 : rect[0];
- rect[2] = (channels >= 3) ? rect[0] + 2 : rect[0];
- rect[3] = (channels >= 4) ? rect[0] + 3 : rect[0]; /* red as alpha, is this needed since alpha isn't written? */
-
- frameBuffer.insert("R", Slice(Imf::FLOAT, (char *)rect[0], xstride, ystride));
- frameBuffer.insert("G", Slice(Imf::FLOAT, (char *)rect[1], xstride, ystride));
- frameBuffer.insert("B", Slice(Imf::FLOAT, (char *)rect[2], xstride, ystride));
- if (is_alpha) {
- frameBuffer.insert("A", Slice(Imf::FLOAT, (char *)rect[3], xstride, ystride));
- }
- if (is_zbuf) {
- frameBuffer.insert("Z", Slice(Imf::FLOAT, (char *) (ibuf->zbuf_float + (height - 1) * width),
- sizeof(float), sizeof(float) * -width));
- }
-
- file.setFrameBuffer(frameBuffer);
- file.writePixels(height);
- }
- catch (const std::exception& exc)
- {
- printf("OpenEXR-save: ERROR: %s\n", exc.what());
- return false;
- }
-
- return true;
+ const int channels = ibuf->channels;
+ const bool is_alpha = (channels >= 4) && (ibuf->planes == 32);
+ const bool is_zbuf = (flags & IB_zbuffloat) && ibuf->zbuf_float != NULL; /* summarize */
+ const int width = ibuf->x;
+ const int height = ibuf->y;
+
+ try {
+ Header header(width, height);
+
+ openexr_header_compression(&header, ibuf->foptions.flag & OPENEXR_COMPRESS);
+ openexr_header_metadata(&header, ibuf);
+
+ /* create channels */
+ header.channels().insert("R", Channel(Imf::FLOAT));
+ header.channels().insert("G", Channel(Imf::FLOAT));
+ header.channels().insert("B", Channel(Imf::FLOAT));
+ if (is_alpha)
+ header.channels().insert("A", Channel(Imf::FLOAT));
+ if (is_zbuf)
+ header.channels().insert("Z", Channel(Imf::FLOAT));
+
+ FrameBuffer frameBuffer;
+
+ /* manually create ofstream, so we can handle utf-8 filepaths on windows */
+ OFileStream file_stream(name);
+ OutputFile file(file_stream, header);
+
+ int xstride = sizeof(float) * channels;
+ int ystride = -xstride * width;
+
+ /* last scanline, stride negative */
+ float *rect[4] = {NULL, NULL, NULL, NULL};
+ rect[0] = ibuf->rect_float + channels * (height - 1) * width;
+ rect[1] = (channels >= 2) ? rect[0] + 1 : rect[0];
+ rect[2] = (channels >= 3) ? rect[0] + 2 : rect[0];
+ rect[3] = (channels >= 4) ?
+ rect[0] + 3 :
+ rect[0]; /* red as alpha, is this needed since alpha isn't written? */
+
+ frameBuffer.insert("R", Slice(Imf::FLOAT, (char *)rect[0], xstride, ystride));
+ frameBuffer.insert("G", Slice(Imf::FLOAT, (char *)rect[1], xstride, ystride));
+ frameBuffer.insert("B", Slice(Imf::FLOAT, (char *)rect[2], xstride, ystride));
+ if (is_alpha) {
+ frameBuffer.insert("A", Slice(Imf::FLOAT, (char *)rect[3], xstride, ystride));
+ }
+ if (is_zbuf) {
+ frameBuffer.insert("Z",
+ Slice(Imf::FLOAT,
+ (char *)(ibuf->zbuf_float + (height - 1) * width),
+ sizeof(float),
+ sizeof(float) * -width));
+ }
+
+ file.setFrameBuffer(frameBuffer);
+ file.writePixels(height);
+ }
+ catch (const std::exception &exc) {
+ printf("OpenEXR-save: ERROR: %s\n", exc.what());
+ return false;
+ }
+
+ return true;
}
int imb_save_openexr(struct ImBuf *ibuf, const char *name, int flags)
{
- if (flags & IB_mem) {
- printf("OpenEXR-save: Create EXR in memory CURRENTLY NOT SUPPORTED !\n");
- imb_addencodedbufferImBuf(ibuf);
- ibuf->encodedsize = 0;
- return(0);
- }
-
- if (ibuf->foptions.flag & OPENEXR_HALF)
- return (int) imb_save_openexr_half(ibuf, name, flags);
- else {
- /* when no float rect, we save as half (16 bits is sufficient) */
- if (ibuf->rect_float == NULL)
- return (int) imb_save_openexr_half(ibuf, name, flags);
- else
- return (int) imb_save_openexr_float(ibuf, name, flags);
- }
+ if (flags & IB_mem) {
+ printf("OpenEXR-save: Create EXR in memory CURRENTLY NOT SUPPORTED !\n");
+ imb_addencodedbufferImBuf(ibuf);
+ ibuf->encodedsize = 0;
+ return (0);
+ }
+
+ if (ibuf->foptions.flag & OPENEXR_HALF)
+ return (int)imb_save_openexr_half(ibuf, name, flags);
+ else {
+ /* when no float rect, we save as half (16 bits is sufficient) */
+ if (ibuf->rect_float == NULL)
+ return (int)imb_save_openexr_half(ibuf, name, flags);
+ else
+ return (int)imb_save_openexr_float(ibuf, name, flags);
+ }
}
/* ********************* Nicer API, MultiLayer and with Tile file support ************************************ */
@@ -555,691 +554,740 @@ int imb_save_openexr(struct ImBuf *ibuf, const char *name, int flags)
static ListBase exrhandles = {NULL, NULL};
typedef struct ExrHandle {
- struct ExrHandle *next, *prev;
- char name[FILE_MAX];
+ struct ExrHandle *next, *prev;
+ char name[FILE_MAX];
- IStream *ifile_stream;
- MultiPartInputFile *ifile;
+ IStream *ifile_stream;
+ MultiPartInputFile *ifile;
- OFileStream *ofile_stream;
- MultiPartOutputFile *mpofile;
- OutputFile *ofile;
+ OFileStream *ofile_stream;
+ MultiPartOutputFile *mpofile;
+ OutputFile *ofile;
- int tilex, tiley;
- int width, height;
- int mipmap;
+ int tilex, tiley;
+ int width, height;
+ int mipmap;
- StringVector *multiView; /* it needs to be a pointer due to Windows release builds of EXR2.0 segfault when opening EXR bug */
- int parts;
+ StringVector *
+ multiView; /* it needs to be a pointer due to Windows release builds of EXR2.0 segfault when opening EXR bug */
+ int parts;
- ListBase channels; /* flattened out, ExrChannel */
- ListBase layers; /* hierarchical, pointing in end to ExrChannel */
+ ListBase channels; /* flattened out, ExrChannel */
+ ListBase layers; /* hierarchical, pointing in end to ExrChannel */
- int num_half_channels; /* used during filr save, allows faster temporary buffers allocation */
+ int num_half_channels; /* used during filr save, allows faster temporary buffers allocation */
} ExrHandle;
/* flattened out channel */
typedef struct ExrChannel {
- struct ExrChannel *next, *prev;
-
- char name[EXR_TOT_MAXNAME + 1]; /* full name with everything */
- struct MultiViewChannelName *m; /* struct to store all multipart channel info */
- int xstride, ystride; /* step to next pixel, to next scanline */
- float *rect; /* first pointer to write in */
- char chan_id; /* quick lookup of channel char */
- int view_id; /* quick lookup of channel view */
- bool use_half_float; /* when saving use half float for file storage */
+ struct ExrChannel *next, *prev;
+
+ char name[EXR_TOT_MAXNAME + 1]; /* full name with everything */
+ struct MultiViewChannelName *m; /* struct to store all multipart channel info */
+ int xstride, ystride; /* step to next pixel, to next scanline */
+ float *rect; /* first pointer to write in */
+ char chan_id; /* quick lookup of channel char */
+ int view_id; /* quick lookup of channel view */
+ bool use_half_float; /* when saving use half float for file storage */
} ExrChannel;
-
/* hierarchical; layers -> passes -> channels[] */
typedef struct ExrPass {
- struct ExrPass *next, *prev;
- char name[EXR_PASS_MAXNAME];
- int totchan;
- float *rect;
- struct ExrChannel *chan[EXR_PASS_MAXCHAN];
- char chan_id[EXR_PASS_MAXCHAN];
-
- char internal_name[EXR_PASS_MAXNAME]; /* name with no view */
- char view[EXR_VIEW_MAXNAME];
- int view_id;
+ struct ExrPass *next, *prev;
+ char name[EXR_PASS_MAXNAME];
+ int totchan;
+ float *rect;
+ struct ExrChannel *chan[EXR_PASS_MAXCHAN];
+ char chan_id[EXR_PASS_MAXCHAN];
+
+ char internal_name[EXR_PASS_MAXNAME]; /* name with no view */
+ char view[EXR_VIEW_MAXNAME];
+ int view_id;
} ExrPass;
typedef struct ExrLayer {
- struct ExrLayer *next, *prev;
- char name[EXR_LAY_MAXNAME + 1];
- ListBase passes;
+ struct ExrLayer *next, *prev;
+ char name[EXR_LAY_MAXNAME + 1];
+ ListBase passes;
} ExrLayer;
/* ********************** */
void *IMB_exr_get_handle(void)
{
- ExrHandle *data = (ExrHandle *)MEM_callocN(sizeof(ExrHandle), "exr handle");
- data->multiView = new StringVector();
+ ExrHandle *data = (ExrHandle *)MEM_callocN(sizeof(ExrHandle), "exr handle");
+ data->multiView = new StringVector();
- BLI_addtail(&exrhandles, data);
- return data;
+ BLI_addtail(&exrhandles, data);
+ return data;
}
void *IMB_exr_get_handle_name(const char *name)
{
- ExrHandle *data = (ExrHandle *) BLI_rfindstring(&exrhandles, name, offsetof(ExrHandle, name));
+ ExrHandle *data = (ExrHandle *)BLI_rfindstring(&exrhandles, name, offsetof(ExrHandle, name));
- if (data == NULL) {
- data = (ExrHandle *)IMB_exr_get_handle();
- BLI_strncpy(data->name, name, strlen(name) + 1);
- }
- return data;
+ if (data == NULL) {
+ data = (ExrHandle *)IMB_exr_get_handle();
+ BLI_strncpy(data->name, name, strlen(name) + 1);
+ }
+ return data;
}
/* multiview functions */
-} // extern "C"
+} // extern "C"
-extern "C"
-{
+extern "C" {
void IMB_exr_add_view(void *handle, const char *name)
{
- ExrHandle *data = (ExrHandle *)handle;
- data->multiView->push_back(name);
+ ExrHandle *data = (ExrHandle *)handle;
+ data->multiView->push_back(name);
}
-static int imb_exr_get_multiView_id(StringVector& views, const std::string& name)
+static int imb_exr_get_multiView_id(StringVector &views, const std::string &name)
{
- int count = 0;
- for (StringVector::const_iterator i = views.begin(); count < views.size(); ++i) {
- if (name == *i)
- return count;
- else
- count ++;
- }
-
- /* no views or wrong name */
- return -1;
+ int count = 0;
+ for (StringVector::const_iterator i = views.begin(); count < views.size(); ++i) {
+ if (name == *i)
+ return count;
+ else
+ count++;
+ }
+
+ /* no views or wrong name */
+ return -1;
}
-static void imb_exr_get_views(MultiPartInputFile& file, StringVector& views)
+static void imb_exr_get_views(MultiPartInputFile &file, StringVector &views)
{
- if (exr_has_multipart_file(file) == false) {
- if (exr_has_multiview(file)) {
- StringVector sv = multiView(file.header(0));
- for (StringVector::const_iterator i = sv.begin(); i != sv.end(); ++i)
- views.push_back(*i);
- }
- }
-
- else {
- for (int p = 0; p < file.parts(); p++) {
- std::string view = "";
- if (file.header(p).hasView())
- view = file.header(p).view();
-
- if (imb_exr_get_multiView_id(views, view) == -1)
- views.push_back(view);
- }
- }
+ if (exr_has_multipart_file(file) == false) {
+ if (exr_has_multiview(file)) {
+ StringVector sv = multiView(file.header(0));
+ for (StringVector::const_iterator i = sv.begin(); i != sv.end(); ++i)
+ views.push_back(*i);
+ }
+ }
+
+ else {
+ for (int p = 0; p < file.parts(); p++) {
+ std::string view = "";
+ if (file.header(p).hasView())
+ view = file.header(p).view();
+
+ if (imb_exr_get_multiView_id(views, view) == -1)
+ views.push_back(view);
+ }
+ }
}
/* Multilayer Blender files have the view name in all the passes (even the default view one) */
static void imb_exr_insert_view_name(char *name_full, const char *passname, const char *viewname)
{
- BLI_assert(!ELEM(name_full, passname, viewname));
-
- if (viewname == NULL || viewname[0] == '\0') {
- BLI_strncpy(name_full, passname, sizeof(((ExrChannel *)NULL)->name));
- return;
- }
-
- const char delims[] = {'.', '\0'};
- const char *sep;
- const char *token;
- size_t len;
-
- len = BLI_str_rpartition(passname, delims, &sep, &token);
-
- if (sep) {
- BLI_snprintf(name_full, EXR_PASS_MAXNAME, "%.*s.%s.%s", (int)len, passname, viewname, token);
- }
- else {
- BLI_snprintf(name_full, EXR_PASS_MAXNAME, "%s.%s", passname, viewname);
- }
+ BLI_assert(!ELEM(name_full, passname, viewname));
+
+ if (viewname == NULL || viewname[0] == '\0') {
+ BLI_strncpy(name_full, passname, sizeof(((ExrChannel *)NULL)->name));
+ return;
+ }
+
+ const char delims[] = {'.', '\0'};
+ const char *sep;
+ const char *token;
+ size_t len;
+
+ len = BLI_str_rpartition(passname, delims, &sep, &token);
+
+ if (sep) {
+ BLI_snprintf(name_full, EXR_PASS_MAXNAME, "%.*s.%s.%s", (int)len, passname, viewname, token);
+ }
+ else {
+ BLI_snprintf(name_full, EXR_PASS_MAXNAME, "%s.%s", passname, viewname);
+ }
}
/* adds flattened ExrChannels */
/* xstride, ystride and rect can be done in set_channel too, for tile writing */
/* passname does not include view */
void IMB_exr_add_channel(void *handle,
- const char *layname, const char *passname, const char *viewname,
- int xstride, int ystride, float *rect,
+ const char *layname,
+ const char *passname,
+ const char *viewname,
+ int xstride,
+ int ystride,
+ float *rect,
bool use_half_float)
{
- ExrHandle *data = (ExrHandle *)handle;
- ExrChannel *echan;
-
- echan = (ExrChannel *)MEM_callocN(sizeof(ExrChannel), "exr channel");
- echan->m = new MultiViewChannelName ();
-
- if (layname && layname[0] != '\0') {
- echan->m->name = layname;
- echan->m->name.append(".");
- echan->m->name.append(passname);
- }
- else {
- echan->m->name.assign(passname);
- }
-
- echan->m->internal_name = echan->m->name;
-
- echan->m->view.assign(viewname ? viewname : "");
-
- /* quick look up */
- echan->view_id = std::max(0, imb_exr_get_multiView_id(*data->multiView, echan->m->view));
-
- /* name has to be unique, thus it's a combination of layer, pass, view, and channel */
- if (layname && layname[0] != '\0') {
- imb_exr_insert_view_name(echan->name, echan->m->name.c_str(), echan->m->view.c_str());
- }
- else if (data->multiView->size() >= 1) {
- std::string raw_name = insertViewName(echan->m->name, *data->multiView, echan->view_id);
- BLI_strncpy(echan->name, raw_name.c_str(), sizeof(echan->name));
- }
- else {
- BLI_strncpy(echan->name, echan->m->name.c_str(), sizeof(echan->name));
- }
-
- echan->xstride = xstride;
- echan->ystride = ystride;
- echan->rect = rect;
- echan->use_half_float = use_half_float;
-
- if (echan->use_half_float) {
- data->num_half_channels++;
- }
-
- exr_printf("added channel %s\n", echan->name);
- BLI_addtail(&data->channels, echan);
+ ExrHandle *data = (ExrHandle *)handle;
+ ExrChannel *echan;
+
+ echan = (ExrChannel *)MEM_callocN(sizeof(ExrChannel), "exr channel");
+ echan->m = new MultiViewChannelName();
+
+ if (layname && layname[0] != '\0') {
+ echan->m->name = layname;
+ echan->m->name.append(".");
+ echan->m->name.append(passname);
+ }
+ else {
+ echan->m->name.assign(passname);
+ }
+
+ echan->m->internal_name = echan->m->name;
+
+ echan->m->view.assign(viewname ? viewname : "");
+
+ /* quick look up */
+ echan->view_id = std::max(0, imb_exr_get_multiView_id(*data->multiView, echan->m->view));
+
+ /* name has to be unique, thus it's a combination of layer, pass, view, and channel */
+ if (layname && layname[0] != '\0') {
+ imb_exr_insert_view_name(echan->name, echan->m->name.c_str(), echan->m->view.c_str());
+ }
+ else if (data->multiView->size() >= 1) {
+ std::string raw_name = insertViewName(echan->m->name, *data->multiView, echan->view_id);
+ BLI_strncpy(echan->name, raw_name.c_str(), sizeof(echan->name));
+ }
+ else {
+ BLI_strncpy(echan->name, echan->m->name.c_str(), sizeof(echan->name));
+ }
+
+ echan->xstride = xstride;
+ echan->ystride = ystride;
+ echan->rect = rect;
+ echan->use_half_float = use_half_float;
+
+ if (echan->use_half_float) {
+ data->num_half_channels++;
+ }
+
+ exr_printf("added channel %s\n", echan->name);
+ BLI_addtail(&data->channels, echan);
}
/* used for output files (from RenderResult) (single and multilayer, single and multiview) */
-int IMB_exr_begin_write(void *handle, const char *filename, int width, int height, int compress, const StampData *stamp)
+int IMB_exr_begin_write(void *handle,
+ const char *filename,
+ int width,
+ int height,
+ int compress,
+ const StampData *stamp)
{
- ExrHandle *data = (ExrHandle *)handle;
- Header header(width, height);
- ExrChannel *echan;
+ ExrHandle *data = (ExrHandle *)handle;
+ Header header(width, height);
+ ExrChannel *echan;
- data->width = width;
- data->height = height;
+ data->width = width;
+ data->height = height;
- bool is_singlelayer, is_multilayer, is_multiview;
+ bool is_singlelayer, is_multilayer, is_multiview;
- for (echan = (ExrChannel *)data->channels.first; echan; echan = echan->next) {
- header.channels().insert(echan->name,
- Channel(echan->use_half_float ? Imf::HALF : Imf::FLOAT));
- }
+ for (echan = (ExrChannel *)data->channels.first; echan; echan = echan->next) {
+ header.channels().insert(echan->name, Channel(echan->use_half_float ? Imf::HALF : Imf::FLOAT));
+ }
- openexr_header_compression(&header, compress);
- BKE_stamp_info_callback(&header, const_cast<StampData *>(stamp), openexr_header_metadata_callback, false);
- /* header.lineOrder() = DECREASING_Y; this crashes in windows for file read! */
+ openexr_header_compression(&header, compress);
+ BKE_stamp_info_callback(
+ &header, const_cast<StampData *>(stamp), openexr_header_metadata_callback, false);
+ /* header.lineOrder() = DECREASING_Y; this crashes in windows for file read! */
- imb_exr_type_by_channels(header.channels(), *data->multiView, &is_singlelayer, &is_multilayer, &is_multiview);
+ imb_exr_type_by_channels(
+ header.channels(), *data->multiView, &is_singlelayer, &is_multilayer, &is_multiview);
- if (is_multilayer)
- header.insert("BlenderMultiChannel", StringAttribute("Blender V2.55.1 and newer"));
+ if (is_multilayer)
+ header.insert("BlenderMultiChannel", StringAttribute("Blender V2.55.1 and newer"));
- if (is_multiview)
- addMultiView(header, *data->multiView);
+ if (is_multiview)
+ addMultiView(header, *data->multiView);
- /* avoid crash/abort when we don't have permission to write here */
- /* manually create ofstream, so we can handle utf-8 filepaths on windows */
- try {
- data->ofile_stream = new OFileStream(filename);
- data->ofile = new OutputFile(*(data->ofile_stream), header);
- }
- catch (const std::exception& exc) {
- std::cerr << "IMB_exr_begin_write: ERROR: " << exc.what() << std::endl;
+ /* avoid crash/abort when we don't have permission to write here */
+ /* manually create ofstream, so we can handle utf-8 filepaths on windows */
+ try {
+ data->ofile_stream = new OFileStream(filename);
+ data->ofile = new OutputFile(*(data->ofile_stream), header);
+ }
+ catch (const std::exception &exc) {
+ std::cerr << "IMB_exr_begin_write: ERROR: " << exc.what() << std::endl;
- delete data->ofile;
- delete data->ofile_stream;
+ delete data->ofile;
+ delete data->ofile_stream;
- data->ofile = NULL;
- data->ofile_stream = NULL;
- }
+ data->ofile = NULL;
+ data->ofile_stream = NULL;
+ }
- return (data->ofile != NULL);
+ return (data->ofile != NULL);
}
/* only used for writing temp. render results (not image files)
* (FSA and Save Buffers) */
-void IMB_exrtile_begin_write(void *handle, const char *filename, int mipmap, int width, int height, int tilex, int tiley)
+void IMB_exrtile_begin_write(
+ void *handle, const char *filename, int mipmap, int width, int height, int tilex, int tiley)
{
- ExrHandle *data = (ExrHandle *)handle;
- Header header(width, height);
- std::vector<Header> headers;
- ExrChannel *echan;
-
- data->tilex = tilex;
- data->tiley = tiley;
- data->width = width;
- data->height = height;
- data->mipmap = mipmap;
-
- header.setTileDescription(TileDescription(tilex, tiley, (mipmap) ? MIPMAP_LEVELS : ONE_LEVEL));
- header.compression() = RLE_COMPRESSION;
- header.setType(TILEDIMAGE);
-
- header.insert("BlenderMultiChannel", StringAttribute("Blender V2.43"));
-
- int numparts = data->multiView->size();
-
- /* copy header from all parts of input to our header array
- * those temporary files have one part per view */
- for (int i = 0; i < numparts; i++) {
- headers.push_back (header);
- headers[headers.size() - 1].setView((*(data->multiView))[i]);
- headers[headers.size() - 1].setName((*(data->multiView))[i]);
- }
-
- exr_printf("\nIMB_exrtile_begin_write\n");
- exr_printf("%s %-6s %-22s \"%s\"\n", "p", "view", "name", "internal_name");
- exr_printf("---------------------------------------------------------------\n");
-
- /* assign channels */
- for (echan = (ExrChannel *)data->channels.first; echan; echan = echan->next) {
- /* Tiles are expected to be saved with full float currently. */
- BLI_assert(echan->use_half_float == 0);
-
- echan->m->internal_name = echan->m->name;
- echan->m->part_number = echan->view_id;
-
- headers[echan->view_id].channels().insert(echan->m->internal_name, Channel(Imf::FLOAT));
- exr_printf("%d %-6s %-22s \"%s\"\n", echan->m->part_number, echan->m->view.c_str(), echan->m->name.c_str(), echan->m->internal_name.c_str());
- }
-
- /* avoid crash/abort when we don't have permission to write here */
- /* manually create ofstream, so we can handle utf-8 filepaths on windows */
- try {
- data->ofile_stream = new OFileStream(filename);
- data->mpofile = new MultiPartOutputFile(*(data->ofile_stream), &headers[0], headers.size());
- }
- catch (const std::exception &) {
- delete data->mpofile;
- delete data->ofile_stream;
-
- data->mpofile = NULL;
- data->ofile_stream = NULL;
- }
+ ExrHandle *data = (ExrHandle *)handle;
+ Header header(width, height);
+ std::vector<Header> headers;
+ ExrChannel *echan;
+
+ data->tilex = tilex;
+ data->tiley = tiley;
+ data->width = width;
+ data->height = height;
+ data->mipmap = mipmap;
+
+ header.setTileDescription(TileDescription(tilex, tiley, (mipmap) ? MIPMAP_LEVELS : ONE_LEVEL));
+ header.compression() = RLE_COMPRESSION;
+ header.setType(TILEDIMAGE);
+
+ header.insert("BlenderMultiChannel", StringAttribute("Blender V2.43"));
+
+ int numparts = data->multiView->size();
+
+ /* copy header from all parts of input to our header array
+ * those temporary files have one part per view */
+ for (int i = 0; i < numparts; i++) {
+ headers.push_back(header);
+ headers[headers.size() - 1].setView((*(data->multiView))[i]);
+ headers[headers.size() - 1].setName((*(data->multiView))[i]);
+ }
+
+ exr_printf("\nIMB_exrtile_begin_write\n");
+ exr_printf("%s %-6s %-22s \"%s\"\n", "p", "view", "name", "internal_name");
+ exr_printf("---------------------------------------------------------------\n");
+
+ /* assign channels */
+ for (echan = (ExrChannel *)data->channels.first; echan; echan = echan->next) {
+ /* Tiles are expected to be saved with full float currently. */
+ BLI_assert(echan->use_half_float == 0);
+
+ echan->m->internal_name = echan->m->name;
+ echan->m->part_number = echan->view_id;
+
+ headers[echan->view_id].channels().insert(echan->m->internal_name, Channel(Imf::FLOAT));
+ exr_printf("%d %-6s %-22s \"%s\"\n",
+ echan->m->part_number,
+ echan->m->view.c_str(),
+ echan->m->name.c_str(),
+ echan->m->internal_name.c_str());
+ }
+
+ /* avoid crash/abort when we don't have permission to write here */
+ /* manually create ofstream, so we can handle utf-8 filepaths on windows */
+ try {
+ data->ofile_stream = new OFileStream(filename);
+ data->mpofile = new MultiPartOutputFile(*(data->ofile_stream), &headers[0], headers.size());
+ }
+ catch (const std::exception &) {
+ delete data->mpofile;
+ delete data->ofile_stream;
+
+ data->mpofile = NULL;
+ data->ofile_stream = NULL;
+ }
}
/* read from file */
int IMB_exr_begin_read(void *handle, const char *filename, int *width, int *height)
{
- ExrHandle *data = (ExrHandle *)handle;
- ExrChannel *echan;
-
- if (BLI_exists(filename) && BLI_file_size(filename) > 32) { /* 32 is arbitrary, but zero length files crashes exr */
- /* avoid crash/abort when we don't have permission to write here */
- try {
- data->ifile_stream = new IFileStream(filename);
- data->ifile = new MultiPartInputFile(*(data->ifile_stream));
- }
- catch (const std::exception &) {
- delete data->ifile;
- delete data->ifile_stream;
-
- data->ifile = NULL;
- data->ifile_stream = NULL;
- }
-
- if (data->ifile) {
- Box2i dw = data->ifile->header(0).dataWindow();
- data->width = *width = dw.max.x - dw.min.x + 1;
- data->height = *height = dw.max.y - dw.min.y + 1;
-
- imb_exr_get_views(*data->ifile, *data->multiView);
-
- std::vector<MultiViewChannelName> channels;
- GetChannelsInMultiPartFile(*data->ifile, channels);
-
- for (size_t i = 0; i < channels.size(); i++) {
- IMB_exr_add_channel(data, NULL, channels[i].name.c_str(), channels[i].view.c_str(), 0, 0, NULL, false);
-
- echan = (ExrChannel *)data->channels.last;
- echan->m->name = channels[i].name;
- echan->m->view = channels[i].view;
- echan->m->part_number = channels[i].part_number;
- echan->m->internal_name = channels[i].internal_name;
- }
-
- return 1;
- }
- }
- return 0;
+ ExrHandle *data = (ExrHandle *)handle;
+ ExrChannel *echan;
+
+ if (BLI_exists(filename) &&
+ BLI_file_size(filename) > 32) { /* 32 is arbitrary, but zero length files crashes exr */
+ /* avoid crash/abort when we don't have permission to write here */
+ try {
+ data->ifile_stream = new IFileStream(filename);
+ data->ifile = new MultiPartInputFile(*(data->ifile_stream));
+ }
+ catch (const std::exception &) {
+ delete data->ifile;
+ delete data->ifile_stream;
+
+ data->ifile = NULL;
+ data->ifile_stream = NULL;
+ }
+
+ if (data->ifile) {
+ Box2i dw = data->ifile->header(0).dataWindow();
+ data->width = *width = dw.max.x - dw.min.x + 1;
+ data->height = *height = dw.max.y - dw.min.y + 1;
+
+ imb_exr_get_views(*data->ifile, *data->multiView);
+
+ std::vector<MultiViewChannelName> channels;
+ GetChannelsInMultiPartFile(*data->ifile, channels);
+
+ for (size_t i = 0; i < channels.size(); i++) {
+ IMB_exr_add_channel(
+ data, NULL, channels[i].name.c_str(), channels[i].view.c_str(), 0, 0, NULL, false);
+
+ echan = (ExrChannel *)data->channels.last;
+ echan->m->name = channels[i].name;
+ echan->m->view = channels[i].view;
+ echan->m->part_number = channels[i].part_number;
+ echan->m->internal_name = channels[i].internal_name;
+ }
+
+ return 1;
+ }
+ }
+ return 0;
}
/* still clumsy name handling, layers/channels can be ordered as list in list later */
/* passname here is the raw channel name without the layer */
-void IMB_exr_set_channel(void *handle, const char *layname, const char *passname, int xstride, int ystride, float *rect)
+void IMB_exr_set_channel(
+ void *handle, const char *layname, const char *passname, int xstride, int ystride, float *rect)
{
- ExrHandle *data = (ExrHandle *)handle;
- ExrChannel *echan;
- char name[EXR_TOT_MAXNAME + 1];
-
- if (layname && layname[0] != '\0') {
- char lay[EXR_LAY_MAXNAME + 1], pass[EXR_PASS_MAXNAME + 1];
- BLI_strncpy(lay, layname, EXR_LAY_MAXNAME);
- BLI_strncpy(pass, passname, EXR_PASS_MAXNAME);
-
- BLI_snprintf(name, sizeof(name), "%s.%s", lay, pass);
- }
- else {
- BLI_strncpy(name, passname, EXR_TOT_MAXNAME - 1);
- }
-
- echan = (ExrChannel *)BLI_findstring(&data->channels, name, offsetof(ExrChannel, name));
-
- if (echan) {
- echan->xstride = xstride;
- echan->ystride = ystride;
- echan->rect = rect;
- }
- else {
- printf("IMB_exr_set_channel error %s\n", name);
- }
+ ExrHandle *data = (ExrHandle *)handle;
+ ExrChannel *echan;
+ char name[EXR_TOT_MAXNAME + 1];
+
+ if (layname && layname[0] != '\0') {
+ char lay[EXR_LAY_MAXNAME + 1], pass[EXR_PASS_MAXNAME + 1];
+ BLI_strncpy(lay, layname, EXR_LAY_MAXNAME);
+ BLI_strncpy(pass, passname, EXR_PASS_MAXNAME);
+
+ BLI_snprintf(name, sizeof(name), "%s.%s", lay, pass);
+ }
+ else {
+ BLI_strncpy(name, passname, EXR_TOT_MAXNAME - 1);
+ }
+
+ echan = (ExrChannel *)BLI_findstring(&data->channels, name, offsetof(ExrChannel, name));
+
+ if (echan) {
+ echan->xstride = xstride;
+ echan->ystride = ystride;
+ echan->rect = rect;
+ }
+ else {
+ printf("IMB_exr_set_channel error %s\n", name);
+ }
}
-float *IMB_exr_channel_rect(void *handle, const char *layname, const char *passname, const char *viewname)
+float *IMB_exr_channel_rect(void *handle,
+ const char *layname,
+ const char *passname,
+ const char *viewname)
{
- ExrHandle *data = (ExrHandle *)handle;
- ExrChannel *echan;
- char name[EXR_TOT_MAXNAME + 1];
-
- if (layname) {
- char lay[EXR_LAY_MAXNAME + 1], pass[EXR_PASS_MAXNAME + 1];
- BLI_strncpy(lay, layname, EXR_LAY_MAXNAME);
- BLI_strncpy(pass, passname, EXR_PASS_MAXNAME);
-
- BLI_snprintf(name, sizeof(name), "%s.%s", lay, pass);
- }
- else
- BLI_strncpy(name, passname, EXR_TOT_MAXNAME - 1);
-
- /* name has to be unique, thus it's a combination of layer, pass, view, and channel */
- if (layname && layname[0] != '\0') {
- char temp_buf[EXR_PASS_MAXNAME];
- imb_exr_insert_view_name(temp_buf, name, viewname);
- BLI_strncpy(name, temp_buf, sizeof(name));
- }
- else if (data->multiView->size() >= 1) {
- const int view_id = std::max(0, imb_exr_get_multiView_id(*data->multiView, viewname));
- std::string raw_name = insertViewName(name, *data->multiView, view_id);
- BLI_strncpy(name, raw_name.c_str(), sizeof(name));
- }
-
- echan = (ExrChannel *)BLI_findstring(&data->channels, name, offsetof(ExrChannel, name));
-
- if (echan)
- return echan->rect;
-
- return NULL;
+ ExrHandle *data = (ExrHandle *)handle;
+ ExrChannel *echan;
+ char name[EXR_TOT_MAXNAME + 1];
+
+ if (layname) {
+ char lay[EXR_LAY_MAXNAME + 1], pass[EXR_PASS_MAXNAME + 1];
+ BLI_strncpy(lay, layname, EXR_LAY_MAXNAME);
+ BLI_strncpy(pass, passname, EXR_PASS_MAXNAME);
+
+ BLI_snprintf(name, sizeof(name), "%s.%s", lay, pass);
+ }
+ else
+ BLI_strncpy(name, passname, EXR_TOT_MAXNAME - 1);
+
+ /* name has to be unique, thus it's a combination of layer, pass, view, and channel */
+ if (layname && layname[0] != '\0') {
+ char temp_buf[EXR_PASS_MAXNAME];
+ imb_exr_insert_view_name(temp_buf, name, viewname);
+ BLI_strncpy(name, temp_buf, sizeof(name));
+ }
+ else if (data->multiView->size() >= 1) {
+ const int view_id = std::max(0, imb_exr_get_multiView_id(*data->multiView, viewname));
+ std::string raw_name = insertViewName(name, *data->multiView, view_id);
+ BLI_strncpy(name, raw_name.c_str(), sizeof(name));
+ }
+
+ echan = (ExrChannel *)BLI_findstring(&data->channels, name, offsetof(ExrChannel, name));
+
+ if (echan)
+ return echan->rect;
+
+ return NULL;
}
void IMB_exr_clear_channels(void *handle)
{
- ExrHandle *data = (ExrHandle *)handle;
- ExrChannel *chan;
+ ExrHandle *data = (ExrHandle *)handle;
+ ExrChannel *chan;
- for (chan = (ExrChannel *)data->channels.first; chan; chan = chan->next)
- delete chan->m;
+ for (chan = (ExrChannel *)data->channels.first; chan; chan = chan->next)
+ delete chan->m;
- BLI_freelistN(&data->channels);
+ BLI_freelistN(&data->channels);
}
void IMB_exr_write_channels(void *handle)
{
- ExrHandle *data = (ExrHandle *)handle;
- FrameBuffer frameBuffer;
- ExrChannel *echan;
-
- if (data->channels.first) {
- const size_t num_pixels = ((size_t)data->width) * data->height;
- half *rect_half = NULL, *current_rect_half = NULL;
-
- /* We allocate teporary storage for half pixels for all the channels at once. */
- if (data->num_half_channels != 0) {
- rect_half = (half *)MEM_mallocN(sizeof(half) * data->num_half_channels * num_pixels, __func__);
- current_rect_half = rect_half;
- }
-
- for (echan = (ExrChannel *)data->channels.first; echan; echan = echan->next) {
- /* Writing starts from last scanline, stride negative. */
- if (echan->use_half_float) {
- float *rect = echan->rect;
- half *cur = current_rect_half;
- for (size_t i = 0; i < num_pixels; ++i, ++cur) {
- *cur = rect[i * echan->xstride];
- }
- half *rect_to_write = current_rect_half + (data->height - 1L) * data->width;
- frameBuffer.insert(echan->name, Slice(Imf::HALF, (char *)rect_to_write,
- sizeof(half), -data->width * sizeof(half)));
- current_rect_half += num_pixels;
- }
- else {
- float *rect = echan->rect + echan->xstride * (data->height - 1L) * data->width;
- frameBuffer.insert(echan->name, Slice(Imf::FLOAT, (char *)rect,
- echan->xstride * sizeof(float), -echan->ystride * sizeof(float)));
- }
- }
-
- data->ofile->setFrameBuffer(frameBuffer);
- try {
- data->ofile->writePixels(data->height);
- }
- catch (const std::exception& exc) {
- std::cerr << "OpenEXR-writePixels: ERROR: " << exc.what() << std::endl;
- }
- /* Free temporary buffers. */
- if (rect_half != NULL) {
- MEM_freeN(rect_half);
- }
- }
- else {
- printf("Error: attempt to save MultiLayer without layers.\n");
- }
+ ExrHandle *data = (ExrHandle *)handle;
+ FrameBuffer frameBuffer;
+ ExrChannel *echan;
+
+ if (data->channels.first) {
+ const size_t num_pixels = ((size_t)data->width) * data->height;
+ half *rect_half = NULL, *current_rect_half = NULL;
+
+ /* We allocate teporary storage for half pixels for all the channels at once. */
+ if (data->num_half_channels != 0) {
+ rect_half = (half *)MEM_mallocN(sizeof(half) * data->num_half_channels * num_pixels,
+ __func__);
+ current_rect_half = rect_half;
+ }
+
+ for (echan = (ExrChannel *)data->channels.first; echan; echan = echan->next) {
+ /* Writing starts from last scanline, stride negative. */
+ if (echan->use_half_float) {
+ float *rect = echan->rect;
+ half *cur = current_rect_half;
+ for (size_t i = 0; i < num_pixels; ++i, ++cur) {
+ *cur = rect[i * echan->xstride];
+ }
+ half *rect_to_write = current_rect_half + (data->height - 1L) * data->width;
+ frameBuffer.insert(
+ echan->name,
+ Slice(Imf::HALF, (char *)rect_to_write, sizeof(half), -data->width * sizeof(half)));
+ current_rect_half += num_pixels;
+ }
+ else {
+ float *rect = echan->rect + echan->xstride * (data->height - 1L) * data->width;
+ frameBuffer.insert(echan->name,
+ Slice(Imf::FLOAT,
+ (char *)rect,
+ echan->xstride * sizeof(float),
+ -echan->ystride * sizeof(float)));
+ }
+ }
+
+ data->ofile->setFrameBuffer(frameBuffer);
+ try {
+ data->ofile->writePixels(data->height);
+ }
+ catch (const std::exception &exc) {
+ std::cerr << "OpenEXR-writePixels: ERROR: " << exc.what() << std::endl;
+ }
+ /* Free temporary buffers. */
+ if (rect_half != NULL) {
+ MEM_freeN(rect_half);
+ }
+ }
+ else {
+ printf("Error: attempt to save MultiLayer without layers.\n");
+ }
}
/* temporary function, used for FSA and Save Buffers */
/* called once per tile * view */
-void IMB_exrtile_write_channels(void *handle, int partx, int party, int level, const char *viewname, bool empty)
+void IMB_exrtile_write_channels(
+ void *handle, int partx, int party, int level, const char *viewname, bool empty)
{
- /* Can write empty channels for incomplete renders. */
- ExrHandle *data = (ExrHandle *)handle;
- FrameBuffer frameBuffer;
- std::string view(viewname);
- const int view_id = imb_exr_get_multiView_id(*data->multiView, view);
-
- exr_printf("\nIMB_exrtile_write_channels(view: %s)\n", viewname);
- exr_printf("%s %-6s %-22s \"%s\"\n", "p", "view", "name", "internal_name");
- exr_printf("---------------------------------------------------------------------\n");
-
- if (!empty) {
- ExrChannel *echan;
-
- for (echan = (ExrChannel *)data->channels.first; echan; echan = echan->next) {
-
- /* eventually we can make the parts' channels to include
- only the current view TODO */
- if (strcmp(viewname, echan->m->view.c_str()) != 0)
- continue;
-
- exr_printf("%d %-6s %-22s \"%s\"\n",
- echan->m->part_number,
- echan->m->view.c_str(),
- echan->m->name.c_str(),
- echan->m->internal_name.c_str()
- );
-
- float *rect = echan->rect - echan->xstride * partx - echan->ystride * party;
- frameBuffer.insert(echan->m->internal_name,
- Slice(Imf::FLOAT,
- (char *)rect,
- echan->xstride * sizeof(float),
- echan->ystride * sizeof(float)
- )
- );
- }
- }
-
- TiledOutputPart out (*data->mpofile, view_id);
- out.setFrameBuffer(frameBuffer);
-
- try {
- // printf("write tile %d %d\n", partx/data->tilex, party/data->tiley);
- out.writeTile(partx / data->tilex, party / data->tiley, level);
- }
- catch (const std::exception& exc) {
- std::cerr << "OpenEXR-writeTile: ERROR: " << exc.what() << std::endl;
- }
+ /* Can write empty channels for incomplete renders. */
+ ExrHandle *data = (ExrHandle *)handle;
+ FrameBuffer frameBuffer;
+ std::string view(viewname);
+ const int view_id = imb_exr_get_multiView_id(*data->multiView, view);
+
+ exr_printf("\nIMB_exrtile_write_channels(view: %s)\n", viewname);
+ exr_printf("%s %-6s %-22s \"%s\"\n", "p", "view", "name", "internal_name");
+ exr_printf("---------------------------------------------------------------------\n");
+
+ if (!empty) {
+ ExrChannel *echan;
+
+ for (echan = (ExrChannel *)data->channels.first; echan; echan = echan->next) {
+
+ /* eventually we can make the parts' channels to include
+ only the current view TODO */
+ if (strcmp(viewname, echan->m->view.c_str()) != 0)
+ continue;
+
+ exr_printf("%d %-6s %-22s \"%s\"\n",
+ echan->m->part_number,
+ echan->m->view.c_str(),
+ echan->m->name.c_str(),
+ echan->m->internal_name.c_str());
+
+ float *rect = echan->rect - echan->xstride * partx - echan->ystride * party;
+ frameBuffer.insert(echan->m->internal_name,
+ Slice(Imf::FLOAT,
+ (char *)rect,
+ echan->xstride * sizeof(float),
+ echan->ystride * sizeof(float)));
+ }
+ }
+
+ TiledOutputPart out(*data->mpofile, view_id);
+ out.setFrameBuffer(frameBuffer);
+
+ try {
+ // printf("write tile %d %d\n", partx/data->tilex, party/data->tiley);
+ out.writeTile(partx / data->tilex, party / data->tiley, level);
+ }
+ catch (const std::exception &exc) {
+ std::cerr << "OpenEXR-writeTile: ERROR: " << exc.what() << std::endl;
+ }
}
void IMB_exr_read_channels(void *handle)
{
- ExrHandle *data = (ExrHandle *)handle;
- int numparts = data->ifile->parts();
-
- /* check if exr was saved with previous versions of blender which flipped images */
- const StringAttribute *ta = data->ifile->header(0).findTypedAttribute <StringAttribute> ("BlenderMultiChannel");
- short flip = (ta && STREQLEN(ta->value().c_str(), "Blender V2.43", 13)); /* 'previous multilayer attribute, flipped */
-
- exr_printf("\nIMB_exr_read_channels\n%s %-6s %-22s \"%s\"\n---------------------------------------------------------------------\n", "p", "view", "name", "internal_name");
-
- for (int i = 0; i < numparts; i++) {
- /* Read part header. */
- InputPart in(*data->ifile, i);
- Header header = in.header();
- Box2i dw = header.dataWindow();
-
- /* Insert all matching channel into framebuffer. */
- FrameBuffer frameBuffer;
- ExrChannel *echan;
-
- for (echan = (ExrChannel *)data->channels.first; echan; echan = echan->next) {
- if (echan->m->part_number != i) {
- continue;
- }
-
- exr_printf("%d %-6s %-22s \"%s\"\n", echan->m->part_number, echan->m->view.c_str(), echan->m->name.c_str(), echan->m->internal_name.c_str());
-
- if (echan->rect) {
- float *rect = echan->rect;
- size_t xstride = echan->xstride * sizeof(float);
- size_t ystride = echan->ystride * sizeof(float);
-
- if (!flip) {
- /* inverse correct first pixel for datawindow coordinates */
- rect -= echan->xstride * (dw.min.x - dw.min.y * data->width);
- /* move to last scanline to flip to Blender convention */
- rect += echan->xstride * (data->height - 1) * data->width;
- ystride = -ystride;
- }
- else {
- /* inverse correct first pixel for datawindow coordinates */
- rect -= echan->xstride * (dw.min.x + dw.min.y * data->width);
- }
-
- frameBuffer.insert(echan->m->internal_name, Slice(Imf::FLOAT, (char *)rect, xstride, ystride));
- }
- else
- printf("warning, channel with no rect set %s\n", echan->m->internal_name.c_str());
- }
-
- /* Read pixels. */
- try {
- in.setFrameBuffer(frameBuffer);
- exr_printf("readPixels:readPixels[%d]: min.y: %d, max.y: %d\n", i, dw.min.y, dw.max.y);
- in.readPixels(dw.min.y, dw.max.y);
- }
- catch (const std::exception& exc) {
- std::cerr << "OpenEXR-readPixels: ERROR: " << exc.what() << std::endl;
- break;
- }
- }
+ ExrHandle *data = (ExrHandle *)handle;
+ int numparts = data->ifile->parts();
+
+ /* check if exr was saved with previous versions of blender which flipped images */
+ const StringAttribute *ta = data->ifile->header(0).findTypedAttribute<StringAttribute>(
+ "BlenderMultiChannel");
+ short flip = (ta && STREQLEN(ta->value().c_str(),
+ "Blender V2.43",
+ 13)); /* 'previous multilayer attribute, flipped */
+
+ exr_printf(
+ "\nIMB_exr_read_channels\n%s %-6s %-22s "
+ "\"%s\"\n---------------------------------------------------------------------\n",
+ "p",
+ "view",
+ "name",
+ "internal_name");
+
+ for (int i = 0; i < numparts; i++) {
+ /* Read part header. */
+ InputPart in(*data->ifile, i);
+ Header header = in.header();
+ Box2i dw = header.dataWindow();
+
+ /* Insert all matching channel into framebuffer. */
+ FrameBuffer frameBuffer;
+ ExrChannel *echan;
+
+ for (echan = (ExrChannel *)data->channels.first; echan; echan = echan->next) {
+ if (echan->m->part_number != i) {
+ continue;
+ }
+
+ exr_printf("%d %-6s %-22s \"%s\"\n",
+ echan->m->part_number,
+ echan->m->view.c_str(),
+ echan->m->name.c_str(),
+ echan->m->internal_name.c_str());
+
+ if (echan->rect) {
+ float *rect = echan->rect;
+ size_t xstride = echan->xstride * sizeof(float);
+ size_t ystride = echan->ystride * sizeof(float);
+
+ if (!flip) {
+ /* inverse correct first pixel for datawindow coordinates */
+ rect -= echan->xstride * (dw.min.x - dw.min.y * data->width);
+ /* move to last scanline to flip to Blender convention */
+ rect += echan->xstride * (data->height - 1) * data->width;
+ ystride = -ystride;
+ }
+ else {
+ /* inverse correct first pixel for datawindow coordinates */
+ rect -= echan->xstride * (dw.min.x + dw.min.y * data->width);
+ }
+
+ frameBuffer.insert(echan->m->internal_name,
+ Slice(Imf::FLOAT, (char *)rect, xstride, ystride));
+ }
+ else
+ printf("warning, channel with no rect set %s\n", echan->m->internal_name.c_str());
+ }
+
+ /* Read pixels. */
+ try {
+ in.setFrameBuffer(frameBuffer);
+ exr_printf("readPixels:readPixels[%d]: min.y: %d, max.y: %d\n", i, dw.min.y, dw.max.y);
+ in.readPixels(dw.min.y, dw.max.y);
+ }
+ catch (const std::exception &exc) {
+ std::cerr << "OpenEXR-readPixels: ERROR: " << exc.what() << std::endl;
+ break;
+ }
+ }
}
-void IMB_exr_multilayer_convert(void *handle, void *base,
- void * (*addview)(void *base, const char *str),
- void * (*addlayer)(void *base, const char *str),
- void (*addpass)(void *base, void *lay, const char *str,
- float *rect, int totchan, const char *chan_id,
+void IMB_exr_multilayer_convert(void *handle,
+ void *base,
+ void *(*addview)(void *base, const char *str),
+ void *(*addlayer)(void *base, const char *str),
+ void (*addpass)(void *base,
+ void *lay,
+ const char *str,
+ float *rect,
+ int totchan,
+ const char *chan_id,
const char *view))
{
- ExrHandle *data = (ExrHandle *)handle;
- ExrLayer *lay;
- ExrPass *pass;
-
- /* RenderResult needs at least one RenderView */
- if (data->multiView->size() == 0) {
- addview(base, "");
- }
- else {
- /* add views to RenderResult */
- for (StringVector::const_iterator i = data->multiView->begin(); i != data->multiView->end(); ++i) {
- addview(base, (*i).c_str());
- }
- }
-
- if (BLI_listbase_is_empty(&data->layers)) {
- printf("cannot convert multilayer, no layers in handle\n");
- return;
- }
-
- for (lay = (ExrLayer *)data->layers.first; lay; lay = lay->next) {
- void *laybase = addlayer(base, lay->name);
- if (laybase) {
- for (pass = (ExrPass *)lay->passes.first; pass; pass = pass->next) {
- addpass(base, laybase, pass->internal_name, pass->rect, pass->totchan, pass->chan_id, pass->view);
- pass->rect = NULL;
- }
- }
- }
+ ExrHandle *data = (ExrHandle *)handle;
+ ExrLayer *lay;
+ ExrPass *pass;
+
+ /* RenderResult needs at least one RenderView */
+ if (data->multiView->size() == 0) {
+ addview(base, "");
+ }
+ else {
+ /* add views to RenderResult */
+ for (StringVector::const_iterator i = data->multiView->begin(); i != data->multiView->end();
+ ++i) {
+ addview(base, (*i).c_str());
+ }
+ }
+
+ if (BLI_listbase_is_empty(&data->layers)) {
+ printf("cannot convert multilayer, no layers in handle\n");
+ return;
+ }
+
+ for (lay = (ExrLayer *)data->layers.first; lay; lay = lay->next) {
+ void *laybase = addlayer(base, lay->name);
+ if (laybase) {
+ for (pass = (ExrPass *)lay->passes.first; pass; pass = pass->next) {
+ addpass(base,
+ laybase,
+ pass->internal_name,
+ pass->rect,
+ pass->totchan,
+ pass->chan_id,
+ pass->view);
+ pass->rect = NULL;
+ }
+ }
+ }
}
void IMB_exr_close(void *handle)
{
- ExrHandle *data = (ExrHandle *)handle;
- ExrLayer *lay;
- ExrPass *pass;
- ExrChannel *chan;
-
- delete data->ifile;
- delete data->ifile_stream;
- delete data->ofile;
- delete data->mpofile;
- delete data->ofile_stream;
- delete data->multiView;
-
- data->ifile = NULL;
- data->ifile_stream = NULL;
- data->ofile = NULL;
- data->mpofile = NULL;
- data->ofile_stream = NULL;
-
- for (chan = (ExrChannel *)data->channels.first; chan; chan = chan->next) {
- delete chan->m;
- }
- BLI_freelistN(&data->channels);
-
- for (lay = (ExrLayer *)data->layers.first; lay; lay = lay->next) {
- for (pass = (ExrPass *)lay->passes.first; pass; pass = pass->next)
- if (pass->rect)
- MEM_freeN(pass->rect);
- BLI_freelistN(&lay->passes);
- }
- BLI_freelistN(&data->layers);
-
- BLI_remlink(&exrhandles, data);
- MEM_freeN(data);
+ ExrHandle *data = (ExrHandle *)handle;
+ ExrLayer *lay;
+ ExrPass *pass;
+ ExrChannel *chan;
+
+ delete data->ifile;
+ delete data->ifile_stream;
+ delete data->ofile;
+ delete data->mpofile;
+ delete data->ofile_stream;
+ delete data->multiView;
+
+ data->ifile = NULL;
+ data->ifile_stream = NULL;
+ data->ofile = NULL;
+ data->mpofile = NULL;
+ data->ofile_stream = NULL;
+
+ for (chan = (ExrChannel *)data->channels.first; chan; chan = chan->next) {
+ delete chan->m;
+ }
+ BLI_freelistN(&data->channels);
+
+ for (lay = (ExrLayer *)data->layers.first; lay; lay = lay->next) {
+ for (pass = (ExrPass *)lay->passes.first; pass; pass = pass->next)
+ if (pass->rect)
+ MEM_freeN(pass->rect);
+ BLI_freelistN(&lay->passes);
+ }
+ BLI_freelistN(&data->layers);
+
+ BLI_remlink(&exrhandles, data);
+ MEM_freeN(data);
}
/* ********* */
@@ -1247,678 +1295,696 @@ void IMB_exr_close(void *handle)
/* get a substring from the end of the name, separated by '.' */
static int imb_exr_split_token(const char *str, const char *end, const char **token)
{
- const char delims[] = {'.', '\0'};
- const char *sep;
+ const char delims[] = {'.', '\0'};
+ const char *sep;
- BLI_str_partition_ex(str, end, delims, &sep, token, true);
+ BLI_str_partition_ex(str, end, delims, &sep, token, true);
- if (!sep) {
- *token = str;
- }
+ if (!sep) {
+ *token = str;
+ }
- return (int)(end - *token);
+ return (int)(end - *token);
}
static int imb_exr_split_channel_name(ExrChannel *echan, char *layname, char *passname)
{
- const char *name = echan->m->name.c_str();
- const char *end = name + strlen(name);
- const char *token;
- char tokenbuf[EXR_TOT_MAXNAME];
- int len;
-
- /* some multilayers have the combined buffer with names A B G R saved */
- if (name[1] == 0) {
- echan->chan_id = name[0];
- layname[0] = '\0';
-
- if (ELEM(name[0], 'R', 'G', 'B', 'A'))
- strcpy(passname, "Combined");
- else if (name[0] == 'Z')
- strcpy(passname, "Depth");
- else
- strcpy(passname, name);
-
- return 1;
- }
-
- /* last token is channel identifier */
- len = imb_exr_split_token(name, end, &token);
- if (len == 0) {
- printf("multilayer read: bad channel name: %s\n", name);
- return 0;
- }
- else if (len == 1) {
- echan->chan_id = token[0];
- }
- else if (len > 1) {
- bool ok = false;
-
- if (len == 2) {
- /* some multilayers are using two-letter channels name,
- * like, MX or NZ, which is basically has structure of
- * <pass_prefix><component>
- *
- * This is a bit silly, but see file from [#35658].
- *
- * Here we do some magic to distinguish such cases.
- */
- if (ELEM(token[1], 'X', 'Y', 'Z') ||
- ELEM(token[1], 'R', 'G', 'B') ||
- ELEM(token[1], 'U', 'V', 'A'))
- {
- echan->chan_id = token[1];
- ok = true;
- }
- }
- else if (BLI_strcaseeq(token, "red")) {
- echan->chan_id = 'R';
- ok = true;
- }
- else if (BLI_strcaseeq(token, "green")) {
- echan->chan_id = 'G';
- ok = true;
- }
- else if (BLI_strcaseeq(token, "blue")) {
- echan->chan_id = 'B';
- ok = true;
- }
- else if (BLI_strcaseeq(token, "alpha")) {
- echan->chan_id = 'A';
- ok = true;
- }
- else if (BLI_strcaseeq(token, "depth")) {
- echan->chan_id = 'Z';
- ok = true;
- }
-
- if (ok == false) {
- BLI_strncpy(tokenbuf, token, std::min(len + 1, EXR_TOT_MAXNAME));
- printf("multilayer read: unknown channel token: %s\n", tokenbuf);
- return 0;
- }
- }
- end -= len + 1; /* +1 to skip '.' separator */
-
- /* second token is pass name */
- len = imb_exr_split_token(name, end, &token);
- if (len == 0) {
- printf("multilayer read: bad channel name: %s\n", name);
- return 0;
- }
- BLI_strncpy(passname, token, len + 1);
- end -= len + 1; /* +1 to skip '.' separator */
-
- /* all preceding tokens combined as layer name */
- if (end > name)
- BLI_strncpy(layname, name, (int)(end - name) + 1);
- else
- layname[0] = '\0';
-
- return 1;
+ const char *name = echan->m->name.c_str();
+ const char *end = name + strlen(name);
+ const char *token;
+ char tokenbuf[EXR_TOT_MAXNAME];
+ int len;
+
+ /* some multilayers have the combined buffer with names A B G R saved */
+ if (name[1] == 0) {
+ echan->chan_id = name[0];
+ layname[0] = '\0';
+
+ if (ELEM(name[0], 'R', 'G', 'B', 'A'))
+ strcpy(passname, "Combined");
+ else if (name[0] == 'Z')
+ strcpy(passname, "Depth");
+ else
+ strcpy(passname, name);
+
+ return 1;
+ }
+
+ /* last token is channel identifier */
+ len = imb_exr_split_token(name, end, &token);
+ if (len == 0) {
+ printf("multilayer read: bad channel name: %s\n", name);
+ return 0;
+ }
+ else if (len == 1) {
+ echan->chan_id = token[0];
+ }
+ else if (len > 1) {
+ bool ok = false;
+
+ if (len == 2) {
+ /* some multilayers are using two-letter channels name,
+ * like, MX or NZ, which is basically has structure of
+ * <pass_prefix><component>
+ *
+ * This is a bit silly, but see file from [#35658].
+ *
+ * Here we do some magic to distinguish such cases.
+ */
+ if (ELEM(token[1], 'X', 'Y', 'Z') || ELEM(token[1], 'R', 'G', 'B') ||
+ ELEM(token[1], 'U', 'V', 'A')) {
+ echan->chan_id = token[1];
+ ok = true;
+ }
+ }
+ else if (BLI_strcaseeq(token, "red")) {
+ echan->chan_id = 'R';
+ ok = true;
+ }
+ else if (BLI_strcaseeq(token, "green")) {
+ echan->chan_id = 'G';
+ ok = true;
+ }
+ else if (BLI_strcaseeq(token, "blue")) {
+ echan->chan_id = 'B';
+ ok = true;
+ }
+ else if (BLI_strcaseeq(token, "alpha")) {
+ echan->chan_id = 'A';
+ ok = true;
+ }
+ else if (BLI_strcaseeq(token, "depth")) {
+ echan->chan_id = 'Z';
+ ok = true;
+ }
+
+ if (ok == false) {
+ BLI_strncpy(tokenbuf, token, std::min(len + 1, EXR_TOT_MAXNAME));
+ printf("multilayer read: unknown channel token: %s\n", tokenbuf);
+ return 0;
+ }
+ }
+ end -= len + 1; /* +1 to skip '.' separator */
+
+ /* second token is pass name */
+ len = imb_exr_split_token(name, end, &token);
+ if (len == 0) {
+ printf("multilayer read: bad channel name: %s\n", name);
+ return 0;
+ }
+ BLI_strncpy(passname, token, len + 1);
+ end -= len + 1; /* +1 to skip '.' separator */
+
+ /* all preceding tokens combined as layer name */
+ if (end > name)
+ BLI_strncpy(layname, name, (int)(end - name) + 1);
+ else
+ layname[0] = '\0';
+
+ return 1;
}
static ExrLayer *imb_exr_get_layer(ListBase *lb, char *layname)
{
- ExrLayer *lay = (ExrLayer *)BLI_findstring(lb, layname, offsetof(ExrLayer, name));
+ ExrLayer *lay = (ExrLayer *)BLI_findstring(lb, layname, offsetof(ExrLayer, name));
- if (lay == NULL) {
- lay = (ExrLayer *)MEM_callocN(sizeof(ExrLayer), "exr layer");
- BLI_addtail(lb, lay);
- BLI_strncpy(lay->name, layname, EXR_LAY_MAXNAME);
- }
+ if (lay == NULL) {
+ lay = (ExrLayer *)MEM_callocN(sizeof(ExrLayer), "exr layer");
+ BLI_addtail(lb, lay);
+ BLI_strncpy(lay->name, layname, EXR_LAY_MAXNAME);
+ }
- return lay;
+ return lay;
}
static ExrPass *imb_exr_get_pass(ListBase *lb, char *passname)
{
- ExrPass *pass = (ExrPass *)BLI_findstring(lb, passname, offsetof(ExrPass, name));
+ ExrPass *pass = (ExrPass *)BLI_findstring(lb, passname, offsetof(ExrPass, name));
- if (pass == NULL) {
- pass = (ExrPass *)MEM_callocN(sizeof(ExrPass), "exr pass");
+ if (pass == NULL) {
+ pass = (ExrPass *)MEM_callocN(sizeof(ExrPass), "exr pass");
- if (STREQ(passname, "Combined"))
- BLI_addhead(lb, pass);
- else
- BLI_addtail(lb, pass);
- }
+ if (STREQ(passname, "Combined"))
+ BLI_addhead(lb, pass);
+ else
+ BLI_addtail(lb, pass);
+ }
- BLI_strncpy(pass->name, passname, EXR_LAY_MAXNAME);
+ BLI_strncpy(pass->name, passname, EXR_LAY_MAXNAME);
- return pass;
+ return pass;
}
/* creates channels, makes a hierarchy and assigns memory to channels */
-static ExrHandle *imb_exr_begin_read_mem(IStream &file_stream, MultiPartInputFile &file, int width, int height)
+static ExrHandle *imb_exr_begin_read_mem(IStream &file_stream,
+ MultiPartInputFile &file,
+ int width,
+ int height)
{
- ExrLayer *lay;
- ExrPass *pass;
- ExrChannel *echan;
- ExrHandle *data = (ExrHandle *)IMB_exr_get_handle();
- int a;
- char layname[EXR_TOT_MAXNAME], passname[EXR_TOT_MAXNAME];
-
- data->ifile_stream = &file_stream;
- data->ifile = &file;
-
- data->width = width;
- data->height = height;
-
- std::vector<MultiViewChannelName> channels;
- GetChannelsInMultiPartFile(*data->ifile, channels);
-
- imb_exr_get_views(*data->ifile, *data->multiView);
-
- for (size_t i = 0; i < channels.size(); i++) {
- IMB_exr_add_channel(data, NULL, channels[i].name.c_str(), channels[i].view.c_str(), 0, 0, NULL, false);
-
- echan = (ExrChannel *)data->channels.last;
- echan->m->name = channels[i].name;
- echan->m->view = channels[i].view;
- echan->m->part_number = channels[i].part_number;
- echan->m->internal_name = channels[i].internal_name;
- }
-
- /* now try to sort out how to assign memory to the channels */
- /* first build hierarchical layer list */
- for (echan = (ExrChannel *)data->channels.first; echan; echan = echan->next) {
- if (imb_exr_split_channel_name(echan, layname, passname)) {
-
- const char *view = echan->m->view.c_str();
- char internal_name[EXR_PASS_MAXNAME];
-
- BLI_strncpy(internal_name, passname, EXR_PASS_MAXNAME);
-
- if (view[0] != '\0') {
- char tmp_pass[EXR_PASS_MAXNAME];
- BLI_snprintf(tmp_pass, sizeof(tmp_pass), "%s.%s", passname, view);
- BLI_strncpy(passname, tmp_pass, sizeof(passname));
- }
-
- ExrLayer *lay = imb_exr_get_layer(&data->layers, layname);
- ExrPass *pass = imb_exr_get_pass(&lay->passes, passname);
-
- pass->chan[pass->totchan] = echan;
- pass->totchan++;
- pass->view_id = echan->view_id;
- BLI_strncpy(pass->view, view, sizeof(pass->view));
- BLI_strncpy(pass->internal_name, internal_name, EXR_PASS_MAXNAME);
-
- if (pass->totchan >= EXR_PASS_MAXCHAN)
- break;
- }
- }
- if (echan) {
- printf("error, too many channels in one pass: %s\n", echan->m->name.c_str());
- IMB_exr_close(data);
- return NULL;
- }
-
- /* with some heuristics, try to merge the channels in buffers */
- for (lay = (ExrLayer *)data->layers.first; lay; lay = lay->next) {
- for (pass = (ExrPass *)lay->passes.first; pass; pass = pass->next) {
- if (pass->totchan) {
- pass->rect = (float *)MEM_mapallocN(width * height * pass->totchan * sizeof(float), "pass rect");
- if (pass->totchan == 1) {
- echan = pass->chan[0];
- echan->rect = pass->rect;
- echan->xstride = 1;
- echan->ystride = width;
- pass->chan_id[0] = echan->chan_id;
- }
- else {
- char lookup[256];
-
- memset(lookup, 0, sizeof(lookup));
-
- /* we can have RGB(A), XYZ(W), UVA */
- if (pass->totchan == 3 || pass->totchan == 4) {
- if (pass->chan[0]->chan_id == 'B' || pass->chan[1]->chan_id == 'B' || pass->chan[2]->chan_id == 'B') {
- lookup[(unsigned int)'R'] = 0;
- lookup[(unsigned int)'G'] = 1;
- lookup[(unsigned int)'B'] = 2;
- lookup[(unsigned int)'A'] = 3;
- }
- else if (pass->chan[0]->chan_id == 'Y' || pass->chan[1]->chan_id == 'Y' || pass->chan[2]->chan_id == 'Y') {
- lookup[(unsigned int)'X'] = 0;
- lookup[(unsigned int)'Y'] = 1;
- lookup[(unsigned int)'Z'] = 2;
- lookup[(unsigned int)'W'] = 3;
- }
- else {
- lookup[(unsigned int)'U'] = 0;
- lookup[(unsigned int)'V'] = 1;
- lookup[(unsigned int)'A'] = 2;
- }
- for (a = 0; a < pass->totchan; a++) {
- echan = pass->chan[a];
- echan->rect = pass->rect + lookup[(unsigned int)echan->chan_id];
- echan->xstride = pass->totchan;
- echan->ystride = width * pass->totchan;
- pass->chan_id[(unsigned int)lookup[(unsigned int)echan->chan_id]] = echan->chan_id;
- }
- }
- else { /* unknown */
- for (a = 0; a < pass->totchan; a++) {
- echan = pass->chan[a];
- echan->rect = pass->rect + a;
- echan->xstride = pass->totchan;
- echan->ystride = width * pass->totchan;
- pass->chan_id[a] = echan->chan_id;
- }
- }
- }
- }
- }
- }
-
- return data;
+ ExrLayer *lay;
+ ExrPass *pass;
+ ExrChannel *echan;
+ ExrHandle *data = (ExrHandle *)IMB_exr_get_handle();
+ int a;
+ char layname[EXR_TOT_MAXNAME], passname[EXR_TOT_MAXNAME];
+
+ data->ifile_stream = &file_stream;
+ data->ifile = &file;
+
+ data->width = width;
+ data->height = height;
+
+ std::vector<MultiViewChannelName> channels;
+ GetChannelsInMultiPartFile(*data->ifile, channels);
+
+ imb_exr_get_views(*data->ifile, *data->multiView);
+
+ for (size_t i = 0; i < channels.size(); i++) {
+ IMB_exr_add_channel(
+ data, NULL, channels[i].name.c_str(), channels[i].view.c_str(), 0, 0, NULL, false);
+
+ echan = (ExrChannel *)data->channels.last;
+ echan->m->name = channels[i].name;
+ echan->m->view = channels[i].view;
+ echan->m->part_number = channels[i].part_number;
+ echan->m->internal_name = channels[i].internal_name;
+ }
+
+ /* now try to sort out how to assign memory to the channels */
+ /* first build hierarchical layer list */
+ for (echan = (ExrChannel *)data->channels.first; echan; echan = echan->next) {
+ if (imb_exr_split_channel_name(echan, layname, passname)) {
+
+ const char *view = echan->m->view.c_str();
+ char internal_name[EXR_PASS_MAXNAME];
+
+ BLI_strncpy(internal_name, passname, EXR_PASS_MAXNAME);
+
+ if (view[0] != '\0') {
+ char tmp_pass[EXR_PASS_MAXNAME];
+ BLI_snprintf(tmp_pass, sizeof(tmp_pass), "%s.%s", passname, view);
+ BLI_strncpy(passname, tmp_pass, sizeof(passname));
+ }
+
+ ExrLayer *lay = imb_exr_get_layer(&data->layers, layname);
+ ExrPass *pass = imb_exr_get_pass(&lay->passes, passname);
+
+ pass->chan[pass->totchan] = echan;
+ pass->totchan++;
+ pass->view_id = echan->view_id;
+ BLI_strncpy(pass->view, view, sizeof(pass->view));
+ BLI_strncpy(pass->internal_name, internal_name, EXR_PASS_MAXNAME);
+
+ if (pass->totchan >= EXR_PASS_MAXCHAN)
+ break;
+ }
+ }
+ if (echan) {
+ printf("error, too many channels in one pass: %s\n", echan->m->name.c_str());
+ IMB_exr_close(data);
+ return NULL;
+ }
+
+ /* with some heuristics, try to merge the channels in buffers */
+ for (lay = (ExrLayer *)data->layers.first; lay; lay = lay->next) {
+ for (pass = (ExrPass *)lay->passes.first; pass; pass = pass->next) {
+ if (pass->totchan) {
+ pass->rect = (float *)MEM_mapallocN(width * height * pass->totchan * sizeof(float),
+ "pass rect");
+ if (pass->totchan == 1) {
+ echan = pass->chan[0];
+ echan->rect = pass->rect;
+ echan->xstride = 1;
+ echan->ystride = width;
+ pass->chan_id[0] = echan->chan_id;
+ }
+ else {
+ char lookup[256];
+
+ memset(lookup, 0, sizeof(lookup));
+
+ /* we can have RGB(A), XYZ(W), UVA */
+ if (pass->totchan == 3 || pass->totchan == 4) {
+ if (pass->chan[0]->chan_id == 'B' || pass->chan[1]->chan_id == 'B' ||
+ pass->chan[2]->chan_id == 'B') {
+ lookup[(unsigned int)'R'] = 0;
+ lookup[(unsigned int)'G'] = 1;
+ lookup[(unsigned int)'B'] = 2;
+ lookup[(unsigned int)'A'] = 3;
+ }
+ else if (pass->chan[0]->chan_id == 'Y' || pass->chan[1]->chan_id == 'Y' ||
+ pass->chan[2]->chan_id == 'Y') {
+ lookup[(unsigned int)'X'] = 0;
+ lookup[(unsigned int)'Y'] = 1;
+ lookup[(unsigned int)'Z'] = 2;
+ lookup[(unsigned int)'W'] = 3;
+ }
+ else {
+ lookup[(unsigned int)'U'] = 0;
+ lookup[(unsigned int)'V'] = 1;
+ lookup[(unsigned int)'A'] = 2;
+ }
+ for (a = 0; a < pass->totchan; a++) {
+ echan = pass->chan[a];
+ echan->rect = pass->rect + lookup[(unsigned int)echan->chan_id];
+ echan->xstride = pass->totchan;
+ echan->ystride = width * pass->totchan;
+ pass->chan_id[(unsigned int)lookup[(unsigned int)echan->chan_id]] = echan->chan_id;
+ }
+ }
+ else { /* unknown */
+ for (a = 0; a < pass->totchan; a++) {
+ echan = pass->chan[a];
+ echan->rect = pass->rect + a;
+ echan->xstride = pass->totchan;
+ echan->ystride = width * pass->totchan;
+ pass->chan_id[a] = echan->chan_id;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return data;
}
-
/* ********************************************************* */
/* debug only */
static void exr_printf(const char *fmt, ...)
{
#if 0
- char output[1024];
- va_list args;
- va_start(args, fmt);
- std::vsprintf(output, fmt, args);
- va_end(args);
- printf("%s", output);
+ char output[1024];
+ va_list args;
+ va_start(args, fmt);
+ std::vsprintf(output, fmt, args);
+ va_end(args);
+ printf("%s", output);
#else
- (void)fmt;
+ (void)fmt;
#endif
}
-static void exr_print_filecontents(MultiPartInputFile& file)
+static void exr_print_filecontents(MultiPartInputFile &file)
{
- int numparts = file.parts();
- if (numparts == 1 && hasMultiView(file.header(0))) {
- const StringVector views = multiView(file.header(0));
- printf("OpenEXR-load: MultiView file\n");
- printf("OpenEXR-load: Default view: %s\n", defaultViewName(views).c_str());
- for (StringVector::const_iterator i = views.begin(); i != views.end(); ++i) {
- printf("OpenEXR-load: Found view %s\n", (*i).c_str());
- }
- }
- else if (numparts > 1) {
- printf("OpenEXR-load: MultiPart file\n");
- for (int i = 0; i < numparts; i++) {
- if (file.header(i).hasView())
- printf("OpenEXR-load: Part %d: view = \"%s\"\n", i, file.header(i).view().c_str());
- }
- }
-
- for (int j = 0; j < numparts; j++) {
- const ChannelList& channels = file.header(j).channels();
- for (ChannelList::ConstIterator i = channels.begin(); i != channels.end(); ++i) {
- const Channel& channel = i.channel();
- printf("OpenEXR-load: Found channel %s of type %d\n", i.name(), channel.type);
- }
- }
+ int numparts = file.parts();
+ if (numparts == 1 && hasMultiView(file.header(0))) {
+ const StringVector views = multiView(file.header(0));
+ printf("OpenEXR-load: MultiView file\n");
+ printf("OpenEXR-load: Default view: %s\n", defaultViewName(views).c_str());
+ for (StringVector::const_iterator i = views.begin(); i != views.end(); ++i) {
+ printf("OpenEXR-load: Found view %s\n", (*i).c_str());
+ }
+ }
+ else if (numparts > 1) {
+ printf("OpenEXR-load: MultiPart file\n");
+ for (int i = 0; i < numparts; i++) {
+ if (file.header(i).hasView())
+ printf("OpenEXR-load: Part %d: view = \"%s\"\n", i, file.header(i).view().c_str());
+ }
+ }
+
+ for (int j = 0; j < numparts; j++) {
+ const ChannelList &channels = file.header(j).channels();
+ for (ChannelList::ConstIterator i = channels.begin(); i != channels.end(); ++i) {
+ const Channel &channel = i.channel();
+ printf("OpenEXR-load: Found channel %s of type %d\n", i.name(), channel.type);
+ }
+ }
}
/* for non-multilayer, map R G B A channel names to something that's in this file */
-static const char *exr_rgba_channelname(MultiPartInputFile& file, const char *chan)
+static const char *exr_rgba_channelname(MultiPartInputFile &file, const char *chan)
{
- const ChannelList& channels = file.header(0).channels();
-
- for (ChannelList::ConstIterator i = channels.begin(); i != channels.end(); ++i) {
- /* const Channel &channel = i.channel(); */ /* Not used yet */
- const char *str = i.name();
- int len = strlen(str);
- if (len) {
- if (BLI_strcasecmp(chan, str + len - 1) == 0) {
- return str;
- }
- }
- }
- return chan;
+ const ChannelList &channels = file.header(0).channels();
+
+ for (ChannelList::ConstIterator i = channels.begin(); i != channels.end(); ++i) {
+ /* const Channel &channel = i.channel(); */ /* Not used yet */
+ const char *str = i.name();
+ int len = strlen(str);
+ if (len) {
+ if (BLI_strcasecmp(chan, str + len - 1) == 0) {
+ return str;
+ }
+ }
+ }
+ return chan;
}
-static bool exr_has_rgb(MultiPartInputFile& file)
+static bool exr_has_rgb(MultiPartInputFile &file)
{
- return file.header(0).channels().findChannel("R") != NULL &&
- file.header(0).channels().findChannel("G") != NULL &&
- file.header(0).channels().findChannel("B") != NULL;
+ return file.header(0).channels().findChannel("R") != NULL &&
+ file.header(0).channels().findChannel("G") != NULL &&
+ file.header(0).channels().findChannel("B") != NULL;
}
-static bool exr_has_luma(MultiPartInputFile& file)
+static bool exr_has_luma(MultiPartInputFile &file)
{
- /* Y channel is the luma and should always present fir luma space images,
- * optionally it could be also channels for chromas called BY and RY.
- */
- return file.header(0).channels().findChannel("Y") != NULL;
+ /* Y channel is the luma and should always present fir luma space images,
+ * optionally it could be also channels for chromas called BY and RY.
+ */
+ return file.header(0).channels().findChannel("Y") != NULL;
}
-static bool exr_has_chroma(MultiPartInputFile& file)
+static bool exr_has_chroma(MultiPartInputFile &file)
{
- return file.header(0).channels().findChannel("BY") != NULL &&
- file.header(0).channels().findChannel("RY") != NULL;
+ return file.header(0).channels().findChannel("BY") != NULL &&
+ file.header(0).channels().findChannel("RY") != NULL;
}
-static bool exr_has_zbuffer(MultiPartInputFile& file)
+static bool exr_has_zbuffer(MultiPartInputFile &file)
{
- return !(file.header(0).channels().findChannel("Z") == NULL);
+ return !(file.header(0).channels().findChannel("Z") == NULL);
}
-static bool exr_has_alpha(MultiPartInputFile& file)
+static bool exr_has_alpha(MultiPartInputFile &file)
{
- return !(file.header(0).channels().findChannel("A") == NULL);
+ return !(file.header(0).channels().findChannel("A") == NULL);
}
-static bool imb_exr_is_multilayer_file(MultiPartInputFile& file)
+static bool imb_exr_is_multilayer_file(MultiPartInputFile &file)
{
- const ChannelList& channels = file.header(0).channels();
- std::set <std::string> layerNames;
-
- /* will not include empty layer names */
- channels.layers(layerNames);
-
- if (layerNames.size() > 1)
- return true;
-
- if (layerNames.size()) {
- /* if layerNames is not empty, it means at least one layer is non-empty,
- * but it also could be layers without names in the file and such case
- * shall be considered a multilayer exr
- *
- * that's what we do here: test whether there're empty layer names together
- * with non-empty ones in the file
- */
- for (ChannelList::ConstIterator i = channels.begin(); i != channels.end(); i++) {
- std::string layerName = i.name();
- size_t pos = layerName.rfind ('.');
-
- if (pos == std::string::npos)
- return true;
- }
- }
-
- return false;
+ const ChannelList &channels = file.header(0).channels();
+ std::set<std::string> layerNames;
+
+ /* will not include empty layer names */
+ channels.layers(layerNames);
+
+ if (layerNames.size() > 1)
+ return true;
+
+ if (layerNames.size()) {
+ /* if layerNames is not empty, it means at least one layer is non-empty,
+ * but it also could be layers without names in the file and such case
+ * shall be considered a multilayer exr
+ *
+ * that's what we do here: test whether there're empty layer names together
+ * with non-empty ones in the file
+ */
+ for (ChannelList::ConstIterator i = channels.begin(); i != channels.end(); i++) {
+ std::string layerName = i.name();
+ size_t pos = layerName.rfind('.');
+
+ if (pos == std::string::npos)
+ return true;
+ }
+ }
+
+ return false;
}
-static void imb_exr_type_by_channels(ChannelList& channels, StringVector& views,
- bool *r_singlelayer, bool *r_multilayer, bool *r_multiview)
+static void imb_exr_type_by_channels(ChannelList &channels,
+ StringVector &views,
+ bool *r_singlelayer,
+ bool *r_multilayer,
+ bool *r_multiview)
{
- std::set <std::string> layerNames;
-
- *r_singlelayer = true;
- *r_multilayer = *r_multiview = false;
-
- /* will not include empty layer names */
- channels.layers(layerNames);
-
- if (views.size() && views[0] != "") {
- *r_multiview = true;
- }
- else {
- *r_singlelayer = false;
- *r_multilayer = (layerNames.size() > 1);
- *r_multiview = false;
- return;
- }
-
- if (layerNames.size()) {
- /* if layerNames is not empty, it means at least one layer is non-empty,
- * but it also could be layers without names in the file and such case
- * shall be considered a multilayer exr
- *
- * that's what we do here: test whether there're empty layer names together
- * with non-empty ones in the file
- */
- for (ChannelList::ConstIterator i = channels.begin(); i != channels.end(); i++)
- for (std::set<string>::iterator i = layerNames.begin(); i != layerNames.end(); i++)
- /* see if any layername differs from a viewname */
- if (imb_exr_get_multiView_id(views, *i) == -1) {
- std::string layerName = *i;
- size_t pos = layerName.rfind ('.');
-
- if (pos == std::string::npos) {
- *r_multilayer = true;
- *r_singlelayer = false;
- return;
- }
- }
- }
- else {
- *r_singlelayer = true;
- *r_multilayer = false;
- }
-
- BLI_assert(r_singlelayer != r_multilayer);
+ std::set<std::string> layerNames;
+
+ *r_singlelayer = true;
+ *r_multilayer = *r_multiview = false;
+
+ /* will not include empty layer names */
+ channels.layers(layerNames);
+
+ if (views.size() && views[0] != "") {
+ *r_multiview = true;
+ }
+ else {
+ *r_singlelayer = false;
+ *r_multilayer = (layerNames.size() > 1);
+ *r_multiview = false;
+ return;
+ }
+
+ if (layerNames.size()) {
+ /* if layerNames is not empty, it means at least one layer is non-empty,
+ * but it also could be layers without names in the file and such case
+ * shall be considered a multilayer exr
+ *
+ * that's what we do here: test whether there're empty layer names together
+ * with non-empty ones in the file
+ */
+ for (ChannelList::ConstIterator i = channels.begin(); i != channels.end(); i++)
+ for (std::set<string>::iterator i = layerNames.begin(); i != layerNames.end(); i++)
+ /* see if any layername differs from a viewname */
+ if (imb_exr_get_multiView_id(views, *i) == -1) {
+ std::string layerName = *i;
+ size_t pos = layerName.rfind('.');
+
+ if (pos == std::string::npos) {
+ *r_multilayer = true;
+ *r_singlelayer = false;
+ return;
+ }
+ }
+ }
+ else {
+ *r_singlelayer = true;
+ *r_multilayer = false;
+ }
+
+ BLI_assert(r_singlelayer != r_multilayer);
}
-static bool exr_has_multiview(MultiPartInputFile& file)
+static bool exr_has_multiview(MultiPartInputFile &file)
{
- for (int p = 0; p < file.parts(); p++) {
- if (hasMultiView(file.header(p))) {
- return true;
- }
- }
+ for (int p = 0; p < file.parts(); p++) {
+ if (hasMultiView(file.header(p))) {
+ return true;
+ }
+ }
- return false;
+ return false;
}
-static bool exr_has_multipart_file(MultiPartInputFile& file)
+static bool exr_has_multipart_file(MultiPartInputFile &file)
{
- return file.parts() > 1;
+ return file.parts() > 1;
}
/* it returns true if the file is multilayer or multiview */
-static bool imb_exr_is_multi(MultiPartInputFile& file)
+static bool imb_exr_is_multi(MultiPartInputFile &file)
{
- /* multipart files are treated as multilayer in blender - even if they are single layer openexr with multiview */
- if (exr_has_multipart_file(file))
- return true;
+ /* multipart files are treated as multilayer in blender - even if they are single layer openexr with multiview */
+ if (exr_has_multipart_file(file))
+ return true;
- if (exr_has_multiview(file))
- return true;
+ if (exr_has_multiview(file))
+ return true;
- if (imb_exr_is_multilayer_file(file))
- return true;
+ if (imb_exr_is_multilayer_file(file))
+ return true;
- return false;
+ return false;
}
bool IMB_exr_has_multilayer(void *handle)
{
- ExrHandle *data = (ExrHandle *)handle;
- return imb_exr_is_multi(*data->ifile);
+ ExrHandle *data = (ExrHandle *)handle;
+ return imb_exr_is_multi(*data->ifile);
}
-struct ImBuf *imb_load_openexr(const unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE])
+struct ImBuf *imb_load_openexr(const unsigned char *mem,
+ size_t size,
+ int flags,
+ char colorspace[IM_MAX_SPACE])
{
- struct ImBuf *ibuf = NULL;
- Mem_IStream *membuf = NULL;
- MultiPartInputFile *file = NULL;
-
- if (imb_is_a_openexr(mem) == 0) return(NULL);
-
- colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_FLOAT);
-
- try
- {
- bool is_multi;
-
- membuf = new Mem_IStream((unsigned char *)mem, size);
- file = new MultiPartInputFile(*membuf);
-
- Box2i dw = file->header(0).dataWindow();
- const int width = dw.max.x - dw.min.x + 1;
- const int height = dw.max.y - dw.min.y + 1;
-
- //printf("OpenEXR-load: image data window %d %d %d %d\n",
- // dw.min.x, dw.min.y, dw.max.x, dw.max.y);
-
- if (0) // debug
- exr_print_filecontents(*file);
-
- is_multi = imb_exr_is_multi(*file);
-
- /* do not make an ibuf when */
- if (is_multi && !(flags & IB_test) && !(flags & IB_multilayer)) {
- printf("Error: can't process EXR multilayer file\n");
- }
- else {
- const int is_alpha = exr_has_alpha(*file);
-
- ibuf = IMB_allocImBuf(width, height, is_alpha ? 32 : 24, 0);
-
- if (hasXDensity(file->header(0))) {
- ibuf->ppm[0] = xDensity(file->header(0)) * 39.3700787f;
- ibuf->ppm[1] = ibuf->ppm[0] * (double)file->header(0).pixelAspectRatio();
- }
-
- ibuf->ftype = IMB_FTYPE_OPENEXR;
-
- if (!(flags & IB_test)) {
-
- if (flags & IB_metadata) {
- 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_set_field(ibuf->metadata, iter.name(), attrib->value().c_str());
- ibuf->flags |= IB_metadata;
- }
- }
- }
-
- if (is_multi && ((flags & IB_thumbnail) == 0)) { /* only enters with IB_multilayer flag set */
- /* constructs channels for reading, allocates memory in channels */
- ExrHandle *handle = imb_exr_begin_read_mem(*membuf, *file, width, height);
- if (handle) {
- IMB_exr_read_channels(handle);
- ibuf->userdata = handle; /* potential danger, the caller has to check for this! */
- }
- }
- else {
- const bool has_rgb = exr_has_rgb(*file);
- const bool has_luma = exr_has_luma(*file);
- FrameBuffer frameBuffer;
- float *first;
- int xstride = sizeof(float) * 4;
- int ystride = -xstride * width;
-
- imb_addrectfloatImBuf(ibuf);
-
- /* inverse correct first pixel for datawindow coordinates (- dw.min.y because of y flip) */
- first = ibuf->rect_float - 4 * (dw.min.x - dw.min.y * width);
- /* but, since we read y-flipped (negative y stride) we move to last scanline */
- first += 4 * (height - 1) * width;
-
- if (has_rgb) {
- frameBuffer.insert(exr_rgba_channelname(*file, "R"),
- Slice(Imf::FLOAT, (char *) first, xstride, ystride));
- frameBuffer.insert(exr_rgba_channelname(*file, "G"),
- Slice(Imf::FLOAT, (char *) (first + 1), xstride, ystride));
- frameBuffer.insert(exr_rgba_channelname(*file, "B"),
- Slice(Imf::FLOAT, (char *) (first + 2), xstride, ystride));
- }
- else if (has_luma) {
- frameBuffer.insert(exr_rgba_channelname(*file, "Y"),
- Slice(Imf::FLOAT, (char *) first, xstride, ystride));
- frameBuffer.insert(exr_rgba_channelname(*file, "BY"),
- Slice(Imf::FLOAT, (char *) (first + 1), xstride, ystride, 1, 1, 0.5f));
- frameBuffer.insert(exr_rgba_channelname(*file, "RY"),
- Slice(Imf::FLOAT, (char *) (first + 2), xstride, ystride, 1, 1, 0.5f));
- }
-
- /* 1.0 is fill value, this still needs to be assigned even when (is_alpha == 0) */
- frameBuffer.insert(exr_rgba_channelname(*file, "A"),
- Slice(Imf::FLOAT, (char *) (first + 3), xstride, ystride, 1, 1, 1.0f));
-
- if (exr_has_zbuffer(*file)) {
- float *firstz;
-
- addzbuffloatImBuf(ibuf);
- firstz = ibuf->zbuf_float - (dw.min.x - dw.min.y * width);
- firstz += (height - 1) * width;
- frameBuffer.insert("Z", Slice(Imf::FLOAT, (char *)firstz, sizeof(float), -width * sizeof(float)));
- }
-
- InputPart in (*file, 0);
- in.setFrameBuffer(frameBuffer);
- in.readPixels(dw.min.y, dw.max.y);
-
- // XXX, ImBuf has no nice way to deal with this.
- // ideally IM_rect would be used when the caller wants a rect BUT
- // at the moment all functions use IM_rect.
- // Disabling this is ok because all functions should check if a rect exists and create one on demand.
- //
- // Disabling this because the sequencer frees immediate.
- //
- // if (flag & IM_rect)
- // IMB_rect_from_float(ibuf);
-
- if (!has_rgb && has_luma) {
- size_t a;
- if (exr_has_chroma(*file)) {
- for (a = 0; a < (size_t) ibuf->x * ibuf->y; ++a) {
- float *color = ibuf->rect_float + a * 4;
- ycc_to_rgb(color[0] * 255.0f, color[1] * 255.0f, color[2] * 255.0f,
- &color[0], &color[1], &color[2],
- BLI_YCC_ITU_BT709);
- }
- }
- else {
- for (a = 0; a < (size_t) ibuf->x * ibuf->y; ++a) {
- float *color = ibuf->rect_float + a * 4;
- color[1] = color[2] = color[0];
- }
- }
- }
-
- /* file is no longer needed */
- delete membuf;
- delete file;
- }
- }
- else {
- delete membuf;
- delete file;
- }
-
- if (flags & IB_alphamode_detect)
- ibuf->flags |= IB_alphamode_premul;
- }
- return(ibuf);
- }
- catch (const std::exception& exc)
- {
- std::cerr << exc.what() << std::endl;
- if (ibuf) IMB_freeImBuf(ibuf);
- delete file;
- delete membuf;
-
- return (0);
- }
-
+ struct ImBuf *ibuf = NULL;
+ Mem_IStream *membuf = NULL;
+ MultiPartInputFile *file = NULL;
+
+ if (imb_is_a_openexr(mem) == 0)
+ return (NULL);
+
+ colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_FLOAT);
+
+ try {
+ bool is_multi;
+
+ membuf = new Mem_IStream((unsigned char *)mem, size);
+ file = new MultiPartInputFile(*membuf);
+
+ Box2i dw = file->header(0).dataWindow();
+ const int width = dw.max.x - dw.min.x + 1;
+ const int height = dw.max.y - dw.min.y + 1;
+
+ //printf("OpenEXR-load: image data window %d %d %d %d\n",
+ // dw.min.x, dw.min.y, dw.max.x, dw.max.y);
+
+ if (0) // debug
+ exr_print_filecontents(*file);
+
+ is_multi = imb_exr_is_multi(*file);
+
+ /* do not make an ibuf when */
+ if (is_multi && !(flags & IB_test) && !(flags & IB_multilayer)) {
+ printf("Error: can't process EXR multilayer file\n");
+ }
+ else {
+ const int is_alpha = exr_has_alpha(*file);
+
+ ibuf = IMB_allocImBuf(width, height, is_alpha ? 32 : 24, 0);
+
+ if (hasXDensity(file->header(0))) {
+ ibuf->ppm[0] = xDensity(file->header(0)) * 39.3700787f;
+ ibuf->ppm[1] = ibuf->ppm[0] * (double)file->header(0).pixelAspectRatio();
+ }
+
+ ibuf->ftype = IMB_FTYPE_OPENEXR;
+
+ if (!(flags & IB_test)) {
+
+ if (flags & IB_metadata) {
+ 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_set_field(ibuf->metadata, iter.name(), attrib->value().c_str());
+ ibuf->flags |= IB_metadata;
+ }
+ }
+ }
+
+ if (is_multi &&
+ ((flags & IB_thumbnail) == 0)) { /* only enters with IB_multilayer flag set */
+ /* constructs channels for reading, allocates memory in channels */
+ ExrHandle *handle = imb_exr_begin_read_mem(*membuf, *file, width, height);
+ if (handle) {
+ IMB_exr_read_channels(handle);
+ ibuf->userdata = handle; /* potential danger, the caller has to check for this! */
+ }
+ }
+ else {
+ const bool has_rgb = exr_has_rgb(*file);
+ const bool has_luma = exr_has_luma(*file);
+ FrameBuffer frameBuffer;
+ float *first;
+ int xstride = sizeof(float) * 4;
+ int ystride = -xstride * width;
+
+ imb_addrectfloatImBuf(ibuf);
+
+ /* inverse correct first pixel for datawindow coordinates (- dw.min.y because of y flip) */
+ first = ibuf->rect_float - 4 * (dw.min.x - dw.min.y * width);
+ /* but, since we read y-flipped (negative y stride) we move to last scanline */
+ first += 4 * (height - 1) * width;
+
+ if (has_rgb) {
+ frameBuffer.insert(exr_rgba_channelname(*file, "R"),
+ Slice(Imf::FLOAT, (char *)first, xstride, ystride));
+ frameBuffer.insert(exr_rgba_channelname(*file, "G"),
+ Slice(Imf::FLOAT, (char *)(first + 1), xstride, ystride));
+ frameBuffer.insert(exr_rgba_channelname(*file, "B"),
+ Slice(Imf::FLOAT, (char *)(first + 2), xstride, ystride));
+ }
+ else if (has_luma) {
+ frameBuffer.insert(exr_rgba_channelname(*file, "Y"),
+ Slice(Imf::FLOAT, (char *)first, xstride, ystride));
+ frameBuffer.insert(
+ exr_rgba_channelname(*file, "BY"),
+ Slice(Imf::FLOAT, (char *)(first + 1), xstride, ystride, 1, 1, 0.5f));
+ frameBuffer.insert(
+ exr_rgba_channelname(*file, "RY"),
+ Slice(Imf::FLOAT, (char *)(first + 2), xstride, ystride, 1, 1, 0.5f));
+ }
+
+ /* 1.0 is fill value, this still needs to be assigned even when (is_alpha == 0) */
+ frameBuffer.insert(exr_rgba_channelname(*file, "A"),
+ Slice(Imf::FLOAT, (char *)(first + 3), xstride, ystride, 1, 1, 1.0f));
+
+ if (exr_has_zbuffer(*file)) {
+ float *firstz;
+
+ addzbuffloatImBuf(ibuf);
+ firstz = ibuf->zbuf_float - (dw.min.x - dw.min.y * width);
+ firstz += (height - 1) * width;
+ frameBuffer.insert(
+ "Z", Slice(Imf::FLOAT, (char *)firstz, sizeof(float), -width * sizeof(float)));
+ }
+
+ InputPart in(*file, 0);
+ in.setFrameBuffer(frameBuffer);
+ in.readPixels(dw.min.y, dw.max.y);
+
+ // XXX, ImBuf has no nice way to deal with this.
+ // ideally IM_rect would be used when the caller wants a rect BUT
+ // at the moment all functions use IM_rect.
+ // Disabling this is ok because all functions should check if a rect exists and create one on demand.
+ //
+ // Disabling this because the sequencer frees immediate.
+ //
+ // if (flag & IM_rect)
+ // IMB_rect_from_float(ibuf);
+
+ if (!has_rgb && has_luma) {
+ size_t a;
+ if (exr_has_chroma(*file)) {
+ for (a = 0; a < (size_t)ibuf->x * ibuf->y; ++a) {
+ float *color = ibuf->rect_float + a * 4;
+ ycc_to_rgb(color[0] * 255.0f,
+ color[1] * 255.0f,
+ color[2] * 255.0f,
+ &color[0],
+ &color[1],
+ &color[2],
+ BLI_YCC_ITU_BT709);
+ }
+ }
+ else {
+ for (a = 0; a < (size_t)ibuf->x * ibuf->y; ++a) {
+ float *color = ibuf->rect_float + a * 4;
+ color[1] = color[2] = color[0];
+ }
+ }
+ }
+
+ /* file is no longer needed */
+ delete membuf;
+ delete file;
+ }
+ }
+ else {
+ delete membuf;
+ delete file;
+ }
+
+ if (flags & IB_alphamode_detect)
+ ibuf->flags |= IB_alphamode_premul;
+ }
+ return (ibuf);
+ }
+ catch (const std::exception &exc) {
+ std::cerr << exc.what() << std::endl;
+ if (ibuf)
+ IMB_freeImBuf(ibuf);
+ delete file;
+ delete membuf;
+
+ return (0);
+ }
}
void imb_initopenexr(void)
{
- int num_threads = BLI_system_thread_count();
+ int num_threads = BLI_system_thread_count();
- setGlobalThreadCount(num_threads);
+ setGlobalThreadCount(num_threads);
}
void imb_exitopenexr(void)
{
- /* Tells OpenEXR to free thread pool, also ensures there is no running
- * tasks.
- */
- setGlobalThreadCount(0);
+ /* Tells OpenEXR to free thread pool, also ensures there is no running
+ * tasks.
+ */
+ setGlobalThreadCount(0);
}
-} // export "C"
+} // export "C"
diff --git a/source/blender/imbuf/intern/openexr/openexr_api.h b/source/blender/imbuf/intern/openexr/openexr_api.h
index 7b9094e7eb6..df03d0d205f 100644
--- a/source/blender/imbuf/intern/openexr/openexr_api.h
+++ b/source/blender/imbuf/intern/openexr/openexr_api.h
@@ -21,7 +21,6 @@
* \ingroup openexr
*/
-
#ifndef __OPENEXR_API_H__
#define __OPENEXR_API_H__
@@ -31,19 +30,17 @@ extern "C" {
#include <stdio.h>
-void imb_initopenexr (void);
-void imb_exitopenexr (void);
+void imb_initopenexr(void);
+void imb_exitopenexr(void);
-int imb_is_a_openexr (const unsigned char *mem);
+int imb_is_a_openexr(const unsigned char *mem);
-int imb_save_openexr (struct ImBuf *ibuf, const char *name, int flags);
+int imb_save_openexr(struct ImBuf *ibuf, const char *name, int flags);
-struct ImBuf *imb_load_openexr (const unsigned char *mem, size_t size, int flags, char *colorspace);
+struct ImBuf *imb_load_openexr(const unsigned char *mem, size_t size, int flags, char *colorspace);
#ifdef __cplusplus
}
#endif
-
-
#endif /* __OPENEXR_API_H */
diff --git a/source/blender/imbuf/intern/openexr/openexr_multi.h b/source/blender/imbuf/intern/openexr/openexr_multi.h
index 974b3fe3ca0..58f103aeba0 100644
--- a/source/blender/imbuf/intern/openexr/openexr_multi.h
+++ b/source/blender/imbuf/intern/openexr/openexr_multi.h
@@ -21,7 +21,6 @@
* \ingroup openexr
*/
-
#ifndef __OPENEXR_MULTI_H__
#define __OPENEXR_MULTI_H__
@@ -29,12 +28,11 @@
/* XXX layer+pass name max 64? */
/* This api also supports max 8 channels per pass now. easy to fix! */
-#define EXR_LAY_MAXNAME 64
-#define EXR_PASS_MAXNAME 64
-#define EXR_VIEW_MAXNAME 64
-#define EXR_TOT_MAXNAME 64
-#define EXR_PASS_MAXCHAN 24
-
+#define EXR_LAY_MAXNAME 64
+#define EXR_PASS_MAXNAME 64
+#define EXR_VIEW_MAXNAME 64
+#define EXR_TOT_MAXNAME 64
+#define EXR_PASS_MAXCHAN 24
#ifdef __cplusplus
extern "C" {
@@ -44,39 +42,62 @@ struct StampData;
void *IMB_exr_get_handle(void);
void *IMB_exr_get_handle_name(const char *name);
-void IMB_exr_add_channel(void *handle,
- const char *layname, const char *passname, const char *view,
- int xstride, int ystride,
- float *rect,
- bool use_half_float);
-
-int IMB_exr_begin_read(void *handle, const char *filename, int *width, int *height);
-int IMB_exr_begin_write(void *handle, const char *filename, int width, int height, int compress, const struct StampData *stamp);
-void IMB_exrtile_begin_write(void *handle, const char *filename, int mipmap, int width, int height, int tilex, int tiley);
-
-void IMB_exr_set_channel(void *handle, const char *layname, const char *passname, int xstride, int ystride, float *rect);
-float *IMB_exr_channel_rect(void *handle, const char *layname, const char *passname, const char *view);
-
-void IMB_exr_read_channels(void *handle);
-void IMB_exr_write_channels(void *handle);
-void IMB_exrtile_write_channels(void *handle, int partx, int party, int level, const char *viewname, bool empty);
-void IMB_exr_clear_channels(void *handle);
-
-void IMB_exr_multilayer_convert(
- void *handle, void *base,
- void * (*addview)(void *base, const char *str),
- void * (*addlayer)(void *base, const char *str),
- void (*addpass)(void *base, void *lay, const char *str, float *rect, int totchan,
- const char *chan_id, const char *view));
-
-void IMB_exr_close(void *handle);
-
-void IMB_exr_add_view(void *handle, const char *name);
+void IMB_exr_add_channel(void *handle,
+ const char *layname,
+ const char *passname,
+ const char *view,
+ int xstride,
+ int ystride,
+ float *rect,
+ bool use_half_float);
+
+int IMB_exr_begin_read(void *handle, const char *filename, int *width, int *height);
+int IMB_exr_begin_write(void *handle,
+ const char *filename,
+ int width,
+ int height,
+ int compress,
+ const struct StampData *stamp);
+void IMB_exrtile_begin_write(
+ void *handle, const char *filename, int mipmap, int width, int height, int tilex, int tiley);
+
+void IMB_exr_set_channel(void *handle,
+ const char *layname,
+ const char *passname,
+ int xstride,
+ int ystride,
+ float *rect);
+float *IMB_exr_channel_rect(void *handle,
+ const char *layname,
+ const char *passname,
+ const char *view);
+
+void IMB_exr_read_channels(void *handle);
+void IMB_exr_write_channels(void *handle);
+void IMB_exrtile_write_channels(
+ void *handle, int partx, int party, int level, const char *viewname, bool empty);
+void IMB_exr_clear_channels(void *handle);
+
+void IMB_exr_multilayer_convert(void *handle,
+ void *base,
+ void *(*addview)(void *base, const char *str),
+ void *(*addlayer)(void *base, const char *str),
+ void (*addpass)(void *base,
+ void *lay,
+ const char *str,
+ float *rect,
+ int totchan,
+ const char *chan_id,
+ const char *view));
+
+void IMB_exr_close(void *handle);
+
+void IMB_exr_add_view(void *handle, const char *name);
bool IMB_exr_has_multilayer(void *handle);
#ifdef __cplusplus
-} // extern "C"
+} // extern "C"
#endif
#endif /* __OPENEXR_MULTI_H */
diff --git a/source/blender/imbuf/intern/openexr/openexr_stub.cpp b/source/blender/imbuf/intern/openexr/openexr_stub.cpp
index 23f4bae1bf8..bfc4291c7b1 100644
--- a/source/blender/imbuf/intern/openexr/openexr_stub.cpp
+++ b/source/blender/imbuf/intern/openexr/openexr_stub.cpp
@@ -24,34 +24,107 @@
#include "openexr_api.h"
#include "openexr_multi.h"
-void *IMB_exr_get_handle (void) {return NULL;}
-void *IMB_exr_get_handle_name (const char * /*name*/) { return NULL;}
-void IMB_exr_add_channel (void * /*handle*/, const char * /*layname*/, const char * /*passname*/, const char * /*view*/,
- int /*xstride*/, int /*ystride*/, float * /*rect*/,
- bool /*use_half_float*/) { }
+void *IMB_exr_get_handle(void)
+{
+ return NULL;
+}
+void *IMB_exr_get_handle_name(const char * /*name*/)
+{
+ return NULL;
+}
+void IMB_exr_add_channel(void * /*handle*/,
+ const char * /*layname*/,
+ const char * /*passname*/,
+ const char * /*view*/,
+ int /*xstride*/,
+ int /*ystride*/,
+ float * /*rect*/,
+ bool /*use_half_float*/)
+{
+}
-int IMB_exr_begin_read (void * /*handle*/, const char * /*filename*/, int * /*width*/, int * /*height*/) { return 0;}
-int IMB_exr_begin_write (void * /*handle*/, const char * /*filename*/, int /*width*/, int /*height*/, int /*compress*/, const struct StampData * /*stamp*/) { return 0;}
-void IMB_exrtile_begin_write (void * /*handle*/, const char * /*filename*/, int /*mipmap*/, int /*width*/, int /*height*/, int /*tilex*/, int /*tiley*/) { }
+int IMB_exr_begin_read(void * /*handle*/,
+ const char * /*filename*/,
+ int * /*width*/,
+ int * /*height*/)
+{
+ return 0;
+}
+int IMB_exr_begin_write(void * /*handle*/,
+ const char * /*filename*/,
+ int /*width*/,
+ int /*height*/,
+ int /*compress*/,
+ const struct StampData * /*stamp*/)
+{
+ return 0;
+}
+void IMB_exrtile_begin_write(void * /*handle*/,
+ const char * /*filename*/,
+ int /*mipmap*/,
+ int /*width*/,
+ int /*height*/,
+ int /*tilex*/,
+ int /*tiley*/)
+{
+}
-void IMB_exr_set_channel (void * /*handle*/, const char * /*layname*/, const char * /*passname*/, int /*xstride*/, int /*ystride*/, float * /*rect*/) { }
-float *IMB_exr_channel_rect (void * /*handle*/, const char * /*layname*/, const char * /*passname*/, const char * /*view*/) { return NULL; }
+void IMB_exr_set_channel(void * /*handle*/,
+ const char * /*layname*/,
+ const char * /*passname*/,
+ int /*xstride*/,
+ int /*ystride*/,
+ float * /*rect*/)
+{
+}
+float *IMB_exr_channel_rect(void * /*handle*/,
+ const char * /*layname*/,
+ const char * /*passname*/,
+ const char * /*view*/)
+{
+ return NULL;
+}
-void IMB_exr_read_channels (void * /*handle*/) { }
-void IMB_exr_write_channels (void * /*handle*/) { }
-void IMB_exrtile_write_channels (void * /*handle*/, int /*partx*/, int /*party*/, int /*level*/, const char * /*viewname*/, bool /*empty*/) { }
-void IMB_exr_clear_channels (void * /*handle*/) { }
+void IMB_exr_read_channels(void * /*handle*/)
+{
+}
+void IMB_exr_write_channels(void * /*handle*/)
+{
+}
+void IMB_exrtile_write_channels(void * /*handle*/,
+ int /*partx*/,
+ int /*party*/,
+ int /*level*/,
+ const char * /*viewname*/,
+ bool /*empty*/)
+{
+}
+void IMB_exr_clear_channels(void * /*handle*/)
+{
+}
-void IMB_exr_multilayer_convert(
- void * /*handle*/, void * /*base*/,
- void * (* /*addview*/)(void *base, const char *str),
- void * (* /*addlayer*/)(void *base, const char *str),
- void (* /*addpass*/)(void *base, void *lay, const char *str, float *rect, int totchan,
- const char *chan_id, const char *view))
+void IMB_exr_multilayer_convert(void * /*handle*/,
+ void * /*base*/,
+ void *(*/*addview*/)(void *base, const char *str),
+ void *(*/*addlayer*/)(void *base, const char *str),
+ void (*/*addpass*/)(void *base,
+ void *lay,
+ const char *str,
+ float *rect,
+ int totchan,
+ const char *chan_id,
+ const char *view))
{
}
-void IMB_exr_close (void * /*handle*/) { }
+void IMB_exr_close(void * /*handle*/)
+{
+}
-void IMB_exr_add_view(void * /*handle*/, const char * /*name*/) { }
-bool IMB_exr_has_multilayer(void * /*handle*/) { return false; }
+void IMB_exr_add_view(void * /*handle*/, const char * /*name*/)
+{
+}
+bool IMB_exr_has_multilayer(void * /*handle*/)
+{
+ return false;
+}
diff --git a/source/blender/imbuf/intern/png.c b/source/blender/imbuf/intern/png.c
index e51f24f67d8..27cf30c71ba 100644
--- a/source/blender/imbuf/intern/png.c
+++ b/source/blender/imbuf/intern/png.c
@@ -45,9 +45,9 @@
#include "IMB_colormanagement_intern.h"
typedef struct PNGReadStruct {
- const unsigned char *data;
- unsigned int size;
- unsigned int seek;
+ const unsigned char *data;
+ unsigned int size;
+ unsigned int seek;
} PNGReadStruct;
static void ReadData(png_structp png_ptr, png_bytep data, png_size_t length);
@@ -56,719 +56,750 @@ static void Flush(png_structp png_ptr);
BLI_INLINE unsigned short UPSAMPLE_8_TO_16(const unsigned char _val)
{
- return (_val << 8) + _val;
+ return (_val << 8) + _val;
}
int imb_is_a_png(const unsigned char *mem)
{
- int ret_val = 0;
+ int ret_val = 0;
- if (mem) {
+ if (mem) {
#if (PNG_LIBPNG_VER_MAJOR == 1) && (PNG_LIBPNG_VER_MINOR == 2)
- /* Older version of libpng doesn't use const pointer to memory. */
- ret_val = !png_sig_cmp((png_bytep)mem, 0, 8);
+ /* Older version of libpng doesn't use const pointer to memory. */
+ ret_val = !png_sig_cmp((png_bytep)mem, 0, 8);
#else
- ret_val = !png_sig_cmp(mem, 0, 8);
+ ret_val = !png_sig_cmp(mem, 0, 8);
#endif
- }
- return(ret_val);
+ }
+ return (ret_val);
}
static void Flush(png_structp png_ptr)
{
- (void)png_ptr;
+ (void)png_ptr;
}
static void WriteData(png_structp png_ptr, png_bytep data, png_size_t length)
{
- ImBuf *ibuf = (ImBuf *) png_get_io_ptr(png_ptr);
+ ImBuf *ibuf = (ImBuf *)png_get_io_ptr(png_ptr);
- /* if buffer is to small increase it. */
- while (ibuf->encodedsize + length > ibuf->encodedbuffersize) {
- imb_enlargeencodedbufferImBuf(ibuf);
- }
+ /* if buffer is to small increase it. */
+ while (ibuf->encodedsize + length > ibuf->encodedbuffersize) {
+ imb_enlargeencodedbufferImBuf(ibuf);
+ }
- memcpy(ibuf->encodedbuffer + ibuf->encodedsize, data, length);
- ibuf->encodedsize += length;
+ memcpy(ibuf->encodedbuffer + ibuf->encodedsize, data, length);
+ ibuf->encodedsize += length;
}
static void ReadData(png_structp png_ptr, png_bytep data, png_size_t length)
{
- PNGReadStruct *rs = (PNGReadStruct *) png_get_io_ptr(png_ptr);
-
- if (rs) {
- if (length <= rs->size - rs->seek) {
- memcpy(data, rs->data + rs->seek, length);
- rs->seek += length;
- return;
- }
- }
-
- printf("Reached EOF while decoding PNG\n");
- longjmp(png_jmpbuf(png_ptr), 1);
+ PNGReadStruct *rs = (PNGReadStruct *)png_get_io_ptr(png_ptr);
+
+ if (rs) {
+ if (length <= rs->size - rs->seek) {
+ memcpy(data, rs->data + rs->seek, length);
+ rs->seek += length;
+ return;
+ }
+ }
+
+ printf("Reached EOF while decoding PNG\n");
+ longjmp(png_jmpbuf(png_ptr), 1);
}
static float channel_colormanage_noop(float value)
{
- return value;
+ return value;
}
/* wrap to avoid macro calling functions multiple times */
BLI_INLINE unsigned short ftoshort(float val)
{
- return unit_float_to_ushort_clamp(val);
+ return unit_float_to_ushort_clamp(val);
}
int imb_savepng(struct ImBuf *ibuf, const char *name, int flags)
{
- png_structp png_ptr;
- png_infop info_ptr;
-
- unsigned char *pixels = NULL;
- unsigned char *from, *to;
- unsigned short *pixels16 = NULL, *to16;
- float *from_float, from_straight[4];
- png_bytepp row_pointers = NULL;
- int i, bytesperpixel, color_type = PNG_COLOR_TYPE_GRAY;
- FILE *fp = NULL;
-
- bool is_16bit = (ibuf->foptions.flag & PNG_16BIT) != 0;
- bool has_float = (ibuf->rect_float != NULL);
- int channels_in_float = ibuf->channels ? ibuf->channels : 4;
-
- float (*chanel_colormanage_cb)(float);
- size_t num_bytes;
-
- /* use the jpeg quality setting for compression */
- int compression;
- compression = (int)(((float)(ibuf->foptions.quality) / 11.1111f));
- compression = compression < 0 ? 0 : (compression > 9 ? 9 : compression);
-
- if (ibuf->float_colorspace || (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA)) {
- /* float buffer was managed already, no need in color space conversion */
- chanel_colormanage_cb = channel_colormanage_noop;
- }
- else {
- /* standard linear-to-srgb conversion if float buffer wasn't managed */
- chanel_colormanage_cb = linearrgb_to_srgb;
- }
-
- /* for prints */
- if (flags & IB_mem)
- name = "<memory>";
-
- bytesperpixel = (ibuf->planes + 7) >> 3;
- if ((bytesperpixel > 4) || (bytesperpixel == 2)) {
- printf("imb_savepng: Unsupported bytes per pixel: %d for file: '%s'\n", bytesperpixel, name);
- return (0);
- }
-
- png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
- NULL, NULL, NULL);
- if (png_ptr == NULL) {
- printf("imb_savepng: Cannot png_create_write_struct for file: '%s'\n", name);
- return 0;
- }
-
- info_ptr = png_create_info_struct(png_ptr);
- if (info_ptr == NULL) {
- png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
- printf("imb_savepng: Cannot png_create_info_struct for file: '%s'\n", name);
- return 0;
- }
-
- if (setjmp(png_jmpbuf(png_ptr))) {
- png_destroy_write_struct(&png_ptr, &info_ptr);
- printf("imb_savepng: Cannot setjmp for file: '%s'\n", name);
- return 0;
- }
-
- /* copy image data */
- num_bytes = ((size_t)ibuf->x) * ibuf->y * bytesperpixel;
- if (is_16bit)
- pixels16 = MEM_mallocN(num_bytes * sizeof(unsigned short), "png 16bit pixels");
- else
- pixels = MEM_mallocN(num_bytes * sizeof(unsigned char), "png 8bit pixels");
-
- if (pixels == NULL && pixels16 == NULL) {
- png_destroy_write_struct(&png_ptr, &info_ptr);
- printf("imb_savepng: Cannot allocate pixels array of %dx%d, %d bytes per pixel for file: '%s'\n", ibuf->x, ibuf->y, bytesperpixel, name);
- return 0;
- }
-
- from = (unsigned char *) ibuf->rect;
- to = pixels;
- from_float = ibuf->rect_float;
- to16 = pixels16;
-
- switch (bytesperpixel) {
- case 4:
- color_type = PNG_COLOR_TYPE_RGBA;
- if (is_16bit) {
- if (has_float) {
- if (channels_in_float == 4) {
- for (i = ibuf->x * ibuf->y; i > 0; i--) {
- premul_to_straight_v4_v4(from_straight, from_float);
- to16[0] = ftoshort(chanel_colormanage_cb(from_straight[0]));
- to16[1] = ftoshort(chanel_colormanage_cb(from_straight[1]));
- to16[2] = ftoshort(chanel_colormanage_cb(from_straight[2]));
- to16[3] = ftoshort(chanel_colormanage_cb(from_straight[3]));
- to16 += 4; from_float += 4;
- }
- }
- else if (channels_in_float == 3) {
- for (i = ibuf->x * ibuf->y; i > 0; i--) {
- to16[0] = ftoshort(chanel_colormanage_cb(from_float[0]));
- to16[1] = ftoshort(chanel_colormanage_cb(from_float[1]));
- to16[2] = ftoshort(chanel_colormanage_cb(from_float[2]));
- to16[3] = 65535;
- to16 += 4; from_float += 3;
- }
- }
- else {
- for (i = ibuf->x * ibuf->y; i > 0; i--) {
- to16[0] = ftoshort(chanel_colormanage_cb(from_float[0]));
- to16[2] = to16[1] = to16[0];
- to16[3] = 65535;
- to16 += 4; from_float++;
- }
- }
- }
- else {
- for (i = ibuf->x * ibuf->y; i > 0; i--) {
- to16[0] = UPSAMPLE_8_TO_16(from[0]);
- to16[1] = UPSAMPLE_8_TO_16(from[1]);
- to16[2] = UPSAMPLE_8_TO_16(from[2]);
- to16[3] = UPSAMPLE_8_TO_16(from[3]);
- to16 += 4; from += 4;
- }
- }
- }
- else {
- for (i = ibuf->x * ibuf->y; i > 0; i--) {
- to[0] = from[0];
- to[1] = from[1];
- to[2] = from[2];
- to[3] = from[3];
- to += 4; from += 4;
- }
- }
- break;
- case 3:
- color_type = PNG_COLOR_TYPE_RGB;
- if (is_16bit) {
- if (has_float) {
- if (channels_in_float == 4) {
- for (i = ibuf->x * ibuf->y; i > 0; i--) {
- premul_to_straight_v4_v4(from_straight, from_float);
- to16[0] = ftoshort(chanel_colormanage_cb(from_straight[0]));
- to16[1] = ftoshort(chanel_colormanage_cb(from_straight[1]));
- to16[2] = ftoshort(chanel_colormanage_cb(from_straight[2]));
- to16 += 3; from_float += 4;
- }
- }
- else if (channels_in_float == 3) {
- for (i = ibuf->x * ibuf->y; i > 0; i--) {
- to16[0] = ftoshort(chanel_colormanage_cb(from_float[0]));
- to16[1] = ftoshort(chanel_colormanage_cb(from_float[1]));
- to16[2] = ftoshort(chanel_colormanage_cb(from_float[2]));
- to16 += 3; from_float += 3;
- }
- }
- else {
- for (i = ibuf->x * ibuf->y; i > 0; i--) {
- to16[0] = ftoshort(chanel_colormanage_cb(from_float[0]));
- to16[2] = to16[1] = to16[0];
- to16 += 3; from_float++;
- }
- }
- }
- else {
- for (i = ibuf->x * ibuf->y; i > 0; i--) {
- to16[0] = UPSAMPLE_8_TO_16(from[0]);
- to16[1] = UPSAMPLE_8_TO_16(from[1]);
- to16[2] = UPSAMPLE_8_TO_16(from[2]);
- to16 += 3; from += 4;
- }
- }
- }
- else {
- for (i = ibuf->x * ibuf->y; i > 0; i--) {
- to[0] = from[0];
- to[1] = from[1];
- to[2] = from[2];
- to += 3; from += 4;
- }
- }
- break;
- case 1:
- color_type = PNG_COLOR_TYPE_GRAY;
- if (is_16bit) {
- if (has_float) {
- float rgb[3];
- if (channels_in_float == 4) {
- for (i = ibuf->x * ibuf->y; i > 0; i--) {
- premul_to_straight_v4_v4(from_straight, from_float);
- rgb[0] = chanel_colormanage_cb(from_straight[0]);
- rgb[1] = chanel_colormanage_cb(from_straight[1]);
- rgb[2] = chanel_colormanage_cb(from_straight[2]);
- to16[0] = ftoshort(IMB_colormanagement_get_luminance(rgb));
- to16++; from_float += 4;
- }
- }
- else if (channels_in_float == 3) {
- for (i = ibuf->x * ibuf->y; i > 0; i--) {
- rgb[0] = chanel_colormanage_cb(from_float[0]);
- rgb[1] = chanel_colormanage_cb(from_float[1]);
- rgb[2] = chanel_colormanage_cb(from_float[2]);
- to16[0] = ftoshort(IMB_colormanagement_get_luminance(rgb));
- to16++; from_float += 3;
- }
- }
- else {
- for (i = ibuf->x * ibuf->y; i > 0; i--) {
- to16[0] = ftoshort(chanel_colormanage_cb(from_float[0]));
- to16++; from_float++;
- }
- }
- }
- else {
- for (i = ibuf->x * ibuf->y; i > 0; i--) {
- to16[0] = UPSAMPLE_8_TO_16(from[0]);
- to16++; from += 4;
- }
- }
- }
- else {
- for (i = ibuf->x * ibuf->y; i > 0; i--) {
- to[0] = from[0];
- to++; from += 4;
- }
- }
- break;
- }
-
- if (flags & IB_mem) {
- /* create image in memory */
- imb_addencodedbufferImBuf(ibuf);
- ibuf->encodedsize = 0;
-
- png_set_write_fn(png_ptr,
- (png_voidp) ibuf,
- WriteData,
- Flush);
- }
- else {
- fp = BLI_fopen(name, "wb");
- if (!fp) {
- png_destroy_write_struct(&png_ptr, &info_ptr);
- if (pixels)
- MEM_freeN(pixels);
- if (pixels16)
- MEM_freeN(pixels16);
- printf("imb_savepng: Cannot open file for writing: '%s'\n", name);
- return 0;
- }
- png_init_io(png_ptr, fp);
- }
+ png_structp png_ptr;
+ png_infop info_ptr;
+
+ unsigned char *pixels = NULL;
+ unsigned char *from, *to;
+ unsigned short *pixels16 = NULL, *to16;
+ float *from_float, from_straight[4];
+ png_bytepp row_pointers = NULL;
+ int i, bytesperpixel, color_type = PNG_COLOR_TYPE_GRAY;
+ FILE *fp = NULL;
+
+ bool is_16bit = (ibuf->foptions.flag & PNG_16BIT) != 0;
+ bool has_float = (ibuf->rect_float != NULL);
+ int channels_in_float = ibuf->channels ? ibuf->channels : 4;
+
+ float (*chanel_colormanage_cb)(float);
+ size_t num_bytes;
+
+ /* use the jpeg quality setting for compression */
+ int compression;
+ compression = (int)(((float)(ibuf->foptions.quality) / 11.1111f));
+ compression = compression < 0 ? 0 : (compression > 9 ? 9 : compression);
+
+ if (ibuf->float_colorspace || (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA)) {
+ /* float buffer was managed already, no need in color space conversion */
+ chanel_colormanage_cb = channel_colormanage_noop;
+ }
+ else {
+ /* standard linear-to-srgb conversion if float buffer wasn't managed */
+ chanel_colormanage_cb = linearrgb_to_srgb;
+ }
+
+ /* for prints */
+ if (flags & IB_mem)
+ name = "<memory>";
+
+ bytesperpixel = (ibuf->planes + 7) >> 3;
+ if ((bytesperpixel > 4) || (bytesperpixel == 2)) {
+ printf("imb_savepng: Unsupported bytes per pixel: %d for file: '%s'\n", bytesperpixel, name);
+ return (0);
+ }
+
+ png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+ if (png_ptr == NULL) {
+ printf("imb_savepng: Cannot png_create_write_struct for file: '%s'\n", name);
+ return 0;
+ }
+
+ info_ptr = png_create_info_struct(png_ptr);
+ if (info_ptr == NULL) {
+ png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
+ printf("imb_savepng: Cannot png_create_info_struct for file: '%s'\n", name);
+ return 0;
+ }
+
+ if (setjmp(png_jmpbuf(png_ptr))) {
+ png_destroy_write_struct(&png_ptr, &info_ptr);
+ printf("imb_savepng: Cannot setjmp for file: '%s'\n", name);
+ return 0;
+ }
+
+ /* copy image data */
+ num_bytes = ((size_t)ibuf->x) * ibuf->y * bytesperpixel;
+ if (is_16bit)
+ pixels16 = MEM_mallocN(num_bytes * sizeof(unsigned short), "png 16bit pixels");
+ else
+ pixels = MEM_mallocN(num_bytes * sizeof(unsigned char), "png 8bit pixels");
+
+ if (pixels == NULL && pixels16 == NULL) {
+ png_destroy_write_struct(&png_ptr, &info_ptr);
+ printf(
+ "imb_savepng: Cannot allocate pixels array of %dx%d, %d bytes per pixel for file: '%s'\n",
+ ibuf->x,
+ ibuf->y,
+ bytesperpixel,
+ name);
+ return 0;
+ }
+
+ from = (unsigned char *)ibuf->rect;
+ to = pixels;
+ from_float = ibuf->rect_float;
+ to16 = pixels16;
+
+ switch (bytesperpixel) {
+ case 4:
+ color_type = PNG_COLOR_TYPE_RGBA;
+ if (is_16bit) {
+ if (has_float) {
+ if (channels_in_float == 4) {
+ for (i = ibuf->x * ibuf->y; i > 0; i--) {
+ premul_to_straight_v4_v4(from_straight, from_float);
+ to16[0] = ftoshort(chanel_colormanage_cb(from_straight[0]));
+ to16[1] = ftoshort(chanel_colormanage_cb(from_straight[1]));
+ to16[2] = ftoshort(chanel_colormanage_cb(from_straight[2]));
+ to16[3] = ftoshort(chanel_colormanage_cb(from_straight[3]));
+ to16 += 4;
+ from_float += 4;
+ }
+ }
+ else if (channels_in_float == 3) {
+ for (i = ibuf->x * ibuf->y; i > 0; i--) {
+ to16[0] = ftoshort(chanel_colormanage_cb(from_float[0]));
+ to16[1] = ftoshort(chanel_colormanage_cb(from_float[1]));
+ to16[2] = ftoshort(chanel_colormanage_cb(from_float[2]));
+ to16[3] = 65535;
+ to16 += 4;
+ from_float += 3;
+ }
+ }
+ else {
+ for (i = ibuf->x * ibuf->y; i > 0; i--) {
+ to16[0] = ftoshort(chanel_colormanage_cb(from_float[0]));
+ to16[2] = to16[1] = to16[0];
+ to16[3] = 65535;
+ to16 += 4;
+ from_float++;
+ }
+ }
+ }
+ else {
+ for (i = ibuf->x * ibuf->y; i > 0; i--) {
+ to16[0] = UPSAMPLE_8_TO_16(from[0]);
+ to16[1] = UPSAMPLE_8_TO_16(from[1]);
+ to16[2] = UPSAMPLE_8_TO_16(from[2]);
+ to16[3] = UPSAMPLE_8_TO_16(from[3]);
+ to16 += 4;
+ from += 4;
+ }
+ }
+ }
+ else {
+ for (i = ibuf->x * ibuf->y; i > 0; i--) {
+ to[0] = from[0];
+ to[1] = from[1];
+ to[2] = from[2];
+ to[3] = from[3];
+ to += 4;
+ from += 4;
+ }
+ }
+ break;
+ case 3:
+ color_type = PNG_COLOR_TYPE_RGB;
+ if (is_16bit) {
+ if (has_float) {
+ if (channels_in_float == 4) {
+ for (i = ibuf->x * ibuf->y; i > 0; i--) {
+ premul_to_straight_v4_v4(from_straight, from_float);
+ to16[0] = ftoshort(chanel_colormanage_cb(from_straight[0]));
+ to16[1] = ftoshort(chanel_colormanage_cb(from_straight[1]));
+ to16[2] = ftoshort(chanel_colormanage_cb(from_straight[2]));
+ to16 += 3;
+ from_float += 4;
+ }
+ }
+ else if (channels_in_float == 3) {
+ for (i = ibuf->x * ibuf->y; i > 0; i--) {
+ to16[0] = ftoshort(chanel_colormanage_cb(from_float[0]));
+ to16[1] = ftoshort(chanel_colormanage_cb(from_float[1]));
+ to16[2] = ftoshort(chanel_colormanage_cb(from_float[2]));
+ to16 += 3;
+ from_float += 3;
+ }
+ }
+ else {
+ for (i = ibuf->x * ibuf->y; i > 0; i--) {
+ to16[0] = ftoshort(chanel_colormanage_cb(from_float[0]));
+ to16[2] = to16[1] = to16[0];
+ to16 += 3;
+ from_float++;
+ }
+ }
+ }
+ else {
+ for (i = ibuf->x * ibuf->y; i > 0; i--) {
+ to16[0] = UPSAMPLE_8_TO_16(from[0]);
+ to16[1] = UPSAMPLE_8_TO_16(from[1]);
+ to16[2] = UPSAMPLE_8_TO_16(from[2]);
+ to16 += 3;
+ from += 4;
+ }
+ }
+ }
+ else {
+ for (i = ibuf->x * ibuf->y; i > 0; i--) {
+ to[0] = from[0];
+ to[1] = from[1];
+ to[2] = from[2];
+ to += 3;
+ from += 4;
+ }
+ }
+ break;
+ case 1:
+ color_type = PNG_COLOR_TYPE_GRAY;
+ if (is_16bit) {
+ if (has_float) {
+ float rgb[3];
+ if (channels_in_float == 4) {
+ for (i = ibuf->x * ibuf->y; i > 0; i--) {
+ premul_to_straight_v4_v4(from_straight, from_float);
+ rgb[0] = chanel_colormanage_cb(from_straight[0]);
+ rgb[1] = chanel_colormanage_cb(from_straight[1]);
+ rgb[2] = chanel_colormanage_cb(from_straight[2]);
+ to16[0] = ftoshort(IMB_colormanagement_get_luminance(rgb));
+ to16++;
+ from_float += 4;
+ }
+ }
+ else if (channels_in_float == 3) {
+ for (i = ibuf->x * ibuf->y; i > 0; i--) {
+ rgb[0] = chanel_colormanage_cb(from_float[0]);
+ rgb[1] = chanel_colormanage_cb(from_float[1]);
+ rgb[2] = chanel_colormanage_cb(from_float[2]);
+ to16[0] = ftoshort(IMB_colormanagement_get_luminance(rgb));
+ to16++;
+ from_float += 3;
+ }
+ }
+ else {
+ for (i = ibuf->x * ibuf->y; i > 0; i--) {
+ to16[0] = ftoshort(chanel_colormanage_cb(from_float[0]));
+ to16++;
+ from_float++;
+ }
+ }
+ }
+ else {
+ for (i = ibuf->x * ibuf->y; i > 0; i--) {
+ to16[0] = UPSAMPLE_8_TO_16(from[0]);
+ to16++;
+ from += 4;
+ }
+ }
+ }
+ else {
+ for (i = ibuf->x * ibuf->y; i > 0; i--) {
+ to[0] = from[0];
+ to++;
+ from += 4;
+ }
+ }
+ break;
+ }
+
+ if (flags & IB_mem) {
+ /* create image in memory */
+ imb_addencodedbufferImBuf(ibuf);
+ ibuf->encodedsize = 0;
+
+ png_set_write_fn(png_ptr, (png_voidp)ibuf, WriteData, Flush);
+ }
+ else {
+ fp = BLI_fopen(name, "wb");
+ if (!fp) {
+ png_destroy_write_struct(&png_ptr, &info_ptr);
+ if (pixels)
+ MEM_freeN(pixels);
+ if (pixels16)
+ MEM_freeN(pixels16);
+ printf("imb_savepng: Cannot open file for writing: '%s'\n", name);
+ return 0;
+ }
+ png_init_io(png_ptr, fp);
+ }
#if 0
- png_set_filter(png_ptr, 0,
- PNG_FILTER_NONE | PNG_FILTER_VALUE_NONE |
- PNG_FILTER_SUB | PNG_FILTER_VALUE_SUB |
- PNG_FILTER_UP | PNG_FILTER_VALUE_UP |
- PNG_FILTER_AVG | PNG_FILTER_VALUE_AVG |
- PNG_FILTER_PAETH | PNG_FILTER_VALUE_PAETH |
- PNG_ALL_FILTERS);
+ png_set_filter(png_ptr, 0,
+ PNG_FILTER_NONE | PNG_FILTER_VALUE_NONE |
+ PNG_FILTER_SUB | PNG_FILTER_VALUE_SUB |
+ PNG_FILTER_UP | PNG_FILTER_VALUE_UP |
+ PNG_FILTER_AVG | PNG_FILTER_VALUE_AVG |
+ PNG_FILTER_PAETH | PNG_FILTER_VALUE_PAETH |
+ PNG_ALL_FILTERS);
#endif
- png_set_compression_level(png_ptr, compression);
-
- /* png image settings */
- png_set_IHDR(png_ptr,
- info_ptr,
- ibuf->x,
- ibuf->y,
- is_16bit ? 16 : 8,
- color_type,
- PNG_INTERLACE_NONE,
- PNG_COMPRESSION_TYPE_DEFAULT,
- PNG_FILTER_TYPE_DEFAULT);
-
- /* image text info */
- if (ibuf->metadata) {
- png_text *metadata;
- IDProperty *prop;
-
- int num_text = 0;
-
- for (prop = ibuf->metadata->data.group.first; prop; prop = prop->next) {
- if (prop->type == IDP_STRING) {
- num_text++;
- }
- }
-
- metadata = MEM_callocN(num_text * sizeof(png_text), "png_metadata");
- num_text = 0;
- for (prop = ibuf->metadata->data.group.first; prop; prop = prop->next) {
- if (prop->type == IDP_STRING) {
- metadata[num_text].compression = PNG_TEXT_COMPRESSION_NONE;
- metadata[num_text].key = prop->name;
- metadata[num_text].text = IDP_String(prop);
- num_text++;
- }
- }
-
- png_set_text(png_ptr, info_ptr, metadata, num_text);
- MEM_freeN(metadata);
-
- }
-
- if (ibuf->ppm[0] > 0.0 && ibuf->ppm[1] > 0.0) {
- png_set_pHYs(png_ptr, info_ptr, (unsigned int)(ibuf->ppm[0] + 0.5), (unsigned int)(ibuf->ppm[1] + 0.5), PNG_RESOLUTION_METER);
- }
-
- /* write the file header information */
- png_write_info(png_ptr, info_ptr);
+ png_set_compression_level(png_ptr, compression);
+
+ /* png image settings */
+ png_set_IHDR(png_ptr,
+ info_ptr,
+ ibuf->x,
+ ibuf->y,
+ is_16bit ? 16 : 8,
+ color_type,
+ PNG_INTERLACE_NONE,
+ PNG_COMPRESSION_TYPE_DEFAULT,
+ PNG_FILTER_TYPE_DEFAULT);
+
+ /* image text info */
+ if (ibuf->metadata) {
+ png_text *metadata;
+ IDProperty *prop;
+
+ int num_text = 0;
+
+ for (prop = ibuf->metadata->data.group.first; prop; prop = prop->next) {
+ if (prop->type == IDP_STRING) {
+ num_text++;
+ }
+ }
+
+ metadata = MEM_callocN(num_text * sizeof(png_text), "png_metadata");
+ num_text = 0;
+ for (prop = ibuf->metadata->data.group.first; prop; prop = prop->next) {
+ if (prop->type == IDP_STRING) {
+ metadata[num_text].compression = PNG_TEXT_COMPRESSION_NONE;
+ metadata[num_text].key = prop->name;
+ metadata[num_text].text = IDP_String(prop);
+ num_text++;
+ }
+ }
+
+ png_set_text(png_ptr, info_ptr, metadata, num_text);
+ MEM_freeN(metadata);
+ }
+
+ if (ibuf->ppm[0] > 0.0 && ibuf->ppm[1] > 0.0) {
+ png_set_pHYs(png_ptr,
+ info_ptr,
+ (unsigned int)(ibuf->ppm[0] + 0.5),
+ (unsigned int)(ibuf->ppm[1] + 0.5),
+ PNG_RESOLUTION_METER);
+ }
+
+ /* write the file header information */
+ png_write_info(png_ptr, info_ptr);
#ifdef __LITTLE_ENDIAN__
- png_set_swap(png_ptr);
+ png_set_swap(png_ptr);
#endif
- /* allocate memory for an array of row-pointers */
- row_pointers = (png_bytepp) MEM_mallocN(ibuf->y * sizeof(png_bytep), "row_pointers");
- if (row_pointers == NULL) {
- printf("imb_savepng: Cannot allocate row-pointers array for file '%s'\n", name);
- png_destroy_write_struct(&png_ptr, &info_ptr);
- if (pixels)
- MEM_freeN(pixels);
- if (pixels16)
- MEM_freeN(pixels16);
- if (fp) {
- fclose(fp);
- }
- return 0;
- }
-
- /* set the individual row-pointers to point at the correct offsets */
- if (is_16bit) {
- for (i = 0; i < ibuf->y; i++) {
- row_pointers[ibuf->y - 1 - i] = (png_bytep)
- ((unsigned short *)pixels16 + (((size_t)i) * ibuf->x) * bytesperpixel);
- }
- }
- else {
- for (i = 0; i < ibuf->y; i++) {
- row_pointers[ibuf->y - 1 - i] = (png_bytep)
- ((unsigned char *)pixels + (((size_t)i) * ibuf->x) * bytesperpixel * sizeof(unsigned char));
- }
- }
-
- /* write out the entire image data in one call */
- png_write_image(png_ptr, row_pointers);
-
- /* write the additional chunks to the PNG file (not really needed) */
- png_write_end(png_ptr, info_ptr);
-
- /* clean up */
- if (pixels)
- MEM_freeN(pixels);
- if (pixels16)
- MEM_freeN(pixels16);
- MEM_freeN(row_pointers);
- png_destroy_write_struct(&png_ptr, &info_ptr);
-
- if (fp) {
- fflush(fp);
- fclose(fp);
- }
-
- return(1);
+ /* allocate memory for an array of row-pointers */
+ row_pointers = (png_bytepp)MEM_mallocN(ibuf->y * sizeof(png_bytep), "row_pointers");
+ if (row_pointers == NULL) {
+ printf("imb_savepng: Cannot allocate row-pointers array for file '%s'\n", name);
+ png_destroy_write_struct(&png_ptr, &info_ptr);
+ if (pixels)
+ MEM_freeN(pixels);
+ if (pixels16)
+ MEM_freeN(pixels16);
+ if (fp) {
+ fclose(fp);
+ }
+ return 0;
+ }
+
+ /* set the individual row-pointers to point at the correct offsets */
+ if (is_16bit) {
+ for (i = 0; i < ibuf->y; i++) {
+ row_pointers[ibuf->y - 1 - i] = (png_bytep)((unsigned short *)pixels16 +
+ (((size_t)i) * ibuf->x) * bytesperpixel);
+ }
+ }
+ else {
+ for (i = 0; i < ibuf->y; i++) {
+ row_pointers[ibuf->y - 1 - i] = (png_bytep)((unsigned char *)pixels +
+ (((size_t)i) * ibuf->x) * bytesperpixel *
+ sizeof(unsigned char));
+ }
+ }
+
+ /* write out the entire image data in one call */
+ png_write_image(png_ptr, row_pointers);
+
+ /* write the additional chunks to the PNG file (not really needed) */
+ png_write_end(png_ptr, info_ptr);
+
+ /* clean up */
+ if (pixels)
+ MEM_freeN(pixels);
+ if (pixels16)
+ MEM_freeN(pixels16);
+ MEM_freeN(row_pointers);
+ png_destroy_write_struct(&png_ptr, &info_ptr);
+
+ if (fp) {
+ fflush(fp);
+ fclose(fp);
+ }
+
+ return (1);
}
static void imb_png_warning(png_structp UNUSED(png_ptr), png_const_charp message)
{
- /* We suppress iCCP warnings. That's how Blender always used to behave,
- * and with new libpng it became too much picky, giving a warning on
- * the splash screen even.
- */
- if ((G.debug & G_DEBUG) == 0 && STREQLEN(message, "iCCP", 4)) {
- return;
- }
- fprintf(stderr, "libpng warning: %s\n", message);
+ /* We suppress iCCP warnings. That's how Blender always used to behave,
+ * and with new libpng it became too much picky, giving a warning on
+ * the splash screen even.
+ */
+ if ((G.debug & G_DEBUG) == 0 && STREQLEN(message, "iCCP", 4)) {
+ return;
+ }
+ fprintf(stderr, "libpng warning: %s\n", message);
}
static void imb_png_error(png_structp UNUSED(png_ptr), png_const_charp message)
{
- fprintf(stderr, "libpng error: %s\n", message);
+ fprintf(stderr, "libpng error: %s\n", message);
}
ImBuf *imb_loadpng(const unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE])
{
- struct ImBuf *ibuf = NULL;
- png_structp png_ptr;
- png_infop info_ptr;
- unsigned char *pixels = NULL;
- unsigned short *pixels16 = NULL;
- png_bytepp row_pointers = NULL;
- png_uint_32 width, height;
- int bit_depth, color_type;
- PNGReadStruct ps;
-
- unsigned char *from, *to;
- unsigned short *from16;
- float *to_float;
- unsigned int channels;
-
- if (imb_is_a_png(mem) == 0) return(NULL);
-
- /* both 8 and 16 bit PNGs are default to standard byte colorspace */
- colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE);
-
- png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
- NULL, NULL, NULL);
- if (png_ptr == NULL) {
- printf("Cannot png_create_read_struct\n");
- return NULL;
- }
-
- png_set_error_fn(png_ptr, NULL, imb_png_error, imb_png_warning);
-
- info_ptr = png_create_info_struct(png_ptr);
- if (info_ptr == NULL) {
- png_destroy_read_struct(&png_ptr, (png_infopp)NULL,
- (png_infopp)NULL);
- printf("Cannot png_create_info_struct\n");
- return NULL;
- }
-
- ps.size = size; /* XXX, 4gig limit! */
- ps.data = mem;
- ps.seek = 0;
-
- png_set_read_fn(png_ptr, (void *) &ps, ReadData);
-
- if (setjmp(png_jmpbuf(png_ptr))) {
- png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
- if (pixels) MEM_freeN(pixels);
- if (pixels16) MEM_freeN(pixels16);
- if (row_pointers) MEM_freeN(row_pointers);
- if (ibuf) IMB_freeImBuf(ibuf);
- return NULL;
- }
-
- // png_set_sig_bytes(png_ptr, 8);
-
- png_read_info(png_ptr, info_ptr);
- png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth,
- &color_type, NULL, NULL, NULL);
-
- channels = png_get_channels(png_ptr, info_ptr);
-
- switch (color_type) {
- case PNG_COLOR_TYPE_RGB:
- case PNG_COLOR_TYPE_RGB_ALPHA:
- break;
- case PNG_COLOR_TYPE_PALETTE:
- png_set_palette_to_rgb(png_ptr);
- if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
- channels = 4;
- }
- else {
- channels = 3;
- }
- break;
- case PNG_COLOR_TYPE_GRAY:
- case PNG_COLOR_TYPE_GRAY_ALPHA:
- if (bit_depth < 8) {
- png_set_expand(png_ptr);
- bit_depth = 8;
- if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
- /* PNG_COLOR_TYPE_GRAY may also have alpha 'values', like with palette. */
- channels = 2;
- }
- }
- break;
- default:
- printf("PNG format not supported\n");
- longjmp(png_jmpbuf(png_ptr), 1);
- }
-
- ibuf = IMB_allocImBuf(width, height, 8 * channels, 0);
-
- if (ibuf) {
- ibuf->ftype = IMB_FTYPE_PNG;
- if (bit_depth == 16)
- ibuf->foptions.flag |= PNG_16BIT;
-
- if (png_get_valid(png_ptr, info_ptr, PNG_INFO_pHYs)) {
- int unit_type;
- png_uint_32 xres, yres;
-
- if (png_get_pHYs(png_ptr, info_ptr, &xres, &yres, &unit_type)) {
- if (unit_type == PNG_RESOLUTION_METER) {
- ibuf->ppm[0] = xres;
- ibuf->ppm[1] = yres;
- }
- }
- }
- }
- else {
- printf("Couldn't allocate memory for PNG image\n");
- }
-
- if (ibuf && ((flags & IB_test) == 0)) {
- if (bit_depth == 16) {
- imb_addrectfloatImBuf(ibuf);
- png_set_swap(png_ptr);
-
- pixels16 = imb_alloc_pixels(ibuf->x, ibuf->y, channels, sizeof(png_uint_16), "pixels");
- if (pixels16 == NULL || ibuf->rect_float == NULL) {
- printf("Cannot allocate pixels array\n");
- longjmp(png_jmpbuf(png_ptr), 1);
- }
-
- /* allocate memory for an array of row-pointers */
- row_pointers = (png_bytepp) MEM_mallocN((size_t)ibuf->y * sizeof(png_uint_16p), "row_pointers");
- if (row_pointers == NULL) {
- printf("Cannot allocate row-pointers array\n");
- longjmp(png_jmpbuf(png_ptr), 1);
- }
-
- /* set the individual row-pointers to point at the correct offsets */
- for (size_t i = 0; i < ibuf->y; i++) {
- row_pointers[ibuf->y - 1 - i] = (png_bytep)
- ((png_uint_16 *)pixels16 + (i * ibuf->x) * channels);
- }
-
- png_read_image(png_ptr, row_pointers);
-
- /* copy image data */
-
- to_float = ibuf->rect_float;
- from16 = pixels16;
-
- switch (channels) {
- case 4:
- for (size_t i = (size_t)ibuf->x * (size_t)ibuf->y; i > 0; i--) {
- to_float[0] = from16[0] / 65535.0;
- to_float[1] = from16[1] / 65535.0;
- to_float[2] = from16[2] / 65535.0;
- to_float[3] = from16[3] / 65535.0;
- to_float += 4; from16 += 4;
- }
- break;
- case 3:
- for (size_t i = (size_t)ibuf->x * (size_t)ibuf->y; i > 0; i--) {
- to_float[0] = from16[0] / 65535.0;
- to_float[1] = from16[1] / 65535.0;
- to_float[2] = from16[2] / 65535.0;
- to_float[3] = 1.0;
- to_float += 4; from16 += 3;
- }
- break;
- case 2:
- for (size_t i = (size_t)ibuf->x * (size_t)ibuf->y; i > 0; i--) {
- to_float[0] = to_float[1] = to_float[2] = from16[0] / 65535.0;
- to_float[3] = from16[1] / 65535.0;
- to_float += 4; from16 += 2;
- }
- break;
- case 1:
- for (size_t i = (size_t)ibuf->x * (size_t)ibuf->y; i > 0; i--) {
- to_float[0] = to_float[1] = to_float[2] = from16[0] / 65535.0;
- to_float[3] = 1.0;
- to_float += 4; from16++;
- }
- break;
- }
- }
- else {
- imb_addrectImBuf(ibuf);
-
- pixels = imb_alloc_pixels(ibuf->x, ibuf->y, channels, sizeof(unsigned char), "pixels");
- if (pixels == NULL || ibuf->rect == NULL) {
- printf("Cannot allocate pixels array\n");
- longjmp(png_jmpbuf(png_ptr), 1);
- }
-
- /* allocate memory for an array of row-pointers */
- row_pointers = (png_bytepp) MEM_mallocN((size_t)ibuf->y * sizeof(png_bytep), "row_pointers");
- if (row_pointers == NULL) {
- printf("Cannot allocate row-pointers array\n");
- longjmp(png_jmpbuf(png_ptr), 1);
- }
-
- /* set the individual row-pointers to point at the correct offsets */
- for (int i = 0; i < ibuf->y; i++) {
- row_pointers[ibuf->y - 1 - i] = (png_bytep)
- ((unsigned char *)pixels + (((size_t)i) * ibuf->x) * channels * sizeof(unsigned char));
- }
-
- png_read_image(png_ptr, row_pointers);
-
- /* copy image data */
-
- to = (unsigned char *) ibuf->rect;
- from = pixels;
-
- switch (channels) {
- case 4:
- for (size_t i = (size_t)ibuf->x * (size_t)ibuf->y; i > 0; i--) {
- to[0] = from[0];
- to[1] = from[1];
- to[2] = from[2];
- to[3] = from[3];
- to += 4; from += 4;
- }
- break;
- case 3:
- for (size_t i = (size_t)ibuf->x * (size_t)ibuf->y; i > 0; i--) {
- to[0] = from[0];
- to[1] = from[1];
- to[2] = from[2];
- to[3] = 0xff;
- to += 4; from += 3;
- }
- break;
- case 2:
- for (size_t i = (size_t)ibuf->x * (size_t)ibuf->y; i > 0; i--) {
- to[0] = to[1] = to[2] = from[0];
- to[3] = from[1];
- to += 4; from += 2;
- }
- break;
- case 1:
- for (size_t i = (size_t)ibuf->x * (size_t)ibuf->y; i > 0; i--) {
- to[0] = to[1] = to[2] = from[0];
- to[3] = 0xff;
- to += 4; from++;
- }
- break;
- }
- }
-
- 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_set_field(ibuf->metadata, text_chunks[i].key, text_chunks[i].text);
- ibuf->flags |= IB_metadata;
- }
- }
-
- png_read_end(png_ptr, info_ptr);
- }
-
- /* clean up */
- if (pixels)
- MEM_freeN(pixels);
- if (pixels16)
- MEM_freeN(pixels16);
- if (row_pointers)
- MEM_freeN(row_pointers);
- png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
-
- return(ibuf);
+ struct ImBuf *ibuf = NULL;
+ png_structp png_ptr;
+ png_infop info_ptr;
+ unsigned char *pixels = NULL;
+ unsigned short *pixels16 = NULL;
+ png_bytepp row_pointers = NULL;
+ png_uint_32 width, height;
+ int bit_depth, color_type;
+ PNGReadStruct ps;
+
+ unsigned char *from, *to;
+ unsigned short *from16;
+ float *to_float;
+ unsigned int channels;
+
+ if (imb_is_a_png(mem) == 0)
+ return (NULL);
+
+ /* both 8 and 16 bit PNGs are default to standard byte colorspace */
+ colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE);
+
+ png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+ if (png_ptr == NULL) {
+ printf("Cannot png_create_read_struct\n");
+ return NULL;
+ }
+
+ png_set_error_fn(png_ptr, NULL, imb_png_error, imb_png_warning);
+
+ info_ptr = png_create_info_struct(png_ptr);
+ if (info_ptr == NULL) {
+ png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
+ printf("Cannot png_create_info_struct\n");
+ return NULL;
+ }
+
+ ps.size = size; /* XXX, 4gig limit! */
+ ps.data = mem;
+ ps.seek = 0;
+
+ png_set_read_fn(png_ptr, (void *)&ps, ReadData);
+
+ if (setjmp(png_jmpbuf(png_ptr))) {
+ png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
+ if (pixels)
+ MEM_freeN(pixels);
+ if (pixels16)
+ MEM_freeN(pixels16);
+ if (row_pointers)
+ MEM_freeN(row_pointers);
+ if (ibuf)
+ IMB_freeImBuf(ibuf);
+ return NULL;
+ }
+
+ // png_set_sig_bytes(png_ptr, 8);
+
+ png_read_info(png_ptr, info_ptr);
+ png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, NULL, NULL, NULL);
+
+ channels = png_get_channels(png_ptr, info_ptr);
+
+ switch (color_type) {
+ case PNG_COLOR_TYPE_RGB:
+ case PNG_COLOR_TYPE_RGB_ALPHA:
+ break;
+ case PNG_COLOR_TYPE_PALETTE:
+ png_set_palette_to_rgb(png_ptr);
+ if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
+ channels = 4;
+ }
+ else {
+ channels = 3;
+ }
+ break;
+ case PNG_COLOR_TYPE_GRAY:
+ case PNG_COLOR_TYPE_GRAY_ALPHA:
+ if (bit_depth < 8) {
+ png_set_expand(png_ptr);
+ bit_depth = 8;
+ if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
+ /* PNG_COLOR_TYPE_GRAY may also have alpha 'values', like with palette. */
+ channels = 2;
+ }
+ }
+ break;
+ default:
+ printf("PNG format not supported\n");
+ longjmp(png_jmpbuf(png_ptr), 1);
+ }
+
+ ibuf = IMB_allocImBuf(width, height, 8 * channels, 0);
+
+ if (ibuf) {
+ ibuf->ftype = IMB_FTYPE_PNG;
+ if (bit_depth == 16)
+ ibuf->foptions.flag |= PNG_16BIT;
+
+ if (png_get_valid(png_ptr, info_ptr, PNG_INFO_pHYs)) {
+ int unit_type;
+ png_uint_32 xres, yres;
+
+ if (png_get_pHYs(png_ptr, info_ptr, &xres, &yres, &unit_type)) {
+ if (unit_type == PNG_RESOLUTION_METER) {
+ ibuf->ppm[0] = xres;
+ ibuf->ppm[1] = yres;
+ }
+ }
+ }
+ }
+ else {
+ printf("Couldn't allocate memory for PNG image\n");
+ }
+
+ if (ibuf && ((flags & IB_test) == 0)) {
+ if (bit_depth == 16) {
+ imb_addrectfloatImBuf(ibuf);
+ png_set_swap(png_ptr);
+
+ pixels16 = imb_alloc_pixels(ibuf->x, ibuf->y, channels, sizeof(png_uint_16), "pixels");
+ if (pixels16 == NULL || ibuf->rect_float == NULL) {
+ printf("Cannot allocate pixels array\n");
+ longjmp(png_jmpbuf(png_ptr), 1);
+ }
+
+ /* allocate memory for an array of row-pointers */
+ row_pointers = (png_bytepp)MEM_mallocN((size_t)ibuf->y * sizeof(png_uint_16p),
+ "row_pointers");
+ if (row_pointers == NULL) {
+ printf("Cannot allocate row-pointers array\n");
+ longjmp(png_jmpbuf(png_ptr), 1);
+ }
+
+ /* set the individual row-pointers to point at the correct offsets */
+ for (size_t i = 0; i < ibuf->y; i++) {
+ row_pointers[ibuf->y - 1 - i] = (png_bytep)((png_uint_16 *)pixels16 +
+ (i * ibuf->x) * channels);
+ }
+
+ png_read_image(png_ptr, row_pointers);
+
+ /* copy image data */
+
+ to_float = ibuf->rect_float;
+ from16 = pixels16;
+
+ switch (channels) {
+ case 4:
+ for (size_t i = (size_t)ibuf->x * (size_t)ibuf->y; i > 0; i--) {
+ to_float[0] = from16[0] / 65535.0;
+ to_float[1] = from16[1] / 65535.0;
+ to_float[2] = from16[2] / 65535.0;
+ to_float[3] = from16[3] / 65535.0;
+ to_float += 4;
+ from16 += 4;
+ }
+ break;
+ case 3:
+ for (size_t i = (size_t)ibuf->x * (size_t)ibuf->y; i > 0; i--) {
+ to_float[0] = from16[0] / 65535.0;
+ to_float[1] = from16[1] / 65535.0;
+ to_float[2] = from16[2] / 65535.0;
+ to_float[3] = 1.0;
+ to_float += 4;
+ from16 += 3;
+ }
+ break;
+ case 2:
+ for (size_t i = (size_t)ibuf->x * (size_t)ibuf->y; i > 0; i--) {
+ to_float[0] = to_float[1] = to_float[2] = from16[0] / 65535.0;
+ to_float[3] = from16[1] / 65535.0;
+ to_float += 4;
+ from16 += 2;
+ }
+ break;
+ case 1:
+ for (size_t i = (size_t)ibuf->x * (size_t)ibuf->y; i > 0; i--) {
+ to_float[0] = to_float[1] = to_float[2] = from16[0] / 65535.0;
+ to_float[3] = 1.0;
+ to_float += 4;
+ from16++;
+ }
+ break;
+ }
+ }
+ else {
+ imb_addrectImBuf(ibuf);
+
+ pixels = imb_alloc_pixels(ibuf->x, ibuf->y, channels, sizeof(unsigned char), "pixels");
+ if (pixels == NULL || ibuf->rect == NULL) {
+ printf("Cannot allocate pixels array\n");
+ longjmp(png_jmpbuf(png_ptr), 1);
+ }
+
+ /* allocate memory for an array of row-pointers */
+ row_pointers = (png_bytepp)MEM_mallocN((size_t)ibuf->y * sizeof(png_bytep), "row_pointers");
+ if (row_pointers == NULL) {
+ printf("Cannot allocate row-pointers array\n");
+ longjmp(png_jmpbuf(png_ptr), 1);
+ }
+
+ /* set the individual row-pointers to point at the correct offsets */
+ for (int i = 0; i < ibuf->y; i++) {
+ row_pointers[ibuf->y - 1 - i] = (png_bytep)(
+ (unsigned char *)pixels + (((size_t)i) * ibuf->x) * channels * sizeof(unsigned char));
+ }
+
+ png_read_image(png_ptr, row_pointers);
+
+ /* copy image data */
+
+ to = (unsigned char *)ibuf->rect;
+ from = pixels;
+
+ switch (channels) {
+ case 4:
+ for (size_t i = (size_t)ibuf->x * (size_t)ibuf->y; i > 0; i--) {
+ to[0] = from[0];
+ to[1] = from[1];
+ to[2] = from[2];
+ to[3] = from[3];
+ to += 4;
+ from += 4;
+ }
+ break;
+ case 3:
+ for (size_t i = (size_t)ibuf->x * (size_t)ibuf->y; i > 0; i--) {
+ to[0] = from[0];
+ to[1] = from[1];
+ to[2] = from[2];
+ to[3] = 0xff;
+ to += 4;
+ from += 3;
+ }
+ break;
+ case 2:
+ for (size_t i = (size_t)ibuf->x * (size_t)ibuf->y; i > 0; i--) {
+ to[0] = to[1] = to[2] = from[0];
+ to[3] = from[1];
+ to += 4;
+ from += 2;
+ }
+ break;
+ case 1:
+ for (size_t i = (size_t)ibuf->x * (size_t)ibuf->y; i > 0; i--) {
+ to[0] = to[1] = to[2] = from[0];
+ to[3] = 0xff;
+ to += 4;
+ from++;
+ }
+ break;
+ }
+ }
+
+ 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_set_field(ibuf->metadata, text_chunks[i].key, text_chunks[i].text);
+ ibuf->flags |= IB_metadata;
+ }
+ }
+
+ png_read_end(png_ptr, info_ptr);
+ }
+
+ /* clean up */
+ if (pixels)
+ MEM_freeN(pixels);
+ if (pixels16)
+ MEM_freeN(pixels16);
+ if (row_pointers)
+ MEM_freeN(row_pointers);
+ png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
+
+ return (ibuf);
}
diff --git a/source/blender/imbuf/intern/radiance_hdr.c b/source/blender/imbuf/intern/radiance_hdr.c
index dce61953432..e3ab460cce4 100644
--- a/source/blender/imbuf/intern/radiance_hdr.c
+++ b/source/blender/imbuf/intern/radiance_hdr.c
@@ -48,7 +48,7 @@
/* needed constants */
#define MINELEN 8
#define MAXELEN 0x7fff
-#define MINRUN 4 /* minimum run length */
+#define MINRUN 4 /* minimum run length */
#define RED 0
#define GRN 1
#define BLU 2
@@ -58,98 +58,105 @@ typedef unsigned char RGBE[4];
typedef float fCOLOR[3];
/* copy source -> dest */
-#define COPY_RGBE(c1, c2) (c2[RED] = c1[RED], c2[GRN] = c1[GRN], c2[BLU] = c1[BLU], c2[EXP] = c1[EXP])
+#define COPY_RGBE(c1, c2) \
+ (c2[RED] = c1[RED], c2[GRN] = c1[GRN], c2[BLU] = c1[BLU], c2[EXP] = c1[EXP])
/* read routines */
-static const unsigned char *oldreadcolrs(RGBE *scan, const unsigned char *mem, int xmax, const unsigned char *mem_eof)
+static const unsigned char *oldreadcolrs(RGBE *scan,
+ const unsigned char *mem,
+ int xmax,
+ const unsigned char *mem_eof)
{
- size_t i, rshift = 0, len = xmax;
- while (len > 0) {
- if (UNLIKELY(mem_eof - mem < 4)) {
- return NULL;
- }
- scan[0][RED] = *mem++;
- scan[0][GRN] = *mem++;
- scan[0][BLU] = *mem++;
- scan[0][EXP] = *mem++;
- if (scan[0][RED] == 1 && scan[0][GRN] == 1 && scan[0][BLU] == 1) {
- for (i = scan[0][EXP] << rshift; i > 0; i--) {
- COPY_RGBE(scan[-1], scan[0]);
- scan++;
- len--;
- }
- rshift += 8;
- }
- else {
- scan++;
- len--;
- rshift = 0;
- }
- }
- return mem;
+ size_t i, rshift = 0, len = xmax;
+ while (len > 0) {
+ if (UNLIKELY(mem_eof - mem < 4)) {
+ return NULL;
+ }
+ scan[0][RED] = *mem++;
+ scan[0][GRN] = *mem++;
+ scan[0][BLU] = *mem++;
+ scan[0][EXP] = *mem++;
+ if (scan[0][RED] == 1 && scan[0][GRN] == 1 && scan[0][BLU] == 1) {
+ for (i = scan[0][EXP] << rshift; i > 0; i--) {
+ COPY_RGBE(scan[-1], scan[0]);
+ scan++;
+ len--;
+ }
+ rshift += 8;
+ }
+ else {
+ scan++;
+ len--;
+ rshift = 0;
+ }
+ }
+ return mem;
}
-static const unsigned char *freadcolrs(RGBE *scan, const unsigned char *mem, int xmax, const unsigned char *mem_eof)
+static const unsigned char *freadcolrs(RGBE *scan,
+ const unsigned char *mem,
+ int xmax,
+ const unsigned char *mem_eof)
{
- if (UNLIKELY(mem_eof - mem < 4)) {
- return NULL;
- }
-
- if (UNLIKELY((xmax < MINELEN) | (xmax > MAXELEN))) {
- return oldreadcolrs(scan, mem, xmax, mem_eof);
- }
-
- int val = *mem++;
- if (val != 2) {
- return oldreadcolrs(scan, mem - 1, xmax, mem_eof);
- }
-
- scan[0][GRN] = *mem++;
- scan[0][BLU] = *mem++;
-
- val = *mem++;
-
- if (scan[0][GRN] != 2 || scan[0][BLU] & 128) {
- scan[0][RED] = 2;
- scan[0][EXP] = val;
- return oldreadcolrs(scan + 1, mem, xmax - 1, mem_eof);
- }
-
- if (UNLIKELY(((scan[0][BLU] << 8) | val) != xmax)) {
- return NULL;
- }
-
- for (size_t i = 0; i < 4; i++) {
- if (UNLIKELY(mem_eof - mem < 2)) {
- return NULL;
- }
- for (size_t j = 0; j < xmax; ) {
- int code = *mem++;
- if (code > 128) {
- code &= 127;
- if (UNLIKELY(code + j > xmax)) {
- return NULL;
- }
- val = *mem++;
- while (code--) {
- scan[j++][i] = (unsigned char)val;
- }
- }
- else {
- if (UNLIKELY(mem_eof - mem < code)) {
- return NULL;
- }
- if (UNLIKELY(code + j > xmax)) {
- return NULL;
- }
- while (code--) {
- scan[j++][i] = *mem++;
- }
- }
- }
- }
-
- return mem;
+ if (UNLIKELY(mem_eof - mem < 4)) {
+ return NULL;
+ }
+
+ if (UNLIKELY((xmax < MINELEN) | (xmax > MAXELEN))) {
+ return oldreadcolrs(scan, mem, xmax, mem_eof);
+ }
+
+ int val = *mem++;
+ if (val != 2) {
+ return oldreadcolrs(scan, mem - 1, xmax, mem_eof);
+ }
+
+ scan[0][GRN] = *mem++;
+ scan[0][BLU] = *mem++;
+
+ val = *mem++;
+
+ if (scan[0][GRN] != 2 || scan[0][BLU] & 128) {
+ scan[0][RED] = 2;
+ scan[0][EXP] = val;
+ return oldreadcolrs(scan + 1, mem, xmax - 1, mem_eof);
+ }
+
+ if (UNLIKELY(((scan[0][BLU] << 8) | val) != xmax)) {
+ return NULL;
+ }
+
+ for (size_t i = 0; i < 4; i++) {
+ if (UNLIKELY(mem_eof - mem < 2)) {
+ return NULL;
+ }
+ for (size_t j = 0; j < xmax;) {
+ int code = *mem++;
+ if (code > 128) {
+ code &= 127;
+ if (UNLIKELY(code + j > xmax)) {
+ return NULL;
+ }
+ val = *mem++;
+ while (code--) {
+ scan[j++][i] = (unsigned char)val;
+ }
+ }
+ else {
+ if (UNLIKELY(mem_eof - mem < code)) {
+ return NULL;
+ }
+ if (UNLIKELY(code + j > xmax)) {
+ return NULL;
+ }
+ while (code--) {
+ scan[j++][i] = *mem++;
+ }
+ }
+ }
+ }
+
+ return mem;
}
/* helper functions */
@@ -157,250 +164,270 @@ static const unsigned char *freadcolrs(RGBE *scan, const unsigned char *mem, int
/* rgbe -> float color */
static void RGBE2FLOAT(RGBE rgbe, fCOLOR fcol)
{
- if (rgbe[EXP] == 0) {
- fcol[RED] = fcol[GRN] = fcol[BLU] = 0;
- }
- else {
- float f = ldexp(1.0, rgbe[EXP] - (COLXS + 8));
- fcol[RED] = f * (rgbe[RED] + 0.5f);
- fcol[GRN] = f * (rgbe[GRN] + 0.5f);
- fcol[BLU] = f * (rgbe[BLU] + 0.5f);
- }
+ if (rgbe[EXP] == 0) {
+ fcol[RED] = fcol[GRN] = fcol[BLU] = 0;
+ }
+ else {
+ float f = ldexp(1.0, rgbe[EXP] - (COLXS + 8));
+ fcol[RED] = f * (rgbe[RED] + 0.5f);
+ fcol[GRN] = f * (rgbe[GRN] + 0.5f);
+ fcol[BLU] = f * (rgbe[BLU] + 0.5f);
+ }
}
/* float color -> rgbe */
static void FLOAT2RGBE(fCOLOR fcol, RGBE rgbe)
{
- int e;
- float d = (fcol[RED] > fcol[GRN]) ? fcol[RED] : fcol[GRN];
- if (fcol[BLU] > d) d = fcol[BLU];
- if (d <= 1e-32f)
- rgbe[RED] = rgbe[GRN] = rgbe[BLU] = rgbe[EXP] = 0;
- else {
- d = (float)frexp(d, &e) * 256.0f / d;
- rgbe[RED] = (unsigned char)(fcol[RED] * d);
- rgbe[GRN] = (unsigned char)(fcol[GRN] * d);
- rgbe[BLU] = (unsigned char)(fcol[BLU] * d);
- rgbe[EXP] = (unsigned char)(e + COLXS);
- }
+ int e;
+ float d = (fcol[RED] > fcol[GRN]) ? fcol[RED] : fcol[GRN];
+ if (fcol[BLU] > d)
+ d = fcol[BLU];
+ if (d <= 1e-32f)
+ rgbe[RED] = rgbe[GRN] = rgbe[BLU] = rgbe[EXP] = 0;
+ else {
+ d = (float)frexp(d, &e) * 256.0f / d;
+ rgbe[RED] = (unsigned char)(fcol[RED] * d);
+ rgbe[GRN] = (unsigned char)(fcol[GRN] * d);
+ rgbe[BLU] = (unsigned char)(fcol[BLU] * d);
+ rgbe[EXP] = (unsigned char)(e + COLXS);
+ }
}
/* ImBuf read */
int imb_is_a_hdr(const unsigned char *buf)
{
- /* For recognition, Blender only loads first 32 bytes, so use #?RADIANCE id instead */
- /* update: actually, the 'RADIANCE' part is just an optional program name, the magic word is really only the '#?' part */
- //if (strstr((char *)buf, "#?RADIANCE")) return 1;
- if (strstr((char *)buf, "#?")) return 1;
- // if (strstr((char *)buf, "32-bit_rle_rgbe")) return 1;
- return 0;
+ /* For recognition, Blender only loads first 32 bytes, so use #?RADIANCE id instead */
+ /* update: actually, the 'RADIANCE' part is just an optional program name, the magic word is really only the '#?' part */
+ //if (strstr((char *)buf, "#?RADIANCE")) return 1;
+ if (strstr((char *)buf, "#?"))
+ return 1;
+ // if (strstr((char *)buf, "32-bit_rle_rgbe")) return 1;
+ return 0;
}
-struct ImBuf *imb_loadhdr(const unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE])
+struct ImBuf *imb_loadhdr(const unsigned char *mem,
+ size_t size,
+ int flags,
+ char colorspace[IM_MAX_SPACE])
{
- struct ImBuf *ibuf;
- RGBE *sline;
- fCOLOR fcol;
- float *rect_float;
- int found = 0;
- int width = 0, height = 0;
- const unsigned char *ptr, *mem_eof = mem + size;
- char oriY[80], oriX[80];
-
- if (imb_is_a_hdr((void *)mem)) {
- colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_FLOAT);
-
- /* find empty line, next line is resolution info */
- size_t x;
- for (x = 1; x < size; x++) {
- if ((mem[x - 1] == '\n') && (mem[x] == '\n')) {
- found = 1;
- break;
- }
- }
- if (found && (x < (size + 2))) {
- if (sscanf((char *)&mem[x + 1], "%79s %d %79s %d", (char *)&oriY, &height,
- (char *)&oriX, &width) != 4)
- {
- return NULL;
- }
-
- /* find end of this line, data right behind it */
- ptr = (unsigned char *)strchr((char *)&mem[x + 1], '\n');
- ptr++;
-
- if (flags & IB_test) ibuf = IMB_allocImBuf(width, height, 32, 0);
- else ibuf = IMB_allocImBuf(width, height, 32, (flags & IB_rect) | IB_rectfloat);
-
- if (UNLIKELY(ibuf == NULL)) {
- return NULL;
- }
- ibuf->ftype = IMB_FTYPE_RADHDR;
-
- if (flags & IB_alphamode_detect)
- ibuf->flags |= IB_alphamode_premul;
-
- if (flags & IB_test) {
- return ibuf;
- }
-
- /* read in and decode the actual data */
- sline = (RGBE *)MEM_mallocN(sizeof(*sline) * width, __func__);
- rect_float = ibuf->rect_float;
-
- for (size_t y = 0; y < height; y++) {
- ptr = freadcolrs(sline, ptr, width, mem_eof);
- if (ptr == NULL) {
- printf("WARNING! HDR decode error, image may be just truncated, or completely wrong...\n");
- break;
- }
- for (x = 0; x < width; x++) {
- /* convert to ldr */
- RGBE2FLOAT(sline[x], fcol);
- *rect_float++ = fcol[RED];
- *rect_float++ = fcol[GRN];
- *rect_float++ = fcol[BLU];
- *rect_float++ = 1.0f;
- }
- }
- MEM_freeN(sline);
- if (oriY[0] == '-') IMB_flipy(ibuf);
-
- if (flags & IB_rect) {
- IMB_rect_from_float(ibuf);
- }
-
- return ibuf;
- }
- //else printf("Data not found!\n");
- }
- //else printf("Not a valid radiance HDR file!\n");
-
- return NULL;
+ struct ImBuf *ibuf;
+ RGBE *sline;
+ fCOLOR fcol;
+ float *rect_float;
+ int found = 0;
+ int width = 0, height = 0;
+ const unsigned char *ptr, *mem_eof = mem + size;
+ char oriY[80], oriX[80];
+
+ if (imb_is_a_hdr((void *)mem)) {
+ colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_FLOAT);
+
+ /* find empty line, next line is resolution info */
+ size_t x;
+ for (x = 1; x < size; x++) {
+ if ((mem[x - 1] == '\n') && (mem[x] == '\n')) {
+ found = 1;
+ break;
+ }
+ }
+ if (found && (x < (size + 2))) {
+ if (sscanf((char *)&mem[x + 1],
+ "%79s %d %79s %d",
+ (char *)&oriY,
+ &height,
+ (char *)&oriX,
+ &width) != 4) {
+ return NULL;
+ }
+
+ /* find end of this line, data right behind it */
+ ptr = (unsigned char *)strchr((char *)&mem[x + 1], '\n');
+ ptr++;
+
+ if (flags & IB_test)
+ ibuf = IMB_allocImBuf(width, height, 32, 0);
+ else
+ ibuf = IMB_allocImBuf(width, height, 32, (flags & IB_rect) | IB_rectfloat);
+
+ if (UNLIKELY(ibuf == NULL)) {
+ return NULL;
+ }
+ ibuf->ftype = IMB_FTYPE_RADHDR;
+
+ if (flags & IB_alphamode_detect)
+ ibuf->flags |= IB_alphamode_premul;
+
+ if (flags & IB_test) {
+ return ibuf;
+ }
+
+ /* read in and decode the actual data */
+ sline = (RGBE *)MEM_mallocN(sizeof(*sline) * width, __func__);
+ rect_float = ibuf->rect_float;
+
+ for (size_t y = 0; y < height; y++) {
+ ptr = freadcolrs(sline, ptr, width, mem_eof);
+ if (ptr == NULL) {
+ printf(
+ "WARNING! HDR decode error, image may be just truncated, or completely wrong...\n");
+ break;
+ }
+ for (x = 0; x < width; x++) {
+ /* convert to ldr */
+ RGBE2FLOAT(sline[x], fcol);
+ *rect_float++ = fcol[RED];
+ *rect_float++ = fcol[GRN];
+ *rect_float++ = fcol[BLU];
+ *rect_float++ = 1.0f;
+ }
+ }
+ MEM_freeN(sline);
+ if (oriY[0] == '-')
+ IMB_flipy(ibuf);
+
+ if (flags & IB_rect) {
+ IMB_rect_from_float(ibuf);
+ }
+
+ return ibuf;
+ }
+ //else printf("Data not found!\n");
+ }
+ //else printf("Not a valid radiance HDR file!\n");
+
+ return NULL;
}
/* ImBuf write */
static int fwritecolrs(FILE *file, int width, int channels, unsigned char *ibufscan, float *fpscan)
{
- int beg, c2, cnt = 0;
- fCOLOR fcol;
- RGBE rgbe, *rgbe_scan;
-
- if (UNLIKELY((ibufscan == NULL) && (fpscan == NULL))) {
- return 0;
- }
-
- rgbe_scan = (RGBE *)MEM_mallocN(sizeof(RGBE) * width, "radhdr_write_tmpscan");
-
- /* convert scanline */
- for (size_t i = 0, j = 0; i < width; i++) {
- if (fpscan) {
- fcol[RED] = fpscan[j];
- fcol[GRN] = (channels >= 2) ? fpscan[j + 1] : fpscan[j];
- fcol[BLU] = (channels >= 3) ? fpscan[j + 2] : fpscan[j];
- }
- else {
- fcol[RED] = (float)ibufscan[j] / 255.f;
- fcol[GRN] = (float)((channels >= 2) ? ibufscan[j + 1] : ibufscan[j]) / 255.f;
- fcol[BLU] = (float)((channels >= 3) ? ibufscan[j + 2] : ibufscan[j]) / 255.f;
- }
- FLOAT2RGBE(fcol, rgbe);
- COPY_RGBE(rgbe, rgbe_scan[i]);
- j += channels;
- }
-
- if ((width < MINELEN) | (width > MAXELEN)) { /* OOBs, write out flat */
- int x = fwrite((char *)rgbe_scan, sizeof(RGBE), width, file) - width;
- MEM_freeN(rgbe_scan);
- return x;
- }
- /* put magic header */
- putc(2, file);
- putc(2, file);
- putc((unsigned char)(width >> 8), file);
- putc((unsigned char)(width & 255), file);
- /* put components separately */
- for (size_t i = 0; i < 4; i++) {
- for (size_t j = 0; j < width; j += cnt) { /* find next run */
- for (beg = j; beg < width; beg += cnt) {
- for (cnt = 1; (cnt < 127) && ((beg + cnt) < width) && (rgbe_scan[beg + cnt][i] == rgbe_scan[beg][i]); cnt++) ;
- if (cnt >= MINRUN) break; /* long enough */
- }
- if (((beg - j) > 1) && ((beg - j) < MINRUN)) {
- c2 = j + 1;
- while (rgbe_scan[c2++][i] == rgbe_scan[j][i]) {
- if (c2 == beg) { /* short run */
- putc((unsigned char)(128 + beg - j), file);
- putc((unsigned char)(rgbe_scan[j][i]), file);
- j = beg;
- break;
- }
- }
- }
- while (j < beg) { /* write out non-run */
- if ((c2 = beg - j) > 128) c2 = 128;
- putc((unsigned char)(c2), file);
- while (c2--) putc(rgbe_scan[j++][i], file);
- }
- if (cnt >= MINRUN) { /* write out run */
- putc((unsigned char)(128 + cnt), file);
- putc(rgbe_scan[beg][i], file);
- }
- else {
- cnt = 0;
- }
- }
- }
- MEM_freeN(rgbe_scan);
- return(ferror(file) ? -1 : 0);
+ int beg, c2, cnt = 0;
+ fCOLOR fcol;
+ RGBE rgbe, *rgbe_scan;
+
+ if (UNLIKELY((ibufscan == NULL) && (fpscan == NULL))) {
+ return 0;
+ }
+
+ rgbe_scan = (RGBE *)MEM_mallocN(sizeof(RGBE) * width, "radhdr_write_tmpscan");
+
+ /* convert scanline */
+ for (size_t i = 0, j = 0; i < width; i++) {
+ if (fpscan) {
+ fcol[RED] = fpscan[j];
+ fcol[GRN] = (channels >= 2) ? fpscan[j + 1] : fpscan[j];
+ fcol[BLU] = (channels >= 3) ? fpscan[j + 2] : fpscan[j];
+ }
+ else {
+ fcol[RED] = (float)ibufscan[j] / 255.f;
+ fcol[GRN] = (float)((channels >= 2) ? ibufscan[j + 1] : ibufscan[j]) / 255.f;
+ fcol[BLU] = (float)((channels >= 3) ? ibufscan[j + 2] : ibufscan[j]) / 255.f;
+ }
+ FLOAT2RGBE(fcol, rgbe);
+ COPY_RGBE(rgbe, rgbe_scan[i]);
+ j += channels;
+ }
+
+ if ((width < MINELEN) | (width > MAXELEN)) { /* OOBs, write out flat */
+ int x = fwrite((char *)rgbe_scan, sizeof(RGBE), width, file) - width;
+ MEM_freeN(rgbe_scan);
+ return x;
+ }
+ /* put magic header */
+ putc(2, file);
+ putc(2, file);
+ putc((unsigned char)(width >> 8), file);
+ putc((unsigned char)(width & 255), file);
+ /* put components separately */
+ for (size_t i = 0; i < 4; i++) {
+ for (size_t j = 0; j < width; j += cnt) { /* find next run */
+ for (beg = j; beg < width; beg += cnt) {
+ for (cnt = 1; (cnt < 127) && ((beg + cnt) < width) &&
+ (rgbe_scan[beg + cnt][i] == rgbe_scan[beg][i]);
+ cnt++)
+ ;
+ if (cnt >= MINRUN)
+ break; /* long enough */
+ }
+ if (((beg - j) > 1) && ((beg - j) < MINRUN)) {
+ c2 = j + 1;
+ while (rgbe_scan[c2++][i] == rgbe_scan[j][i]) {
+ if (c2 == beg) { /* short run */
+ putc((unsigned char)(128 + beg - j), file);
+ putc((unsigned char)(rgbe_scan[j][i]), file);
+ j = beg;
+ break;
+ }
+ }
+ }
+ while (j < beg) { /* write out non-run */
+ if ((c2 = beg - j) > 128)
+ c2 = 128;
+ putc((unsigned char)(c2), file);
+ while (c2--)
+ putc(rgbe_scan[j++][i], file);
+ }
+ if (cnt >= MINRUN) { /* write out run */
+ putc((unsigned char)(128 + cnt), file);
+ putc(rgbe_scan[beg][i], file);
+ }
+ else {
+ cnt = 0;
+ }
+ }
+ }
+ MEM_freeN(rgbe_scan);
+ return (ferror(file) ? -1 : 0);
}
static void writeHeader(FILE *file, int width, int height)
{
- fprintf(file, "#?RADIANCE");
- fputc(10, file);
- fprintf(file, "# %s", "Created with Blender");
- fputc(10, file);
- fprintf(file, "EXPOSURE=%25.13f", 1.0);
- fputc(10, file);
- fprintf(file, "FORMAT=32-bit_rle_rgbe");
- fputc(10, file);
- fputc(10, file);
- fprintf(file, "-Y %d +X %d", height, width);
- fputc(10, file);
+ fprintf(file, "#?RADIANCE");
+ fputc(10, file);
+ fprintf(file, "# %s", "Created with Blender");
+ fputc(10, file);
+ fprintf(file, "EXPOSURE=%25.13f", 1.0);
+ fputc(10, file);
+ fprintf(file, "FORMAT=32-bit_rle_rgbe");
+ fputc(10, file);
+ fputc(10, file);
+ fprintf(file, "-Y %d +X %d", height, width);
+ fputc(10, file);
}
int imb_savehdr(struct ImBuf *ibuf, const char *name, int flags)
{
- FILE *file = BLI_fopen(name, "wb");
- float *fp = NULL;
- size_t width = ibuf->x, height = ibuf->y;
- unsigned char *cp = NULL;
-
- (void)flags; /* unused */
-
- if (file == NULL) {
- return 0;
- }
-
- writeHeader(file, width, height);
-
- if (ibuf->rect)
- cp = (unsigned char *)ibuf->rect + ibuf->channels * (height - 1) * width;
- if (ibuf->rect_float)
- fp = ibuf->rect_float + ibuf->channels * (height - 1) * width;
-
- for (size_t y = 0; y < height; y++) {
- if (fwritecolrs(file, width, ibuf->channels, cp, fp) < 0) {
- fclose(file);
- printf("HDR write error\n");
- return 0;
- }
- if (cp) cp -= ibuf->channels * width;
- if (fp) fp -= ibuf->channels * width;
- }
-
- fclose(file);
- return 1;
+ FILE *file = BLI_fopen(name, "wb");
+ float *fp = NULL;
+ size_t width = ibuf->x, height = ibuf->y;
+ unsigned char *cp = NULL;
+
+ (void)flags; /* unused */
+
+ if (file == NULL) {
+ return 0;
+ }
+
+ writeHeader(file, width, height);
+
+ if (ibuf->rect)
+ cp = (unsigned char *)ibuf->rect + ibuf->channels * (height - 1) * width;
+ if (ibuf->rect_float)
+ fp = ibuf->rect_float + ibuf->channels * (height - 1) * width;
+
+ for (size_t y = 0; y < height; y++) {
+ if (fwritecolrs(file, width, ibuf->channels, cp, fp) < 0) {
+ fclose(file);
+ printf("HDR write error\n");
+ return 0;
+ }
+ if (cp)
+ cp -= ibuf->channels * width;
+ if (fp)
+ fp -= ibuf->channels * width;
+ }
+
+ fclose(file);
+ return 1;
}
diff --git a/source/blender/imbuf/intern/readimage.c b/source/blender/imbuf/intern/readimage.c
index ad4e07030d1..34bae007979 100644
--- a/source/blender/imbuf/intern/readimage.c
+++ b/source/blender/imbuf/intern/readimage.c
@@ -22,7 +22,6 @@
* \ingroup imbuf
*/
-
#ifdef _WIN32
# include <io.h>
# include <stddef.h>
@@ -45,256 +44,267 @@
#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])
+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 != NULL && ibuf->rect_float == NULL) {
- /* 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);
+ int alpha_flags;
+
+ if (colorspace) {
+ if (ibuf->rect != NULL && ibuf->rect_float == NULL) {
+ /* 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(
- const unsigned char *mem, size_t size, int flags,
- char colorspace[IM_MAX_SPACE], const char *descr)
+ImBuf *IMB_ibImageFromMemory(const unsigned char *mem,
+ size_t size,
+ int flags,
+ char colorspace[IM_MAX_SPACE],
+ const char *descr)
{
- ImBuf *ibuf;
- const ImFileType *type;
- char effective_colorspace[IM_MAX_SPACE] = "";
-
- if (mem == NULL) {
- fprintf(stderr, "%s: NULL pointer\n", __func__);
- return NULL;
- }
-
- if (colorspace)
- BLI_strncpy(effective_colorspace, colorspace, sizeof(effective_colorspace));
-
- for (type = IMB_FILE_TYPES; type < IMB_FILE_TYPES_LAST; type++) {
- if (type->load) {
- ibuf = type->load(mem, size, flags, effective_colorspace);
- if (ibuf) {
- 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;
+ ImBuf *ibuf;
+ const ImFileType *type;
+ char effective_colorspace[IM_MAX_SPACE] = "";
+
+ if (mem == NULL) {
+ fprintf(stderr, "%s: NULL pointer\n", __func__);
+ return NULL;
+ }
+
+ if (colorspace)
+ BLI_strncpy(effective_colorspace, colorspace, sizeof(effective_colorspace));
+
+ for (type = IMB_FILE_TYPES; type < IMB_FILE_TYPES_LAST; type++) {
+ if (type->load) {
+ ibuf = type->load(mem, size, flags, effective_colorspace);
+ if (ibuf) {
+ 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)
+static ImBuf *IMB_ibImageFromFile(const char *filepath,
+ int flags,
+ char colorspace[IM_MAX_SPACE],
+ const char *descr)
{
- ImBuf *ibuf;
- const 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;
- }
- }
- }
-
- if ((flags & IB_test) == 0)
- fprintf(stderr, "%s: unknown fileformat (%s)\n", __func__, descr);
-
- return NULL;
+ ImBuf *ibuf;
+ const 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;
+ }
+ }
+ }
+
+ if ((flags & IB_test) == 0)
+ fprintf(stderr, "%s: unknown fileformat (%s)\n", __func__, descr);
+
+ return NULL;
}
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_path_extension_check_array(filepath, imb_ext_image_filepath_only);
+ /* return true if this is one of the formats that can't be loaded from memory */
+ return BLI_path_extension_check_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 *IMB_loadifffile(
+ int file, const char *filepath, int flags, char colorspace[IM_MAX_SPACE], const char *descr)
{
- ImBuf *ibuf;
- unsigned char *mem;
- size_t size;
+ ImBuf *ibuf;
+ unsigned char *mem;
+ size_t size;
- if (file == -1) return NULL;
+ if (file == -1)
+ return NULL;
- if (imb_is_filepath_format(filepath))
- return IMB_ibImageFromFile(filepath, flags, colorspace, descr);
+ if (imb_is_filepath_format(filepath))
+ return IMB_ibImageFromFile(filepath, flags, colorspace, descr);
- size = BLI_file_descriptor_size(file);
+ size = BLI_file_descriptor_size(file);
- imb_mmap_lock();
- mem = mmap(NULL, size, PROT_READ, MAP_SHARED, file, 0);
- imb_mmap_unlock();
+ imb_mmap_lock();
+ mem = mmap(NULL, size, PROT_READ, MAP_SHARED, file, 0);
+ imb_mmap_unlock();
- if (mem == (unsigned char *) -1) {
- fprintf(stderr, "%s: couldn't get mapping %s\n", __func__, descr);
- return NULL;
- }
+ if (mem == (unsigned char *)-1) {
+ fprintf(stderr, "%s: couldn't get mapping %s\n", __func__, descr);
+ return NULL;
+ }
- ibuf = IMB_ibImageFromMemory(mem, size, flags, colorspace, descr);
+ ibuf = IMB_ibImageFromMemory(mem, size, flags, colorspace, descr);
- imb_mmap_lock();
- if (munmap(mem, size))
- fprintf(stderr, "%s: couldn't unmap file %s\n", __func__, descr);
- imb_mmap_unlock();
+ imb_mmap_lock();
+ if (munmap(mem, size))
+ fprintf(stderr, "%s: couldn't unmap file %s\n", __func__, descr);
+ imb_mmap_unlock();
- return ibuf;
+ return ibuf;
}
static void imb_cache_filename(char *filename, const char *name, int flags)
{
- /* read .tx instead if it exists and is not older */
- if (flags & IB_tilecache) {
- BLI_strncpy(filename, name, IMB_FILENAME_SIZE);
- if (!BLI_path_extension_replace(filename, IMB_FILENAME_SIZE, ".tx"))
- return;
+ /* read .tx instead if it exists and is not older */
+ if (flags & IB_tilecache) {
+ BLI_strncpy(filename, name, IMB_FILENAME_SIZE);
+ if (!BLI_path_extension_replace(filename, IMB_FILENAME_SIZE, ".tx"))
+ return;
- if (BLI_file_older(name, filename))
- return;
- }
+ if (BLI_file_older(name, filename))
+ return;
+ }
- BLI_strncpy(filename, name, IMB_FILENAME_SIZE);
+ BLI_strncpy(filename, name, IMB_FILENAME_SIZE);
}
ImBuf *IMB_loadiffname(const char *filepath, int flags, char colorspace[IM_MAX_SPACE])
{
- ImBuf *ibuf;
- int file, a;
- char filepath_tx[IMB_FILENAME_SIZE];
+ ImBuf *ibuf;
+ int file, a;
+ char filepath_tx[IMB_FILENAME_SIZE];
- BLI_assert(!BLI_path_is_rel(filepath));
+ BLI_assert(!BLI_path_is_rel(filepath));
- imb_cache_filename(filepath_tx, filepath, flags);
+ imb_cache_filename(filepath_tx, filepath, flags);
- file = BLI_open(filepath_tx, O_BINARY | O_RDONLY, 0);
- if (file == -1)
- return NULL;
+ file = BLI_open(filepath_tx, O_BINARY | O_RDONLY, 0);
+ if (file == -1)
+ return NULL;
- ibuf = IMB_loadifffile(file, filepath, flags, colorspace, filepath_tx);
+ ibuf = IMB_loadifffile(file, filepath, flags, colorspace, filepath_tx);
- if (ibuf) {
- BLI_strncpy(ibuf->name, filepath, sizeof(ibuf->name));
- BLI_strncpy(ibuf->cachename, filepath_tx, sizeof(ibuf->cachename));
- for (a = 1; a < ibuf->miptot; a++)
- BLI_strncpy(ibuf->mipmap[a - 1]->cachename, filepath_tx, sizeof(ibuf->cachename));
- }
+ if (ibuf) {
+ BLI_strncpy(ibuf->name, filepath, sizeof(ibuf->name));
+ BLI_strncpy(ibuf->cachename, filepath_tx, sizeof(ibuf->cachename));
+ for (a = 1; a < ibuf->miptot; a++)
+ BLI_strncpy(ibuf->mipmap[a - 1]->cachename, filepath_tx, sizeof(ibuf->cachename));
+ }
- close(file);
+ close(file);
- return ibuf;
+ return ibuf;
}
ImBuf *IMB_testiffname(const char *filepath, int flags)
{
- ImBuf *ibuf;
- int file;
- char filepath_tx[IMB_FILENAME_SIZE];
- char colorspace[IM_MAX_SPACE] = "\0";
+ ImBuf *ibuf;
+ int file;
+ char filepath_tx[IMB_FILENAME_SIZE];
+ char colorspace[IM_MAX_SPACE] = "\0";
- BLI_assert(!BLI_path_is_rel(filepath));
+ BLI_assert(!BLI_path_is_rel(filepath));
- imb_cache_filename(filepath_tx, filepath, flags);
+ imb_cache_filename(filepath_tx, filepath, flags);
- file = BLI_open(filepath_tx, O_BINARY | O_RDONLY, 0);
- if (file == -1)
- return NULL;
+ file = BLI_open(filepath_tx, O_BINARY | O_RDONLY, 0);
+ if (file == -1)
+ return NULL;
- ibuf = IMB_loadifffile(file, filepath, 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));
- BLI_strncpy(ibuf->cachename, filepath_tx, sizeof(ibuf->cachename));
- }
+ if (ibuf) {
+ BLI_strncpy(ibuf->name, filepath, sizeof(ibuf->name));
+ BLI_strncpy(ibuf->cachename, filepath_tx, sizeof(ibuf->cachename));
+ }
- close(file);
+ close(file);
- return ibuf;
+ return ibuf;
}
static void imb_loadtilefile(ImBuf *ibuf, int file, int tx, int ty, unsigned int *rect)
{
- const ImFileType *type;
- unsigned char *mem;
- size_t size;
+ const ImFileType *type;
+ unsigned char *mem;
+ size_t size;
- if (file == -1) return;
+ if (file == -1)
+ return;
- size = BLI_file_descriptor_size(file);
+ size = BLI_file_descriptor_size(file);
- imb_mmap_lock();
- mem = mmap(NULL, size, PROT_READ, MAP_SHARED, file, 0);
- imb_mmap_unlock();
+ imb_mmap_lock();
+ mem = mmap(NULL, size, PROT_READ, MAP_SHARED, file, 0);
+ imb_mmap_unlock();
- if (mem == (unsigned char *) -1) {
- fprintf(stderr, "Couldn't get memory mapping for %s\n", ibuf->cachename);
- return;
- }
+ if (mem == (unsigned char *)-1) {
+ fprintf(stderr, "Couldn't get memory mapping for %s\n", ibuf->cachename);
+ return;
+ }
- 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);
+ 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);
- imb_mmap_lock();
- if (munmap(mem, size))
- fprintf(stderr, "Couldn't unmap memory for %s.\n", ibuf->cachename);
- imb_mmap_unlock();
+ imb_mmap_lock();
+ if (munmap(mem, size))
+ fprintf(stderr, "Couldn't unmap memory for %s.\n", ibuf->cachename);
+ imb_mmap_unlock();
}
void imb_loadtile(ImBuf *ibuf, int tx, int ty, unsigned int *rect)
{
- int file;
+ int file;
- file = BLI_open(ibuf->cachename, O_BINARY | O_RDONLY, 0);
- if (file == -1)
- return;
+ file = BLI_open(ibuf->cachename, O_BINARY | O_RDONLY, 0);
+ if (file == -1)
+ return;
- imb_loadtilefile(ibuf, file, tx, ty, rect);
+ imb_loadtilefile(ibuf, file, tx, ty, rect);
- close(file);
+ close(file);
}
diff --git a/source/blender/imbuf/intern/rectop.c b/source/blender/imbuf/intern/rectop.c
index ef869e35a36..a069e79b337 100644
--- a/source/blender/imbuf/intern/rectop.c
+++ b/source/blender/imbuf/intern/rectop.c
@@ -35,890 +35,1059 @@
#include "IMB_colormanagement.h"
-void IMB_blend_color_byte(unsigned char dst[4], unsigned char src1[4], unsigned char src2[4], IMB_BlendMode mode)
+void IMB_blend_color_byte(unsigned char dst[4],
+ unsigned char src1[4],
+ unsigned char src2[4],
+ IMB_BlendMode mode)
{
- switch (mode) {
- case IMB_BLEND_MIX:
- blend_color_mix_byte(dst, src1, src2); break;
- case IMB_BLEND_ADD:
- blend_color_add_byte(dst, src1, src2); break;
- case IMB_BLEND_SUB:
- blend_color_sub_byte(dst, src1, src2); break;
- case IMB_BLEND_MUL:
- blend_color_mul_byte(dst, src1, src2); break;
- case IMB_BLEND_LIGHTEN:
- blend_color_lighten_byte(dst, src1, src2); break;
- case IMB_BLEND_DARKEN:
- blend_color_darken_byte(dst, src1, src2); break;
- case IMB_BLEND_ERASE_ALPHA:
- blend_color_erase_alpha_byte(dst, src1, src2); break;
- case IMB_BLEND_ADD_ALPHA:
- blend_color_add_alpha_byte(dst, src1, src2); break;
- case IMB_BLEND_OVERLAY:
- blend_color_overlay_byte(dst, src1, src2); break;
- case IMB_BLEND_HARDLIGHT:
- blend_color_hardlight_byte(dst, src1, src2); break;
- case IMB_BLEND_COLORBURN:
- blend_color_burn_byte(dst, src1, src2); break;
- case IMB_BLEND_LINEARBURN:
- blend_color_linearburn_byte(dst, src1, src2); break;
- case IMB_BLEND_COLORDODGE:
- blend_color_dodge_byte(dst, src1, src2); break;
- case IMB_BLEND_SCREEN:
- blend_color_screen_byte(dst, src1, src2); break;
- case IMB_BLEND_SOFTLIGHT:
- blend_color_softlight_byte(dst, src1, src2); break;
- case IMB_BLEND_PINLIGHT:
- blend_color_pinlight_byte(dst, src1, src2); break;
- case IMB_BLEND_LINEARLIGHT:
- blend_color_linearlight_byte(dst, src1, src2); break;
- case IMB_BLEND_VIVIDLIGHT:
- blend_color_vividlight_byte(dst, src1, src2); break;
- case IMB_BLEND_DIFFERENCE:
- blend_color_difference_byte(dst, src1, src2); break;
- case IMB_BLEND_EXCLUSION:
- blend_color_exclusion_byte(dst, src1, src2); break;
- case IMB_BLEND_COLOR:
- blend_color_color_byte(dst, src1, src2); break;
- case IMB_BLEND_HUE:
- blend_color_hue_byte(dst, src1, src2); break;
- case IMB_BLEND_SATURATION:
- blend_color_saturation_byte(dst, src1, src2); break;
- case IMB_BLEND_LUMINOSITY:
- blend_color_luminosity_byte(dst, src1, src2); break;
-
- default:
- dst[0] = src1[0];
- dst[1] = src1[1];
- dst[2] = src1[2];
- dst[3] = src1[3];
- break;
- }
+ switch (mode) {
+ case IMB_BLEND_MIX:
+ blend_color_mix_byte(dst, src1, src2);
+ break;
+ case IMB_BLEND_ADD:
+ blend_color_add_byte(dst, src1, src2);
+ break;
+ case IMB_BLEND_SUB:
+ blend_color_sub_byte(dst, src1, src2);
+ break;
+ case IMB_BLEND_MUL:
+ blend_color_mul_byte(dst, src1, src2);
+ break;
+ case IMB_BLEND_LIGHTEN:
+ blend_color_lighten_byte(dst, src1, src2);
+ break;
+ case IMB_BLEND_DARKEN:
+ blend_color_darken_byte(dst, src1, src2);
+ break;
+ case IMB_BLEND_ERASE_ALPHA:
+ blend_color_erase_alpha_byte(dst, src1, src2);
+ break;
+ case IMB_BLEND_ADD_ALPHA:
+ blend_color_add_alpha_byte(dst, src1, src2);
+ break;
+ case IMB_BLEND_OVERLAY:
+ blend_color_overlay_byte(dst, src1, src2);
+ break;
+ case IMB_BLEND_HARDLIGHT:
+ blend_color_hardlight_byte(dst, src1, src2);
+ break;
+ case IMB_BLEND_COLORBURN:
+ blend_color_burn_byte(dst, src1, src2);
+ break;
+ case IMB_BLEND_LINEARBURN:
+ blend_color_linearburn_byte(dst, src1, src2);
+ break;
+ case IMB_BLEND_COLORDODGE:
+ blend_color_dodge_byte(dst, src1, src2);
+ break;
+ case IMB_BLEND_SCREEN:
+ blend_color_screen_byte(dst, src1, src2);
+ break;
+ case IMB_BLEND_SOFTLIGHT:
+ blend_color_softlight_byte(dst, src1, src2);
+ break;
+ case IMB_BLEND_PINLIGHT:
+ blend_color_pinlight_byte(dst, src1, src2);
+ break;
+ case IMB_BLEND_LINEARLIGHT:
+ blend_color_linearlight_byte(dst, src1, src2);
+ break;
+ case IMB_BLEND_VIVIDLIGHT:
+ blend_color_vividlight_byte(dst, src1, src2);
+ break;
+ case IMB_BLEND_DIFFERENCE:
+ blend_color_difference_byte(dst, src1, src2);
+ break;
+ case IMB_BLEND_EXCLUSION:
+ blend_color_exclusion_byte(dst, src1, src2);
+ break;
+ case IMB_BLEND_COLOR:
+ blend_color_color_byte(dst, src1, src2);
+ break;
+ case IMB_BLEND_HUE:
+ blend_color_hue_byte(dst, src1, src2);
+ break;
+ case IMB_BLEND_SATURATION:
+ blend_color_saturation_byte(dst, src1, src2);
+ break;
+ case IMB_BLEND_LUMINOSITY:
+ blend_color_luminosity_byte(dst, src1, src2);
+ break;
+
+ default:
+ dst[0] = src1[0];
+ dst[1] = src1[1];
+ dst[2] = src1[2];
+ dst[3] = src1[3];
+ break;
+ }
}
void IMB_blend_color_float(float dst[4], float src1[4], float src2[4], IMB_BlendMode mode)
{
- switch (mode) {
- case IMB_BLEND_MIX:
- blend_color_mix_float(dst, src1, src2); break;
- case IMB_BLEND_ADD:
- blend_color_add_float(dst, src1, src2); break;
- case IMB_BLEND_SUB:
- blend_color_sub_float(dst, src1, src2); break;
- case IMB_BLEND_MUL:
- blend_color_mul_float(dst, src1, src2); break;
- case IMB_BLEND_LIGHTEN:
- blend_color_lighten_float(dst, src1, src2); break;
- case IMB_BLEND_DARKEN:
- blend_color_darken_float(dst, src1, src2); break;
- case IMB_BLEND_ERASE_ALPHA:
- blend_color_erase_alpha_float(dst, src1, src2); break;
- case IMB_BLEND_ADD_ALPHA:
- blend_color_add_alpha_float(dst, src1, src2); break;
- case IMB_BLEND_OVERLAY:
- blend_color_overlay_float(dst, src1, src2); break;
- case IMB_BLEND_HARDLIGHT:
- blend_color_hardlight_float(dst, src1, src2); break;
- case IMB_BLEND_COLORBURN:
- blend_color_burn_float(dst, src1, src2); break;
- case IMB_BLEND_LINEARBURN:
- blend_color_linearburn_float(dst, src1, src2); break;
- case IMB_BLEND_COLORDODGE:
- blend_color_dodge_float(dst, src1, src2); break;
- case IMB_BLEND_SCREEN:
- blend_color_screen_float(dst, src1, src2); break;
- case IMB_BLEND_SOFTLIGHT:
- blend_color_softlight_float(dst, src1, src2); break;
- case IMB_BLEND_PINLIGHT:
- blend_color_pinlight_float(dst, src1, src2); break;
- case IMB_BLEND_LINEARLIGHT:
- blend_color_linearlight_float(dst, src1, src2); break;
- case IMB_BLEND_VIVIDLIGHT:
- blend_color_vividlight_float(dst, src1, src2); break;
- case IMB_BLEND_DIFFERENCE:
- blend_color_difference_float(dst, src1, src2); break;
- case IMB_BLEND_EXCLUSION:
- blend_color_exclusion_float(dst, src1, src2); break;
- case IMB_BLEND_COLOR:
- blend_color_color_float(dst, src1, src2); break;
- case IMB_BLEND_HUE:
- blend_color_hue_float(dst, src1, src2); break;
- case IMB_BLEND_SATURATION:
- blend_color_saturation_float(dst, src1, src2); break;
- case IMB_BLEND_LUMINOSITY:
- blend_color_luminosity_float(dst, src1, src2); break;
- default:
- dst[0] = src1[0];
- dst[1] = src1[1];
- dst[2] = src1[2];
- dst[3] = src1[3];
- break;
- }
+ switch (mode) {
+ case IMB_BLEND_MIX:
+ blend_color_mix_float(dst, src1, src2);
+ break;
+ case IMB_BLEND_ADD:
+ blend_color_add_float(dst, src1, src2);
+ break;
+ case IMB_BLEND_SUB:
+ blend_color_sub_float(dst, src1, src2);
+ break;
+ case IMB_BLEND_MUL:
+ blend_color_mul_float(dst, src1, src2);
+ break;
+ case IMB_BLEND_LIGHTEN:
+ blend_color_lighten_float(dst, src1, src2);
+ break;
+ case IMB_BLEND_DARKEN:
+ blend_color_darken_float(dst, src1, src2);
+ break;
+ case IMB_BLEND_ERASE_ALPHA:
+ blend_color_erase_alpha_float(dst, src1, src2);
+ break;
+ case IMB_BLEND_ADD_ALPHA:
+ blend_color_add_alpha_float(dst, src1, src2);
+ break;
+ case IMB_BLEND_OVERLAY:
+ blend_color_overlay_float(dst, src1, src2);
+ break;
+ case IMB_BLEND_HARDLIGHT:
+ blend_color_hardlight_float(dst, src1, src2);
+ break;
+ case IMB_BLEND_COLORBURN:
+ blend_color_burn_float(dst, src1, src2);
+ break;
+ case IMB_BLEND_LINEARBURN:
+ blend_color_linearburn_float(dst, src1, src2);
+ break;
+ case IMB_BLEND_COLORDODGE:
+ blend_color_dodge_float(dst, src1, src2);
+ break;
+ case IMB_BLEND_SCREEN:
+ blend_color_screen_float(dst, src1, src2);
+ break;
+ case IMB_BLEND_SOFTLIGHT:
+ blend_color_softlight_float(dst, src1, src2);
+ break;
+ case IMB_BLEND_PINLIGHT:
+ blend_color_pinlight_float(dst, src1, src2);
+ break;
+ case IMB_BLEND_LINEARLIGHT:
+ blend_color_linearlight_float(dst, src1, src2);
+ break;
+ case IMB_BLEND_VIVIDLIGHT:
+ blend_color_vividlight_float(dst, src1, src2);
+ break;
+ case IMB_BLEND_DIFFERENCE:
+ blend_color_difference_float(dst, src1, src2);
+ break;
+ case IMB_BLEND_EXCLUSION:
+ blend_color_exclusion_float(dst, src1, src2);
+ break;
+ case IMB_BLEND_COLOR:
+ blend_color_color_float(dst, src1, src2);
+ break;
+ case IMB_BLEND_HUE:
+ blend_color_hue_float(dst, src1, src2);
+ break;
+ case IMB_BLEND_SATURATION:
+ blend_color_saturation_float(dst, src1, src2);
+ break;
+ case IMB_BLEND_LUMINOSITY:
+ blend_color_luminosity_float(dst, src1, src2);
+ break;
+ default:
+ dst[0] = src1[0];
+ dst[1] = src1[1];
+ dst[2] = src1[2];
+ dst[3] = src1[3];
+ break;
+ }
}
/* clipping */
-void IMB_rectclip(ImBuf *dbuf, ImBuf *sbuf, int *destx,
- int *desty, int *srcx, int *srcy, int *width, int *height)
+void IMB_rectclip(ImBuf *dbuf,
+ ImBuf *sbuf,
+ int *destx,
+ int *desty,
+ int *srcx,
+ int *srcy,
+ int *width,
+ int *height)
{
- int tmp;
-
- if (dbuf == NULL) return;
-
- if (*destx < 0) {
- *srcx -= *destx;
- *width += *destx;
- *destx = 0;
- }
- if (*srcx < 0) {
- *destx -= *srcx;
- *width += *srcx;
- *srcx = 0;
- }
- if (*desty < 0) {
- *srcy -= *desty;
- *height += *desty;
- *desty = 0;
- }
- if (*srcy < 0) {
- *desty -= *srcy;
- *height += *srcy;
- *srcy = 0;
- }
-
- tmp = dbuf->x - *destx;
- if (*width > tmp) *width = tmp;
- tmp = dbuf->y - *desty;
- if (*height > tmp) *height = tmp;
-
- if (sbuf) {
- tmp = sbuf->x - *srcx;
- if (*width > tmp) *width = tmp;
- tmp = sbuf->y - *srcy;
- if (*height > tmp) *height = tmp;
- }
-
- if ((*height <= 0) || (*width <= 0)) {
- *width = 0;
- *height = 0;
- }
+ int tmp;
+
+ if (dbuf == NULL)
+ return;
+
+ if (*destx < 0) {
+ *srcx -= *destx;
+ *width += *destx;
+ *destx = 0;
+ }
+ if (*srcx < 0) {
+ *destx -= *srcx;
+ *width += *srcx;
+ *srcx = 0;
+ }
+ if (*desty < 0) {
+ *srcy -= *desty;
+ *height += *desty;
+ *desty = 0;
+ }
+ if (*srcy < 0) {
+ *desty -= *srcy;
+ *height += *srcy;
+ *srcy = 0;
+ }
+
+ tmp = dbuf->x - *destx;
+ if (*width > tmp)
+ *width = tmp;
+ tmp = dbuf->y - *desty;
+ if (*height > tmp)
+ *height = tmp;
+
+ if (sbuf) {
+ tmp = sbuf->x - *srcx;
+ if (*width > tmp)
+ *width = tmp;
+ tmp = sbuf->y - *srcy;
+ if (*height > tmp)
+ *height = tmp;
+ }
+
+ if ((*height <= 0) || (*width <= 0)) {
+ *width = 0;
+ *height = 0;
+ }
}
-static void imb_rectclip3(ImBuf *dbuf, ImBuf *obuf, ImBuf *sbuf, int *destx,
- int *desty, int *origx, int *origy, int *srcx, int *srcy,
- int *width, int *height)
+static void imb_rectclip3(ImBuf *dbuf,
+ ImBuf *obuf,
+ ImBuf *sbuf,
+ int *destx,
+ int *desty,
+ int *origx,
+ int *origy,
+ int *srcx,
+ int *srcy,
+ int *width,
+ int *height)
{
- int tmp;
-
- if (dbuf == NULL) return;
-
- if (*destx < 0) {
- *srcx -= *destx;
- *origx -= *destx;
- *width += *destx;
- *destx = 0;
- }
- if (*origx < 0) {
- *destx -= *origx;
- *srcx -= *origx;
- *width += *origx;
- *origx = 0;
- }
- if (*srcx < 0) {
- *destx -= *srcx;
- *origx -= *srcx;
- *width += *srcx;
- *srcx = 0;
- }
-
- if (*desty < 0) {
- *srcy -= *desty;
- *origy -= *desty;
- *height += *desty;
- *desty = 0;
- }
- if (*origy < 0) {
- *desty -= *origy;
- *srcy -= *origy;
- *height += *origy;
- *origy = 0;
- }
- if (*srcy < 0) {
- *desty -= *srcy;
- *origy -= *srcy;
- *height += *srcy;
- *srcy = 0;
- }
-
- tmp = dbuf->x - *destx;
- if (*width > tmp) *width = tmp;
- tmp = dbuf->y - *desty;
- if (*height > tmp) *height = tmp;
-
- if (obuf) {
- tmp = obuf->x - *origx;
- if (*width > tmp) *width = tmp;
- tmp = obuf->y - *origy;
- if (*height > tmp) *height = tmp;
- }
-
- if (sbuf) {
- tmp = sbuf->x - *srcx;
- if (*width > tmp) *width = tmp;
- tmp = sbuf->y - *srcy;
- if (*height > tmp) *height = tmp;
- }
-
- if ((*height <= 0) || (*width <= 0)) {
- *width = 0;
- *height = 0;
- }
+ int tmp;
+
+ if (dbuf == NULL)
+ return;
+
+ if (*destx < 0) {
+ *srcx -= *destx;
+ *origx -= *destx;
+ *width += *destx;
+ *destx = 0;
+ }
+ if (*origx < 0) {
+ *destx -= *origx;
+ *srcx -= *origx;
+ *width += *origx;
+ *origx = 0;
+ }
+ if (*srcx < 0) {
+ *destx -= *srcx;
+ *origx -= *srcx;
+ *width += *srcx;
+ *srcx = 0;
+ }
+
+ if (*desty < 0) {
+ *srcy -= *desty;
+ *origy -= *desty;
+ *height += *desty;
+ *desty = 0;
+ }
+ if (*origy < 0) {
+ *desty -= *origy;
+ *srcy -= *origy;
+ *height += *origy;
+ *origy = 0;
+ }
+ if (*srcy < 0) {
+ *desty -= *srcy;
+ *origy -= *srcy;
+ *height += *srcy;
+ *srcy = 0;
+ }
+
+ tmp = dbuf->x - *destx;
+ if (*width > tmp)
+ *width = tmp;
+ tmp = dbuf->y - *desty;
+ if (*height > tmp)
+ *height = tmp;
+
+ if (obuf) {
+ tmp = obuf->x - *origx;
+ if (*width > tmp)
+ *width = tmp;
+ tmp = obuf->y - *origy;
+ if (*height > tmp)
+ *height = tmp;
+ }
+
+ if (sbuf) {
+ tmp = sbuf->x - *srcx;
+ if (*width > tmp)
+ *width = tmp;
+ tmp = sbuf->y - *srcy;
+ if (*height > tmp)
+ *height = tmp;
+ }
+
+ if ((*height <= 0) || (*width <= 0)) {
+ *width = 0;
+ *height = 0;
+ }
}
/* copy and blend */
-void IMB_rectcpy(ImBuf *dbuf, ImBuf *sbuf, int destx,
- int desty, int srcx, int srcy, int width, int height)
+void IMB_rectcpy(
+ ImBuf *dbuf, ImBuf *sbuf, int destx, int desty, int srcx, int srcy, int width, int height)
{
- IMB_rectblend(dbuf, dbuf, sbuf, NULL, NULL, NULL, 0, destx, desty, destx, desty, srcx, srcy, width, height, IMB_BLEND_COPY, false);
+ IMB_rectblend(dbuf,
+ dbuf,
+ sbuf,
+ NULL,
+ NULL,
+ NULL,
+ 0,
+ destx,
+ desty,
+ destx,
+ desty,
+ srcx,
+ srcy,
+ width,
+ height,
+ IMB_BLEND_COPY,
+ false);
}
-typedef void (*IMB_blend_func)(unsigned char *dst, const unsigned char *src1, const unsigned char *src2);
+typedef void (*IMB_blend_func)(unsigned char *dst,
+ const unsigned char *src1,
+ const unsigned char *src2);
typedef void (*IMB_blend_func_float)(float *dst, const float *src1, const float *src2);
-
-void IMB_rectblend(ImBuf *dbuf, ImBuf *obuf, ImBuf *sbuf, unsigned short *dmask, unsigned short *curvemask,
- unsigned short *texmask, float mask_max,
- int destx, int desty, int origx, int origy, int srcx, int srcy, int width, int height,
- IMB_BlendMode mode, bool accumulate)
+void IMB_rectblend(ImBuf *dbuf,
+ ImBuf *obuf,
+ ImBuf *sbuf,
+ unsigned short *dmask,
+ unsigned short *curvemask,
+ unsigned short *texmask,
+ float mask_max,
+ int destx,
+ int desty,
+ int origx,
+ int origy,
+ int srcx,
+ int srcy,
+ int width,
+ int height,
+ IMB_BlendMode mode,
+ bool accumulate)
{
- unsigned int *drect = NULL, *orect = NULL, *srect = NULL, *dr, *or, *sr;
- float *drectf = NULL, *orectf = NULL, *srectf = NULL, *drf, *orf, *srf;
- unsigned short *cmaskrect = curvemask, *cmr;
- unsigned short *dmaskrect = dmask, *dmr;
- unsigned short *texmaskrect = texmask, *tmr;
- int do_float, do_char, srcskip, destskip, origskip, x;
- IMB_blend_func func = NULL;
- IMB_blend_func_float func_float = NULL;
-
- if (dbuf == NULL || obuf == NULL) return;
-
- imb_rectclip3(dbuf, obuf, sbuf, &destx, &desty, &origx, &origy, &srcx, &srcy, &width, &height);
-
- if (width == 0 || height == 0) return;
- if (sbuf && sbuf->channels != 4) return;
- if (dbuf->channels != 4) return;
-
- do_char = (sbuf && sbuf->rect && dbuf->rect && obuf->rect);
- do_float = (sbuf && sbuf->rect_float && dbuf->rect_float && obuf->rect_float);
-
- if (do_char) {
- drect = dbuf->rect + ((size_t)desty) * dbuf->x + destx;
- orect = obuf->rect + ((size_t)origy) * obuf->x + origx;
- }
- if (do_float) {
- drectf = dbuf->rect_float + (((size_t)desty) * dbuf->x + destx) * 4;
- orectf = obuf->rect_float + (((size_t)origy) * obuf->x + origx) * 4;
- }
-
- if (dmaskrect)
- dmaskrect += ((size_t)origy) * obuf->x + origx;
-
- destskip = dbuf->x;
- origskip = obuf->x;
-
- if (sbuf) {
- if (do_char) srect = sbuf->rect + ((size_t)srcy) * sbuf->x + srcx;
- if (do_float) srectf = sbuf->rect_float + (((size_t)srcy) * sbuf->x + srcx) * 4;
- srcskip = sbuf->x;
-
- if (cmaskrect)
- cmaskrect += ((size_t)srcy) * sbuf->x + srcx;
-
- if (texmaskrect)
- texmaskrect += ((size_t)srcy) * sbuf->x + srcx;
- }
- else {
- srect = drect;
- srectf = drectf;
- srcskip = destskip;
- }
-
- if (mode == IMB_BLEND_COPY) {
- /* copy */
- for (; height > 0; height--) {
- if (do_char) {
- memcpy(drect, srect, width * sizeof(int));
- drect += destskip;
- srect += srcskip;
- }
-
- if (do_float) {
- memcpy(drectf, srectf, width * sizeof(float) * 4);
- drectf += destskip * 4;
- srectf += srcskip * 4;
- }
- }
- }
- else if (mode == IMB_BLEND_COPY_RGB) {
- /* copy rgb only */
- for (; height > 0; height--) {
- if (do_char) {
- dr = drect;
- sr = srect;
- for (x = width; x > 0; x--, dr++, sr++) {
- ((char *)dr)[0] = ((char *)sr)[0];
- ((char *)dr)[1] = ((char *)sr)[1];
- ((char *)dr)[2] = ((char *)sr)[2];
- }
- drect += destskip;
- srect += srcskip;
- }
-
- if (do_float) {
- drf = drectf;
- srf = srectf;
- for (x = width; x > 0; x--, drf += 4, srf += 4) {
- float map_alpha = (srf[3] == 0.0f) ? drf[3] : drf[3] / srf[3];
-
- drf[0] = srf[0] * map_alpha;
- drf[1] = srf[1] * map_alpha;
- drf[2] = srf[2] * map_alpha;
- }
- drectf += destskip * 4;
- srectf += srcskip * 4;
- }
- }
- }
- else if (mode == IMB_BLEND_COPY_ALPHA) {
- /* copy alpha only */
- for (; height > 0; height--) {
- if (do_char) {
- dr = drect;
- sr = srect;
- for (x = width; x > 0; x--, dr++, sr++)
- ((char *)dr)[3] = ((char *)sr)[3];
- drect += destskip;
- srect += srcskip;
- }
-
- if (do_float) {
- drf = drectf;
- srf = srectf;
- for (x = width; x > 0; x--, drf += 4, srf += 4)
- drf[3] = srf[3];
- drectf += destskip * 4;
- srectf += srcskip * 4;
- }
- }
- }
- else {
- switch (mode) {
- case IMB_BLEND_MIX:
- case IMB_BLEND_INTERPOLATE:
- func = blend_color_mix_byte;
- func_float = blend_color_mix_float;
- break;
- case IMB_BLEND_ADD:
- func = blend_color_add_byte;
- func_float = blend_color_add_float;
- break;
- case IMB_BLEND_SUB:
- func = blend_color_sub_byte;
- func_float = blend_color_sub_float;
- break;
- case IMB_BLEND_MUL:
- func = blend_color_mul_byte;
- func_float = blend_color_mul_float;
- break;
- case IMB_BLEND_LIGHTEN:
- func = blend_color_lighten_byte;
- func_float = blend_color_lighten_float;
- break;
- case IMB_BLEND_DARKEN:
- func = blend_color_darken_byte;
- func_float = blend_color_darken_float;
- break;
- case IMB_BLEND_ERASE_ALPHA:
- func = blend_color_erase_alpha_byte;
- func_float = blend_color_erase_alpha_float;
- break;
- case IMB_BLEND_ADD_ALPHA:
- func = blend_color_add_alpha_byte;
- func_float = blend_color_add_alpha_float;
- break;
- case IMB_BLEND_OVERLAY:
- func = blend_color_overlay_byte;
- func_float = blend_color_overlay_float;
- break;
- case IMB_BLEND_HARDLIGHT:
- func = blend_color_hardlight_byte;
- func_float = blend_color_hardlight_float;
- break;
- case IMB_BLEND_COLORBURN:
- func = blend_color_burn_byte;
- func_float = blend_color_burn_float;
- break;
- case IMB_BLEND_LINEARBURN:
- func = blend_color_linearburn_byte;
- func_float = blend_color_linearburn_float;
- break;
- case IMB_BLEND_COLORDODGE:
- func = blend_color_dodge_byte;
- func_float = blend_color_dodge_float;
- break;
- case IMB_BLEND_SCREEN:
- func = blend_color_screen_byte;
- func_float = blend_color_screen_float;
- break;
- case IMB_BLEND_SOFTLIGHT:
- func = blend_color_softlight_byte;
- func_float = blend_color_softlight_float;
- break;
- case IMB_BLEND_PINLIGHT:
- func = blend_color_pinlight_byte;
- func_float = blend_color_pinlight_float;
- break;
- case IMB_BLEND_LINEARLIGHT:
- func = blend_color_linearlight_byte;
- func_float = blend_color_linearlight_float;
- break;
- case IMB_BLEND_VIVIDLIGHT:
- func = blend_color_vividlight_byte;
- func_float = blend_color_vividlight_float;
- break;
- case IMB_BLEND_DIFFERENCE:
- func = blend_color_difference_byte;
- func_float = blend_color_difference_float;
- break;
- case IMB_BLEND_EXCLUSION:
- func = blend_color_exclusion_byte;
- func_float = blend_color_exclusion_float;
- break;
- case IMB_BLEND_COLOR:
- func = blend_color_color_byte;
- func_float = blend_color_color_float;
- break;
- case IMB_BLEND_HUE:
- func = blend_color_hue_byte;
- func_float = blend_color_hue_float;
- break;
- case IMB_BLEND_SATURATION:
- func = blend_color_saturation_byte;
- func_float = blend_color_saturation_float;
- break;
- case IMB_BLEND_LUMINOSITY:
- func = blend_color_luminosity_byte;
- func_float = blend_color_luminosity_float;
- break;
- default:
- break;
- }
-
- /* blend */
- for (; height > 0; height--) {
- if (do_char) {
- dr = drect;
- or = orect;
- sr = srect;
-
- if (cmaskrect) {
- /* mask accumulation for painting */
- cmr = cmaskrect;
- tmr = texmaskrect;
-
- /* destination mask present, do max alpha masking */
- if (dmaskrect) {
- dmr = dmaskrect;
- for (x = width; x > 0; x--, dr++, or++, sr++, dmr++, cmr++) {
- unsigned char *src = (unsigned char *)sr;
- float mask_lim = mask_max * (*cmr);
-
- if (texmaskrect)
- mask_lim *= ((*tmr++) / 65535.0f);
-
- if (src[3] && mask_lim) {
- float mask;
-
- if (accumulate)
- mask = *dmr + mask_lim;
- else
- mask = *dmr + mask_lim - (*dmr * (*cmr / 65535.0f));
-
- mask = min_ff(mask, 65535.0);
-
- if (mask > *dmr) {
- unsigned char mask_src[4];
-
- *dmr = mask;
-
- mask_src[0] = src[0];
- mask_src[1] = src[1];
- mask_src[2] = src[2];
-
- if (mode == IMB_BLEND_INTERPOLATE) {
- mask_src[3] = src[3];
- blend_color_interpolate_byte((unsigned char *)dr, (unsigned char *)or, mask_src, mask / 65535.0f);
- }
- else {
- mask_src[3] = divide_round_i(src[3] * mask, 65535);
- func((unsigned char *)dr, (unsigned char *)or, mask_src);
- }
- }
- }
- }
- dmaskrect += origskip;
- }
- /* no destination mask buffer, do regular blend with masktexture if present */
- else {
- for (x = width; x > 0; x--, dr++, or++, sr++, cmr++) {
- unsigned char *src = (unsigned char *)sr;
- float mask = (float)mask_max * ((float)(*cmr));
-
- if (texmaskrect)
- mask *= ((float)(*tmr++) / 65535.0f);
-
- mask = min_ff(mask, 65535.0);
-
- if (src[3] && (mask > 0.0f)) {
- unsigned char mask_src[4];
-
- mask_src[0] = src[0];
- mask_src[1] = src[1];
- mask_src[2] = src[2];
-
- if (mode == IMB_BLEND_INTERPOLATE) {
- mask_src[3] = src[3];
- blend_color_interpolate_byte((unsigned char *)dr, (unsigned char *)or, mask_src, mask / 65535.0f);
- }
- else {
- mask_src[3] = divide_round_i(src[3] * mask, 65535);
- func((unsigned char *)dr, (unsigned char *)or, mask_src);
- }
- }
- }
- }
-
- cmaskrect += srcskip;
- if (texmaskrect)
- texmaskrect += srcskip;
- }
- else {
- /* regular blending */
- for (x = width; x > 0; x--, dr++, or++, sr++) {
- if (((unsigned char *)sr)[3])
- func((unsigned char *)dr, (unsigned char *)or, (unsigned char *)sr);
- }
- }
-
- drect += destskip;
- orect += origskip;
- srect += srcskip;
- }
-
- if (do_float) {
- drf = drectf;
- orf = orectf;
- srf = srectf;
-
- if (cmaskrect) {
- /* mask accumulation for painting */
- cmr = cmaskrect;
- tmr = texmaskrect;
-
- /* destination mask present, do max alpha masking */
- if (dmaskrect) {
- dmr = dmaskrect;
- for (x = width; x > 0; x--, drf += 4, orf += 4, srf += 4, dmr++, cmr++) {
- float mask_lim = mask_max * (*cmr);
-
- if (texmaskrect)
- mask_lim *= ((*tmr++) / 65535.0f);
-
- if (srf[3] && mask_lim) {
- float mask;
-
- if (accumulate)
- mask = min_ff(*dmr + mask_lim, 65535.0);
- else
- mask = *dmr + mask_lim - (*dmr * (*cmr / 65535.0f));
-
- mask = min_ff(mask, 65535.0);
-
- if (mask > *dmr) {
- *dmr = mask;
-
- if (mode == IMB_BLEND_INTERPOLATE) {
- blend_color_interpolate_float(drf, orf, srf, mask / 65535.0f);
- }
- else {
- float mask_srf[4];
- mul_v4_v4fl(mask_srf, srf, mask / 65535.0f);
- func_float(drf, orf, mask_srf);
- }
- }
- }
- }
- dmaskrect += origskip;
- }
- /* no destination mask buffer, do regular blend with masktexture if present */
- else {
- for (x = width; x > 0; x--, drf += 4, orf += 4, srf += 4, cmr++) {
- float mask = (float)mask_max * ((float)(*cmr));
-
- if (texmaskrect)
- mask *= ((float)(*tmr++) / 65535.0f);
-
- mask = min_ff(mask, 65535.0);
-
- if (srf[3] && (mask > 0.0f)) {
- if (mode == IMB_BLEND_INTERPOLATE) {
- blend_color_interpolate_float(drf, orf, srf, mask / 65535.0f);
- }
- else {
- float mask_srf[4];
- mul_v4_v4fl(mask_srf, srf, mask / 65535.0f);
- func_float(drf, orf, mask_srf);
- }
-
- }
- }
- }
-
- cmaskrect += srcskip;
- if (texmaskrect)
- texmaskrect += srcskip;
- }
- else {
- /* regular blending */
- for (x = width; x > 0; x--, drf += 4, orf += 4, srf += 4) {
- if (srf[3] != 0)
- func_float(drf, orf, srf);
- }
- }
-
- drectf += destskip * 4;
- orectf += origskip * 4;
- srectf += srcskip * 4;
- }
- }
- }
+ unsigned int *drect = NULL, *orect = NULL, *srect = NULL, *dr, * or, *sr;
+ float *drectf = NULL, *orectf = NULL, *srectf = NULL, *drf, *orf, *srf;
+ unsigned short *cmaskrect = curvemask, *cmr;
+ unsigned short *dmaskrect = dmask, *dmr;
+ unsigned short *texmaskrect = texmask, *tmr;
+ int do_float, do_char, srcskip, destskip, origskip, x;
+ IMB_blend_func func = NULL;
+ IMB_blend_func_float func_float = NULL;
+
+ if (dbuf == NULL || obuf == NULL)
+ return;
+
+ imb_rectclip3(dbuf, obuf, sbuf, &destx, &desty, &origx, &origy, &srcx, &srcy, &width, &height);
+
+ if (width == 0 || height == 0)
+ return;
+ if (sbuf && sbuf->channels != 4)
+ return;
+ if (dbuf->channels != 4)
+ return;
+
+ do_char = (sbuf && sbuf->rect && dbuf->rect && obuf->rect);
+ do_float = (sbuf && sbuf->rect_float && dbuf->rect_float && obuf->rect_float);
+
+ if (do_char) {
+ drect = dbuf->rect + ((size_t)desty) * dbuf->x + destx;
+ orect = obuf->rect + ((size_t)origy) * obuf->x + origx;
+ }
+ if (do_float) {
+ drectf = dbuf->rect_float + (((size_t)desty) * dbuf->x + destx) * 4;
+ orectf = obuf->rect_float + (((size_t)origy) * obuf->x + origx) * 4;
+ }
+
+ if (dmaskrect)
+ dmaskrect += ((size_t)origy) * obuf->x + origx;
+
+ destskip = dbuf->x;
+ origskip = obuf->x;
+
+ if (sbuf) {
+ if (do_char)
+ srect = sbuf->rect + ((size_t)srcy) * sbuf->x + srcx;
+ if (do_float)
+ srectf = sbuf->rect_float + (((size_t)srcy) * sbuf->x + srcx) * 4;
+ srcskip = sbuf->x;
+
+ if (cmaskrect)
+ cmaskrect += ((size_t)srcy) * sbuf->x + srcx;
+
+ if (texmaskrect)
+ texmaskrect += ((size_t)srcy) * sbuf->x + srcx;
+ }
+ else {
+ srect = drect;
+ srectf = drectf;
+ srcskip = destskip;
+ }
+
+ if (mode == IMB_BLEND_COPY) {
+ /* copy */
+ for (; height > 0; height--) {
+ if (do_char) {
+ memcpy(drect, srect, width * sizeof(int));
+ drect += destskip;
+ srect += srcskip;
+ }
+
+ if (do_float) {
+ memcpy(drectf, srectf, width * sizeof(float) * 4);
+ drectf += destskip * 4;
+ srectf += srcskip * 4;
+ }
+ }
+ }
+ else if (mode == IMB_BLEND_COPY_RGB) {
+ /* copy rgb only */
+ for (; height > 0; height--) {
+ if (do_char) {
+ dr = drect;
+ sr = srect;
+ for (x = width; x > 0; x--, dr++, sr++) {
+ ((char *)dr)[0] = ((char *)sr)[0];
+ ((char *)dr)[1] = ((char *)sr)[1];
+ ((char *)dr)[2] = ((char *)sr)[2];
+ }
+ drect += destskip;
+ srect += srcskip;
+ }
+
+ if (do_float) {
+ drf = drectf;
+ srf = srectf;
+ for (x = width; x > 0; x--, drf += 4, srf += 4) {
+ float map_alpha = (srf[3] == 0.0f) ? drf[3] : drf[3] / srf[3];
+
+ drf[0] = srf[0] * map_alpha;
+ drf[1] = srf[1] * map_alpha;
+ drf[2] = srf[2] * map_alpha;
+ }
+ drectf += destskip * 4;
+ srectf += srcskip * 4;
+ }
+ }
+ }
+ else if (mode == IMB_BLEND_COPY_ALPHA) {
+ /* copy alpha only */
+ for (; height > 0; height--) {
+ if (do_char) {
+ dr = drect;
+ sr = srect;
+ for (x = width; x > 0; x--, dr++, sr++)
+ ((char *)dr)[3] = ((char *)sr)[3];
+ drect += destskip;
+ srect += srcskip;
+ }
+
+ if (do_float) {
+ drf = drectf;
+ srf = srectf;
+ for (x = width; x > 0; x--, drf += 4, srf += 4)
+ drf[3] = srf[3];
+ drectf += destskip * 4;
+ srectf += srcskip * 4;
+ }
+ }
+ }
+ else {
+ switch (mode) {
+ case IMB_BLEND_MIX:
+ case IMB_BLEND_INTERPOLATE:
+ func = blend_color_mix_byte;
+ func_float = blend_color_mix_float;
+ break;
+ case IMB_BLEND_ADD:
+ func = blend_color_add_byte;
+ func_float = blend_color_add_float;
+ break;
+ case IMB_BLEND_SUB:
+ func = blend_color_sub_byte;
+ func_float = blend_color_sub_float;
+ break;
+ case IMB_BLEND_MUL:
+ func = blend_color_mul_byte;
+ func_float = blend_color_mul_float;
+ break;
+ case IMB_BLEND_LIGHTEN:
+ func = blend_color_lighten_byte;
+ func_float = blend_color_lighten_float;
+ break;
+ case IMB_BLEND_DARKEN:
+ func = blend_color_darken_byte;
+ func_float = blend_color_darken_float;
+ break;
+ case IMB_BLEND_ERASE_ALPHA:
+ func = blend_color_erase_alpha_byte;
+ func_float = blend_color_erase_alpha_float;
+ break;
+ case IMB_BLEND_ADD_ALPHA:
+ func = blend_color_add_alpha_byte;
+ func_float = blend_color_add_alpha_float;
+ break;
+ case IMB_BLEND_OVERLAY:
+ func = blend_color_overlay_byte;
+ func_float = blend_color_overlay_float;
+ break;
+ case IMB_BLEND_HARDLIGHT:
+ func = blend_color_hardlight_byte;
+ func_float = blend_color_hardlight_float;
+ break;
+ case IMB_BLEND_COLORBURN:
+ func = blend_color_burn_byte;
+ func_float = blend_color_burn_float;
+ break;
+ case IMB_BLEND_LINEARBURN:
+ func = blend_color_linearburn_byte;
+ func_float = blend_color_linearburn_float;
+ break;
+ case IMB_BLEND_COLORDODGE:
+ func = blend_color_dodge_byte;
+ func_float = blend_color_dodge_float;
+ break;
+ case IMB_BLEND_SCREEN:
+ func = blend_color_screen_byte;
+ func_float = blend_color_screen_float;
+ break;
+ case IMB_BLEND_SOFTLIGHT:
+ func = blend_color_softlight_byte;
+ func_float = blend_color_softlight_float;
+ break;
+ case IMB_BLEND_PINLIGHT:
+ func = blend_color_pinlight_byte;
+ func_float = blend_color_pinlight_float;
+ break;
+ case IMB_BLEND_LINEARLIGHT:
+ func = blend_color_linearlight_byte;
+ func_float = blend_color_linearlight_float;
+ break;
+ case IMB_BLEND_VIVIDLIGHT:
+ func = blend_color_vividlight_byte;
+ func_float = blend_color_vividlight_float;
+ break;
+ case IMB_BLEND_DIFFERENCE:
+ func = blend_color_difference_byte;
+ func_float = blend_color_difference_float;
+ break;
+ case IMB_BLEND_EXCLUSION:
+ func = blend_color_exclusion_byte;
+ func_float = blend_color_exclusion_float;
+ break;
+ case IMB_BLEND_COLOR:
+ func = blend_color_color_byte;
+ func_float = blend_color_color_float;
+ break;
+ case IMB_BLEND_HUE:
+ func = blend_color_hue_byte;
+ func_float = blend_color_hue_float;
+ break;
+ case IMB_BLEND_SATURATION:
+ func = blend_color_saturation_byte;
+ func_float = blend_color_saturation_float;
+ break;
+ case IMB_BLEND_LUMINOSITY:
+ func = blend_color_luminosity_byte;
+ func_float = blend_color_luminosity_float;
+ break;
+ default:
+ break;
+ }
+
+ /* blend */
+ for (; height > 0; height--) {
+ if (do_char) {
+ dr = drect;
+ or = orect;
+ sr = srect;
+
+ if (cmaskrect) {
+ /* mask accumulation for painting */
+ cmr = cmaskrect;
+ tmr = texmaskrect;
+
+ /* destination mask present, do max alpha masking */
+ if (dmaskrect) {
+ dmr = dmaskrect;
+ for (x = width; x > 0; x--, dr++, or ++, sr++, dmr++, cmr++) {
+ unsigned char *src = (unsigned char *)sr;
+ float mask_lim = mask_max * (*cmr);
+
+ if (texmaskrect)
+ mask_lim *= ((*tmr++) / 65535.0f);
+
+ if (src[3] && mask_lim) {
+ float mask;
+
+ if (accumulate)
+ mask = *dmr + mask_lim;
+ else
+ mask = *dmr + mask_lim - (*dmr * (*cmr / 65535.0f));
+
+ mask = min_ff(mask, 65535.0);
+
+ if (mask > *dmr) {
+ unsigned char mask_src[4];
+
+ *dmr = mask;
+
+ mask_src[0] = src[0];
+ mask_src[1] = src[1];
+ mask_src[2] = src[2];
+
+ if (mode == IMB_BLEND_INTERPOLATE) {
+ mask_src[3] = src[3];
+ blend_color_interpolate_byte(
+ (unsigned char *)dr, (unsigned char *) or, mask_src, mask / 65535.0f);
+ }
+ else {
+ mask_src[3] = divide_round_i(src[3] * mask, 65535);
+ func((unsigned char *)dr, (unsigned char *) or, mask_src);
+ }
+ }
+ }
+ }
+ dmaskrect += origskip;
+ }
+ /* no destination mask buffer, do regular blend with masktexture if present */
+ else {
+ for (x = width; x > 0; x--, dr++, or ++, sr++, cmr++) {
+ unsigned char *src = (unsigned char *)sr;
+ float mask = (float)mask_max * ((float)(*cmr));
+
+ if (texmaskrect)
+ mask *= ((float)(*tmr++) / 65535.0f);
+
+ mask = min_ff(mask, 65535.0);
+
+ if (src[3] && (mask > 0.0f)) {
+ unsigned char mask_src[4];
+
+ mask_src[0] = src[0];
+ mask_src[1] = src[1];
+ mask_src[2] = src[2];
+
+ if (mode == IMB_BLEND_INTERPOLATE) {
+ mask_src[3] = src[3];
+ blend_color_interpolate_byte(
+ (unsigned char *)dr, (unsigned char *) or, mask_src, mask / 65535.0f);
+ }
+ else {
+ mask_src[3] = divide_round_i(src[3] * mask, 65535);
+ func((unsigned char *)dr, (unsigned char *) or, mask_src);
+ }
+ }
+ }
+ }
+
+ cmaskrect += srcskip;
+ if (texmaskrect)
+ texmaskrect += srcskip;
+ }
+ else {
+ /* regular blending */
+ for (x = width; x > 0; x--, dr++, or ++, sr++) {
+ if (((unsigned char *)sr)[3])
+ func((unsigned char *)dr, (unsigned char *) or, (unsigned char *)sr);
+ }
+ }
+
+ drect += destskip;
+ orect += origskip;
+ srect += srcskip;
+ }
+
+ if (do_float) {
+ drf = drectf;
+ orf = orectf;
+ srf = srectf;
+
+ if (cmaskrect) {
+ /* mask accumulation for painting */
+ cmr = cmaskrect;
+ tmr = texmaskrect;
+
+ /* destination mask present, do max alpha masking */
+ if (dmaskrect) {
+ dmr = dmaskrect;
+ for (x = width; x > 0; x--, drf += 4, orf += 4, srf += 4, dmr++, cmr++) {
+ float mask_lim = mask_max * (*cmr);
+
+ if (texmaskrect)
+ mask_lim *= ((*tmr++) / 65535.0f);
+
+ if (srf[3] && mask_lim) {
+ float mask;
+
+ if (accumulate)
+ mask = min_ff(*dmr + mask_lim, 65535.0);
+ else
+ mask = *dmr + mask_lim - (*dmr * (*cmr / 65535.0f));
+
+ mask = min_ff(mask, 65535.0);
+
+ if (mask > *dmr) {
+ *dmr = mask;
+
+ if (mode == IMB_BLEND_INTERPOLATE) {
+ blend_color_interpolate_float(drf, orf, srf, mask / 65535.0f);
+ }
+ else {
+ float mask_srf[4];
+ mul_v4_v4fl(mask_srf, srf, mask / 65535.0f);
+ func_float(drf, orf, mask_srf);
+ }
+ }
+ }
+ }
+ dmaskrect += origskip;
+ }
+ /* no destination mask buffer, do regular blend with masktexture if present */
+ else {
+ for (x = width; x > 0; x--, drf += 4, orf += 4, srf += 4, cmr++) {
+ float mask = (float)mask_max * ((float)(*cmr));
+
+ if (texmaskrect)
+ mask *= ((float)(*tmr++) / 65535.0f);
+
+ mask = min_ff(mask, 65535.0);
+
+ if (srf[3] && (mask > 0.0f)) {
+ if (mode == IMB_BLEND_INTERPOLATE) {
+ blend_color_interpolate_float(drf, orf, srf, mask / 65535.0f);
+ }
+ else {
+ float mask_srf[4];
+ mul_v4_v4fl(mask_srf, srf, mask / 65535.0f);
+ func_float(drf, orf, mask_srf);
+ }
+ }
+ }
+ }
+
+ cmaskrect += srcskip;
+ if (texmaskrect)
+ texmaskrect += srcskip;
+ }
+ else {
+ /* regular blending */
+ for (x = width; x > 0; x--, drf += 4, orf += 4, srf += 4) {
+ if (srf[3] != 0)
+ func_float(drf, orf, srf);
+ }
+ }
+
+ drectf += destskip * 4;
+ orectf += origskip * 4;
+ srectf += srcskip * 4;
+ }
+ }
+ }
}
typedef struct RectBlendThreadData {
- ImBuf *dbuf, *obuf, *sbuf;
- unsigned short *dmask, *curvemask, *texmask;
- float mask_max;
- int destx, desty, origx, origy;
- int srcx, srcy, width;
- IMB_BlendMode mode;
- bool accumulate;
+ ImBuf *dbuf, *obuf, *sbuf;
+ unsigned short *dmask, *curvemask, *texmask;
+ float mask_max;
+ int destx, desty, origx, origy;
+ int srcx, srcy, width;
+ IMB_BlendMode mode;
+ bool accumulate;
} RectBlendThreadData;
-static void rectblend_thread_do(void *data_v,
- int start_scanline,
- int num_scanlines)
+static void rectblend_thread_do(void *data_v, int start_scanline, int num_scanlines)
{
- RectBlendThreadData *data = (RectBlendThreadData *)data_v;
- IMB_rectblend(data->dbuf, data->obuf, data->sbuf,
- data->dmask, data->curvemask, data->texmask,
- data->mask_max,
- data->destx,
- data->desty + start_scanline,
- data->origx,
- data->origy + start_scanline,
- data->srcx,
- data->srcy + start_scanline,
- data->width, num_scanlines,
- data->mode, data->accumulate);
+ RectBlendThreadData *data = (RectBlendThreadData *)data_v;
+ IMB_rectblend(data->dbuf,
+ data->obuf,
+ data->sbuf,
+ data->dmask,
+ data->curvemask,
+ data->texmask,
+ data->mask_max,
+ data->destx,
+ data->desty + start_scanline,
+ data->origx,
+ data->origy + start_scanline,
+ data->srcx,
+ data->srcy + start_scanline,
+ data->width,
+ num_scanlines,
+ data->mode,
+ data->accumulate);
}
-void IMB_rectblend_threaded(ImBuf *dbuf, ImBuf *obuf, ImBuf *sbuf,
- unsigned short *dmask, unsigned short *curvemask,
- unsigned short *texmask, float mask_max,
- int destx, int desty, int origx, int origy,
- int srcx, int srcy, int width, int height,
- IMB_BlendMode mode, bool accumulate)
+void IMB_rectblend_threaded(ImBuf *dbuf,
+ ImBuf *obuf,
+ ImBuf *sbuf,
+ unsigned short *dmask,
+ unsigned short *curvemask,
+ unsigned short *texmask,
+ float mask_max,
+ int destx,
+ int desty,
+ int origx,
+ int origy,
+ int srcx,
+ int srcy,
+ int width,
+ int height,
+ IMB_BlendMode mode,
+ bool accumulate)
{
- if (((size_t)width) * height < 64 * 64) {
- IMB_rectblend(dbuf, obuf, sbuf, dmask, curvemask, texmask,
- mask_max, destx, desty, origx, origy,
- srcx, srcy, width, height, mode, accumulate);
- }
- else {
- RectBlendThreadData data;
- data.dbuf = dbuf;
- data.obuf = obuf;
- data.sbuf = sbuf;
- data.dmask = dmask;
- data.curvemask = curvemask;
- data.texmask = texmask;
- data.mask_max = mask_max;
- data.destx = destx;
- data.desty = desty;
- data.origx = origx;
- data.origy = origy;
- data.srcx = srcx;
- data.srcy = srcy;
- data.width = width;
- data.mode = mode;
- data.accumulate = accumulate;
- IMB_processor_apply_threaded_scanlines(
- height, rectblend_thread_do, &data);
- }
+ if (((size_t)width) * height < 64 * 64) {
+ IMB_rectblend(dbuf,
+ obuf,
+ sbuf,
+ dmask,
+ curvemask,
+ texmask,
+ mask_max,
+ destx,
+ desty,
+ origx,
+ origy,
+ srcx,
+ srcy,
+ width,
+ height,
+ mode,
+ accumulate);
+ }
+ else {
+ RectBlendThreadData data;
+ data.dbuf = dbuf;
+ data.obuf = obuf;
+ data.sbuf = sbuf;
+ data.dmask = dmask;
+ data.curvemask = curvemask;
+ data.texmask = texmask;
+ data.mask_max = mask_max;
+ data.destx = destx;
+ data.desty = desty;
+ data.origx = origx;
+ data.origy = origy;
+ data.srcx = srcx;
+ data.srcy = srcy;
+ data.width = width;
+ data.mode = mode;
+ data.accumulate = accumulate;
+ IMB_processor_apply_threaded_scanlines(height, rectblend_thread_do, &data);
+ }
}
/* fill */
void IMB_rectfill(ImBuf *drect, const float col[4])
{
- int num;
-
- if (drect->rect) {
- unsigned int *rrect = drect->rect;
- char ccol[4];
-
- ccol[0] = (int)(col[0] * 255);
- ccol[1] = (int)(col[1] * 255);
- ccol[2] = (int)(col[2] * 255);
- ccol[3] = (int)(col[3] * 255);
-
- num = drect->x * drect->y;
- for (; num > 0; num--)
- *rrect++ = *((unsigned int *)ccol);
- }
-
- if (drect->rect_float) {
- float *rrectf = drect->rect_float;
-
- num = drect->x * drect->y;
- for (; num > 0; num--) {
- *rrectf++ = col[0];
- *rrectf++ = col[1];
- *rrectf++ = col[2];
- *rrectf++ = col[3];
- }
- }
+ int num;
+
+ if (drect->rect) {
+ unsigned int *rrect = drect->rect;
+ char ccol[4];
+
+ ccol[0] = (int)(col[0] * 255);
+ ccol[1] = (int)(col[1] * 255);
+ ccol[2] = (int)(col[2] * 255);
+ ccol[3] = (int)(col[3] * 255);
+
+ num = drect->x * drect->y;
+ for (; num > 0; num--)
+ *rrect++ = *((unsigned int *)ccol);
+ }
+
+ if (drect->rect_float) {
+ float *rrectf = drect->rect_float;
+
+ num = drect->x * drect->y;
+ for (; num > 0; num--) {
+ *rrectf++ = col[0];
+ *rrectf++ = col[1];
+ *rrectf++ = col[2];
+ *rrectf++ = col[3];
+ }
+ }
}
-
-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)
+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)
{
- int i, j;
- float a; /* alpha */
- float ai; /* alpha inverted */
- float aich; /* alpha, inverted, ai/255.0 - Convert char to float at the same time */
- if ((!rect && !rectf) || (!col) || col[3] == 0.0f)
- return;
-
- /* sanity checks for coords */
- CLAMP(x1, 0, width);
- CLAMP(x2, 0, width);
- CLAMP(y1, 0, height);
- CLAMP(y2, 0, height);
-
- if (x1 > x2) SWAP(int, x1, x2);
- if (y1 > y2) SWAP(int, y1, y2);
- if (x1 == x2 || y1 == y2) return;
-
- a = col[3];
- ai = 1 - a;
- aich = ai / 255.0f;
-
- if (rect) {
- unsigned char *pixel;
- unsigned char chr = 0, chg = 0, chb = 0;
- float fr = 0, fg = 0, fb = 0;
-
- const int alphaint = unit_float_to_uchar_clamp(a);
-
- if (a == 1.0f) {
- chr = unit_float_to_uchar_clamp(col[0]);
- chg = unit_float_to_uchar_clamp(col[1]);
- chb = unit_float_to_uchar_clamp(col[2]);
- }
- else {
- fr = col[0] * a;
- fg = col[1] * a;
- fb = col[2] * a;
- }
- for (j = 0; j < y2 - y1; j++) {
- for (i = 0; i < x2 - x1; i++) {
- pixel = rect + 4 * (((y1 + j) * width) + (x1 + i));
- if (pixel >= rect && pixel < rect + (4 * (width * height))) {
- if (a == 1.0f) {
- pixel[0] = chr;
- pixel[1] = chg;
- pixel[2] = chb;
- pixel[3] = 255;
- }
- else {
- int alphatest;
- pixel[0] = (char)((fr + ((float)pixel[0] * aich)) * 255.0f);
- pixel[1] = (char)((fg + ((float)pixel[1] * aich)) * 255.0f);
- pixel[2] = (char)((fb + ((float)pixel[2] * aich)) * 255.0f);
- pixel[3] = (char)((alphatest = ((int)pixel[3] + alphaint)) < 255 ? alphatest : 255);
- }
- }
- }
- }
- }
-
- if (rectf) {
- float col_conv[4];
- float *pixel;
-
- if (display) {
- copy_v4_v4(col_conv, col);
- IMB_colormanagement_display_to_scene_linear_v3(col_conv, display);
- }
- else {
- srgb_to_linearrgb_v4(col_conv, col);
- }
-
- for (j = 0; j < y2 - y1; j++) {
- for (i = 0; i < x2 - x1; i++) {
- pixel = rectf + 4 * (((y1 + j) * width) + (x1 + i));
- if (a == 1.0f) {
- pixel[0] = col_conv[0];
- pixel[1] = col_conv[1];
- pixel[2] = col_conv[2];
- pixel[3] = 1.0f;
- }
- else {
- float alphatest;
- pixel[0] = (col_conv[0] * a) + (pixel[0] * ai);
- pixel[1] = (col_conv[1] * a) + (pixel[1] * ai);
- pixel[2] = (col_conv[2] * a) + (pixel[2] * ai);
- pixel[3] = (alphatest = (pixel[3] + a)) < 1.0f ? alphatest : 1.0f;
- }
- }
- }
- }
+ int i, j;
+ float a; /* alpha */
+ float ai; /* alpha inverted */
+ float aich; /* alpha, inverted, ai/255.0 - Convert char to float at the same time */
+ if ((!rect && !rectf) || (!col) || col[3] == 0.0f)
+ return;
+
+ /* sanity checks for coords */
+ CLAMP(x1, 0, width);
+ CLAMP(x2, 0, width);
+ CLAMP(y1, 0, height);
+ CLAMP(y2, 0, height);
+
+ if (x1 > x2)
+ SWAP(int, x1, x2);
+ if (y1 > y2)
+ SWAP(int, y1, y2);
+ if (x1 == x2 || y1 == y2)
+ return;
+
+ a = col[3];
+ ai = 1 - a;
+ aich = ai / 255.0f;
+
+ if (rect) {
+ unsigned char *pixel;
+ unsigned char chr = 0, chg = 0, chb = 0;
+ float fr = 0, fg = 0, fb = 0;
+
+ const int alphaint = unit_float_to_uchar_clamp(a);
+
+ if (a == 1.0f) {
+ chr = unit_float_to_uchar_clamp(col[0]);
+ chg = unit_float_to_uchar_clamp(col[1]);
+ chb = unit_float_to_uchar_clamp(col[2]);
+ }
+ else {
+ fr = col[0] * a;
+ fg = col[1] * a;
+ fb = col[2] * a;
+ }
+ for (j = 0; j < y2 - y1; j++) {
+ for (i = 0; i < x2 - x1; i++) {
+ pixel = rect + 4 * (((y1 + j) * width) + (x1 + i));
+ if (pixel >= rect && pixel < rect + (4 * (width * height))) {
+ if (a == 1.0f) {
+ pixel[0] = chr;
+ pixel[1] = chg;
+ pixel[2] = chb;
+ pixel[3] = 255;
+ }
+ else {
+ int alphatest;
+ pixel[0] = (char)((fr + ((float)pixel[0] * aich)) * 255.0f);
+ pixel[1] = (char)((fg + ((float)pixel[1] * aich)) * 255.0f);
+ pixel[2] = (char)((fb + ((float)pixel[2] * aich)) * 255.0f);
+ pixel[3] = (char)((alphatest = ((int)pixel[3] + alphaint)) < 255 ? alphatest : 255);
+ }
+ }
+ }
+ }
+ }
+
+ if (rectf) {
+ float col_conv[4];
+ float *pixel;
+
+ if (display) {
+ copy_v4_v4(col_conv, col);
+ IMB_colormanagement_display_to_scene_linear_v3(col_conv, display);
+ }
+ else {
+ srgb_to_linearrgb_v4(col_conv, col);
+ }
+
+ for (j = 0; j < y2 - y1; j++) {
+ for (i = 0; i < x2 - x1; i++) {
+ pixel = rectf + 4 * (((y1 + j) * width) + (x1 + i));
+ if (a == 1.0f) {
+ pixel[0] = col_conv[0];
+ pixel[1] = col_conv[1];
+ pixel[2] = col_conv[2];
+ pixel[3] = 1.0f;
+ }
+ else {
+ float alphatest;
+ pixel[0] = (col_conv[0] * a) + (pixel[0] * ai);
+ pixel[1] = (col_conv[1] * a) + (pixel[1] * ai);
+ pixel[2] = (col_conv[2] * a) + (pixel[2] * ai);
+ pixel[3] = (alphatest = (pixel[3] + a)) < 1.0f ? alphatest : 1.0f;
+ }
+ }
+ }
+ }
}
-void IMB_rectfill_area(ImBuf *ibuf, const float col[4], int x1, int y1, int x2, int y2, struct ColorManagedDisplay *display)
+void IMB_rectfill_area(ImBuf *ibuf,
+ const float col[4],
+ int x1,
+ int y1,
+ int x2,
+ int y2,
+ struct ColorManagedDisplay *display)
{
- if (!ibuf) return;
- buf_rectfill_area((unsigned char *) ibuf->rect, ibuf->rect_float, ibuf->x, ibuf->y, col, display,
- x1, y1, x2, y2);
+ if (!ibuf)
+ return;
+ buf_rectfill_area((unsigned char *)ibuf->rect,
+ ibuf->rect_float,
+ ibuf->x,
+ ibuf->y,
+ col,
+ display,
+ x1,
+ y1,
+ x2,
+ y2);
}
-
void IMB_rectfill_alpha(ImBuf *ibuf, const float value)
{
- int i;
-
- if (ibuf->rect_float && (ibuf->channels == 4)) {
- float *fbuf = ibuf->rect_float + 3;
- for (i = ibuf->x * ibuf->y; i > 0; i--, fbuf += 4) { *fbuf = value; }
- }
-
- if (ibuf->rect) {
- const unsigned char cvalue = value * 255;
- unsigned char *cbuf = ((unsigned char *)ibuf->rect) + 3;
- for (i = ibuf->x * ibuf->y; i > 0; i--, cbuf += 4) { *cbuf = cvalue; }
- }
+ int i;
+
+ if (ibuf->rect_float && (ibuf->channels == 4)) {
+ float *fbuf = ibuf->rect_float + 3;
+ for (i = ibuf->x * ibuf->y; i > 0; i--, fbuf += 4) {
+ *fbuf = value;
+ }
+ }
+
+ if (ibuf->rect) {
+ const unsigned char cvalue = value * 255;
+ unsigned char *cbuf = ((unsigned char *)ibuf->rect) + 3;
+ for (i = ibuf->x * ibuf->y; i > 0; i--, cbuf += 4) {
+ *cbuf = cvalue;
+ }
+ }
}
diff --git a/source/blender/imbuf/intern/rotate.c b/source/blender/imbuf/intern/rotate.c
index 277a2d0c491..2b200abc852 100644
--- a/source/blender/imbuf/intern/rotate.c
+++ b/source/blender/imbuf/intern/rotate.c
@@ -32,82 +32,86 @@
void IMB_flipy(struct ImBuf *ibuf)
{
- int x, y;
+ int x, y;
- if (ibuf == NULL) return;
+ if (ibuf == NULL)
+ return;
- if (ibuf->rect) {
- unsigned int *top, *bottom, *line;
+ if (ibuf->rect) {
+ unsigned int *top, *bottom, *line;
- x = ibuf->x;
- y = ibuf->y;
+ x = ibuf->x;
+ y = ibuf->y;
- top = ibuf->rect;
- bottom = top + ((y - 1) * x);
- line = MEM_mallocN(x * sizeof(int), "linebuf");
+ top = ibuf->rect;
+ bottom = top + ((y - 1) * x);
+ line = MEM_mallocN(x * sizeof(int), "linebuf");
- y >>= 1;
+ y >>= 1;
- for (; y > 0; y--) {
- memcpy(line, top, x * sizeof(int));
- memcpy(top, bottom, x * sizeof(int));
- memcpy(bottom, line, x * sizeof(int));
- bottom -= x;
- top += x;
- }
+ for (; y > 0; y--) {
+ memcpy(line, top, x * sizeof(int));
+ memcpy(top, bottom, x * sizeof(int));
+ memcpy(bottom, line, x * sizeof(int));
+ bottom -= x;
+ top += x;
+ }
- MEM_freeN(line);
- }
+ MEM_freeN(line);
+ }
- if (ibuf->rect_float) {
- float *topf = NULL, *bottomf = NULL, *linef = NULL;
+ if (ibuf->rect_float) {
+ float *topf = NULL, *bottomf = NULL, *linef = NULL;
- x = ibuf->x;
- y = ibuf->y;
+ x = ibuf->x;
+ y = ibuf->y;
- topf = ibuf->rect_float;
- bottomf = topf + 4 * ((y - 1) * x);
- linef = MEM_mallocN(4 * x * sizeof(float), "linebuff");
+ topf = ibuf->rect_float;
+ bottomf = topf + 4 * ((y - 1) * x);
+ linef = MEM_mallocN(4 * x * sizeof(float), "linebuff");
- y >>= 1;
+ y >>= 1;
- for (; y > 0; y--) {
- memcpy(linef, topf, 4 * x * sizeof(float));
- memcpy(topf, bottomf, 4 * x * sizeof(float));
- memcpy(bottomf, linef, 4 * x * sizeof(float));
- bottomf -= 4 * x;
- topf += 4 * x;
- }
+ for (; y > 0; y--) {
+ memcpy(linef, topf, 4 * x * sizeof(float));
+ memcpy(topf, bottomf, 4 * x * sizeof(float));
+ memcpy(bottomf, linef, 4 * x * sizeof(float));
+ bottomf -= 4 * x;
+ topf += 4 * x;
+ }
- MEM_freeN(linef);
- }
+ MEM_freeN(linef);
+ }
}
void IMB_flipx(struct ImBuf *ibuf)
{
- int x, y, xr, xl, yi;
- float px_f[4];
-
- if (ibuf == NULL) return;
-
- x = ibuf->x;
- y = ibuf->y;
-
- if (ibuf->rect) {
- for (yi = y - 1; yi >= 0; yi--) {
- for (xr = x - 1, xl = 0; xr >= xl; xr--, xl++) {
- SWAP(unsigned int, ibuf->rect[(x * yi) + xr], ibuf->rect[(x * yi) + xl]);
- }
- }
- }
-
- if (ibuf->rect_float) {
- for (yi = y - 1; yi >= 0; yi--) {
- for (xr = x - 1, xl = 0; xr >= xl; xr--, xl++) {
- memcpy(&px_f, &ibuf->rect_float[((x * yi) + xr) * 4], 4 * sizeof(float));
- memcpy(&ibuf->rect_float[((x * yi) + xr) * 4], &ibuf->rect_float[((x * yi) + xl) * 4], 4 * sizeof(float));
- memcpy(&ibuf->rect_float[((x * yi) + xl) * 4], &px_f, 4 * sizeof(float));
- }
- }
- }
+ int x, y, xr, xl, yi;
+ float px_f[4];
+
+ if (ibuf == NULL)
+ return;
+
+ x = ibuf->x;
+ y = ibuf->y;
+
+ if (ibuf->rect) {
+ for (yi = y - 1; yi >= 0; yi--) {
+ for (xr = x - 1, xl = 0; xr >= xl; xr--, xl++) {
+ SWAP(unsigned int, ibuf->rect[(x * yi) + xr], ibuf->rect[(x * yi) + xl]);
+ }
+ }
+ }
+
+ if (ibuf->rect_float) {
+ for (yi = y - 1; yi >= 0; yi--) {
+ for (xr = x - 1, xl = 0; xr >= xl; xr--, xl++) {
+ memcpy(&px_f, &ibuf->rect_float[((x * yi) + xr) * 4], 4 * sizeof(float));
+ memcpy(&ibuf->rect_float[((x * yi) + xr) * 4],
+ &ibuf->rect_float[((x * yi) + xl) * 4],
+ 4 * sizeof(float));
+ memcpy(&ibuf->rect_float[((x * yi) + xl) * 4], &px_f, 4 * sizeof(float));
+ }
+ }
+ }
}
diff --git a/source/blender/imbuf/intern/scaling.c b/source/blender/imbuf/intern/scaling.c
index c722f91670e..e57f3bb08f4 100644
--- a/source/blender/imbuf/intern/scaling.c
+++ b/source/blender/imbuf/intern/scaling.c
@@ -22,7 +22,6 @@
* \ingroup imbuf
*/
-
#include "BLI_utildefines.h"
#include "BLI_math_color.h"
#include "BLI_math_interp.h"
@@ -34,781 +33,797 @@
#include "IMB_filter.h"
-#include "BLI_sys_types.h" // for intptr_t support
+#include "BLI_sys_types.h" // for intptr_t support
static void imb_half_x_no_alloc(struct ImBuf *ibuf2, struct ImBuf *ibuf1)
{
- uchar *p1, *_p1, *dest;
- short a, r, g, b;
- int x, y;
- float af, rf, gf, bf, *p1f, *_p1f, *destf;
- bool do_rect, do_float;
-
- do_rect = (ibuf1->rect != NULL);
- do_float = (ibuf1->rect_float != NULL && ibuf2->rect_float != NULL);
-
- _p1 = (uchar *) ibuf1->rect;
- dest = (uchar *) ibuf2->rect;
-
- _p1f = ibuf1->rect_float;
- destf = ibuf2->rect_float;
-
- for (y = ibuf2->y; y > 0; y--) {
- p1 = _p1;
- p1f = _p1f;
- for (x = ibuf2->x; x > 0; x--) {
- if (do_rect) {
- a = *(p1++);
- b = *(p1++);
- g = *(p1++);
- r = *(p1++);
- a += *(p1++);
- b += *(p1++);
- g += *(p1++);
- r += *(p1++);
- *(dest++) = a >> 1;
- *(dest++) = b >> 1;
- *(dest++) = g >> 1;
- *(dest++) = r >> 1;
- }
- if (do_float) {
- af = *(p1f++);
- bf = *(p1f++);
- gf = *(p1f++);
- rf = *(p1f++);
- af += *(p1f++);
- bf += *(p1f++);
- gf += *(p1f++);
- rf += *(p1f++);
- *(destf++) = 0.5f * af;
- *(destf++) = 0.5f * bf;
- *(destf++) = 0.5f * gf;
- *(destf++) = 0.5f * rf;
- }
- }
- if (do_rect) _p1 += (ibuf1->x << 2);
- if (do_float) _p1f += (ibuf1->x << 2);
- }
+ uchar *p1, *_p1, *dest;
+ short a, r, g, b;
+ int x, y;
+ float af, rf, gf, bf, *p1f, *_p1f, *destf;
+ bool do_rect, do_float;
+
+ do_rect = (ibuf1->rect != NULL);
+ do_float = (ibuf1->rect_float != NULL && ibuf2->rect_float != NULL);
+
+ _p1 = (uchar *)ibuf1->rect;
+ dest = (uchar *)ibuf2->rect;
+
+ _p1f = ibuf1->rect_float;
+ destf = ibuf2->rect_float;
+
+ for (y = ibuf2->y; y > 0; y--) {
+ p1 = _p1;
+ p1f = _p1f;
+ for (x = ibuf2->x; x > 0; x--) {
+ if (do_rect) {
+ a = *(p1++);
+ b = *(p1++);
+ g = *(p1++);
+ r = *(p1++);
+ a += *(p1++);
+ b += *(p1++);
+ g += *(p1++);
+ r += *(p1++);
+ *(dest++) = a >> 1;
+ *(dest++) = b >> 1;
+ *(dest++) = g >> 1;
+ *(dest++) = r >> 1;
+ }
+ if (do_float) {
+ af = *(p1f++);
+ bf = *(p1f++);
+ gf = *(p1f++);
+ rf = *(p1f++);
+ af += *(p1f++);
+ bf += *(p1f++);
+ gf += *(p1f++);
+ rf += *(p1f++);
+ *(destf++) = 0.5f * af;
+ *(destf++) = 0.5f * bf;
+ *(destf++) = 0.5f * gf;
+ *(destf++) = 0.5f * rf;
+ }
+ }
+ if (do_rect)
+ _p1 += (ibuf1->x << 2);
+ if (do_float)
+ _p1f += (ibuf1->x << 2);
+ }
}
struct ImBuf *IMB_half_x(struct ImBuf *ibuf1)
{
- struct ImBuf *ibuf2;
+ struct ImBuf *ibuf2;
- if (ibuf1 == NULL) return (NULL);
- if (ibuf1->rect == NULL && ibuf1->rect_float == NULL) return (NULL);
+ if (ibuf1 == NULL)
+ return (NULL);
+ if (ibuf1->rect == NULL && ibuf1->rect_float == NULL)
+ return (NULL);
- if (ibuf1->x <= 1) return(IMB_dupImBuf(ibuf1));
+ if (ibuf1->x <= 1)
+ return (IMB_dupImBuf(ibuf1));
- ibuf2 = IMB_allocImBuf((ibuf1->x) / 2, ibuf1->y, ibuf1->planes, ibuf1->flags);
- if (ibuf2 == NULL) return (NULL);
+ ibuf2 = IMB_allocImBuf((ibuf1->x) / 2, ibuf1->y, ibuf1->planes, ibuf1->flags);
+ if (ibuf2 == NULL)
+ return (NULL);
- imb_half_x_no_alloc(ibuf2, ibuf1);
+ imb_half_x_no_alloc(ibuf2, ibuf1);
- return (ibuf2);
+ return (ibuf2);
}
struct ImBuf *IMB_double_fast_x(struct ImBuf *ibuf1)
{
- struct ImBuf *ibuf2;
- int *p1, *dest, i, col, do_rect, do_float;
- float *p1f, *destf;
-
- if (ibuf1 == NULL) return (NULL);
- if (ibuf1->rect == NULL && ibuf1->rect_float == NULL) return (NULL);
-
- do_rect = (ibuf1->rect != NULL);
- do_float = (ibuf1->rect_float != NULL);
-
- ibuf2 = IMB_allocImBuf(2 * ibuf1->x, ibuf1->y, ibuf1->planes, ibuf1->flags);
- if (ibuf2 == NULL) return (NULL);
-
- p1 = (int *) ibuf1->rect;
- dest = (int *) ibuf2->rect;
- p1f = (float *)ibuf1->rect_float;
- destf = (float *)ibuf2->rect_float;
-
- for (i = ibuf1->y * ibuf1->x; i > 0; i--) {
- if (do_rect) {
- col = *p1++;
- *dest++ = col;
- *dest++ = col;
- }
- if (do_float) {
- destf[0] = destf[4] = p1f[0];
- destf[1] = destf[5] = p1f[1];
- destf[2] = destf[6] = p1f[2];
- destf[3] = destf[7] = p1f[3];
- destf += 8;
- p1f += 4;
- }
- }
-
- return (ibuf2);
+ struct ImBuf *ibuf2;
+ int *p1, *dest, i, col, do_rect, do_float;
+ float *p1f, *destf;
+
+ if (ibuf1 == NULL)
+ return (NULL);
+ if (ibuf1->rect == NULL && ibuf1->rect_float == NULL)
+ return (NULL);
+
+ do_rect = (ibuf1->rect != NULL);
+ do_float = (ibuf1->rect_float != NULL);
+
+ ibuf2 = IMB_allocImBuf(2 * ibuf1->x, ibuf1->y, ibuf1->planes, ibuf1->flags);
+ if (ibuf2 == NULL)
+ return (NULL);
+
+ p1 = (int *)ibuf1->rect;
+ dest = (int *)ibuf2->rect;
+ p1f = (float *)ibuf1->rect_float;
+ destf = (float *)ibuf2->rect_float;
+
+ for (i = ibuf1->y * ibuf1->x; i > 0; i--) {
+ if (do_rect) {
+ col = *p1++;
+ *dest++ = col;
+ *dest++ = col;
+ }
+ if (do_float) {
+ destf[0] = destf[4] = p1f[0];
+ destf[1] = destf[5] = p1f[1];
+ destf[2] = destf[6] = p1f[2];
+ destf[3] = destf[7] = p1f[3];
+ destf += 8;
+ p1f += 4;
+ }
+ }
+
+ return (ibuf2);
}
struct ImBuf *IMB_double_x(struct ImBuf *ibuf1)
{
- struct ImBuf *ibuf2;
+ struct ImBuf *ibuf2;
- if (ibuf1 == NULL) return (NULL);
- if (ibuf1->rect == NULL && ibuf1->rect_float == NULL) return (NULL);
+ if (ibuf1 == NULL)
+ return (NULL);
+ if (ibuf1->rect == NULL && ibuf1->rect_float == NULL)
+ return (NULL);
- ibuf2 = IMB_double_fast_x(ibuf1);
+ ibuf2 = IMB_double_fast_x(ibuf1);
- imb_filterx(ibuf2);
- return (ibuf2);
+ imb_filterx(ibuf2);
+ return (ibuf2);
}
-
static void imb_half_y_no_alloc(struct ImBuf *ibuf2, struct ImBuf *ibuf1)
{
- uchar *p1, *p2, *_p1, *dest;
- short a, r, g, b;
- int x, y;
- int do_rect, do_float;
- float af, rf, gf, bf, *p1f, *p2f, *_p1f, *destf;
-
- p1 = p2 = NULL;
- p1f = p2f = NULL;
-
- do_rect = (ibuf1->rect != NULL);
- do_float = (ibuf1->rect_float != NULL && ibuf2->rect_float != NULL);
-
- _p1 = (uchar *) ibuf1->rect;
- dest = (uchar *) ibuf2->rect;
- _p1f = (float *) ibuf1->rect_float;
- destf = (float *) ibuf2->rect_float;
-
- for (y = ibuf2->y; y > 0; y--) {
- if (do_rect) {
- p1 = _p1;
- p2 = _p1 + (ibuf1->x << 2);
- }
- if (do_float) {
- p1f = _p1f;
- p2f = _p1f + (ibuf1->x << 2);
- }
- for (x = ibuf2->x; x > 0; x--) {
- if (do_rect) {
- a = *(p1++);
- b = *(p1++);
- g = *(p1++);
- r = *(p1++);
- a += *(p2++);
- b += *(p2++);
- g += *(p2++);
- r += *(p2++);
- *(dest++) = a >> 1;
- *(dest++) = b >> 1;
- *(dest++) = g >> 1;
- *(dest++) = r >> 1;
- }
- if (do_float) {
- af = *(p1f++);
- bf = *(p1f++);
- gf = *(p1f++);
- rf = *(p1f++);
- af += *(p2f++);
- bf += *(p2f++);
- gf += *(p2f++);
- rf += *(p2f++);
- *(destf++) = 0.5f * af;
- *(destf++) = 0.5f * bf;
- *(destf++) = 0.5f * gf;
- *(destf++) = 0.5f * rf;
- }
- }
- if (do_rect) _p1 += (ibuf1->x << 3);
- if (do_float) _p1f += (ibuf1->x << 3);
- }
+ uchar *p1, *p2, *_p1, *dest;
+ short a, r, g, b;
+ int x, y;
+ int do_rect, do_float;
+ float af, rf, gf, bf, *p1f, *p2f, *_p1f, *destf;
+
+ p1 = p2 = NULL;
+ p1f = p2f = NULL;
+
+ do_rect = (ibuf1->rect != NULL);
+ do_float = (ibuf1->rect_float != NULL && ibuf2->rect_float != NULL);
+
+ _p1 = (uchar *)ibuf1->rect;
+ dest = (uchar *)ibuf2->rect;
+ _p1f = (float *)ibuf1->rect_float;
+ destf = (float *)ibuf2->rect_float;
+
+ for (y = ibuf2->y; y > 0; y--) {
+ if (do_rect) {
+ p1 = _p1;
+ p2 = _p1 + (ibuf1->x << 2);
+ }
+ if (do_float) {
+ p1f = _p1f;
+ p2f = _p1f + (ibuf1->x << 2);
+ }
+ for (x = ibuf2->x; x > 0; x--) {
+ if (do_rect) {
+ a = *(p1++);
+ b = *(p1++);
+ g = *(p1++);
+ r = *(p1++);
+ a += *(p2++);
+ b += *(p2++);
+ g += *(p2++);
+ r += *(p2++);
+ *(dest++) = a >> 1;
+ *(dest++) = b >> 1;
+ *(dest++) = g >> 1;
+ *(dest++) = r >> 1;
+ }
+ if (do_float) {
+ af = *(p1f++);
+ bf = *(p1f++);
+ gf = *(p1f++);
+ rf = *(p1f++);
+ af += *(p2f++);
+ bf += *(p2f++);
+ gf += *(p2f++);
+ rf += *(p2f++);
+ *(destf++) = 0.5f * af;
+ *(destf++) = 0.5f * bf;
+ *(destf++) = 0.5f * gf;
+ *(destf++) = 0.5f * rf;
+ }
+ }
+ if (do_rect)
+ _p1 += (ibuf1->x << 3);
+ if (do_float)
+ _p1f += (ibuf1->x << 3);
+ }
}
-
struct ImBuf *IMB_half_y(struct ImBuf *ibuf1)
{
- struct ImBuf *ibuf2;
+ struct ImBuf *ibuf2;
- if (ibuf1 == NULL) return (NULL);
- if (ibuf1->rect == NULL && ibuf1->rect_float == NULL) return (NULL);
+ if (ibuf1 == NULL)
+ return (NULL);
+ if (ibuf1->rect == NULL && ibuf1->rect_float == NULL)
+ return (NULL);
- if (ibuf1->y <= 1) return(IMB_dupImBuf(ibuf1));
+ if (ibuf1->y <= 1)
+ return (IMB_dupImBuf(ibuf1));
- ibuf2 = IMB_allocImBuf(ibuf1->x, (ibuf1->y) / 2, ibuf1->planes, ibuf1->flags);
- if (ibuf2 == NULL) return (NULL);
+ ibuf2 = IMB_allocImBuf(ibuf1->x, (ibuf1->y) / 2, ibuf1->planes, ibuf1->flags);
+ if (ibuf2 == NULL)
+ return (NULL);
- imb_half_y_no_alloc(ibuf2, ibuf1);
+ imb_half_y_no_alloc(ibuf2, ibuf1);
- return (ibuf2);
+ return (ibuf2);
}
-
struct ImBuf *IMB_double_fast_y(struct ImBuf *ibuf1)
{
- struct ImBuf *ibuf2;
- int *p1, *dest1, *dest2;
- float *p1f, *dest1f, *dest2f;
- int x, y;
- int do_rect, do_float;
-
- if (ibuf1 == NULL) return (NULL);
- if (ibuf1->rect == NULL && ibuf1->rect_float == NULL) return (NULL);
-
- do_rect = (ibuf1->rect != NULL);
- do_float = (ibuf1->rect_float != NULL);
-
- ibuf2 = IMB_allocImBuf(ibuf1->x, 2 * ibuf1->y, ibuf1->planes, ibuf1->flags);
- if (ibuf2 == NULL) return (NULL);
-
- p1 = (int *) ibuf1->rect;
- dest1 = (int *) ibuf2->rect;
- p1f = (float *) ibuf1->rect_float;
- dest1f = (float *) ibuf2->rect_float;
-
- for (y = ibuf1->y; y > 0; y--) {
- if (do_rect) {
- dest2 = dest1 + ibuf2->x;
- for (x = ibuf2->x; x > 0; x--) *dest1++ = *dest2++ = *p1++;
- dest1 = dest2;
- }
- if (do_float) {
- dest2f = dest1f + (4 * ibuf2->x);
- for (x = ibuf2->x * 4; x > 0; x--) *dest1f++ = *dest2f++ = *p1f++;
- dest1f = dest2f;
- }
- }
-
- return (ibuf2);
+ struct ImBuf *ibuf2;
+ int *p1, *dest1, *dest2;
+ float *p1f, *dest1f, *dest2f;
+ int x, y;
+ int do_rect, do_float;
+
+ if (ibuf1 == NULL)
+ return (NULL);
+ if (ibuf1->rect == NULL && ibuf1->rect_float == NULL)
+ return (NULL);
+
+ do_rect = (ibuf1->rect != NULL);
+ do_float = (ibuf1->rect_float != NULL);
+
+ ibuf2 = IMB_allocImBuf(ibuf1->x, 2 * ibuf1->y, ibuf1->planes, ibuf1->flags);
+ if (ibuf2 == NULL)
+ return (NULL);
+
+ p1 = (int *)ibuf1->rect;
+ dest1 = (int *)ibuf2->rect;
+ p1f = (float *)ibuf1->rect_float;
+ dest1f = (float *)ibuf2->rect_float;
+
+ for (y = ibuf1->y; y > 0; y--) {
+ if (do_rect) {
+ dest2 = dest1 + ibuf2->x;
+ for (x = ibuf2->x; x > 0; x--)
+ *dest1++ = *dest2++ = *p1++;
+ dest1 = dest2;
+ }
+ if (do_float) {
+ dest2f = dest1f + (4 * ibuf2->x);
+ for (x = ibuf2->x * 4; x > 0; x--)
+ *dest1f++ = *dest2f++ = *p1f++;
+ dest1f = dest2f;
+ }
+ }
+
+ return (ibuf2);
}
struct ImBuf *IMB_double_y(struct ImBuf *ibuf1)
{
- struct ImBuf *ibuf2;
+ struct ImBuf *ibuf2;
- if (ibuf1 == NULL) return (NULL);
- if (ibuf1->rect == NULL) return (NULL);
+ if (ibuf1 == NULL)
+ return (NULL);
+ if (ibuf1->rect == NULL)
+ return (NULL);
- ibuf2 = IMB_double_fast_y(ibuf1);
+ ibuf2 = IMB_double_fast_y(ibuf1);
- IMB_filtery(ibuf2);
- return (ibuf2);
+ IMB_filtery(ibuf2);
+ return (ibuf2);
}
/* pretty much specific functions which converts uchar <-> ushort but assumes
* ushort range of 255*255 which is more convenient here
*/
-MINLINE void straight_uchar_to_premul_ushort(unsigned short result[4], const unsigned char color[4])
+MINLINE void straight_uchar_to_premul_ushort(unsigned short result[4],
+ const unsigned char color[4])
{
- unsigned short alpha = color[3];
+ unsigned short alpha = color[3];
- result[0] = color[0] * alpha;
- result[1] = color[1] * alpha;
- result[2] = color[2] * alpha;
- result[3] = alpha * 256;
+ result[0] = color[0] * alpha;
+ result[1] = color[1] * alpha;
+ result[2] = color[2] * alpha;
+ result[3] = alpha * 256;
}
MINLINE void premul_ushort_to_straight_uchar(unsigned char *result, const unsigned short color[4])
{
- if (color[3] <= 255) {
- result[0] = unit_ushort_to_uchar(color[0]);
- result[1] = unit_ushort_to_uchar(color[1]);
- result[2] = unit_ushort_to_uchar(color[2]);
- result[3] = unit_ushort_to_uchar(color[3]);
- }
- else {
- unsigned short alpha = color[3] / 256;
-
- result[0] = unit_ushort_to_uchar((ushort)(color[0] / alpha * 256));
- result[1] = unit_ushort_to_uchar((ushort)(color[1] / alpha * 256));
- result[2] = unit_ushort_to_uchar((ushort)(color[2] / alpha * 256));
- result[3] = unit_ushort_to_uchar(color[3]);
- }
+ if (color[3] <= 255) {
+ result[0] = unit_ushort_to_uchar(color[0]);
+ result[1] = unit_ushort_to_uchar(color[1]);
+ result[2] = unit_ushort_to_uchar(color[2]);
+ result[3] = unit_ushort_to_uchar(color[3]);
+ }
+ else {
+ unsigned short alpha = color[3] / 256;
+
+ result[0] = unit_ushort_to_uchar((ushort)(color[0] / alpha * 256));
+ result[1] = unit_ushort_to_uchar((ushort)(color[1] / alpha * 256));
+ result[2] = unit_ushort_to_uchar((ushort)(color[2] / alpha * 256));
+ result[3] = unit_ushort_to_uchar(color[3]);
+ }
}
/* result in ibuf2, scaling should be done correctly */
void imb_onehalf_no_alloc(struct ImBuf *ibuf2, struct ImBuf *ibuf1)
{
- int x, y;
- const short do_rect = (ibuf1->rect != NULL);
- const short do_float = (ibuf1->rect_float != NULL) && (ibuf2->rect_float != NULL);
-
- if (do_rect && (ibuf2->rect == NULL)) {
- imb_addrectImBuf(ibuf2);
- }
-
- if (ibuf1->x <= 1) {
- imb_half_y_no_alloc(ibuf2, ibuf1);
- return;
- }
- if (ibuf1->y <= 1) {
- imb_half_x_no_alloc(ibuf2, ibuf1);
- return;
- }
-
- if (do_rect) {
- unsigned char *cp1, *cp2, *dest;
-
- cp1 = (unsigned char *) ibuf1->rect;
- dest = (unsigned char *) ibuf2->rect;
-
- for (y = ibuf2->y; y > 0; y--) {
- cp2 = cp1 + (ibuf1->x << 2);
- for (x = ibuf2->x; x > 0; x--) {
- unsigned short p1i[8], p2i[8], desti[4];
-
- straight_uchar_to_premul_ushort(p1i, cp1);
- straight_uchar_to_premul_ushort(p2i, cp2);
- straight_uchar_to_premul_ushort(p1i + 4, cp1 + 4);
- straight_uchar_to_premul_ushort(p2i + 4, cp2 + 4);
-
- desti[0] = ((unsigned int) p1i[0] + p2i[0] + p1i[4] + p2i[4]) >> 2;
- desti[1] = ((unsigned int) p1i[1] + p2i[1] + p1i[5] + p2i[5]) >> 2;
- desti[2] = ((unsigned int) p1i[2] + p2i[2] + p1i[6] + p2i[6]) >> 2;
- desti[3] = ((unsigned int) p1i[3] + p2i[3] + p1i[7] + p2i[7]) >> 2;
-
- premul_ushort_to_straight_uchar(dest, desti);
-
- cp1 += 8;
- cp2 += 8;
- dest += 4;
- }
- cp1 = cp2;
- if (ibuf1->x & 1) cp1 += 4;
- }
- }
-
- if (do_float) {
- float *p1f, *p2f, *destf;
-
- p1f = ibuf1->rect_float;
- destf = ibuf2->rect_float;
- for (y = ibuf2->y; y > 0; y--) {
- p2f = p1f + (ibuf1->x << 2);
- for (x = ibuf2->x; x > 0; x--) {
- destf[0] = 0.25f * (p1f[0] + p2f[0] + p1f[4] + p2f[4]);
- destf[1] = 0.25f * (p1f[1] + p2f[1] + p1f[5] + p2f[5]);
- destf[2] = 0.25f * (p1f[2] + p2f[2] + p1f[6] + p2f[6]);
- destf[3] = 0.25f * (p1f[3] + p2f[3] + p1f[7] + p2f[7]);
- p1f += 8;
- p2f += 8;
- destf += 4;
- }
- p1f = p2f;
- if (ibuf1->x & 1) p1f += 4;
- }
- }
+ int x, y;
+ const short do_rect = (ibuf1->rect != NULL);
+ const short do_float = (ibuf1->rect_float != NULL) && (ibuf2->rect_float != NULL);
+
+ if (do_rect && (ibuf2->rect == NULL)) {
+ imb_addrectImBuf(ibuf2);
+ }
+
+ if (ibuf1->x <= 1) {
+ imb_half_y_no_alloc(ibuf2, ibuf1);
+ return;
+ }
+ if (ibuf1->y <= 1) {
+ imb_half_x_no_alloc(ibuf2, ibuf1);
+ return;
+ }
+
+ if (do_rect) {
+ unsigned char *cp1, *cp2, *dest;
+
+ cp1 = (unsigned char *)ibuf1->rect;
+ dest = (unsigned char *)ibuf2->rect;
+
+ for (y = ibuf2->y; y > 0; y--) {
+ cp2 = cp1 + (ibuf1->x << 2);
+ for (x = ibuf2->x; x > 0; x--) {
+ unsigned short p1i[8], p2i[8], desti[4];
+
+ straight_uchar_to_premul_ushort(p1i, cp1);
+ straight_uchar_to_premul_ushort(p2i, cp2);
+ straight_uchar_to_premul_ushort(p1i + 4, cp1 + 4);
+ straight_uchar_to_premul_ushort(p2i + 4, cp2 + 4);
+
+ desti[0] = ((unsigned int)p1i[0] + p2i[0] + p1i[4] + p2i[4]) >> 2;
+ desti[1] = ((unsigned int)p1i[1] + p2i[1] + p1i[5] + p2i[5]) >> 2;
+ desti[2] = ((unsigned int)p1i[2] + p2i[2] + p1i[6] + p2i[6]) >> 2;
+ desti[3] = ((unsigned int)p1i[3] + p2i[3] + p1i[7] + p2i[7]) >> 2;
+
+ premul_ushort_to_straight_uchar(dest, desti);
+
+ cp1 += 8;
+ cp2 += 8;
+ dest += 4;
+ }
+ cp1 = cp2;
+ if (ibuf1->x & 1)
+ cp1 += 4;
+ }
+ }
+
+ if (do_float) {
+ float *p1f, *p2f, *destf;
+
+ p1f = ibuf1->rect_float;
+ destf = ibuf2->rect_float;
+ for (y = ibuf2->y; y > 0; y--) {
+ p2f = p1f + (ibuf1->x << 2);
+ for (x = ibuf2->x; x > 0; x--) {
+ destf[0] = 0.25f * (p1f[0] + p2f[0] + p1f[4] + p2f[4]);
+ destf[1] = 0.25f * (p1f[1] + p2f[1] + p1f[5] + p2f[5]);
+ destf[2] = 0.25f * (p1f[2] + p2f[2] + p1f[6] + p2f[6]);
+ destf[3] = 0.25f * (p1f[3] + p2f[3] + p1f[7] + p2f[7]);
+ p1f += 8;
+ p2f += 8;
+ destf += 4;
+ }
+ p1f = p2f;
+ if (ibuf1->x & 1)
+ p1f += 4;
+ }
+ }
}
ImBuf *IMB_onehalf(struct ImBuf *ibuf1)
{
- struct ImBuf *ibuf2;
+ struct ImBuf *ibuf2;
- if (ibuf1 == NULL) return (NULL);
- if (ibuf1->rect == NULL && ibuf1->rect_float == NULL) return (NULL);
+ if (ibuf1 == NULL)
+ return (NULL);
+ if (ibuf1->rect == NULL && ibuf1->rect_float == NULL)
+ return (NULL);
- if (ibuf1->x <= 1) return(IMB_half_y(ibuf1));
- if (ibuf1->y <= 1) return(IMB_half_x(ibuf1));
+ if (ibuf1->x <= 1)
+ return (IMB_half_y(ibuf1));
+ if (ibuf1->y <= 1)
+ return (IMB_half_x(ibuf1));
- ibuf2 = IMB_allocImBuf((ibuf1->x) / 2, (ibuf1->y) / 2, ibuf1->planes, ibuf1->flags);
- if (ibuf2 == NULL) return (NULL);
+ ibuf2 = IMB_allocImBuf((ibuf1->x) / 2, (ibuf1->y) / 2, ibuf1->planes, ibuf1->flags);
+ if (ibuf2 == NULL)
+ return (NULL);
- imb_onehalf_no_alloc(ibuf2, ibuf1);
+ imb_onehalf_no_alloc(ibuf2, ibuf1);
- return (ibuf2);
+ return (ibuf2);
}
/* q_scale_linear_interpolation helper functions */
-static void enlarge_picture_byte(
- unsigned char *src, unsigned char *dst, int src_width,
- int src_height, int dst_width, int dst_height)
+static void enlarge_picture_byte(unsigned char *src,
+ unsigned char *dst,
+ int src_width,
+ int src_height,
+ int dst_width,
+ int dst_height)
{
- double ratiox = (double) (dst_width - 1.0) / (double) (src_width - 1.001);
- double ratioy = (double) (dst_height - 1.0) / (double) (src_height - 1.001);
- uintptr_t x_src, dx_src, x_dst;
- uintptr_t y_src, dy_src, y_dst;
-
- dx_src = 65536.0 / ratiox;
- dy_src = 65536.0 / ratioy;
-
- y_src = 0;
- for (y_dst = 0; y_dst < dst_height; y_dst++) {
- unsigned char *line1 = src + (y_src >> 16) * 4 * src_width;
- unsigned char *line2 = line1 + 4 * src_width;
- uintptr_t weight1y = 65536 - (y_src & 0xffff);
- uintptr_t weight2y = 65536 - weight1y;
-
- if ((y_src >> 16) == src_height - 1) {
- line2 = line1;
- }
-
- x_src = 0;
- for (x_dst = 0; x_dst < dst_width; x_dst++) {
- uintptr_t weight1x = 65536 - (x_src & 0xffff);
- uintptr_t weight2x = 65536 - weight1x;
-
- unsigned long x = (x_src >> 16) * 4;
-
- *dst++ = ((((line1[x] * weight1y) >> 16) * weight1x) >> 16) +
- ((((line2[x] * weight2y) >> 16) * weight1x) >> 16) +
- ((((line1[4 + x] * weight1y) >> 16) * weight2x) >> 16) +
- ((((line2[4 + x] * weight2y) >> 16) * weight2x) >> 16);
-
- *dst++ = ((((line1[x + 1] * weight1y) >> 16) * weight1x) >> 16) +
- ((((line2[x + 1] * weight2y) >> 16) * weight1x) >> 16) +
- ((((line1[4 + x + 1] * weight1y) >> 16) * weight2x) >> 16) +
- ((((line2[4 + x + 1] * weight2y) >> 16) * weight2x) >> 16);
-
- *dst++ = ((((line1[x + 2] * weight1y) >> 16) * weight1x) >> 16) +
- ((((line2[x + 2] * weight2y) >> 16) * weight1x) >> 16) +
- ((((line1[4 + x + 2] * weight1y) >> 16) * weight2x) >> 16) +
- ((((line2[4 + x + 2] * weight2y) >> 16) * weight2x) >> 16);
-
- *dst++ = ((((line1[x + 3] * weight1y) >> 16) * weight1x) >> 16) +
- ((((line2[x + 3] * weight2y) >> 16) * weight1x) >> 16) +
- ((((line1[4 + x + 3] * weight1y) >> 16) * weight2x) >> 16) +
- ((((line2[4 + x + 3] * weight2y) >> 16) * weight2x) >> 16);
-
- x_src += dx_src;
- }
- y_src += dy_src;
- }
+ double ratiox = (double)(dst_width - 1.0) / (double)(src_width - 1.001);
+ double ratioy = (double)(dst_height - 1.0) / (double)(src_height - 1.001);
+ uintptr_t x_src, dx_src, x_dst;
+ uintptr_t y_src, dy_src, y_dst;
+
+ dx_src = 65536.0 / ratiox;
+ dy_src = 65536.0 / ratioy;
+
+ y_src = 0;
+ for (y_dst = 0; y_dst < dst_height; y_dst++) {
+ unsigned char *line1 = src + (y_src >> 16) * 4 * src_width;
+ unsigned char *line2 = line1 + 4 * src_width;
+ uintptr_t weight1y = 65536 - (y_src & 0xffff);
+ uintptr_t weight2y = 65536 - weight1y;
+
+ if ((y_src >> 16) == src_height - 1) {
+ line2 = line1;
+ }
+
+ x_src = 0;
+ for (x_dst = 0; x_dst < dst_width; x_dst++) {
+ uintptr_t weight1x = 65536 - (x_src & 0xffff);
+ uintptr_t weight2x = 65536 - weight1x;
+
+ unsigned long x = (x_src >> 16) * 4;
+
+ *dst++ = ((((line1[x] * weight1y) >> 16) * weight1x) >> 16) +
+ ((((line2[x] * weight2y) >> 16) * weight1x) >> 16) +
+ ((((line1[4 + x] * weight1y) >> 16) * weight2x) >> 16) +
+ ((((line2[4 + x] * weight2y) >> 16) * weight2x) >> 16);
+
+ *dst++ = ((((line1[x + 1] * weight1y) >> 16) * weight1x) >> 16) +
+ ((((line2[x + 1] * weight2y) >> 16) * weight1x) >> 16) +
+ ((((line1[4 + x + 1] * weight1y) >> 16) * weight2x) >> 16) +
+ ((((line2[4 + x + 1] * weight2y) >> 16) * weight2x) >> 16);
+
+ *dst++ = ((((line1[x + 2] * weight1y) >> 16) * weight1x) >> 16) +
+ ((((line2[x + 2] * weight2y) >> 16) * weight1x) >> 16) +
+ ((((line1[4 + x + 2] * weight1y) >> 16) * weight2x) >> 16) +
+ ((((line2[4 + x + 2] * weight2y) >> 16) * weight2x) >> 16);
+
+ *dst++ = ((((line1[x + 3] * weight1y) >> 16) * weight1x) >> 16) +
+ ((((line2[x + 3] * weight2y) >> 16) * weight1x) >> 16) +
+ ((((line1[4 + x + 3] * weight1y) >> 16) * weight2x) >> 16) +
+ ((((line2[4 + x + 3] * weight2y) >> 16) * weight2x) >> 16);
+
+ x_src += dx_src;
+ }
+ y_src += dy_src;
+ }
}
struct scale_outpix_byte {
- uintptr_t r;
- uintptr_t g;
- uintptr_t b;
- uintptr_t a;
+ uintptr_t r;
+ uintptr_t g;
+ uintptr_t b;
+ uintptr_t a;
- uintptr_t weight;
+ uintptr_t weight;
};
-static void shrink_picture_byte(
- unsigned char *src, unsigned char *dst, int src_width,
- int src_height, int dst_width, int dst_height)
+static void shrink_picture_byte(unsigned char *src,
+ unsigned char *dst,
+ int src_width,
+ int src_height,
+ int dst_width,
+ int dst_height)
{
- double ratiox = (double) (dst_width) / (double) (src_width);
- double ratioy = (double) (dst_height) / (double) (src_height);
- uintptr_t x_src, dx_dst, x_dst;
- uintptr_t y_src, dy_dst, y_dst;
- intptr_t y_counter;
- unsigned char *dst_begin = dst;
-
- struct scale_outpix_byte *dst_line1 = NULL;
- struct scale_outpix_byte *dst_line2 = NULL;
-
- dst_line1 = (struct scale_outpix_byte *) MEM_callocN(
- (dst_width + 1) * sizeof(struct scale_outpix_byte),
- "shrink_picture_byte 1");
- dst_line2 = (struct scale_outpix_byte *) MEM_callocN(
- (dst_width + 1) * sizeof(struct scale_outpix_byte),
- "shrink_picture_byte 2");
-
- dx_dst = 65536.0 * ratiox;
- dy_dst = 65536.0 * ratioy;
-
- y_dst = 0;
- y_counter = 65536;
- for (y_src = 0; y_src < src_height; y_src++) {
- unsigned char *line = src + y_src * 4 * src_width;
- uintptr_t weight1y = 65535 - (y_dst & 0xffff);
- uintptr_t weight2y = 65535 - weight1y;
- x_dst = 0;
- for (x_src = 0; x_src < src_width; x_src++) {
- uintptr_t weight1x = 65535 - (x_dst & 0xffff);
- uintptr_t weight2x = 65535 - weight1x;
-
- uintptr_t x = x_dst >> 16;
-
- uintptr_t w;
-
- w = (weight1y * weight1x) >> 16;
-
- /* ensure correct rounding, without this you get ugly banding, or too low color values (ton) */
- dst_line1[x].r += (line[0] * w + 32767) >> 16;
- dst_line1[x].g += (line[1] * w + 32767) >> 16;
- dst_line1[x].b += (line[2] * w + 32767) >> 16;
- dst_line1[x].a += (line[3] * w + 32767) >> 16;
- dst_line1[x].weight += w;
-
- w = (weight2y * weight1x) >> 16;
-
- dst_line2[x].r += (line[0] * w + 32767) >> 16;
- dst_line2[x].g += (line[1] * w + 32767) >> 16;
- dst_line2[x].b += (line[2] * w + 32767) >> 16;
- dst_line2[x].a += (line[3] * w + 32767) >> 16;
- dst_line2[x].weight += w;
-
- w = (weight1y * weight2x) >> 16;
-
- dst_line1[x + 1].r += (line[0] * w + 32767) >> 16;
- dst_line1[x + 1].g += (line[1] * w + 32767) >> 16;
- dst_line1[x + 1].b += (line[2] * w + 32767) >> 16;
- dst_line1[x + 1].a += (line[3] * w + 32767) >> 16;
- dst_line1[x + 1].weight += w;
-
- w = (weight2y * weight2x) >> 16;
-
- dst_line2[x + 1].r += (line[0] * w + 32767) >> 16;
- dst_line2[x + 1].g += (line[1] * w + 32767) >> 16;
- dst_line2[x + 1].b += (line[2] * w + 32767) >> 16;
- dst_line2[x + 1].a += (line[3] * w + 32767) >> 16;
- dst_line2[x + 1].weight += w;
-
- x_dst += dx_dst;
- line += 4;
- }
-
- y_dst += dy_dst;
- y_counter -= dy_dst;
- if (y_counter < 0) {
- int val;
- uintptr_t x;
- struct scale_outpix_byte *temp;
-
- y_counter += 65536;
-
- for (x = 0; x < dst_width; x++) {
- uintptr_t f = 0x80000000UL / dst_line1[x].weight;
- *dst++ = (val = (dst_line1[x].r * f) >> 15) > 255 ? 255 : val;
- *dst++ = (val = (dst_line1[x].g * f) >> 15) > 255 ? 255 : val;
- *dst++ = (val = (dst_line1[x].b * f) >> 15) > 255 ? 255 : val;
- *dst++ = (val = (dst_line1[x].a * f) >> 15) > 255 ? 255 : val;
- }
- memset(dst_line1, 0, dst_width *
- sizeof(struct scale_outpix_byte));
- temp = dst_line1;
- dst_line1 = dst_line2;
- dst_line2 = temp;
- }
- }
- if (dst - dst_begin < dst_width * dst_height * 4) {
- int val;
- uintptr_t x;
- for (x = 0; x < dst_width; x++) {
- uintptr_t f = 0x80000000UL / dst_line1[x].weight;
- *dst++ = (val = (dst_line1[x].r * f) >> 15) > 255 ? 255 : val;
- *dst++ = (val = (dst_line1[x].g * f) >> 15) > 255 ? 255 : val;
- *dst++ = (val = (dst_line1[x].b * f) >> 15) > 255 ? 255 : val;
- *dst++ = (val = (dst_line1[x].a * f) >> 15) > 255 ? 255 : val;
- }
- }
- MEM_freeN(dst_line1);
- MEM_freeN(dst_line2);
+ double ratiox = (double)(dst_width) / (double)(src_width);
+ double ratioy = (double)(dst_height) / (double)(src_height);
+ uintptr_t x_src, dx_dst, x_dst;
+ uintptr_t y_src, dy_dst, y_dst;
+ intptr_t y_counter;
+ unsigned char *dst_begin = dst;
+
+ struct scale_outpix_byte *dst_line1 = NULL;
+ struct scale_outpix_byte *dst_line2 = NULL;
+
+ dst_line1 = (struct scale_outpix_byte *)MEM_callocN(
+ (dst_width + 1) * sizeof(struct scale_outpix_byte), "shrink_picture_byte 1");
+ dst_line2 = (struct scale_outpix_byte *)MEM_callocN(
+ (dst_width + 1) * sizeof(struct scale_outpix_byte), "shrink_picture_byte 2");
+
+ dx_dst = 65536.0 * ratiox;
+ dy_dst = 65536.0 * ratioy;
+
+ y_dst = 0;
+ y_counter = 65536;
+ for (y_src = 0; y_src < src_height; y_src++) {
+ unsigned char *line = src + y_src * 4 * src_width;
+ uintptr_t weight1y = 65535 - (y_dst & 0xffff);
+ uintptr_t weight2y = 65535 - weight1y;
+ x_dst = 0;
+ for (x_src = 0; x_src < src_width; x_src++) {
+ uintptr_t weight1x = 65535 - (x_dst & 0xffff);
+ uintptr_t weight2x = 65535 - weight1x;
+
+ uintptr_t x = x_dst >> 16;
+
+ uintptr_t w;
+
+ w = (weight1y * weight1x) >> 16;
+
+ /* ensure correct rounding, without this you get ugly banding, or too low color values (ton) */
+ dst_line1[x].r += (line[0] * w + 32767) >> 16;
+ dst_line1[x].g += (line[1] * w + 32767) >> 16;
+ dst_line1[x].b += (line[2] * w + 32767) >> 16;
+ dst_line1[x].a += (line[3] * w + 32767) >> 16;
+ dst_line1[x].weight += w;
+
+ w = (weight2y * weight1x) >> 16;
+
+ dst_line2[x].r += (line[0] * w + 32767) >> 16;
+ dst_line2[x].g += (line[1] * w + 32767) >> 16;
+ dst_line2[x].b += (line[2] * w + 32767) >> 16;
+ dst_line2[x].a += (line[3] * w + 32767) >> 16;
+ dst_line2[x].weight += w;
+
+ w = (weight1y * weight2x) >> 16;
+
+ dst_line1[x + 1].r += (line[0] * w + 32767) >> 16;
+ dst_line1[x + 1].g += (line[1] * w + 32767) >> 16;
+ dst_line1[x + 1].b += (line[2] * w + 32767) >> 16;
+ dst_line1[x + 1].a += (line[3] * w + 32767) >> 16;
+ dst_line1[x + 1].weight += w;
+
+ w = (weight2y * weight2x) >> 16;
+
+ dst_line2[x + 1].r += (line[0] * w + 32767) >> 16;
+ dst_line2[x + 1].g += (line[1] * w + 32767) >> 16;
+ dst_line2[x + 1].b += (line[2] * w + 32767) >> 16;
+ dst_line2[x + 1].a += (line[3] * w + 32767) >> 16;
+ dst_line2[x + 1].weight += w;
+
+ x_dst += dx_dst;
+ line += 4;
+ }
+
+ y_dst += dy_dst;
+ y_counter -= dy_dst;
+ if (y_counter < 0) {
+ int val;
+ uintptr_t x;
+ struct scale_outpix_byte *temp;
+
+ y_counter += 65536;
+
+ for (x = 0; x < dst_width; x++) {
+ uintptr_t f = 0x80000000UL / dst_line1[x].weight;
+ *dst++ = (val = (dst_line1[x].r * f) >> 15) > 255 ? 255 : val;
+ *dst++ = (val = (dst_line1[x].g * f) >> 15) > 255 ? 255 : val;
+ *dst++ = (val = (dst_line1[x].b * f) >> 15) > 255 ? 255 : val;
+ *dst++ = (val = (dst_line1[x].a * f) >> 15) > 255 ? 255 : val;
+ }
+ memset(dst_line1, 0, dst_width * sizeof(struct scale_outpix_byte));
+ temp = dst_line1;
+ dst_line1 = dst_line2;
+ dst_line2 = temp;
+ }
+ }
+ if (dst - dst_begin < dst_width * dst_height * 4) {
+ int val;
+ uintptr_t x;
+ for (x = 0; x < dst_width; x++) {
+ uintptr_t f = 0x80000000UL / dst_line1[x].weight;
+ *dst++ = (val = (dst_line1[x].r * f) >> 15) > 255 ? 255 : val;
+ *dst++ = (val = (dst_line1[x].g * f) >> 15) > 255 ? 255 : val;
+ *dst++ = (val = (dst_line1[x].b * f) >> 15) > 255 ? 255 : val;
+ *dst++ = (val = (dst_line1[x].a * f) >> 15) > 255 ? 255 : val;
+ }
+ }
+ MEM_freeN(dst_line1);
+ MEM_freeN(dst_line2);
}
-
-static void q_scale_byte(unsigned char *in, unsigned char *out, int in_width,
- int in_height, int dst_width, int dst_height)
+static void q_scale_byte(unsigned char *in,
+ unsigned char *out,
+ int in_width,
+ int in_height,
+ int dst_width,
+ int dst_height)
{
- if (dst_width > in_width && dst_height > in_height) {
- enlarge_picture_byte(in, out, in_width, in_height,
- dst_width, dst_height);
- }
- else if (dst_width < in_width && dst_height < in_height) {
- shrink_picture_byte(in, out, in_width, in_height,
- dst_width, dst_height);
- }
+ if (dst_width > in_width && dst_height > in_height) {
+ enlarge_picture_byte(in, out, in_width, in_height, dst_width, dst_height);
+ }
+ else if (dst_width < in_width && dst_height < in_height) {
+ shrink_picture_byte(in, out, in_width, in_height, dst_width, dst_height);
+ }
}
static void enlarge_picture_float(
- float *src, float *dst, int src_width,
- int src_height, int dst_width, int dst_height)
+ float *src, float *dst, int src_width, int src_height, int dst_width, int dst_height)
{
- double ratiox = (double) (dst_width - 1.0) / (double) (src_width - 1.001);
- double ratioy = (double) (dst_height - 1.0) / (double) (src_height - 1.001);
- uintptr_t x_dst;
- uintptr_t y_dst;
- double x_src, dx_src;
- double y_src, dy_src;
-
- dx_src = 1.0 / ratiox;
- dy_src = 1.0 / ratioy;
-
- y_src = 0;
- for (y_dst = 0; y_dst < dst_height; y_dst++) {
- float *line1 = src + ((int) y_src) * 4 * src_width;
- const float *line2 = line1 + 4 * src_width;
- const float weight1y = (float)(1.0 - (y_src - (int) y_src));
- const float weight2y = 1.0f - weight1y;
-
- if ((int) y_src == src_height - 1) {
- line2 = line1;
- }
-
- x_src = 0;
- for (x_dst = 0; x_dst < dst_width; x_dst++) {
- const float weight1x = (float)(1.0 - (x_src - (int) x_src));
- const float weight2x = (float)(1.0f - weight1x);
-
- const float w11 = weight1y * weight1x;
- const float w21 = weight2y * weight1x;
- const float w12 = weight1y * weight2x;
- const float w22 = weight2y * weight2x;
-
- uintptr_t x = ((int) x_src) * 4;
-
- *dst++ = line1[x] * w11 +
- line2[x] * w21 +
- line1[4 + x] * w12 +
- line2[4 + x] * w22;
-
- *dst++ = line1[x + 1] * w11 +
- line2[x + 1] * w21 +
- line1[4 + x + 1] * w12 +
- line2[4 + x + 1] * w22;
-
- *dst++ = line1[x + 2] * w11 +
- line2[x + 2] * w21 +
- line1[4 + x + 2] * w12 +
- line2[4 + x + 2] * w22;
-
- *dst++ = line1[x + 3] * w11 +
- line2[x + 3] * w21 +
- line1[4 + x + 3] * w12 +
- line2[4 + x + 3] * w22;
-
- x_src += dx_src;
- }
- y_src += dy_src;
- }
+ double ratiox = (double)(dst_width - 1.0) / (double)(src_width - 1.001);
+ double ratioy = (double)(dst_height - 1.0) / (double)(src_height - 1.001);
+ uintptr_t x_dst;
+ uintptr_t y_dst;
+ double x_src, dx_src;
+ double y_src, dy_src;
+
+ dx_src = 1.0 / ratiox;
+ dy_src = 1.0 / ratioy;
+
+ y_src = 0;
+ for (y_dst = 0; y_dst < dst_height; y_dst++) {
+ float *line1 = src + ((int)y_src) * 4 * src_width;
+ const float *line2 = line1 + 4 * src_width;
+ const float weight1y = (float)(1.0 - (y_src - (int)y_src));
+ const float weight2y = 1.0f - weight1y;
+
+ if ((int)y_src == src_height - 1) {
+ line2 = line1;
+ }
+
+ x_src = 0;
+ for (x_dst = 0; x_dst < dst_width; x_dst++) {
+ const float weight1x = (float)(1.0 - (x_src - (int)x_src));
+ const float weight2x = (float)(1.0f - weight1x);
+
+ const float w11 = weight1y * weight1x;
+ const float w21 = weight2y * weight1x;
+ const float w12 = weight1y * weight2x;
+ const float w22 = weight2y * weight2x;
+
+ uintptr_t x = ((int)x_src) * 4;
+
+ *dst++ = line1[x] * w11 + line2[x] * w21 + line1[4 + x] * w12 + line2[4 + x] * w22;
+
+ *dst++ = line1[x + 1] * w11 + line2[x + 1] * w21 + line1[4 + x + 1] * w12 +
+ line2[4 + x + 1] * w22;
+
+ *dst++ = line1[x + 2] * w11 + line2[x + 2] * w21 + line1[4 + x + 2] * w12 +
+ line2[4 + x + 2] * w22;
+
+ *dst++ = line1[x + 3] * w11 + line2[x + 3] * w21 + line1[4 + x + 3] * w12 +
+ line2[4 + x + 3] * w22;
+
+ x_src += dx_src;
+ }
+ y_src += dy_src;
+ }
}
struct scale_outpix_float {
- float r;
- float g;
- float b;
- float a;
+ float r;
+ float g;
+ float b;
+ float a;
- float weight;
+ float weight;
};
static void shrink_picture_float(
- const float *src, float *dst, int src_width,
- int src_height, int dst_width, int dst_height)
+ const float *src, float *dst, int src_width, int src_height, int dst_width, int dst_height)
{
- double ratiox = (double) (dst_width) / (double) (src_width);
- double ratioy = (double) (dst_height) / (double) (src_height);
- uintptr_t x_src;
- uintptr_t y_src;
- float dx_dst, x_dst;
- float dy_dst, y_dst;
- float y_counter;
- const float *dst_begin = dst;
-
- struct scale_outpix_float *dst_line1;
- struct scale_outpix_float *dst_line2;
-
- dst_line1 = (struct scale_outpix_float *) MEM_callocN(
- (dst_width + 1) * sizeof(struct scale_outpix_float),
- "shrink_picture_float 1");
- dst_line2 = (struct scale_outpix_float *) MEM_callocN(
- (dst_width + 1) * sizeof(struct scale_outpix_float),
- "shrink_picture_float 2");
-
- dx_dst = ratiox;
- dy_dst = ratioy;
-
- y_dst = 0;
- y_counter = 1.0;
- for (y_src = 0; y_src < src_height; y_src++) {
- const float *line = src + y_src * 4 * src_width;
- uintptr_t weight1y = 1.0f - (y_dst - (int) y_dst);
- uintptr_t weight2y = 1.0f - weight1y;
- x_dst = 0;
- for (x_src = 0; x_src < src_width; x_src++) {
- uintptr_t weight1x = 1.0f - (x_dst - (int) x_dst);
- uintptr_t weight2x = 1.0f - weight1x;
-
- uintptr_t x = (int) x_dst;
-
- float w;
-
- w = weight1y * weight1x;
-
- dst_line1[x].r += line[0] * w;
- dst_line1[x].g += line[1] * w;
- dst_line1[x].b += line[2] * w;
- dst_line1[x].a += line[3] * w;
- dst_line1[x].weight += w;
-
- w = weight2y * weight1x;
-
- dst_line2[x].r += line[0] * w;
- dst_line2[x].g += line[1] * w;
- dst_line2[x].b += line[2] * w;
- dst_line2[x].a += line[3] * w;
- dst_line2[x].weight += w;
-
- w = weight1y * weight2x;
-
- dst_line1[x + 1].r += line[0] * w;
- dst_line1[x + 1].g += line[1] * w;
- dst_line1[x + 1].b += line[2] * w;
- dst_line1[x + 1].a += line[3] * w;
- dst_line1[x + 1].weight += w;
-
- w = weight2y * weight2x;
-
- dst_line2[x + 1].r += line[0] * w;
- dst_line2[x + 1].g += line[1] * w;
- dst_line2[x + 1].b += line[2] * w;
- dst_line2[x + 1].a += line[3] * w;
- dst_line2[x + 1].weight += w;
-
- x_dst += dx_dst;
- line += 4;
- }
-
- y_dst += dy_dst;
- y_counter -= dy_dst;
- if (y_counter < 0) {
- uintptr_t x;
- struct scale_outpix_float *temp;
-
- y_counter += 1.0f;
-
- for (x = 0; x < dst_width; x++) {
- float f = 1.0f / dst_line1[x].weight;
- *dst++ = dst_line1[x].r * f;
- *dst++ = dst_line1[x].g * f;
- *dst++ = dst_line1[x].b * f;
- *dst++ = dst_line1[x].a * f;
- }
- memset(dst_line1, 0, dst_width *
- sizeof(struct scale_outpix_float));
- temp = dst_line1;
- dst_line1 = dst_line2;
- dst_line2 = temp;
- }
- }
- if (dst - dst_begin < dst_width * dst_height * 4) {
- uintptr_t x;
- for (x = 0; x < dst_width; x++) {
- float f = 1.0f / dst_line1[x].weight;
- *dst++ = dst_line1[x].r * f;
- *dst++ = dst_line1[x].g * f;
- *dst++ = dst_line1[x].b * f;
- *dst++ = dst_line1[x].a * f;
- }
- }
- MEM_freeN(dst_line1);
- MEM_freeN(dst_line2);
+ double ratiox = (double)(dst_width) / (double)(src_width);
+ double ratioy = (double)(dst_height) / (double)(src_height);
+ uintptr_t x_src;
+ uintptr_t y_src;
+ float dx_dst, x_dst;
+ float dy_dst, y_dst;
+ float y_counter;
+ const float *dst_begin = dst;
+
+ struct scale_outpix_float *dst_line1;
+ struct scale_outpix_float *dst_line2;
+
+ dst_line1 = (struct scale_outpix_float *)MEM_callocN(
+ (dst_width + 1) * sizeof(struct scale_outpix_float), "shrink_picture_float 1");
+ dst_line2 = (struct scale_outpix_float *)MEM_callocN(
+ (dst_width + 1) * sizeof(struct scale_outpix_float), "shrink_picture_float 2");
+
+ dx_dst = ratiox;
+ dy_dst = ratioy;
+
+ y_dst = 0;
+ y_counter = 1.0;
+ for (y_src = 0; y_src < src_height; y_src++) {
+ const float *line = src + y_src * 4 * src_width;
+ uintptr_t weight1y = 1.0f - (y_dst - (int)y_dst);
+ uintptr_t weight2y = 1.0f - weight1y;
+ x_dst = 0;
+ for (x_src = 0; x_src < src_width; x_src++) {
+ uintptr_t weight1x = 1.0f - (x_dst - (int)x_dst);
+ uintptr_t weight2x = 1.0f - weight1x;
+
+ uintptr_t x = (int)x_dst;
+
+ float w;
+
+ w = weight1y * weight1x;
+
+ dst_line1[x].r += line[0] * w;
+ dst_line1[x].g += line[1] * w;
+ dst_line1[x].b += line[2] * w;
+ dst_line1[x].a += line[3] * w;
+ dst_line1[x].weight += w;
+
+ w = weight2y * weight1x;
+
+ dst_line2[x].r += line[0] * w;
+ dst_line2[x].g += line[1] * w;
+ dst_line2[x].b += line[2] * w;
+ dst_line2[x].a += line[3] * w;
+ dst_line2[x].weight += w;
+
+ w = weight1y * weight2x;
+
+ dst_line1[x + 1].r += line[0] * w;
+ dst_line1[x + 1].g += line[1] * w;
+ dst_line1[x + 1].b += line[2] * w;
+ dst_line1[x + 1].a += line[3] * w;
+ dst_line1[x + 1].weight += w;
+
+ w = weight2y * weight2x;
+
+ dst_line2[x + 1].r += line[0] * w;
+ dst_line2[x + 1].g += line[1] * w;
+ dst_line2[x + 1].b += line[2] * w;
+ dst_line2[x + 1].a += line[3] * w;
+ dst_line2[x + 1].weight += w;
+
+ x_dst += dx_dst;
+ line += 4;
+ }
+
+ y_dst += dy_dst;
+ y_counter -= dy_dst;
+ if (y_counter < 0) {
+ uintptr_t x;
+ struct scale_outpix_float *temp;
+
+ y_counter += 1.0f;
+
+ for (x = 0; x < dst_width; x++) {
+ float f = 1.0f / dst_line1[x].weight;
+ *dst++ = dst_line1[x].r * f;
+ *dst++ = dst_line1[x].g * f;
+ *dst++ = dst_line1[x].b * f;
+ *dst++ = dst_line1[x].a * f;
+ }
+ memset(dst_line1, 0, dst_width * sizeof(struct scale_outpix_float));
+ temp = dst_line1;
+ dst_line1 = dst_line2;
+ dst_line2 = temp;
+ }
+ }
+ if (dst - dst_begin < dst_width * dst_height * 4) {
+ uintptr_t x;
+ for (x = 0; x < dst_width; x++) {
+ float f = 1.0f / dst_line1[x].weight;
+ *dst++ = dst_line1[x].r * f;
+ *dst++ = dst_line1[x].g * f;
+ *dst++ = dst_line1[x].b * f;
+ *dst++ = dst_line1[x].a * f;
+ }
+ }
+ MEM_freeN(dst_line1);
+ MEM_freeN(dst_line2);
}
-
-static void q_scale_float(float *in, float *out, int in_width,
- int in_height, int dst_width, int dst_height)
+static void q_scale_float(
+ float *in, float *out, int in_width, int in_height, int dst_width, int dst_height)
{
- if (dst_width > in_width && dst_height > in_height) {
- enlarge_picture_float(in, out, in_width, in_height,
- dst_width, dst_height);
- }
- else if (dst_width < in_width && dst_height < in_height) {
- shrink_picture_float(in, out, in_width, in_height,
- dst_width, dst_height);
- }
+ if (dst_width > in_width && dst_height > in_height) {
+ enlarge_picture_float(in, out, in_width, in_height, dst_width, dst_height);
+ }
+ else if (dst_width < in_width && dst_height < in_height) {
+ shrink_picture_float(in, out, in_width, in_height, dst_width, dst_height);
+ }
}
/**
@@ -832,708 +847,724 @@ static void q_scale_float(float *in, float *out, int in_width,
*
* NOTE: disabled, due to unacceptable inaccuracy and quality loss, see bug #18609 (ton)
*/
-static bool q_scale_linear_interpolation(
- struct ImBuf *ibuf, int newx, int newy)
+static bool q_scale_linear_interpolation(struct ImBuf *ibuf, int newx, int newy)
{
- if ((newx >= ibuf->x && newy <= ibuf->y) ||
- (newx <= ibuf->x && newy >= ibuf->y))
- {
- return false;
- }
-
- if (ibuf->rect) {
- unsigned char *newrect =
- MEM_mallocN(newx * newy * sizeof(int), "q_scale rect");
- q_scale_byte((unsigned char *)ibuf->rect, newrect, ibuf->x, ibuf->y,
- newx, newy);
-
- imb_freerectImBuf(ibuf);
- ibuf->mall |= IB_rect;
- ibuf->rect = (unsigned int *) newrect;
- }
- if (ibuf->rect_float) {
- float *newrect =
- MEM_mallocN(newx * newy * 4 * sizeof(float),
- "q_scale rectfloat");
- q_scale_float(ibuf->rect_float, newrect, ibuf->x, ibuf->y,
- newx, newy);
- imb_freerectfloatImBuf(ibuf);
- ibuf->mall |= IB_rectfloat;
- ibuf->rect_float = newrect;
- }
- ibuf->x = newx;
- ibuf->y = newy;
-
- return true;
+ if ((newx >= ibuf->x && newy <= ibuf->y) || (newx <= ibuf->x && newy >= ibuf->y)) {
+ return false;
+ }
+
+ if (ibuf->rect) {
+ unsigned char *newrect = MEM_mallocN(newx * newy * sizeof(int), "q_scale rect");
+ q_scale_byte((unsigned char *)ibuf->rect, newrect, ibuf->x, ibuf->y, newx, newy);
+
+ imb_freerectImBuf(ibuf);
+ ibuf->mall |= IB_rect;
+ ibuf->rect = (unsigned int *)newrect;
+ }
+ if (ibuf->rect_float) {
+ float *newrect = MEM_mallocN(newx * newy * 4 * sizeof(float), "q_scale rectfloat");
+ q_scale_float(ibuf->rect_float, newrect, ibuf->x, ibuf->y, newx, newy);
+ imb_freerectfloatImBuf(ibuf);
+ ibuf->mall |= IB_rectfloat;
+ ibuf->rect_float = newrect;
+ }
+ ibuf->x = newx;
+ ibuf->y = newy;
+
+ return true;
}
static ImBuf *scaledownx(struct ImBuf *ibuf, int newx)
{
- const int do_rect = (ibuf->rect != NULL);
- const int do_float = (ibuf->rect_float != NULL);
- const size_t rect_size = ibuf->x * ibuf->y * 4;
-
- uchar *rect, *_newrect, *newrect;
- float *rectf, *_newrectf, *newrectf;
- float sample, add, val[4], nval[4], valf[4], nvalf[4];
- int x, y;
-
- rectf = _newrectf = newrectf = NULL;
- rect = _newrect = newrect = NULL;
- nval[0] = nval[1] = nval[2] = nval[3] = 0.0f;
- nvalf[0] = nvalf[1] = nvalf[2] = nvalf[3] = 0.0f;
-
- if (!do_rect && !do_float) return (ibuf);
-
- if (do_rect) {
- _newrect = MEM_mallocN(newx * ibuf->y * sizeof(uchar) * 4, "scaledownx");
- if (_newrect == NULL) return(ibuf);
- }
- if (do_float) {
- _newrectf = MEM_mallocN(newx * ibuf->y * sizeof(float) * 4, "scaledownxf");
- if (_newrectf == NULL) {
- if (_newrect) MEM_freeN(_newrect);
- return(ibuf);
- }
- }
-
- add = (ibuf->x - 0.01) / newx;
-
- if (do_rect) {
- rect = (uchar *) ibuf->rect;
- newrect = _newrect;
- }
- if (do_float) {
- rectf = ibuf->rect_float;
- newrectf = _newrectf;
- }
-
- for (y = ibuf->y; y > 0; y--) {
- sample = 0.0f;
- val[0] = val[1] = val[2] = val[3] = 0.0f;
- valf[0] = valf[1] = valf[2] = valf[3] = 0.0f;
-
- for (x = newx; x > 0; x--) {
- if (do_rect) {
- nval[0] = -val[0] * sample;
- nval[1] = -val[1] * sample;
- nval[2] = -val[2] * sample;
- nval[3] = -val[3] * sample;
- }
- if (do_float) {
- nvalf[0] = -valf[0] * sample;
- nvalf[1] = -valf[1] * sample;
- nvalf[2] = -valf[2] * sample;
- nvalf[3] = -valf[3] * sample;
- }
-
- sample += add;
-
- while (sample >= 1.0f) {
- sample -= 1.0f;
-
- if (do_rect) {
- nval[0] += rect[0];
- nval[1] += rect[1];
- nval[2] += rect[2];
- nval[3] += rect[3];
- rect += 4;
- }
- if (do_float) {
- nvalf[0] += rectf[0];
- nvalf[1] += rectf[1];
- nvalf[2] += rectf[2];
- nvalf[3] += rectf[3];
- rectf += 4;
- }
- }
-
- if (do_rect) {
- val[0] = rect[0]; val[1] = rect[1]; val[2] = rect[2]; val[3] = rect[3];
- rect += 4;
-
- newrect[0] = ((nval[0] + sample * val[0]) / add + 0.5f);
- newrect[1] = ((nval[1] + sample * val[1]) / add + 0.5f);
- newrect[2] = ((nval[2] + sample * val[2]) / add + 0.5f);
- newrect[3] = ((nval[3] + sample * val[3]) / add + 0.5f);
-
- newrect += 4;
- }
- if (do_float) {
-
- valf[0] = rectf[0]; valf[1] = rectf[1]; valf[2] = rectf[2]; valf[3] = rectf[3];
- rectf += 4;
-
- newrectf[0] = ((nvalf[0] + sample * valf[0]) / add);
- newrectf[1] = ((nvalf[1] + sample * valf[1]) / add);
- newrectf[2] = ((nvalf[2] + sample * valf[2]) / add);
- newrectf[3] = ((nvalf[3] + sample * valf[3]) / add);
-
- newrectf += 4;
- }
-
- sample -= 1.0f;
- }
- }
-
- if (do_rect) {
- // printf("%ld %ld\n", (uchar *)rect - ((uchar *)ibuf->rect), rect_size);
- BLI_assert((uchar *)rect - ((uchar *)ibuf->rect) == rect_size); /* see bug [#26502] */
- imb_freerectImBuf(ibuf);
- ibuf->mall |= IB_rect;
- ibuf->rect = (unsigned int *) _newrect;
- }
- if (do_float) {
- // printf("%ld %ld\n", rectf - ibuf->rect_float, rect_size);
- BLI_assert((rectf - ibuf->rect_float) == rect_size); /* see bug [#26502] */
- imb_freerectfloatImBuf(ibuf);
- ibuf->mall |= IB_rectfloat;
- ibuf->rect_float = _newrectf;
- }
- (void)rect_size; /* UNUSED in release builds */
-
- ibuf->x = newx;
- return(ibuf);
+ const int do_rect = (ibuf->rect != NULL);
+ const int do_float = (ibuf->rect_float != NULL);
+ const size_t rect_size = ibuf->x * ibuf->y * 4;
+
+ uchar *rect, *_newrect, *newrect;
+ float *rectf, *_newrectf, *newrectf;
+ float sample, add, val[4], nval[4], valf[4], nvalf[4];
+ int x, y;
+
+ rectf = _newrectf = newrectf = NULL;
+ rect = _newrect = newrect = NULL;
+ nval[0] = nval[1] = nval[2] = nval[3] = 0.0f;
+ nvalf[0] = nvalf[1] = nvalf[2] = nvalf[3] = 0.0f;
+
+ if (!do_rect && !do_float)
+ return (ibuf);
+
+ if (do_rect) {
+ _newrect = MEM_mallocN(newx * ibuf->y * sizeof(uchar) * 4, "scaledownx");
+ if (_newrect == NULL)
+ return (ibuf);
+ }
+ if (do_float) {
+ _newrectf = MEM_mallocN(newx * ibuf->y * sizeof(float) * 4, "scaledownxf");
+ if (_newrectf == NULL) {
+ if (_newrect)
+ MEM_freeN(_newrect);
+ return (ibuf);
+ }
+ }
+
+ add = (ibuf->x - 0.01) / newx;
+
+ if (do_rect) {
+ rect = (uchar *)ibuf->rect;
+ newrect = _newrect;
+ }
+ if (do_float) {
+ rectf = ibuf->rect_float;
+ newrectf = _newrectf;
+ }
+
+ for (y = ibuf->y; y > 0; y--) {
+ sample = 0.0f;
+ val[0] = val[1] = val[2] = val[3] = 0.0f;
+ valf[0] = valf[1] = valf[2] = valf[3] = 0.0f;
+
+ for (x = newx; x > 0; x--) {
+ if (do_rect) {
+ nval[0] = -val[0] * sample;
+ nval[1] = -val[1] * sample;
+ nval[2] = -val[2] * sample;
+ nval[3] = -val[3] * sample;
+ }
+ if (do_float) {
+ nvalf[0] = -valf[0] * sample;
+ nvalf[1] = -valf[1] * sample;
+ nvalf[2] = -valf[2] * sample;
+ nvalf[3] = -valf[3] * sample;
+ }
+
+ sample += add;
+
+ while (sample >= 1.0f) {
+ sample -= 1.0f;
+
+ if (do_rect) {
+ nval[0] += rect[0];
+ nval[1] += rect[1];
+ nval[2] += rect[2];
+ nval[3] += rect[3];
+ rect += 4;
+ }
+ if (do_float) {
+ nvalf[0] += rectf[0];
+ nvalf[1] += rectf[1];
+ nvalf[2] += rectf[2];
+ nvalf[3] += rectf[3];
+ rectf += 4;
+ }
+ }
+
+ if (do_rect) {
+ val[0] = rect[0];
+ val[1] = rect[1];
+ val[2] = rect[2];
+ val[3] = rect[3];
+ rect += 4;
+
+ newrect[0] = ((nval[0] + sample * val[0]) / add + 0.5f);
+ newrect[1] = ((nval[1] + sample * val[1]) / add + 0.5f);
+ newrect[2] = ((nval[2] + sample * val[2]) / add + 0.5f);
+ newrect[3] = ((nval[3] + sample * val[3]) / add + 0.5f);
+
+ newrect += 4;
+ }
+ if (do_float) {
+
+ valf[0] = rectf[0];
+ valf[1] = rectf[1];
+ valf[2] = rectf[2];
+ valf[3] = rectf[3];
+ rectf += 4;
+
+ newrectf[0] = ((nvalf[0] + sample * valf[0]) / add);
+ newrectf[1] = ((nvalf[1] + sample * valf[1]) / add);
+ newrectf[2] = ((nvalf[2] + sample * valf[2]) / add);
+ newrectf[3] = ((nvalf[3] + sample * valf[3]) / add);
+
+ newrectf += 4;
+ }
+
+ sample -= 1.0f;
+ }
+ }
+
+ if (do_rect) {
+ // printf("%ld %ld\n", (uchar *)rect - ((uchar *)ibuf->rect), rect_size);
+ BLI_assert((uchar *)rect - ((uchar *)ibuf->rect) == rect_size); /* see bug [#26502] */
+ imb_freerectImBuf(ibuf);
+ ibuf->mall |= IB_rect;
+ ibuf->rect = (unsigned int *)_newrect;
+ }
+ if (do_float) {
+ // printf("%ld %ld\n", rectf - ibuf->rect_float, rect_size);
+ BLI_assert((rectf - ibuf->rect_float) == rect_size); /* see bug [#26502] */
+ imb_freerectfloatImBuf(ibuf);
+ ibuf->mall |= IB_rectfloat;
+ ibuf->rect_float = _newrectf;
+ }
+ (void)rect_size; /* UNUSED in release builds */
+
+ ibuf->x = newx;
+ return (ibuf);
}
-
static ImBuf *scaledowny(struct ImBuf *ibuf, int newy)
{
- const int do_rect = (ibuf->rect != NULL);
- const int do_float = (ibuf->rect_float != NULL);
- const size_t rect_size = ibuf->x * ibuf->y * 4;
-
- uchar *rect, *_newrect, *newrect;
- float *rectf, *_newrectf, *newrectf;
- float sample, add, val[4], nval[4], valf[4], nvalf[4];
- int x, y, skipx;
-
- rectf = _newrectf = newrectf = NULL;
- rect = _newrect = newrect = NULL;
- nval[0] = nval[1] = nval[2] = nval[3] = 0.0f;
- nvalf[0] = nvalf[1] = nvalf[2] = nvalf[3] = 0.0f;
-
- if (!do_rect && !do_float) return (ibuf);
-
- if (do_rect) {
- _newrect = MEM_mallocN(newy * ibuf->x * sizeof(uchar) * 4, "scaledowny");
- if (_newrect == NULL) return(ibuf);
- }
- if (do_float) {
- _newrectf = MEM_mallocN(newy * ibuf->x * sizeof(float) * 4, "scaledownyf");
- if (_newrectf == NULL) {
- if (_newrect) MEM_freeN(_newrect);
- return(ibuf);
- }
- }
-
- add = (ibuf->y - 0.01) / newy;
- skipx = 4 * ibuf->x;
-
- for (x = skipx - 4; x >= 0; x -= 4) {
- if (do_rect) {
- rect = ((uchar *) ibuf->rect) + x;
- newrect = _newrect + x;
- }
- if (do_float) {
- rectf = ibuf->rect_float + x;
- newrectf = _newrectf + x;
- }
-
- sample = 0.0f;
- val[0] = val[1] = val[2] = val[3] = 0.0f;
- valf[0] = valf[1] = valf[2] = valf[3] = 0.0f;
-
- for (y = newy; y > 0; y--) {
- if (do_rect) {
- nval[0] = -val[0] * sample;
- nval[1] = -val[1] * sample;
- nval[2] = -val[2] * sample;
- nval[3] = -val[3] * sample;
- }
- if (do_float) {
- nvalf[0] = -valf[0] * sample;
- nvalf[1] = -valf[1] * sample;
- nvalf[2] = -valf[2] * sample;
- nvalf[3] = -valf[3] * sample;
- }
-
- sample += add;
-
- while (sample >= 1.0f) {
- sample -= 1.0f;
-
- if (do_rect) {
- nval[0] += rect[0];
- nval[1] += rect[1];
- nval[2] += rect[2];
- nval[3] += rect[3];
- rect += skipx;
- }
- if (do_float) {
- nvalf[0] += rectf[0];
- nvalf[1] += rectf[1];
- nvalf[2] += rectf[2];
- nvalf[3] += rectf[3];
- rectf += skipx;
- }
- }
-
- if (do_rect) {
- val[0] = rect[0]; val[1] = rect[1]; val[2] = rect[2]; val[3] = rect[3];
- rect += skipx;
-
- newrect[0] = ((nval[0] + sample * val[0]) / add + 0.5f);
- newrect[1] = ((nval[1] + sample * val[1]) / add + 0.5f);
- newrect[2] = ((nval[2] + sample * val[2]) / add + 0.5f);
- newrect[3] = ((nval[3] + sample * val[3]) / add + 0.5f);
-
- newrect += skipx;
- }
- if (do_float) {
-
- valf[0] = rectf[0]; valf[1] = rectf[1]; valf[2] = rectf[2]; valf[3] = rectf[3];
- rectf += skipx;
-
- newrectf[0] = ((nvalf[0] + sample * valf[0]) / add);
- newrectf[1] = ((nvalf[1] + sample * valf[1]) / add);
- newrectf[2] = ((nvalf[2] + sample * valf[2]) / add);
- newrectf[3] = ((nvalf[3] + sample * valf[3]) / add);
-
- newrectf += skipx;
- }
-
- sample -= 1.0f;
- }
- }
-
- if (do_rect) {
- // printf("%ld %ld\n", (uchar *)rect - ((uchar *)ibuf->rect), rect_size);
- BLI_assert((uchar *)rect - ((uchar *)ibuf->rect) == rect_size); /* see bug [#26502] */
- imb_freerectImBuf(ibuf);
- ibuf->mall |= IB_rect;
- ibuf->rect = (unsigned int *) _newrect;
- }
- if (do_float) {
- // printf("%ld %ld\n", rectf - ibuf->rect_float, rect_size);
- BLI_assert((rectf - ibuf->rect_float) == rect_size); /* see bug [#26502] */
- imb_freerectfloatImBuf(ibuf);
- ibuf->mall |= IB_rectfloat;
- ibuf->rect_float = (float *) _newrectf;
- }
- (void)rect_size; /* UNUSED in release builds */
-
- ibuf->y = newy;
- return(ibuf);
+ const int do_rect = (ibuf->rect != NULL);
+ const int do_float = (ibuf->rect_float != NULL);
+ const size_t rect_size = ibuf->x * ibuf->y * 4;
+
+ uchar *rect, *_newrect, *newrect;
+ float *rectf, *_newrectf, *newrectf;
+ float sample, add, val[4], nval[4], valf[4], nvalf[4];
+ int x, y, skipx;
+
+ rectf = _newrectf = newrectf = NULL;
+ rect = _newrect = newrect = NULL;
+ nval[0] = nval[1] = nval[2] = nval[3] = 0.0f;
+ nvalf[0] = nvalf[1] = nvalf[2] = nvalf[3] = 0.0f;
+
+ if (!do_rect && !do_float)
+ return (ibuf);
+
+ if (do_rect) {
+ _newrect = MEM_mallocN(newy * ibuf->x * sizeof(uchar) * 4, "scaledowny");
+ if (_newrect == NULL)
+ return (ibuf);
+ }
+ if (do_float) {
+ _newrectf = MEM_mallocN(newy * ibuf->x * sizeof(float) * 4, "scaledownyf");
+ if (_newrectf == NULL) {
+ if (_newrect)
+ MEM_freeN(_newrect);
+ return (ibuf);
+ }
+ }
+
+ add = (ibuf->y - 0.01) / newy;
+ skipx = 4 * ibuf->x;
+
+ for (x = skipx - 4; x >= 0; x -= 4) {
+ if (do_rect) {
+ rect = ((uchar *)ibuf->rect) + x;
+ newrect = _newrect + x;
+ }
+ if (do_float) {
+ rectf = ibuf->rect_float + x;
+ newrectf = _newrectf + x;
+ }
+
+ sample = 0.0f;
+ val[0] = val[1] = val[2] = val[3] = 0.0f;
+ valf[0] = valf[1] = valf[2] = valf[3] = 0.0f;
+
+ for (y = newy; y > 0; y--) {
+ if (do_rect) {
+ nval[0] = -val[0] * sample;
+ nval[1] = -val[1] * sample;
+ nval[2] = -val[2] * sample;
+ nval[3] = -val[3] * sample;
+ }
+ if (do_float) {
+ nvalf[0] = -valf[0] * sample;
+ nvalf[1] = -valf[1] * sample;
+ nvalf[2] = -valf[2] * sample;
+ nvalf[3] = -valf[3] * sample;
+ }
+
+ sample += add;
+
+ while (sample >= 1.0f) {
+ sample -= 1.0f;
+
+ if (do_rect) {
+ nval[0] += rect[0];
+ nval[1] += rect[1];
+ nval[2] += rect[2];
+ nval[3] += rect[3];
+ rect += skipx;
+ }
+ if (do_float) {
+ nvalf[0] += rectf[0];
+ nvalf[1] += rectf[1];
+ nvalf[2] += rectf[2];
+ nvalf[3] += rectf[3];
+ rectf += skipx;
+ }
+ }
+
+ if (do_rect) {
+ val[0] = rect[0];
+ val[1] = rect[1];
+ val[2] = rect[2];
+ val[3] = rect[3];
+ rect += skipx;
+
+ newrect[0] = ((nval[0] + sample * val[0]) / add + 0.5f);
+ newrect[1] = ((nval[1] + sample * val[1]) / add + 0.5f);
+ newrect[2] = ((nval[2] + sample * val[2]) / add + 0.5f);
+ newrect[3] = ((nval[3] + sample * val[3]) / add + 0.5f);
+
+ newrect += skipx;
+ }
+ if (do_float) {
+
+ valf[0] = rectf[0];
+ valf[1] = rectf[1];
+ valf[2] = rectf[2];
+ valf[3] = rectf[3];
+ rectf += skipx;
+
+ newrectf[0] = ((nvalf[0] + sample * valf[0]) / add);
+ newrectf[1] = ((nvalf[1] + sample * valf[1]) / add);
+ newrectf[2] = ((nvalf[2] + sample * valf[2]) / add);
+ newrectf[3] = ((nvalf[3] + sample * valf[3]) / add);
+
+ newrectf += skipx;
+ }
+
+ sample -= 1.0f;
+ }
+ }
+
+ if (do_rect) {
+ // printf("%ld %ld\n", (uchar *)rect - ((uchar *)ibuf->rect), rect_size);
+ BLI_assert((uchar *)rect - ((uchar *)ibuf->rect) == rect_size); /* see bug [#26502] */
+ imb_freerectImBuf(ibuf);
+ ibuf->mall |= IB_rect;
+ ibuf->rect = (unsigned int *)_newrect;
+ }
+ if (do_float) {
+ // printf("%ld %ld\n", rectf - ibuf->rect_float, rect_size);
+ BLI_assert((rectf - ibuf->rect_float) == rect_size); /* see bug [#26502] */
+ imb_freerectfloatImBuf(ibuf);
+ ibuf->mall |= IB_rectfloat;
+ ibuf->rect_float = (float *)_newrectf;
+ }
+ (void)rect_size; /* UNUSED in release builds */
+
+ ibuf->y = newy;
+ return (ibuf);
}
-
static ImBuf *scaleupx(struct ImBuf *ibuf, int newx)
{
- uchar *rect, *_newrect = NULL, *newrect;
- float *rectf, *_newrectf = NULL, *newrectf;
- float sample, add;
- float val_a, nval_a, diff_a;
- float val_b, nval_b, diff_b;
- float val_g, nval_g, diff_g;
- float val_r, nval_r, diff_r;
- float val_af, nval_af, diff_af;
- float val_bf, nval_bf, diff_bf;
- float val_gf, nval_gf, diff_gf;
- float val_rf, nval_rf, diff_rf;
- int x, y;
- bool do_rect = false, do_float = false;
-
- val_a = nval_a = diff_a = val_b = nval_b = diff_b = 0;
- val_g = nval_g = diff_g = val_r = nval_r = diff_r = 0;
- val_af = nval_af = diff_af = val_bf = nval_bf = diff_bf = 0;
- val_gf = nval_gf = diff_gf = val_rf = nval_rf = diff_rf = 0;
- if (ibuf == NULL) return(NULL);
- if (ibuf->rect == NULL && ibuf->rect_float == NULL) return (ibuf);
-
- if (ibuf->rect) {
- do_rect = true;
- _newrect = MEM_mallocN(newx * ibuf->y * sizeof(int), "scaleupx");
- if (_newrect == NULL) return(ibuf);
- }
- if (ibuf->rect_float) {
- do_float = true;
- _newrectf = MEM_mallocN(newx * ibuf->y * sizeof(float) * 4, "scaleupxf");
- if (_newrectf == NULL) {
- if (_newrect) MEM_freeN(_newrect);
- return(ibuf);
- }
- }
-
- add = (ibuf->x - 1.001) / (newx - 1.0);
-
- rect = (uchar *) ibuf->rect;
- rectf = (float *) ibuf->rect_float;
- newrect = _newrect;
- newrectf = _newrectf;
-
- for (y = ibuf->y; y > 0; y--) {
-
- sample = 0;
-
- if (do_rect) {
- val_a = rect[0];
- nval_a = rect[4];
- diff_a = nval_a - val_a;
- val_a += 0.5f;
-
- val_b = rect[1];
- nval_b = rect[5];
- diff_b = nval_b - val_b;
- val_b += 0.5f;
-
- val_g = rect[2];
- nval_g = rect[6];
- diff_g = nval_g - val_g;
- val_g += 0.5f;
-
- val_r = rect[3];
- nval_r = rect[7];
- diff_r = nval_r - val_r;
- val_r += 0.5f;
-
- rect += 8;
- }
- if (do_float) {
- val_af = rectf[0];
- nval_af = rectf[4];
- diff_af = nval_af - val_af;
-
- val_bf = rectf[1];
- nval_bf = rectf[5];
- diff_bf = nval_bf - val_bf;
-
- val_gf = rectf[2];
- nval_gf = rectf[6];
- diff_gf = nval_gf - val_gf;
-
- val_rf = rectf[3];
- nval_rf = rectf[7];
- diff_rf = nval_rf - val_rf;
-
- rectf += 8;
- }
- for (x = newx; x > 0; x--) {
- if (sample >= 1.0f) {
- sample -= 1.0f;
-
- if (do_rect) {
- val_a = nval_a;
- nval_a = rect[0];
- diff_a = nval_a - val_a;
- val_a += 0.5f;
-
- val_b = nval_b;
- nval_b = rect[1];
- diff_b = nval_b - val_b;
- val_b += 0.5f;
-
- val_g = nval_g;
- nval_g = rect[2];
- diff_g = nval_g - val_g;
- val_g += 0.5f;
-
- val_r = nval_r;
- nval_r = rect[3];
- diff_r = nval_r - val_r;
- val_r += 0.5f;
- rect += 4;
- }
- if (do_float) {
- val_af = nval_af;
- nval_af = rectf[0];
- diff_af = nval_af - val_af;
-
- val_bf = nval_bf;
- nval_bf = rectf[1];
- diff_bf = nval_bf - val_bf;
-
- val_gf = nval_gf;
- nval_gf = rectf[2];
- diff_gf = nval_gf - val_gf;
-
- val_rf = nval_rf;
- nval_rf = rectf[3];
- diff_rf = nval_rf - val_rf;
- rectf += 4;
- }
- }
- if (do_rect) {
- newrect[0] = val_a + sample * diff_a;
- newrect[1] = val_b + sample * diff_b;
- newrect[2] = val_g + sample * diff_g;
- newrect[3] = val_r + sample * diff_r;
- newrect += 4;
- }
- if (do_float) {
- newrectf[0] = val_af + sample * diff_af;
- newrectf[1] = val_bf + sample * diff_bf;
- newrectf[2] = val_gf + sample * diff_gf;
- newrectf[3] = val_rf + sample * diff_rf;
- newrectf += 4;
- }
- sample += add;
- }
- }
-
- if (do_rect) {
- imb_freerectImBuf(ibuf);
- ibuf->mall |= IB_rect;
- ibuf->rect = (unsigned int *) _newrect;
- }
- if (do_float) {
- imb_freerectfloatImBuf(ibuf);
- ibuf->mall |= IB_rectfloat;
- ibuf->rect_float = (float *) _newrectf;
- }
-
- ibuf->x = newx;
- return(ibuf);
+ uchar *rect, *_newrect = NULL, *newrect;
+ float *rectf, *_newrectf = NULL, *newrectf;
+ float sample, add;
+ float val_a, nval_a, diff_a;
+ float val_b, nval_b, diff_b;
+ float val_g, nval_g, diff_g;
+ float val_r, nval_r, diff_r;
+ float val_af, nval_af, diff_af;
+ float val_bf, nval_bf, diff_bf;
+ float val_gf, nval_gf, diff_gf;
+ float val_rf, nval_rf, diff_rf;
+ int x, y;
+ bool do_rect = false, do_float = false;
+
+ val_a = nval_a = diff_a = val_b = nval_b = diff_b = 0;
+ val_g = nval_g = diff_g = val_r = nval_r = diff_r = 0;
+ val_af = nval_af = diff_af = val_bf = nval_bf = diff_bf = 0;
+ val_gf = nval_gf = diff_gf = val_rf = nval_rf = diff_rf = 0;
+ if (ibuf == NULL)
+ return (NULL);
+ if (ibuf->rect == NULL && ibuf->rect_float == NULL)
+ return (ibuf);
+
+ if (ibuf->rect) {
+ do_rect = true;
+ _newrect = MEM_mallocN(newx * ibuf->y * sizeof(int), "scaleupx");
+ if (_newrect == NULL)
+ return (ibuf);
+ }
+ if (ibuf->rect_float) {
+ do_float = true;
+ _newrectf = MEM_mallocN(newx * ibuf->y * sizeof(float) * 4, "scaleupxf");
+ if (_newrectf == NULL) {
+ if (_newrect)
+ MEM_freeN(_newrect);
+ return (ibuf);
+ }
+ }
+
+ add = (ibuf->x - 1.001) / (newx - 1.0);
+
+ rect = (uchar *)ibuf->rect;
+ rectf = (float *)ibuf->rect_float;
+ newrect = _newrect;
+ newrectf = _newrectf;
+
+ for (y = ibuf->y; y > 0; y--) {
+
+ sample = 0;
+
+ if (do_rect) {
+ val_a = rect[0];
+ nval_a = rect[4];
+ diff_a = nval_a - val_a;
+ val_a += 0.5f;
+
+ val_b = rect[1];
+ nval_b = rect[5];
+ diff_b = nval_b - val_b;
+ val_b += 0.5f;
+
+ val_g = rect[2];
+ nval_g = rect[6];
+ diff_g = nval_g - val_g;
+ val_g += 0.5f;
+
+ val_r = rect[3];
+ nval_r = rect[7];
+ diff_r = nval_r - val_r;
+ val_r += 0.5f;
+
+ rect += 8;
+ }
+ if (do_float) {
+ val_af = rectf[0];
+ nval_af = rectf[4];
+ diff_af = nval_af - val_af;
+
+ val_bf = rectf[1];
+ nval_bf = rectf[5];
+ diff_bf = nval_bf - val_bf;
+
+ val_gf = rectf[2];
+ nval_gf = rectf[6];
+ diff_gf = nval_gf - val_gf;
+
+ val_rf = rectf[3];
+ nval_rf = rectf[7];
+ diff_rf = nval_rf - val_rf;
+
+ rectf += 8;
+ }
+ for (x = newx; x > 0; x--) {
+ if (sample >= 1.0f) {
+ sample -= 1.0f;
+
+ if (do_rect) {
+ val_a = nval_a;
+ nval_a = rect[0];
+ diff_a = nval_a - val_a;
+ val_a += 0.5f;
+
+ val_b = nval_b;
+ nval_b = rect[1];
+ diff_b = nval_b - val_b;
+ val_b += 0.5f;
+
+ val_g = nval_g;
+ nval_g = rect[2];
+ diff_g = nval_g - val_g;
+ val_g += 0.5f;
+
+ val_r = nval_r;
+ nval_r = rect[3];
+ diff_r = nval_r - val_r;
+ val_r += 0.5f;
+ rect += 4;
+ }
+ if (do_float) {
+ val_af = nval_af;
+ nval_af = rectf[0];
+ diff_af = nval_af - val_af;
+
+ val_bf = nval_bf;
+ nval_bf = rectf[1];
+ diff_bf = nval_bf - val_bf;
+
+ val_gf = nval_gf;
+ nval_gf = rectf[2];
+ diff_gf = nval_gf - val_gf;
+
+ val_rf = nval_rf;
+ nval_rf = rectf[3];
+ diff_rf = nval_rf - val_rf;
+ rectf += 4;
+ }
+ }
+ if (do_rect) {
+ newrect[0] = val_a + sample * diff_a;
+ newrect[1] = val_b + sample * diff_b;
+ newrect[2] = val_g + sample * diff_g;
+ newrect[3] = val_r + sample * diff_r;
+ newrect += 4;
+ }
+ if (do_float) {
+ newrectf[0] = val_af + sample * diff_af;
+ newrectf[1] = val_bf + sample * diff_bf;
+ newrectf[2] = val_gf + sample * diff_gf;
+ newrectf[3] = val_rf + sample * diff_rf;
+ newrectf += 4;
+ }
+ sample += add;
+ }
+ }
+
+ if (do_rect) {
+ imb_freerectImBuf(ibuf);
+ ibuf->mall |= IB_rect;
+ ibuf->rect = (unsigned int *)_newrect;
+ }
+ if (do_float) {
+ imb_freerectfloatImBuf(ibuf);
+ ibuf->mall |= IB_rectfloat;
+ ibuf->rect_float = (float *)_newrectf;
+ }
+
+ ibuf->x = newx;
+ return (ibuf);
}
static ImBuf *scaleupy(struct ImBuf *ibuf, int newy)
{
- uchar *rect, *_newrect = NULL, *newrect;
- float *rectf, *_newrectf = NULL, *newrectf;
- float sample, add;
- float val_a, nval_a, diff_a;
- float val_b, nval_b, diff_b;
- float val_g, nval_g, diff_g;
- float val_r, nval_r, diff_r;
- float val_af, nval_af, diff_af;
- float val_bf, nval_bf, diff_bf;
- float val_gf, nval_gf, diff_gf;
- float val_rf, nval_rf, diff_rf;
- int x, y, skipx;
- bool do_rect = false, do_float = false;
-
- val_a = nval_a = diff_a = val_b = nval_b = diff_b = 0;
- val_g = nval_g = diff_g = val_r = nval_r = diff_r = 0;
- val_af = nval_af = diff_af = val_bf = nval_bf = diff_bf = 0;
- val_gf = nval_gf = diff_gf = val_rf = nval_rf = diff_rf = 0;
- if (ibuf == NULL) return(NULL);
- if (ibuf->rect == NULL && ibuf->rect_float == NULL) return (ibuf);
-
- if (ibuf->rect) {
- do_rect = true;
- _newrect = MEM_mallocN(ibuf->x * newy * sizeof(int), "scaleupy");
- if (_newrect == NULL) return(ibuf);
- }
- if (ibuf->rect_float) {
- do_float = true;
- _newrectf = MEM_mallocN(ibuf->x * newy * sizeof(float) * 4, "scaleupyf");
- if (_newrectf == NULL) {
- if (_newrect) MEM_freeN(_newrect);
- return(ibuf);
- }
- }
-
- add = (ibuf->y - 1.001) / (newy - 1.0);
- skipx = 4 * ibuf->x;
-
- rect = (uchar *) ibuf->rect;
- rectf = (float *) ibuf->rect_float;
- newrect = _newrect;
- newrectf = _newrectf;
-
- for (x = ibuf->x; x > 0; x--) {
-
- sample = 0;
- if (do_rect) {
- rect = ((uchar *)ibuf->rect) + 4 * (x - 1);
- newrect = _newrect + 4 * (x - 1);
-
- val_a = rect[0];
- nval_a = rect[skipx];
- diff_a = nval_a - val_a;
- val_a += 0.5f;
-
- val_b = rect[1];
- nval_b = rect[skipx + 1];
- diff_b = nval_b - val_b;
- val_b += 0.5f;
-
- val_g = rect[2];
- nval_g = rect[skipx + 2];
- diff_g = nval_g - val_g;
- val_g += 0.5f;
-
- val_r = rect[3];
- nval_r = rect[skipx + 3];
- diff_r = nval_r - val_r;
- val_r += 0.5f;
-
- rect += 2 * skipx;
- }
- if (do_float) {
- rectf = ibuf->rect_float + 4 * (x - 1);
- newrectf = _newrectf + 4 * (x - 1);
-
- val_af = rectf[0];
- nval_af = rectf[skipx];
- diff_af = nval_af - val_af;
-
- val_bf = rectf[1];
- nval_bf = rectf[skipx + 1];
- diff_bf = nval_bf - val_bf;
-
- val_gf = rectf[2];
- nval_gf = rectf[skipx + 2];
- diff_gf = nval_gf - val_gf;
-
- val_rf = rectf[3];
- nval_rf = rectf[skipx + 3];
- diff_rf = nval_rf - val_rf;
-
- rectf += 2 * skipx;
- }
-
- for (y = newy; y > 0; y--) {
- if (sample >= 1.0f) {
- sample -= 1.0f;
-
- if (do_rect) {
- val_a = nval_a;
- nval_a = rect[0];
- diff_a = nval_a - val_a;
- val_a += 0.5f;
-
- val_b = nval_b;
- nval_b = rect[1];
- diff_b = nval_b - val_b;
- val_b += 0.5f;
-
- val_g = nval_g;
- nval_g = rect[2];
- diff_g = nval_g - val_g;
- val_g += 0.5f;
-
- val_r = nval_r;
- nval_r = rect[3];
- diff_r = nval_r - val_r;
- val_r += 0.5f;
- rect += skipx;
- }
- if (do_float) {
- val_af = nval_af;
- nval_af = rectf[0];
- diff_af = nval_af - val_af;
-
- val_bf = nval_bf;
- nval_bf = rectf[1];
- diff_bf = nval_bf - val_bf;
-
- val_gf = nval_gf;
- nval_gf = rectf[2];
- diff_gf = nval_gf - val_gf;
-
- val_rf = nval_rf;
- nval_rf = rectf[3];
- diff_rf = nval_rf - val_rf;
- rectf += skipx;
- }
- }
- if (do_rect) {
- newrect[0] = val_a + sample * diff_a;
- newrect[1] = val_b + sample * diff_b;
- newrect[2] = val_g + sample * diff_g;
- newrect[3] = val_r + sample * diff_r;
- newrect += skipx;
- }
- if (do_float) {
- newrectf[0] = val_af + sample * diff_af;
- newrectf[1] = val_bf + sample * diff_bf;
- newrectf[2] = val_gf + sample * diff_gf;
- newrectf[3] = val_rf + sample * diff_rf;
- newrectf += skipx;
- }
- sample += add;
- }
- }
-
- if (do_rect) {
- imb_freerectImBuf(ibuf);
- ibuf->mall |= IB_rect;
- ibuf->rect = (unsigned int *) _newrect;
- }
- if (do_float) {
- imb_freerectfloatImBuf(ibuf);
- ibuf->mall |= IB_rectfloat;
- ibuf->rect_float = (float *) _newrectf;
- }
-
- ibuf->y = newy;
- return(ibuf);
+ uchar *rect, *_newrect = NULL, *newrect;
+ float *rectf, *_newrectf = NULL, *newrectf;
+ float sample, add;
+ float val_a, nval_a, diff_a;
+ float val_b, nval_b, diff_b;
+ float val_g, nval_g, diff_g;
+ float val_r, nval_r, diff_r;
+ float val_af, nval_af, diff_af;
+ float val_bf, nval_bf, diff_bf;
+ float val_gf, nval_gf, diff_gf;
+ float val_rf, nval_rf, diff_rf;
+ int x, y, skipx;
+ bool do_rect = false, do_float = false;
+
+ val_a = nval_a = diff_a = val_b = nval_b = diff_b = 0;
+ val_g = nval_g = diff_g = val_r = nval_r = diff_r = 0;
+ val_af = nval_af = diff_af = val_bf = nval_bf = diff_bf = 0;
+ val_gf = nval_gf = diff_gf = val_rf = nval_rf = diff_rf = 0;
+ if (ibuf == NULL)
+ return (NULL);
+ if (ibuf->rect == NULL && ibuf->rect_float == NULL)
+ return (ibuf);
+
+ if (ibuf->rect) {
+ do_rect = true;
+ _newrect = MEM_mallocN(ibuf->x * newy * sizeof(int), "scaleupy");
+ if (_newrect == NULL)
+ return (ibuf);
+ }
+ if (ibuf->rect_float) {
+ do_float = true;
+ _newrectf = MEM_mallocN(ibuf->x * newy * sizeof(float) * 4, "scaleupyf");
+ if (_newrectf == NULL) {
+ if (_newrect)
+ MEM_freeN(_newrect);
+ return (ibuf);
+ }
+ }
+
+ add = (ibuf->y - 1.001) / (newy - 1.0);
+ skipx = 4 * ibuf->x;
+
+ rect = (uchar *)ibuf->rect;
+ rectf = (float *)ibuf->rect_float;
+ newrect = _newrect;
+ newrectf = _newrectf;
+
+ for (x = ibuf->x; x > 0; x--) {
+
+ sample = 0;
+ if (do_rect) {
+ rect = ((uchar *)ibuf->rect) + 4 * (x - 1);
+ newrect = _newrect + 4 * (x - 1);
+
+ val_a = rect[0];
+ nval_a = rect[skipx];
+ diff_a = nval_a - val_a;
+ val_a += 0.5f;
+
+ val_b = rect[1];
+ nval_b = rect[skipx + 1];
+ diff_b = nval_b - val_b;
+ val_b += 0.5f;
+
+ val_g = rect[2];
+ nval_g = rect[skipx + 2];
+ diff_g = nval_g - val_g;
+ val_g += 0.5f;
+
+ val_r = rect[3];
+ nval_r = rect[skipx + 3];
+ diff_r = nval_r - val_r;
+ val_r += 0.5f;
+
+ rect += 2 * skipx;
+ }
+ if (do_float) {
+ rectf = ibuf->rect_float + 4 * (x - 1);
+ newrectf = _newrectf + 4 * (x - 1);
+
+ val_af = rectf[0];
+ nval_af = rectf[skipx];
+ diff_af = nval_af - val_af;
+
+ val_bf = rectf[1];
+ nval_bf = rectf[skipx + 1];
+ diff_bf = nval_bf - val_bf;
+
+ val_gf = rectf[2];
+ nval_gf = rectf[skipx + 2];
+ diff_gf = nval_gf - val_gf;
+
+ val_rf = rectf[3];
+ nval_rf = rectf[skipx + 3];
+ diff_rf = nval_rf - val_rf;
+
+ rectf += 2 * skipx;
+ }
+
+ for (y = newy; y > 0; y--) {
+ if (sample >= 1.0f) {
+ sample -= 1.0f;
+
+ if (do_rect) {
+ val_a = nval_a;
+ nval_a = rect[0];
+ diff_a = nval_a - val_a;
+ val_a += 0.5f;
+
+ val_b = nval_b;
+ nval_b = rect[1];
+ diff_b = nval_b - val_b;
+ val_b += 0.5f;
+
+ val_g = nval_g;
+ nval_g = rect[2];
+ diff_g = nval_g - val_g;
+ val_g += 0.5f;
+
+ val_r = nval_r;
+ nval_r = rect[3];
+ diff_r = nval_r - val_r;
+ val_r += 0.5f;
+ rect += skipx;
+ }
+ if (do_float) {
+ val_af = nval_af;
+ nval_af = rectf[0];
+ diff_af = nval_af - val_af;
+
+ val_bf = nval_bf;
+ nval_bf = rectf[1];
+ diff_bf = nval_bf - val_bf;
+
+ val_gf = nval_gf;
+ nval_gf = rectf[2];
+ diff_gf = nval_gf - val_gf;
+
+ val_rf = nval_rf;
+ nval_rf = rectf[3];
+ diff_rf = nval_rf - val_rf;
+ rectf += skipx;
+ }
+ }
+ if (do_rect) {
+ newrect[0] = val_a + sample * diff_a;
+ newrect[1] = val_b + sample * diff_b;
+ newrect[2] = val_g + sample * diff_g;
+ newrect[3] = val_r + sample * diff_r;
+ newrect += skipx;
+ }
+ if (do_float) {
+ newrectf[0] = val_af + sample * diff_af;
+ newrectf[1] = val_bf + sample * diff_bf;
+ newrectf[2] = val_gf + sample * diff_gf;
+ newrectf[3] = val_rf + sample * diff_rf;
+ newrectf += skipx;
+ }
+ sample += add;
+ }
+ }
+
+ if (do_rect) {
+ imb_freerectImBuf(ibuf);
+ ibuf->mall |= IB_rect;
+ ibuf->rect = (unsigned int *)_newrect;
+ }
+ if (do_float) {
+ imb_freerectfloatImBuf(ibuf);
+ ibuf->mall |= IB_rectfloat;
+ ibuf->rect_float = (float *)_newrectf;
+ }
+
+ ibuf->y = newy;
+ return (ibuf);
}
static void scalefast_Z_ImBuf(ImBuf *ibuf, int newx, int newy)
{
- int *zbuf, *newzbuf, *_newzbuf = NULL;
- float *zbuf_float, *newzbuf_float, *_newzbuf_float = NULL;
- int x, y;
- int ofsx, ofsy, stepx, stepy;
-
- if (ibuf->zbuf) {
- _newzbuf = MEM_mallocN(newx * newy * sizeof(int), __func__);
- if (_newzbuf == NULL) {
- IMB_freezbufImBuf(ibuf);
- }
- }
-
- if (ibuf->zbuf_float) {
- _newzbuf_float = MEM_mallocN((size_t)newx * newy * sizeof(float), __func__);
- if (_newzbuf_float == NULL) {
- IMB_freezbuffloatImBuf(ibuf);
- }
- }
-
- if (!_newzbuf && !_newzbuf_float) {
- return;
- }
-
- stepx = (65536.0 * (ibuf->x - 1.0) / (newx - 1.0)) + 0.5;
- stepy = (65536.0 * (ibuf->y - 1.0) / (newy - 1.0)) + 0.5;
- ofsy = 32768;
-
- newzbuf = _newzbuf;
- newzbuf_float = _newzbuf_float;
-
- for (y = newy; y > 0; y--, ofsy += stepy) {
- if (newzbuf) {
- zbuf = ibuf->zbuf;
- zbuf += (ofsy >> 16) * ibuf->x;
- ofsx = 32768;
- for (x = newx; x > 0; x--, ofsx += stepx) {
- *newzbuf++ = zbuf[ofsx >> 16];
- }
- }
-
- if (newzbuf_float) {
- zbuf_float = ibuf->zbuf_float;
- zbuf_float += (ofsy >> 16) * ibuf->x;
- ofsx = 32768;
- for (x = newx; x > 0; x--, ofsx += stepx) {
- *newzbuf_float++ = zbuf_float[ofsx >> 16];
- }
- }
- }
-
- if (_newzbuf) {
- IMB_freezbufImBuf(ibuf);
- ibuf->mall |= IB_zbuf;
- ibuf->zbuf = _newzbuf;
- }
-
- if (_newzbuf_float) {
- IMB_freezbuffloatImBuf(ibuf);
- ibuf->mall |= IB_zbuffloat;
- ibuf->zbuf_float = _newzbuf_float;
- }
+ int *zbuf, *newzbuf, *_newzbuf = NULL;
+ float *zbuf_float, *newzbuf_float, *_newzbuf_float = NULL;
+ int x, y;
+ int ofsx, ofsy, stepx, stepy;
+
+ if (ibuf->zbuf) {
+ _newzbuf = MEM_mallocN(newx * newy * sizeof(int), __func__);
+ if (_newzbuf == NULL) {
+ IMB_freezbufImBuf(ibuf);
+ }
+ }
+
+ if (ibuf->zbuf_float) {
+ _newzbuf_float = MEM_mallocN((size_t)newx * newy * sizeof(float), __func__);
+ if (_newzbuf_float == NULL) {
+ IMB_freezbuffloatImBuf(ibuf);
+ }
+ }
+
+ if (!_newzbuf && !_newzbuf_float) {
+ return;
+ }
+
+ stepx = (65536.0 * (ibuf->x - 1.0) / (newx - 1.0)) + 0.5;
+ stepy = (65536.0 * (ibuf->y - 1.0) / (newy - 1.0)) + 0.5;
+ ofsy = 32768;
+
+ newzbuf = _newzbuf;
+ newzbuf_float = _newzbuf_float;
+
+ for (y = newy; y > 0; y--, ofsy += stepy) {
+ if (newzbuf) {
+ zbuf = ibuf->zbuf;
+ zbuf += (ofsy >> 16) * ibuf->x;
+ ofsx = 32768;
+ for (x = newx; x > 0; x--, ofsx += stepx) {
+ *newzbuf++ = zbuf[ofsx >> 16];
+ }
+ }
+
+ if (newzbuf_float) {
+ zbuf_float = ibuf->zbuf_float;
+ zbuf_float += (ofsy >> 16) * ibuf->x;
+ ofsx = 32768;
+ for (x = newx; x > 0; x--, ofsx += stepx) {
+ *newzbuf_float++ = zbuf_float[ofsx >> 16];
+ }
+ }
+ }
+
+ if (_newzbuf) {
+ IMB_freezbufImBuf(ibuf);
+ ibuf->mall |= IB_zbuf;
+ ibuf->zbuf = _newzbuf;
+ }
+
+ if (_newzbuf_float) {
+ IMB_freezbuffloatImBuf(ibuf);
+ ibuf->mall |= IB_zbuffloat;
+ ibuf->zbuf_float = _newzbuf_float;
+ }
}
/**
@@ -1541,33 +1572,39 @@ static void scalefast_Z_ImBuf(ImBuf *ibuf, int newx, int newy)
*/
bool IMB_scaleImBuf(struct ImBuf *ibuf, unsigned int newx, unsigned int newy)
{
- if (ibuf == NULL) return false;
- if (ibuf->rect == NULL && ibuf->rect_float == NULL) return false;
-
- if (newx == ibuf->x && newy == ibuf->y) {
- return false;
- }
-
- /* scaleup / scaledown functions below change ibuf->x and ibuf->y
- * so we first scale the Z-buffer (if any) */
- scalefast_Z_ImBuf(ibuf, newx, newy);
-
- /* try to scale common cases in a fast way */
- /* disabled, quality loss is unacceptable, see report #18609 (ton) */
- if (0 && q_scale_linear_interpolation(ibuf, newx, newy)) {
- return true;
- }
-
- if (newx && (newx < ibuf->x)) scaledownx(ibuf, newx);
- if (newy && (newy < ibuf->y)) scaledowny(ibuf, newy);
- if (newx && (newx > ibuf->x)) scaleupx(ibuf, newx);
- if (newy && (newy > ibuf->y)) scaleupy(ibuf, newy);
-
- return true;
+ if (ibuf == NULL)
+ return false;
+ if (ibuf->rect == NULL && ibuf->rect_float == NULL)
+ return false;
+
+ if (newx == ibuf->x && newy == ibuf->y) {
+ return false;
+ }
+
+ /* scaleup / scaledown functions below change ibuf->x and ibuf->y
+ * so we first scale the Z-buffer (if any) */
+ scalefast_Z_ImBuf(ibuf, newx, newy);
+
+ /* try to scale common cases in a fast way */
+ /* disabled, quality loss is unacceptable, see report #18609 (ton) */
+ if (0 && q_scale_linear_interpolation(ibuf, newx, newy)) {
+ return true;
+ }
+
+ if (newx && (newx < ibuf->x))
+ scaledownx(ibuf, newx);
+ if (newy && (newy < ibuf->y))
+ scaledowny(ibuf, newy);
+ if (newx && (newx > ibuf->x))
+ scaleupx(ibuf, newx);
+ if (newy && (newy > ibuf->y))
+ scaleupy(ibuf, newy);
+
+ return true;
}
struct imbufRGBA {
- float r, g, b, a;
+ float r, g, b, a;
};
/**
@@ -1575,189 +1612,204 @@ struct imbufRGBA {
*/
bool IMB_scalefastImBuf(struct ImBuf *ibuf, unsigned int newx, unsigned int newy)
{
- unsigned int *rect, *_newrect, *newrect;
- struct imbufRGBA *rectf, *_newrectf, *newrectf;
- int x, y;
- bool do_float = false, do_rect = false;
- size_t ofsx, ofsy, stepx, stepy;
-
- rect = NULL; _newrect = NULL; newrect = NULL;
- rectf = NULL; _newrectf = NULL; newrectf = NULL;
-
- if (ibuf == NULL) return false;
- if (ibuf->rect) do_rect = true;
- if (ibuf->rect_float) do_float = true;
- if (do_rect == false && do_float == false) return false;
-
- if (newx == ibuf->x && newy == ibuf->y) return false;
-
- if (do_rect) {
- _newrect = MEM_mallocN(newx * newy * sizeof(int), "scalefastimbuf");
- if (_newrect == NULL) return false;
- newrect = _newrect;
- }
-
- if (do_float) {
- _newrectf = MEM_mallocN(newx * newy * sizeof(float) * 4, "scalefastimbuf f");
- if (_newrectf == NULL) {
- if (_newrect) MEM_freeN(_newrect);
- return false;
- }
- newrectf = _newrectf;
- }
-
- stepx = (65536.0 * (ibuf->x - 1.0) / (newx - 1.0)) + 0.5;
- stepy = (65536.0 * (ibuf->y - 1.0) / (newy - 1.0)) + 0.5;
- ofsy = 32768;
-
- for (y = newy; y > 0; y--, ofsy += stepy) {
- if (do_rect) {
- rect = ibuf->rect;
- rect += (ofsy >> 16) * ibuf->x;
- ofsx = 32768;
-
- for (x = newx; x > 0; x--, ofsx += stepx) {
- *newrect++ = rect[ofsx >> 16];
- }
- }
-
- if (do_float) {
- rectf = (struct imbufRGBA *)ibuf->rect_float;
- rectf += (ofsy >> 16) * ibuf->x;
- ofsx = 32768;
-
- for (x = newx; x > 0; x--, ofsx += stepx) {
- *newrectf++ = rectf[ofsx >> 16];
- }
- }
- }
-
- if (do_rect) {
- imb_freerectImBuf(ibuf);
- ibuf->mall |= IB_rect;
- ibuf->rect = _newrect;
- }
-
- if (do_float) {
- imb_freerectfloatImBuf(ibuf);
- ibuf->mall |= IB_rectfloat;
- ibuf->rect_float = (float *)_newrectf;
- }
-
- scalefast_Z_ImBuf(ibuf, newx, newy);
-
- ibuf->x = newx;
- ibuf->y = newy;
- return true;
+ unsigned int *rect, *_newrect, *newrect;
+ struct imbufRGBA *rectf, *_newrectf, *newrectf;
+ int x, y;
+ bool do_float = false, do_rect = false;
+ size_t ofsx, ofsy, stepx, stepy;
+
+ rect = NULL;
+ _newrect = NULL;
+ newrect = NULL;
+ rectf = NULL;
+ _newrectf = NULL;
+ newrectf = NULL;
+
+ if (ibuf == NULL)
+ return false;
+ if (ibuf->rect)
+ do_rect = true;
+ if (ibuf->rect_float)
+ do_float = true;
+ if (do_rect == false && do_float == false)
+ return false;
+
+ if (newx == ibuf->x && newy == ibuf->y)
+ return false;
+
+ if (do_rect) {
+ _newrect = MEM_mallocN(newx * newy * sizeof(int), "scalefastimbuf");
+ if (_newrect == NULL)
+ return false;
+ newrect = _newrect;
+ }
+
+ if (do_float) {
+ _newrectf = MEM_mallocN(newx * newy * sizeof(float) * 4, "scalefastimbuf f");
+ if (_newrectf == NULL) {
+ if (_newrect)
+ MEM_freeN(_newrect);
+ return false;
+ }
+ newrectf = _newrectf;
+ }
+
+ stepx = (65536.0 * (ibuf->x - 1.0) / (newx - 1.0)) + 0.5;
+ stepy = (65536.0 * (ibuf->y - 1.0) / (newy - 1.0)) + 0.5;
+ ofsy = 32768;
+
+ for (y = newy; y > 0; y--, ofsy += stepy) {
+ if (do_rect) {
+ rect = ibuf->rect;
+ rect += (ofsy >> 16) * ibuf->x;
+ ofsx = 32768;
+
+ for (x = newx; x > 0; x--, ofsx += stepx) {
+ *newrect++ = rect[ofsx >> 16];
+ }
+ }
+
+ if (do_float) {
+ rectf = (struct imbufRGBA *)ibuf->rect_float;
+ rectf += (ofsy >> 16) * ibuf->x;
+ ofsx = 32768;
+
+ for (x = newx; x > 0; x--, ofsx += stepx) {
+ *newrectf++ = rectf[ofsx >> 16];
+ }
+ }
+ }
+
+ if (do_rect) {
+ imb_freerectImBuf(ibuf);
+ ibuf->mall |= IB_rect;
+ ibuf->rect = _newrect;
+ }
+
+ if (do_float) {
+ imb_freerectfloatImBuf(ibuf);
+ ibuf->mall |= IB_rectfloat;
+ ibuf->rect_float = (float *)_newrectf;
+ }
+
+ scalefast_Z_ImBuf(ibuf, newx, newy);
+
+ ibuf->x = newx;
+ ibuf->y = newy;
+ return true;
}
/* ******** threaded scaling ******** */
typedef struct ScaleTreadInitData {
- ImBuf *ibuf;
+ ImBuf *ibuf;
- unsigned int newx;
- unsigned int newy;
+ unsigned int newx;
+ unsigned int newy;
- unsigned char *byte_buffer;
- float *float_buffer;
+ unsigned char *byte_buffer;
+ float *float_buffer;
} ScaleTreadInitData;
typedef struct ScaleThreadData {
- ImBuf *ibuf;
+ ImBuf *ibuf;
- unsigned int newx;
- unsigned int newy;
+ unsigned int newx;
+ unsigned int newy;
- int start_line;
- int tot_line;
+ int start_line;
+ int tot_line;
- unsigned char *byte_buffer;
- float *float_buffer;
+ unsigned char *byte_buffer;
+ float *float_buffer;
} ScaleThreadData;
static void scale_thread_init(void *data_v, int start_line, int tot_line, void *init_data_v)
{
- ScaleThreadData *data = (ScaleThreadData *) data_v;
- ScaleTreadInitData *init_data = (ScaleTreadInitData *) init_data_v;
+ ScaleThreadData *data = (ScaleThreadData *)data_v;
+ ScaleTreadInitData *init_data = (ScaleTreadInitData *)init_data_v;
- data->ibuf = init_data->ibuf;
+ data->ibuf = init_data->ibuf;
- data->newx = init_data->newx;
- data->newy = init_data->newy;
+ data->newx = init_data->newx;
+ data->newy = init_data->newy;
- data->start_line = start_line;
- data->tot_line = tot_line;
+ data->start_line = start_line;
+ data->tot_line = tot_line;
- data->byte_buffer = init_data->byte_buffer;
- data->float_buffer = init_data->float_buffer;
+ data->byte_buffer = init_data->byte_buffer;
+ data->float_buffer = init_data->float_buffer;
}
static void *do_scale_thread(void *data_v)
{
- ScaleThreadData *data = (ScaleThreadData *) data_v;
- ImBuf *ibuf = data->ibuf;
- int i;
- float factor_x = (float) ibuf->x / data->newx;
- float factor_y = (float) ibuf->y / data->newy;
-
- for (i = 0; i < data->tot_line; i++) {
- int y = data->start_line + i;
- int x;
-
- for (x = 0; x < data->newx; x++) {
- float u = (float) x * factor_x;
- float v = (float) y * factor_y;
- int offset = y * data->newx + x;
-
- if (data->byte_buffer) {
- unsigned char *pixel = data->byte_buffer + 4 * offset;
- BLI_bilinear_interpolation_char((unsigned char *) ibuf->rect, pixel, ibuf->x, ibuf->y, 4, u, v);
- }
-
- if (data->float_buffer) {
- float *pixel = data->float_buffer + ibuf->channels * offset;
- BLI_bilinear_interpolation_fl(ibuf->rect_float, pixel, ibuf->x, ibuf->y, ibuf->channels, u, v);
- }
- }
- }
-
- return NULL;
+ ScaleThreadData *data = (ScaleThreadData *)data_v;
+ ImBuf *ibuf = data->ibuf;
+ int i;
+ float factor_x = (float)ibuf->x / data->newx;
+ float factor_y = (float)ibuf->y / data->newy;
+
+ for (i = 0; i < data->tot_line; i++) {
+ int y = data->start_line + i;
+ int x;
+
+ for (x = 0; x < data->newx; x++) {
+ float u = (float)x * factor_x;
+ float v = (float)y * factor_y;
+ int offset = y * data->newx + x;
+
+ if (data->byte_buffer) {
+ unsigned char *pixel = data->byte_buffer + 4 * offset;
+ BLI_bilinear_interpolation_char(
+ (unsigned char *)ibuf->rect, pixel, ibuf->x, ibuf->y, 4, u, v);
+ }
+
+ if (data->float_buffer) {
+ float *pixel = data->float_buffer + ibuf->channels * offset;
+ BLI_bilinear_interpolation_fl(
+ ibuf->rect_float, pixel, ibuf->x, ibuf->y, ibuf->channels, u, v);
+ }
+ }
+ }
+
+ return NULL;
}
void IMB_scaleImBuf_threaded(ImBuf *ibuf, unsigned int newx, unsigned int newy)
{
- ScaleTreadInitData init_data = {NULL};
+ ScaleTreadInitData init_data = {NULL};
- /* prepare initialization data */
- init_data.ibuf = ibuf;
+ /* prepare initialization data */
+ init_data.ibuf = ibuf;
- init_data.newx = newx;
- init_data.newy = newy;
+ init_data.newx = newx;
+ init_data.newy = newy;
- if (ibuf->rect)
- init_data.byte_buffer = MEM_mallocN(4 * newx * newy * sizeof(char), "threaded scale byte buffer");
+ if (ibuf->rect)
+ init_data.byte_buffer = MEM_mallocN(4 * newx * newy * sizeof(char),
+ "threaded scale byte buffer");
- if (ibuf->rect_float)
- init_data.float_buffer = MEM_mallocN(ibuf->channels * newx * newy * sizeof(float), "threaded scale float buffer");
+ if (ibuf->rect_float)
+ init_data.float_buffer = MEM_mallocN(ibuf->channels * newx * newy * sizeof(float),
+ "threaded scale float buffer");
- /* actual scaling threads */
- IMB_processor_apply_threaded(newy, sizeof(ScaleThreadData), &init_data,
- scale_thread_init, do_scale_thread);
+ /* actual scaling threads */
+ IMB_processor_apply_threaded(
+ newy, sizeof(ScaleThreadData), &init_data, scale_thread_init, do_scale_thread);
- /* alter image buffer */
- ibuf->x = newx;
- ibuf->y = newy;
+ /* alter image buffer */
+ ibuf->x = newx;
+ ibuf->y = newy;
- if (ibuf->rect) {
- imb_freerectImBuf(ibuf);
- ibuf->mall |= IB_rect;
- ibuf->rect = (unsigned int *) init_data.byte_buffer;
- }
+ if (ibuf->rect) {
+ imb_freerectImBuf(ibuf);
+ ibuf->mall |= IB_rect;
+ ibuf->rect = (unsigned int *)init_data.byte_buffer;
+ }
- if (ibuf->rect_float) {
- imb_freerectfloatImBuf(ibuf);
- ibuf->mall |= IB_rectfloat;
- ibuf->rect_float = init_data.float_buffer;
- }
+ if (ibuf->rect_float) {
+ imb_freerectfloatImBuf(ibuf);
+ ibuf->mall |= IB_rectfloat;
+ ibuf->rect_float = init_data.float_buffer;
+ }
}
diff --git a/source/blender/imbuf/intern/stereoimbuf.c b/source/blender/imbuf/intern/stereoimbuf.c
index 52f1de1794d..30356fd4e4e 100644
--- a/source/blender/imbuf/intern/stereoimbuf.c
+++ b/source/blender/imbuf/intern/stereoimbuf.c
@@ -48,1237 +48,1298 @@ static void imb_stereo3d_write_doit(struct Stereo3DData *s3d_data, struct Stereo
static void imb_stereo3d_read_doit(struct Stereo3DData *s3d_data, struct Stereo3dFormat *s3d);
typedef struct Stereo3DData {
- struct { float *left, *right, *stereo; } rectf;
- struct { uchar *left, *right, *stereo; } rect;
- size_t x, y, channels;
- bool is_float;
+ struct {
+ float *left, *right, *stereo;
+ } rectf;
+ struct {
+ uchar *left, *right, *stereo;
+ } rect;
+ size_t x, y, channels;
+ bool is_float;
} Stereo3DData;
static void imb_stereo3d_write_anaglyph(Stereo3DData *s3d, enum eStereo3dAnaglyphType mode)
{
- int x, y;
- size_t width = s3d->x;
- size_t height = s3d->y;
- const size_t channels = s3d->channels;
-
- const int stride_from = width;
- const int stride_to = width;
-
- int anaglyph_encoding[3][3] = {
- {0, 1, 1},
- {1, 0, 1},
- {0, 0, 1},
- };
-
- int r, g, b;
-
- r = anaglyph_encoding[mode][0];
- g = anaglyph_encoding[mode][1];
- b = anaglyph_encoding[mode][2];
-
- if (s3d->is_float) {
- float *rect_left = s3d->rectf.left;
- float *rect_right = s3d->rectf.right;
- float *rect_to = s3d->rectf.stereo;
-
- if (channels == 3) {
- for (y = 0; y < height; y++) {
- float *to = rect_to + stride_to * y * 3;
- float *from[2] = {
- rect_left + stride_from * y * 3,
- rect_right + stride_from * y * 3,
- };
-
- for (x = 0; x < width; x++, from[0] += 3, from[1] += 3, to += 3) {
- to[0] = from[r][0];
- to[1] = from[g][1];
- to[2] = from[b][2];
- }
- }
- }
- else if (channels == 4) {
- for (y = 0; y < height; y++) {
- float *to = rect_to + stride_to * y * 4;
- float *from[2] = {
- rect_left + stride_from * y * 4,
- rect_right + stride_from * y * 4,
- };
-
- for (x = 0; x < width; x++, from[0] += 4, from[1] += 4, to += 4) {
- to[0] = from[r][0];
- to[1] = from[g][1];
- to[2] = from[b][2];
- to[3] = MAX2(from[0][3], from[1][3]);
- }
- }
- }
- }
- else {
- uchar *rect_left = s3d->rect.left;
- uchar *rect_right = s3d->rect.right;
- uchar *rect_to = s3d->rect.stereo;
-
- if (channels == 3) {
- for (y = 0; y < height; y++) {
- uchar *to = rect_to + stride_to * y * 3;
- uchar *from[2] = {
- rect_left + stride_from * y * 3,
- rect_right + stride_from * y * 3,
- };
-
- for (x = 0; x < width; x++, from[0] += 3, from[1] += 3, to += 3) {
- to[0] = from[r][0];
- to[1] = from[g][1];
- to[2] = from[b][2];
- }
- }
- }
- else if (channels == 4) {
- for (y = 0; y < height; y++) {
- uchar *to = rect_to + stride_to * y * 4;
- uchar *from[2] = {
- rect_left + stride_from * y * 4,
- rect_right + stride_from * y * 4,
- };
-
- for (x = 0; x < width; x++, from[0] += 4, from[1] += 4, to += 4) {
- to[0] = from[r][0];
- to[1] = from[g][1];
- to[2] = from[b][2];
- to[3] = MAX2(from[0][3], from[1][3]);
- }
- }
- }
- }
+ int x, y;
+ size_t width = s3d->x;
+ size_t height = s3d->y;
+ const size_t channels = s3d->channels;
+
+ const int stride_from = width;
+ const int stride_to = width;
+
+ int anaglyph_encoding[3][3] = {
+ {0, 1, 1},
+ {1, 0, 1},
+ {0, 0, 1},
+ };
+
+ int r, g, b;
+
+ r = anaglyph_encoding[mode][0];
+ g = anaglyph_encoding[mode][1];
+ b = anaglyph_encoding[mode][2];
+
+ if (s3d->is_float) {
+ float *rect_left = s3d->rectf.left;
+ float *rect_right = s3d->rectf.right;
+ float *rect_to = s3d->rectf.stereo;
+
+ if (channels == 3) {
+ for (y = 0; y < height; y++) {
+ float *to = rect_to + stride_to * y * 3;
+ float *from[2] = {
+ rect_left + stride_from * y * 3,
+ rect_right + stride_from * y * 3,
+ };
+
+ for (x = 0; x < width; x++, from[0] += 3, from[1] += 3, to += 3) {
+ to[0] = from[r][0];
+ to[1] = from[g][1];
+ to[2] = from[b][2];
+ }
+ }
+ }
+ else if (channels == 4) {
+ for (y = 0; y < height; y++) {
+ float *to = rect_to + stride_to * y * 4;
+ float *from[2] = {
+ rect_left + stride_from * y * 4,
+ rect_right + stride_from * y * 4,
+ };
+
+ for (x = 0; x < width; x++, from[0] += 4, from[1] += 4, to += 4) {
+ to[0] = from[r][0];
+ to[1] = from[g][1];
+ to[2] = from[b][2];
+ to[3] = MAX2(from[0][3], from[1][3]);
+ }
+ }
+ }
+ }
+ else {
+ uchar *rect_left = s3d->rect.left;
+ uchar *rect_right = s3d->rect.right;
+ uchar *rect_to = s3d->rect.stereo;
+
+ if (channels == 3) {
+ for (y = 0; y < height; y++) {
+ uchar *to = rect_to + stride_to * y * 3;
+ uchar *from[2] = {
+ rect_left + stride_from * y * 3,
+ rect_right + stride_from * y * 3,
+ };
+
+ for (x = 0; x < width; x++, from[0] += 3, from[1] += 3, to += 3) {
+ to[0] = from[r][0];
+ to[1] = from[g][1];
+ to[2] = from[b][2];
+ }
+ }
+ }
+ else if (channels == 4) {
+ for (y = 0; y < height; y++) {
+ uchar *to = rect_to + stride_to * y * 4;
+ uchar *from[2] = {
+ rect_left + stride_from * y * 4,
+ rect_right + stride_from * y * 4,
+ };
+
+ for (x = 0; x < width; x++, from[0] += 4, from[1] += 4, to += 4) {
+ to[0] = from[r][0];
+ to[1] = from[g][1];
+ to[2] = from[b][2];
+ to[3] = MAX2(from[0][3], from[1][3]);
+ }
+ }
+ }
+ }
}
-static void imb_stereo3d_write_interlace(Stereo3DData *s3d, enum eStereo3dInterlaceType mode, const bool swap)
+static void imb_stereo3d_write_interlace(Stereo3DData *s3d,
+ enum eStereo3dInterlaceType mode,
+ const bool swap)
{
- int x, y;
- size_t width = s3d->x;
- size_t height = s3d->y;
- const size_t channels = s3d->channels;
-
- const int stride_from = width;
- const int stride_to = width;
-
- if (s3d->is_float) {
- const float *rect_left = s3d->rectf.left;
- const float *rect_right = s3d->rectf.right;
- float *rect_to = s3d->rectf.stereo;
-
- switch (mode) {
- case S3D_INTERLACE_ROW:
- {
- char i = (char) swap;
- for (y = 0; y < height; y++) {
- float *to = rect_to + stride_to * y * channels;
- const float *from[2] = {
- rect_left + stride_from * y * channels,
- rect_right + stride_from * y * channels,
- };
- memcpy(to, from[i], sizeof(float) * channels * stride_from);
- i = !i;
- }
- break;
- }
- case S3D_INTERLACE_COLUMN:
- {
- if (channels == 1) {
- for (y = 0; y < height; y++) {
- float *to = rect_to + stride_to * y;
- const float *from[2] = {
- rect_left + stride_from * y,
- rect_right + stride_from * y,
- };
-
- char i = (char) swap;
- for (x = 0; x < width; x++, from[0] += 1, from[1] += 1, to += 1) {
- to[0] = from[i][0];
- i = !i;
- }
- }
- }
- else if (channels == 3) {
- for (y = 0; y < height; y++) {
- float *to = rect_to + stride_to * y * 3;
- const float *from[2] = {
- rect_left + stride_from * y * 3,
- rect_right + stride_from * y * 3,
- };
-
- char i = (char) swap;
- for (x = 0; x < width; x++, from[0] += 3, from[1] += 3, to += 3) {
- copy_v3_v3(to, from[i]);
- i = !i;
- }
- }
- }
- else if (channels == 4) {
- for (y = 0; y < height; y++) {
- float *to = rect_to + stride_to * y * channels;
- const float *from[2] = {
- rect_left + stride_from * y * channels,
- rect_right + stride_from * y * channels,
- };
-
- char i = (char) swap;
- for (x = 0; x < width; x++, from[0] += 4, from[1] += 4, to += 4) {
- copy_v4_v4(to, from[i]);
- i = !i;
- }
- }
- }
- break;
- }
- case S3D_INTERLACE_CHECKERBOARD:
- {
- if (channels == 1) {
- char i = (char) swap;
- for (y = 0; y < height; y++) {
- float *to = rect_to + stride_to * y;
- const float *from[2] = {
- rect_left + stride_from * y,
- rect_right + stride_from * y,
- };
- char j = i;
- for (x = 0; x < width; x++, from[0] += 1, from[1] += 1, to += 1) {
- to[0] = from[j][0];
- j = !j;
- }
- i = !i;
- }
- }
- else if (channels == 3) {
- char i = (char) swap;
- for (y = 0; y < height; y++) {
- float *to = rect_to + stride_to * y * 3;
- const float *from[2] = {
- rect_left + stride_from * y * 3,
- rect_right + stride_from * y * 3,
- };
- char j = i;
- for (x = 0; x < width; x++, from[0] += 3, from[1] += 3, to += 3) {
- copy_v3_v3(to, from[j]);
- j = !j;
- }
- i = !i;
- }
- }
- else if (channels == 4) {
- char i = (char) swap;
- for (y = 0; y < height; y++) {
- float *to = rect_to + stride_to * y * 4;
- const float *from[2] = {
- rect_left + stride_from * y * 4,
- rect_right + stride_from * y * 4,
- };
- char j = i;
- for (x = 0; x < width; x++, from[0] += 4, from[1] += 4, to += 4) {
- copy_v4_v4(to, from[j]);
- j = !j;
- }
- i = !i;
- }
- }
- break;
- }
- default:
- {
- break;
- }
- }
- }
- else {
- const uchar *rect_left = s3d->rect.left;
- const uchar *rect_right = s3d->rect.right;
- uchar *rect_to = s3d->rect.stereo;
-
- switch (mode) {
- case S3D_INTERLACE_ROW:
- {
- char i = (char) swap;
- for (y = 0; y < height; y++) {
- uchar *to = rect_to + stride_to * y * channels;
- const uchar *from[2] = {
- rect_left + stride_from * y * channels,
- rect_right + stride_from * y * channels,
- };
- memcpy(to, from[i], sizeof(uchar) * channels * stride_from);
- i = !i;
- }
- break;
- }
- case S3D_INTERLACE_COLUMN:
- {
- if (channels == 1) {
- for (y = 0; y < height; y++) {
- uchar *to = rect_to + stride_to * y;
- const uchar *from[2] = {
- rect_left + stride_from * y,
- rect_right + stride_from * y,
- };
- char i = (char) swap;
- for (x = 0; x < width; x++, from[0] += 1, from[1] += 1, to += 1) {
- to[0] = from[i][0];
- i = !i;
- }
- }
- }
- else if (channels == 3) {
- for (y = 0; y < height; y++) {
- uchar *to = rect_to + stride_to * y * 3;
- const uchar *from[2] = {
- rect_left + stride_from * y * 3,
- rect_right + stride_from * y * 3,
- };
- char i = (char) swap;
- for (x = 0; x < width; x++, from[0] += 3, from[1] += 3, to += 3) {
- copy_v3_v3_uchar(to, from[i]);
- i = !i;
- }
- }
- }
- else if (channels == 4) {
- for (y = 0; y < height; y++) {
- uchar *to = rect_to + stride_to * y * 4;
- const uchar *from[2] = {
- rect_left + stride_from * y * 4,
- rect_right + stride_from * y * 4,
- };
- char i = (char) swap;
- for (x = 0; x < width; x++, from[0] += 4, from[1] += 4, to += 4) {
- copy_v4_v4_uchar(to, from[i]);
- i = !i;
- }
- }
- }
- break;
- }
- case S3D_INTERLACE_CHECKERBOARD:
- {
- if (channels == 1) {
- char i = (char) swap;
- for (y = 0; y < height; y++) {
- uchar *to = rect_to + stride_to * y;
- const uchar *from[2] = {
- rect_left + stride_from * y,
- rect_right + stride_from * y,
- };
- char j = i;
- for (x = 0; x < width; x++, from[0] += 1, from[1] += 1, to += 1) {
- to[0] = from[j][0];
- j = !j;
- }
- i = !i;
- }
- }
- else if (channels == 3) {
- char i = (char) swap;
- for (y = 0; y < height; y++) {
- uchar *to = rect_to + stride_to * y * 3;
- const uchar *from[2] = {
- rect_left + stride_from * y * 3,
- rect_right + stride_from * y * 3,
- };
- char j = i;
- for (x = 0; x < width; x++, from[0] += 3, from[1] += 3, to += 3) {
- copy_v3_v3_uchar(to, from[j]);
- j = !j;
- }
- i = !i;
- }
- }
- else if (channels == 4) {
- char i = (char) swap;
- for (y = 0; y < height; y++) {
- uchar *to = rect_to + stride_to * y * 4;
- const uchar *from[2] = {
- rect_left + stride_from * y * 4,
- rect_right + stride_from * y * 4,
- };
- char j = i;
- for (x = 0; x < width; x++, from[0] += 4, from[1] += 4, to += 4) {
- copy_v4_v4_uchar(to, from[j]);
- j = !j;
- }
- i = !i;
- }
- }
- break;
- }
- default:
- {
- break;
- }
- }
- }
+ int x, y;
+ size_t width = s3d->x;
+ size_t height = s3d->y;
+ const size_t channels = s3d->channels;
+
+ const int stride_from = width;
+ const int stride_to = width;
+
+ if (s3d->is_float) {
+ const float *rect_left = s3d->rectf.left;
+ const float *rect_right = s3d->rectf.right;
+ float *rect_to = s3d->rectf.stereo;
+
+ switch (mode) {
+ case S3D_INTERLACE_ROW: {
+ char i = (char)swap;
+ for (y = 0; y < height; y++) {
+ float *to = rect_to + stride_to * y * channels;
+ const float *from[2] = {
+ rect_left + stride_from * y * channels,
+ rect_right + stride_from * y * channels,
+ };
+ memcpy(to, from[i], sizeof(float) * channels * stride_from);
+ i = !i;
+ }
+ break;
+ }
+ case S3D_INTERLACE_COLUMN: {
+ if (channels == 1) {
+ for (y = 0; y < height; y++) {
+ float *to = rect_to + stride_to * y;
+ const float *from[2] = {
+ rect_left + stride_from * y,
+ rect_right + stride_from * y,
+ };
+
+ char i = (char)swap;
+ for (x = 0; x < width; x++, from[0] += 1, from[1] += 1, to += 1) {
+ to[0] = from[i][0];
+ i = !i;
+ }
+ }
+ }
+ else if (channels == 3) {
+ for (y = 0; y < height; y++) {
+ float *to = rect_to + stride_to * y * 3;
+ const float *from[2] = {
+ rect_left + stride_from * y * 3,
+ rect_right + stride_from * y * 3,
+ };
+
+ char i = (char)swap;
+ for (x = 0; x < width; x++, from[0] += 3, from[1] += 3, to += 3) {
+ copy_v3_v3(to, from[i]);
+ i = !i;
+ }
+ }
+ }
+ else if (channels == 4) {
+ for (y = 0; y < height; y++) {
+ float *to = rect_to + stride_to * y * channels;
+ const float *from[2] = {
+ rect_left + stride_from * y * channels,
+ rect_right + stride_from * y * channels,
+ };
+
+ char i = (char)swap;
+ for (x = 0; x < width; x++, from[0] += 4, from[1] += 4, to += 4) {
+ copy_v4_v4(to, from[i]);
+ i = !i;
+ }
+ }
+ }
+ break;
+ }
+ case S3D_INTERLACE_CHECKERBOARD: {
+ if (channels == 1) {
+ char i = (char)swap;
+ for (y = 0; y < height; y++) {
+ float *to = rect_to + stride_to * y;
+ const float *from[2] = {
+ rect_left + stride_from * y,
+ rect_right + stride_from * y,
+ };
+ char j = i;
+ for (x = 0; x < width; x++, from[0] += 1, from[1] += 1, to += 1) {
+ to[0] = from[j][0];
+ j = !j;
+ }
+ i = !i;
+ }
+ }
+ else if (channels == 3) {
+ char i = (char)swap;
+ for (y = 0; y < height; y++) {
+ float *to = rect_to + stride_to * y * 3;
+ const float *from[2] = {
+ rect_left + stride_from * y * 3,
+ rect_right + stride_from * y * 3,
+ };
+ char j = i;
+ for (x = 0; x < width; x++, from[0] += 3, from[1] += 3, to += 3) {
+ copy_v3_v3(to, from[j]);
+ j = !j;
+ }
+ i = !i;
+ }
+ }
+ else if (channels == 4) {
+ char i = (char)swap;
+ for (y = 0; y < height; y++) {
+ float *to = rect_to + stride_to * y * 4;
+ const float *from[2] = {
+ rect_left + stride_from * y * 4,
+ rect_right + stride_from * y * 4,
+ };
+ char j = i;
+ for (x = 0; x < width; x++, from[0] += 4, from[1] += 4, to += 4) {
+ copy_v4_v4(to, from[j]);
+ j = !j;
+ }
+ i = !i;
+ }
+ }
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ }
+ else {
+ const uchar *rect_left = s3d->rect.left;
+ const uchar *rect_right = s3d->rect.right;
+ uchar *rect_to = s3d->rect.stereo;
+
+ switch (mode) {
+ case S3D_INTERLACE_ROW: {
+ char i = (char)swap;
+ for (y = 0; y < height; y++) {
+ uchar *to = rect_to + stride_to * y * channels;
+ const uchar *from[2] = {
+ rect_left + stride_from * y * channels,
+ rect_right + stride_from * y * channels,
+ };
+ memcpy(to, from[i], sizeof(uchar) * channels * stride_from);
+ i = !i;
+ }
+ break;
+ }
+ case S3D_INTERLACE_COLUMN: {
+ if (channels == 1) {
+ for (y = 0; y < height; y++) {
+ uchar *to = rect_to + stride_to * y;
+ const uchar *from[2] = {
+ rect_left + stride_from * y,
+ rect_right + stride_from * y,
+ };
+ char i = (char)swap;
+ for (x = 0; x < width; x++, from[0] += 1, from[1] += 1, to += 1) {
+ to[0] = from[i][0];
+ i = !i;
+ }
+ }
+ }
+ else if (channels == 3) {
+ for (y = 0; y < height; y++) {
+ uchar *to = rect_to + stride_to * y * 3;
+ const uchar *from[2] = {
+ rect_left + stride_from * y * 3,
+ rect_right + stride_from * y * 3,
+ };
+ char i = (char)swap;
+ for (x = 0; x < width; x++, from[0] += 3, from[1] += 3, to += 3) {
+ copy_v3_v3_uchar(to, from[i]);
+ i = !i;
+ }
+ }
+ }
+ else if (channels == 4) {
+ for (y = 0; y < height; y++) {
+ uchar *to = rect_to + stride_to * y * 4;
+ const uchar *from[2] = {
+ rect_left + stride_from * y * 4,
+ rect_right + stride_from * y * 4,
+ };
+ char i = (char)swap;
+ for (x = 0; x < width; x++, from[0] += 4, from[1] += 4, to += 4) {
+ copy_v4_v4_uchar(to, from[i]);
+ i = !i;
+ }
+ }
+ }
+ break;
+ }
+ case S3D_INTERLACE_CHECKERBOARD: {
+ if (channels == 1) {
+ char i = (char)swap;
+ for (y = 0; y < height; y++) {
+ uchar *to = rect_to + stride_to * y;
+ const uchar *from[2] = {
+ rect_left + stride_from * y,
+ rect_right + stride_from * y,
+ };
+ char j = i;
+ for (x = 0; x < width; x++, from[0] += 1, from[1] += 1, to += 1) {
+ to[0] = from[j][0];
+ j = !j;
+ }
+ i = !i;
+ }
+ }
+ else if (channels == 3) {
+ char i = (char)swap;
+ for (y = 0; y < height; y++) {
+ uchar *to = rect_to + stride_to * y * 3;
+ const uchar *from[2] = {
+ rect_left + stride_from * y * 3,
+ rect_right + stride_from * y * 3,
+ };
+ char j = i;
+ for (x = 0; x < width; x++, from[0] += 3, from[1] += 3, to += 3) {
+ copy_v3_v3_uchar(to, from[j]);
+ j = !j;
+ }
+ i = !i;
+ }
+ }
+ else if (channels == 4) {
+ char i = (char)swap;
+ for (y = 0; y < height; y++) {
+ uchar *to = rect_to + stride_to * y * 4;
+ const uchar *from[2] = {
+ rect_left + stride_from * y * 4,
+ rect_right + stride_from * y * 4,
+ };
+ char j = i;
+ for (x = 0; x < width; x++, from[0] += 4, from[1] += 4, to += 4) {
+ copy_v4_v4_uchar(to, from[j]);
+ j = !j;
+ }
+ i = !i;
+ }
+ }
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ }
}
/* stereo3d output (s3d->rectf.stereo) is always unsqueezed */
static void imb_stereo3d_write_sidebyside(Stereo3DData *s3d, const bool crosseyed)
{
- int y;
- size_t width = s3d->x;
- size_t height = s3d->y;
- const size_t channels = s3d->channels;
-
- const int stride_from = width;
- const int stride_to = width * 2;
-
- const int l = (int) crosseyed;
- const int r = !l;
-
- if (s3d->is_float) {
- const float *rect_left = s3d->rectf.left;
- const float *rect_right = s3d->rectf.right;
- float *rect_to = s3d->rectf.stereo;
-
- for (y = 0; y < height; y++) {
- float *to = rect_to + stride_to * y * channels;
- const float *from[2] = {
- rect_left + stride_from * y * channels,
- rect_right + stride_from * y * channels,
- };
-
- memcpy(to, from[l], sizeof(float) * channels * stride_from);
- memcpy(to + channels * stride_from, from[r], sizeof(float) * channels * stride_from);
- }
- }
- else {
- const uchar *rect_left = s3d->rect.left;
- const uchar *rect_right = s3d->rect.right;
- uchar *rect_to = s3d->rect.stereo;
-
- for (y = 0; y < height; y++) {
- uchar *to = rect_to + stride_to * y * channels;
- const uchar *from[2] = {
- rect_left + stride_from * y * channels,
- rect_right + stride_from * y * channels,
- };
-
- memcpy(to, from[l], sizeof(uchar) * channels * stride_from);
- memcpy(to + channels * stride_from, from[r], sizeof(uchar) * channels * stride_from);
- }
- }
+ int y;
+ size_t width = s3d->x;
+ size_t height = s3d->y;
+ const size_t channels = s3d->channels;
+
+ const int stride_from = width;
+ const int stride_to = width * 2;
+
+ const int l = (int)crosseyed;
+ const int r = !l;
+
+ if (s3d->is_float) {
+ const float *rect_left = s3d->rectf.left;
+ const float *rect_right = s3d->rectf.right;
+ float *rect_to = s3d->rectf.stereo;
+
+ for (y = 0; y < height; y++) {
+ float *to = rect_to + stride_to * y * channels;
+ const float *from[2] = {
+ rect_left + stride_from * y * channels,
+ rect_right + stride_from * y * channels,
+ };
+
+ memcpy(to, from[l], sizeof(float) * channels * stride_from);
+ memcpy(to + channels * stride_from, from[r], sizeof(float) * channels * stride_from);
+ }
+ }
+ else {
+ const uchar *rect_left = s3d->rect.left;
+ const uchar *rect_right = s3d->rect.right;
+ uchar *rect_to = s3d->rect.stereo;
+
+ for (y = 0; y < height; y++) {
+ uchar *to = rect_to + stride_to * y * channels;
+ const uchar *from[2] = {
+ rect_left + stride_from * y * channels,
+ rect_right + stride_from * y * channels,
+ };
+
+ memcpy(to, from[l], sizeof(uchar) * channels * stride_from);
+ memcpy(to + channels * stride_from, from[r], sizeof(uchar) * channels * stride_from);
+ }
+ }
}
/* stereo3d output (s3d->rectf.stereo) is always unsqueezed */
static void imb_stereo3d_write_topbottom(Stereo3DData *s3d)
{
- int y;
- size_t width = s3d->x;
- size_t height = s3d->y;
- const size_t channels = s3d->channels;
-
- const int stride_from = width;
- const int stride_to = width;
-
- if (s3d->is_float) {
- const float *rect_left = s3d->rectf.left;
- const float *rect_right = s3d->rectf.right;
- float *rect_to = s3d->rectf.stereo;
-
- for (y = 0; y < height; y++) {
- float *to = rect_to + stride_to * y * channels;
- const float *from[2] = {
- rect_left + stride_from * y * channels,
- rect_right + stride_from * y * channels,
- };
-
- memcpy(to, from[1], sizeof(float) * channels * stride_from);
- memcpy(to + channels * height * stride_from, from[0], sizeof(float) * channels * stride_from);
- }
- }
- else {
- const uchar *rect_left = s3d->rect.left;
- const uchar *rect_right = s3d->rect.right;
- uchar *rect_to = s3d->rect.stereo;
-
- for (y = 0; y < height; y++) {
- uchar *to = rect_to + stride_to * y * channels;
- const uchar *from[2] = {
- rect_left + stride_from * y * channels,
- rect_right + stride_from * y * channels,
- };
-
- memcpy(to, from[1], sizeof(uchar) * channels * stride_from);
- memcpy(to + channels * height * stride_from, from[0], sizeof(uchar) * channels * stride_from);
- }
- }
+ int y;
+ size_t width = s3d->x;
+ size_t height = s3d->y;
+ const size_t channels = s3d->channels;
+
+ const int stride_from = width;
+ const int stride_to = width;
+
+ if (s3d->is_float) {
+ const float *rect_left = s3d->rectf.left;
+ const float *rect_right = s3d->rectf.right;
+ float *rect_to = s3d->rectf.stereo;
+
+ for (y = 0; y < height; y++) {
+ float *to = rect_to + stride_to * y * channels;
+ const float *from[2] = {
+ rect_left + stride_from * y * channels,
+ rect_right + stride_from * y * channels,
+ };
+
+ memcpy(to, from[1], sizeof(float) * channels * stride_from);
+ memcpy(
+ to + channels * height * stride_from, from[0], sizeof(float) * channels * stride_from);
+ }
+ }
+ else {
+ const uchar *rect_left = s3d->rect.left;
+ const uchar *rect_right = s3d->rect.right;
+ uchar *rect_to = s3d->rect.stereo;
+
+ for (y = 0; y < height; y++) {
+ uchar *to = rect_to + stride_to * y * channels;
+ const uchar *from[2] = {
+ rect_left + stride_from * y * channels,
+ rect_right + stride_from * y * channels,
+ };
+
+ memcpy(to, from[1], sizeof(uchar) * channels * stride_from);
+ memcpy(
+ to + channels * height * stride_from, from[0], sizeof(uchar) * channels * stride_from);
+ }
+ }
}
/**************************** dimension utils ****************************************/
-void IMB_stereo3d_write_dimensions(
- const char mode, const bool is_squeezed, const size_t width, const size_t height,
- size_t *r_width, size_t *r_height)
+void IMB_stereo3d_write_dimensions(const char mode,
+ const bool is_squeezed,
+ const size_t width,
+ const size_t height,
+ size_t *r_width,
+ size_t *r_height)
{
- switch (mode) {
- case S3D_DISPLAY_SIDEBYSIDE:
- {
- *r_width = is_squeezed ? width : width * 2;
- *r_height = height;
- break;
- }
- case S3D_DISPLAY_TOPBOTTOM:
- {
- *r_width = width;
- *r_height = is_squeezed ? height : height * 2;
- break;
- }
- case S3D_DISPLAY_ANAGLYPH:
- case S3D_DISPLAY_INTERLACE:
- default:
- {
- *r_width = width;
- *r_height = height;
- break;
- }
- }
+ switch (mode) {
+ case S3D_DISPLAY_SIDEBYSIDE: {
+ *r_width = is_squeezed ? width : width * 2;
+ *r_height = height;
+ break;
+ }
+ case S3D_DISPLAY_TOPBOTTOM: {
+ *r_width = width;
+ *r_height = is_squeezed ? height : height * 2;
+ break;
+ }
+ case S3D_DISPLAY_ANAGLYPH:
+ case S3D_DISPLAY_INTERLACE:
+ default: {
+ *r_width = width;
+ *r_height = height;
+ break;
+ }
+ }
}
-void IMB_stereo3d_read_dimensions(
- const char mode, const bool is_squeezed, const size_t width, const size_t height,
- size_t *r_width, size_t *r_height)
+void IMB_stereo3d_read_dimensions(const char mode,
+ const bool is_squeezed,
+ const size_t width,
+ const size_t height,
+ size_t *r_width,
+ size_t *r_height)
{
- switch (mode) {
- case S3D_DISPLAY_SIDEBYSIDE:
- {
- *r_width = is_squeezed ? width / 2 : width;
- *r_height = height;
- break;
- }
- case S3D_DISPLAY_TOPBOTTOM:
- {
- *r_width = width;
- *r_height = is_squeezed ? height / 2 : height;
- break;
- }
- case S3D_DISPLAY_ANAGLYPH:
- case S3D_DISPLAY_INTERLACE:
- default:
- {
- *r_width = width;
- *r_height = height;
- break;
- }
- }
+ switch (mode) {
+ case S3D_DISPLAY_SIDEBYSIDE: {
+ *r_width = is_squeezed ? width / 2 : width;
+ *r_height = height;
+ break;
+ }
+ case S3D_DISPLAY_TOPBOTTOM: {
+ *r_width = width;
+ *r_height = is_squeezed ? height / 2 : height;
+ break;
+ }
+ case S3D_DISPLAY_ANAGLYPH:
+ case S3D_DISPLAY_INTERLACE:
+ default: {
+ *r_width = width;
+ *r_height = height;
+ break;
+ }
+ }
}
/**************************** un/squeeze frame ****************************************/
-static void imb_stereo3d_squeeze_ImBuf(ImBuf *ibuf, Stereo3dFormat *s3d, const size_t x, const size_t y)
+static void imb_stereo3d_squeeze_ImBuf(ImBuf *ibuf,
+ Stereo3dFormat *s3d,
+ const size_t x,
+ const size_t y)
{
- if (ELEM(s3d->display_mode, S3D_DISPLAY_SIDEBYSIDE, S3D_DISPLAY_TOPBOTTOM) == false)
- return;
+ if (ELEM(s3d->display_mode, S3D_DISPLAY_SIDEBYSIDE, S3D_DISPLAY_TOPBOTTOM) == false)
+ return;
- if ((s3d->flag & S3D_SQUEEZED_FRAME) == 0)
- return;
+ if ((s3d->flag & S3D_SQUEEZED_FRAME) == 0)
+ return;
- IMB_scaleImBuf_threaded(ibuf, x, y);
+ IMB_scaleImBuf_threaded(ibuf, x, y);
}
-static void imb_stereo3d_unsqueeze_ImBuf(ImBuf *ibuf, Stereo3dFormat *s3d, const size_t x, const size_t y)
+static void imb_stereo3d_unsqueeze_ImBuf(ImBuf *ibuf,
+ Stereo3dFormat *s3d,
+ const size_t x,
+ const size_t y)
{
- if (ELEM(s3d->display_mode, S3D_DISPLAY_SIDEBYSIDE, S3D_DISPLAY_TOPBOTTOM) == false)
- return;
+ if (ELEM(s3d->display_mode, S3D_DISPLAY_SIDEBYSIDE, S3D_DISPLAY_TOPBOTTOM) == false)
+ return;
- if ((s3d->flag & S3D_SQUEEZED_FRAME) == 0)
- return;
+ if ((s3d->flag & S3D_SQUEEZED_FRAME) == 0)
+ return;
- IMB_scaleImBuf_threaded(ibuf, x, y);
+ IMB_scaleImBuf_threaded(ibuf, x, y);
}
-static void imb_stereo3d_squeeze_rectf(float *rectf, Stereo3dFormat *s3d, const size_t x, const size_t y, const size_t channels)
+static void imb_stereo3d_squeeze_rectf(
+ float *rectf, Stereo3dFormat *s3d, const size_t x, const size_t y, const size_t channels)
{
- ImBuf *ibuf;
- size_t width, height;
-
- if (ELEM(s3d->display_mode, S3D_DISPLAY_SIDEBYSIDE, S3D_DISPLAY_TOPBOTTOM) == false)
- return;
-
- if ((s3d->flag & S3D_SQUEEZED_FRAME) == 0)
- return;
-
- /* creates temporary imbuf to store the rectf */
- IMB_stereo3d_write_dimensions(s3d->display_mode, false, x, y, &width, &height);
- ibuf = IMB_allocImBuf(width, height, channels, IB_rectfloat);
-
- IMB_buffer_float_from_float(
- ibuf->rect_float, rectf, channels,
- IB_PROFILE_LINEAR_RGB, IB_PROFILE_LINEAR_RGB, false,
- width, height, width, width);
-
- IMB_scaleImBuf_threaded(ibuf, x, y);
- memcpy(rectf, ibuf->rect_float, x * y * sizeof(float[4]));
- IMB_freeImBuf(ibuf);
+ ImBuf *ibuf;
+ size_t width, height;
+
+ if (ELEM(s3d->display_mode, S3D_DISPLAY_SIDEBYSIDE, S3D_DISPLAY_TOPBOTTOM) == false)
+ return;
+
+ if ((s3d->flag & S3D_SQUEEZED_FRAME) == 0)
+ return;
+
+ /* creates temporary imbuf to store the rectf */
+ IMB_stereo3d_write_dimensions(s3d->display_mode, false, x, y, &width, &height);
+ ibuf = IMB_allocImBuf(width, height, channels, IB_rectfloat);
+
+ IMB_buffer_float_from_float(ibuf->rect_float,
+ rectf,
+ channels,
+ IB_PROFILE_LINEAR_RGB,
+ IB_PROFILE_LINEAR_RGB,
+ false,
+ width,
+ height,
+ width,
+ width);
+
+ IMB_scaleImBuf_threaded(ibuf, x, y);
+ memcpy(rectf, ibuf->rect_float, x * y * sizeof(float[4]));
+ IMB_freeImBuf(ibuf);
}
-static void imb_stereo3d_squeeze_rect(int *rect, Stereo3dFormat *s3d, const size_t x, const size_t y, const size_t channels)
+static void imb_stereo3d_squeeze_rect(
+ int *rect, Stereo3dFormat *s3d, const size_t x, const size_t y, const size_t channels)
{
- ImBuf *ibuf;
- size_t width, height;
-
- if (ELEM(s3d->display_mode, S3D_DISPLAY_SIDEBYSIDE, S3D_DISPLAY_TOPBOTTOM) == false)
- return;
-
- if ((s3d->flag & S3D_SQUEEZED_FRAME) == 0)
- return;
-
- /* creates temporary imbuf to store the rectf */
- IMB_stereo3d_write_dimensions(s3d->display_mode, false, x, y, &width, &height);
- ibuf = IMB_allocImBuf(width, height, channels, IB_rect);
-
- IMB_buffer_byte_from_byte(
- (unsigned char *)ibuf->rect, (unsigned char *)rect,
- IB_PROFILE_SRGB, IB_PROFILE_SRGB, false,
- width, height, width, width);
-
- IMB_scaleImBuf_threaded(ibuf, x, y);
- memcpy(rect, ibuf->rect, x * y * sizeof(unsigned int));
- IMB_freeImBuf(ibuf);
+ ImBuf *ibuf;
+ size_t width, height;
+
+ if (ELEM(s3d->display_mode, S3D_DISPLAY_SIDEBYSIDE, S3D_DISPLAY_TOPBOTTOM) == false)
+ return;
+
+ if ((s3d->flag & S3D_SQUEEZED_FRAME) == 0)
+ return;
+
+ /* creates temporary imbuf to store the rectf */
+ IMB_stereo3d_write_dimensions(s3d->display_mode, false, x, y, &width, &height);
+ ibuf = IMB_allocImBuf(width, height, channels, IB_rect);
+
+ IMB_buffer_byte_from_byte((unsigned char *)ibuf->rect,
+ (unsigned char *)rect,
+ IB_PROFILE_SRGB,
+ IB_PROFILE_SRGB,
+ false,
+ width,
+ height,
+ width,
+ width);
+
+ IMB_scaleImBuf_threaded(ibuf, x, y);
+ memcpy(rect, ibuf->rect, x * y * sizeof(unsigned int));
+ IMB_freeImBuf(ibuf);
}
-
/*************************** preparing to call the write functions **************************/
-static void imb_stereo3d_data_initialize(
- Stereo3DData *s3d_data, const bool is_float,
- const size_t x, const size_t y, const size_t channels,
- int *rect_left, int *rect_right, int *rect_stereo,
- float *rectf_left, float *rectf_right, float *rectf_stereo)
+static void imb_stereo3d_data_initialize(Stereo3DData *s3d_data,
+ const bool is_float,
+ const size_t x,
+ const size_t y,
+ const size_t channels,
+ int *rect_left,
+ int *rect_right,
+ int *rect_stereo,
+ float *rectf_left,
+ float *rectf_right,
+ float *rectf_stereo)
{
- s3d_data->is_float = is_float;
- s3d_data->x = x;
- s3d_data->y = y;
- s3d_data->channels = channels;
- s3d_data->rect.left = (uchar *)rect_left;
- s3d_data->rect.right = (uchar *)rect_right;
- s3d_data->rect.stereo = (uchar *)rect_stereo;
- s3d_data->rectf.left = rectf_left;
- s3d_data->rectf.right = rectf_right;
- s3d_data->rectf.stereo = rectf_stereo;
+ s3d_data->is_float = is_float;
+ s3d_data->x = x;
+ s3d_data->y = y;
+ s3d_data->channels = channels;
+ s3d_data->rect.left = (uchar *)rect_left;
+ s3d_data->rect.right = (uchar *)rect_right;
+ s3d_data->rect.stereo = (uchar *)rect_stereo;
+ s3d_data->rectf.left = rectf_left;
+ s3d_data->rectf.right = rectf_right;
+ s3d_data->rectf.stereo = rectf_stereo;
}
-int *IMB_stereo3d_from_rect(
- ImageFormatData *im_format, const size_t x, const size_t y, const size_t channels,
- int *rect_left, int *rect_right)
+int *IMB_stereo3d_from_rect(ImageFormatData *im_format,
+ const size_t x,
+ const size_t y,
+ const size_t channels,
+ int *rect_left,
+ int *rect_right)
{
- int *r_rect;
- Stereo3DData s3d_data = {{NULL}};
- size_t width, height;
- const bool is_float = im_format->depth > 8;
+ int *r_rect;
+ Stereo3DData s3d_data = {{NULL}};
+ size_t width, height;
+ const bool is_float = im_format->depth > 8;
- IMB_stereo3d_write_dimensions(im_format->stereo3d_format.display_mode, false, x, y, &width, &height);
- r_rect = MEM_mallocN(channels * sizeof(int) * width * height, __func__);
+ IMB_stereo3d_write_dimensions(
+ im_format->stereo3d_format.display_mode, false, x, y, &width, &height);
+ r_rect = MEM_mallocN(channels * sizeof(int) * width * height, __func__);
- imb_stereo3d_data_initialize(&s3d_data, is_float, x, y, channels, rect_left, rect_right, r_rect, NULL, NULL, NULL);
- imb_stereo3d_write_doit(&s3d_data, &im_format->stereo3d_format);
- imb_stereo3d_squeeze_rect(r_rect, &im_format->stereo3d_format, x, y, channels);
+ imb_stereo3d_data_initialize(
+ &s3d_data, is_float, x, y, channels, rect_left, rect_right, r_rect, NULL, NULL, NULL);
+ imb_stereo3d_write_doit(&s3d_data, &im_format->stereo3d_format);
+ imb_stereo3d_squeeze_rect(r_rect, &im_format->stereo3d_format, x, y, channels);
- return r_rect;
+ return r_rect;
}
-float *IMB_stereo3d_from_rectf(
- ImageFormatData *im_format, const size_t x, const size_t y, const size_t channels,
- float *rectf_left, float *rectf_right)
+float *IMB_stereo3d_from_rectf(ImageFormatData *im_format,
+ const size_t x,
+ const size_t y,
+ const size_t channels,
+ float *rectf_left,
+ float *rectf_right)
{
- float *r_rectf;
- Stereo3DData s3d_data = {{NULL}};
- size_t width, height;
- const bool is_float = im_format->depth > 8;
+ float *r_rectf;
+ Stereo3DData s3d_data = {{NULL}};
+ size_t width, height;
+ const bool is_float = im_format->depth > 8;
- IMB_stereo3d_write_dimensions(im_format->stereo3d_format.display_mode, false, x, y, &width, &height);
- r_rectf = MEM_mallocN(channels * sizeof(float) * width * height, __func__);
+ IMB_stereo3d_write_dimensions(
+ im_format->stereo3d_format.display_mode, false, x, y, &width, &height);
+ r_rectf = MEM_mallocN(channels * sizeof(float) * width * height, __func__);
- imb_stereo3d_data_initialize(&s3d_data, is_float, x, y, channels, NULL, NULL, NULL, rectf_left, rectf_right, r_rectf);
- imb_stereo3d_write_doit(&s3d_data, &im_format->stereo3d_format);
- imb_stereo3d_squeeze_rectf(r_rectf, &im_format->stereo3d_format, x, y, channels);
+ imb_stereo3d_data_initialize(
+ &s3d_data, is_float, x, y, channels, NULL, NULL, NULL, rectf_left, rectf_right, r_rectf);
+ imb_stereo3d_write_doit(&s3d_data, &im_format->stereo3d_format);
+ imb_stereo3d_squeeze_rectf(r_rectf, &im_format->stereo3d_format, x, y, channels);
- return r_rectf;
+ return r_rectf;
}
/* left/right are always float */
ImBuf *IMB_stereo3d_ImBuf(ImageFormatData *im_format, ImBuf *ibuf_left, ImBuf *ibuf_right)
{
- ImBuf *ibuf_stereo = NULL;
- Stereo3DData s3d_data = {{NULL}};
- size_t width, height;
- const bool is_float = im_format->depth > 8;
-
- IMB_stereo3d_write_dimensions(im_format->stereo3d_format.display_mode, false, ibuf_left->x, ibuf_left->y, &width, &height);
- ibuf_stereo = IMB_allocImBuf(width, height, ibuf_left->planes, (is_float ? IB_rectfloat : IB_rect));
-
- ibuf_stereo->rect_colorspace = ibuf_left->rect_colorspace;
- ibuf_stereo->float_colorspace = ibuf_left->float_colorspace;
-
- ibuf_stereo->flags = ibuf_left->flags;
-
- imb_stereo3d_data_initialize(
- &s3d_data, is_float, ibuf_left->x, ibuf_left->y, 4,
- (int *)ibuf_left->rect, (int *)ibuf_right->rect, (int *)ibuf_stereo->rect,
- ibuf_left->rect_float, ibuf_right->rect_float, ibuf_stereo->rect_float);
-
- imb_stereo3d_write_doit(&s3d_data, &im_format->stereo3d_format);
- imb_stereo3d_squeeze_ImBuf(ibuf_stereo, &im_format->stereo3d_format, ibuf_left->x, ibuf_left->y);
-
- return ibuf_stereo;
+ ImBuf *ibuf_stereo = NULL;
+ Stereo3DData s3d_data = {{NULL}};
+ size_t width, height;
+ const bool is_float = im_format->depth > 8;
+
+ IMB_stereo3d_write_dimensions(
+ im_format->stereo3d_format.display_mode, false, ibuf_left->x, ibuf_left->y, &width, &height);
+ ibuf_stereo = IMB_allocImBuf(
+ width, height, ibuf_left->planes, (is_float ? IB_rectfloat : IB_rect));
+
+ ibuf_stereo->rect_colorspace = ibuf_left->rect_colorspace;
+ ibuf_stereo->float_colorspace = ibuf_left->float_colorspace;
+
+ ibuf_stereo->flags = ibuf_left->flags;
+
+ imb_stereo3d_data_initialize(&s3d_data,
+ is_float,
+ ibuf_left->x,
+ ibuf_left->y,
+ 4,
+ (int *)ibuf_left->rect,
+ (int *)ibuf_right->rect,
+ (int *)ibuf_stereo->rect,
+ ibuf_left->rect_float,
+ ibuf_right->rect_float,
+ ibuf_stereo->rect_float);
+
+ imb_stereo3d_write_doit(&s3d_data, &im_format->stereo3d_format);
+ imb_stereo3d_squeeze_ImBuf(ibuf_stereo, &im_format->stereo3d_format, ibuf_left->x, ibuf_left->y);
+
+ return ibuf_stereo;
}
static void imb_stereo3d_write_doit(Stereo3DData *s3d_data, Stereo3dFormat *s3d)
{
- switch (s3d->display_mode) {
- case S3D_DISPLAY_ANAGLYPH:
- imb_stereo3d_write_anaglyph(s3d_data, s3d->anaglyph_type);
- break;
- case S3D_DISPLAY_INTERLACE:
- imb_stereo3d_write_interlace(s3d_data, s3d->interlace_type, (s3d->flag & S3D_INTERLACE_SWAP) != 0);
- break;
- case S3D_DISPLAY_SIDEBYSIDE:
- imb_stereo3d_write_sidebyside(s3d_data, (s3d->flag & S3D_SIDEBYSIDE_CROSSEYED) != 0);
- break;
- case S3D_DISPLAY_TOPBOTTOM:
- imb_stereo3d_write_topbottom(s3d_data);
- break;
- default:
- break;
- }
+ switch (s3d->display_mode) {
+ case S3D_DISPLAY_ANAGLYPH:
+ imb_stereo3d_write_anaglyph(s3d_data, s3d->anaglyph_type);
+ break;
+ case S3D_DISPLAY_INTERLACE:
+ imb_stereo3d_write_interlace(
+ s3d_data, s3d->interlace_type, (s3d->flag & S3D_INTERLACE_SWAP) != 0);
+ break;
+ case S3D_DISPLAY_SIDEBYSIDE:
+ imb_stereo3d_write_sidebyside(s3d_data, (s3d->flag & S3D_SIDEBYSIDE_CROSSEYED) != 0);
+ break;
+ case S3D_DISPLAY_TOPBOTTOM:
+ imb_stereo3d_write_topbottom(s3d_data);
+ break;
+ default:
+ break;
+ }
}
/******************************** reading stereo imbufs **********************/
static void imb_stereo3d_read_anaglyph(Stereo3DData *s3d, enum eStereo3dAnaglyphType mode)
{
- int x, y;
- size_t width = s3d->x;
- size_t height = s3d->y;
- const size_t channels = s3d->channels;
-
- const int stride_from = width;
- const int stride_to = width;
-
- int anaglyph_encoding[3][3] = {
- {0, 1, 1},
- {1, 0, 1},
- {0, 0, 1},
- };
-
- int r, g, b;
-
- r = anaglyph_encoding[mode][0];
- g = anaglyph_encoding[mode][1];
- b = anaglyph_encoding[mode][2];
-
- if (s3d->is_float) {
- float *rect_left = s3d->rectf.left;
- float *rect_right = s3d->rectf.right;
- float *rect_from = s3d->rectf.stereo;
-
- if (channels == 3) {
- for (y = 0; y < height; y++) {
- float *from = rect_from + stride_from * y * 3;
- float *to[2] = {
- rect_left + stride_to * y * 3,
- rect_right + stride_to * y * 3,
- };
-
- for (x = 0; x < width; x++, from += 3, to[0] += 3, to[1] += 3) {
- to[r][0] = from[0];
- to[g][1] = from[1];
- to[b][2] = from[2];
- }
- }
- }
- else if (channels == 4) {
- for (y = 0; y < height; y++) {
- float *from = rect_from + stride_from * y * 4;
- float *to[2] = {
- rect_left + stride_to * y * 4,
- rect_right + stride_to * y * 4,
- };
-
- for (x = 0; x < width; x++, from += 4, to[0] += 4, to[1] += 4) {
- to[r][0] = from[0];
- to[g][1] = from[1];
- to[b][2] = from[2];
- to[0][3] = to[1][3] = from[3];
- }
- }
- }
- }
- else {
- uchar *rect_left = s3d->rect.left;
- uchar *rect_right = s3d->rect.right;
- uchar *rect_from = s3d->rect.stereo;
-
- if (channels == 3) {
- for (y = 0; y < height; y++) {
- uchar *from = rect_from + stride_from * y * 3;
- uchar *to[2] = {
- rect_left + stride_to * y * 3,
- rect_right + stride_to * y * 3,
- };
-
- for (x = 0; x < width; x++, from += 3, to[0] += 3, to[1] += 3) {
- to[r][0] = from[0];
- to[g][1] = from[1];
- to[b][2] = from[2];
- }
- }
- }
- else if (channels == 4) {
- for (y = 0; y < height; y++) {
- uchar *from = rect_from + stride_from * y * 4;
- uchar *to[2] = {
- rect_left + stride_to * y * 4,
- rect_right + stride_to * y * 4,
- };
-
- for (x = 0; x < width; x++, from += 4, to[0] += 4, to[1] += 4) {
- to[r][0] = from[0];
- to[g][1] = from[1];
- to[b][2] = from[2];
- to[0][3] = to[1][3] = from[3];
- }
- }
- }
- }
+ int x, y;
+ size_t width = s3d->x;
+ size_t height = s3d->y;
+ const size_t channels = s3d->channels;
+
+ const int stride_from = width;
+ const int stride_to = width;
+
+ int anaglyph_encoding[3][3] = {
+ {0, 1, 1},
+ {1, 0, 1},
+ {0, 0, 1},
+ };
+
+ int r, g, b;
+
+ r = anaglyph_encoding[mode][0];
+ g = anaglyph_encoding[mode][1];
+ b = anaglyph_encoding[mode][2];
+
+ if (s3d->is_float) {
+ float *rect_left = s3d->rectf.left;
+ float *rect_right = s3d->rectf.right;
+ float *rect_from = s3d->rectf.stereo;
+
+ if (channels == 3) {
+ for (y = 0; y < height; y++) {
+ float *from = rect_from + stride_from * y * 3;
+ float *to[2] = {
+ rect_left + stride_to * y * 3,
+ rect_right + stride_to * y * 3,
+ };
+
+ for (x = 0; x < width; x++, from += 3, to[0] += 3, to[1] += 3) {
+ to[r][0] = from[0];
+ to[g][1] = from[1];
+ to[b][2] = from[2];
+ }
+ }
+ }
+ else if (channels == 4) {
+ for (y = 0; y < height; y++) {
+ float *from = rect_from + stride_from * y * 4;
+ float *to[2] = {
+ rect_left + stride_to * y * 4,
+ rect_right + stride_to * y * 4,
+ };
+
+ for (x = 0; x < width; x++, from += 4, to[0] += 4, to[1] += 4) {
+ to[r][0] = from[0];
+ to[g][1] = from[1];
+ to[b][2] = from[2];
+ to[0][3] = to[1][3] = from[3];
+ }
+ }
+ }
+ }
+ else {
+ uchar *rect_left = s3d->rect.left;
+ uchar *rect_right = s3d->rect.right;
+ uchar *rect_from = s3d->rect.stereo;
+
+ if (channels == 3) {
+ for (y = 0; y < height; y++) {
+ uchar *from = rect_from + stride_from * y * 3;
+ uchar *to[2] = {
+ rect_left + stride_to * y * 3,
+ rect_right + stride_to * y * 3,
+ };
+
+ for (x = 0; x < width; x++, from += 3, to[0] += 3, to[1] += 3) {
+ to[r][0] = from[0];
+ to[g][1] = from[1];
+ to[b][2] = from[2];
+ }
+ }
+ }
+ else if (channels == 4) {
+ for (y = 0; y < height; y++) {
+ uchar *from = rect_from + stride_from * y * 4;
+ uchar *to[2] = {
+ rect_left + stride_to * y * 4,
+ rect_right + stride_to * y * 4,
+ };
+
+ for (x = 0; x < width; x++, from += 4, to[0] += 4, to[1] += 4) {
+ to[r][0] = from[0];
+ to[g][1] = from[1];
+ to[b][2] = from[2];
+ to[0][3] = to[1][3] = from[3];
+ }
+ }
+ }
+ }
}
-static void imb_stereo3d_read_interlace(Stereo3DData *s3d, enum eStereo3dInterlaceType mode, const bool swap)
+static void imb_stereo3d_read_interlace(Stereo3DData *s3d,
+ enum eStereo3dInterlaceType mode,
+ const bool swap)
{
- int x, y;
- size_t width = s3d->x;
- size_t height = s3d->y;
- const size_t channels = s3d->channels;
-
- const int stride_from = width;
- const int stride_to = width;
-
- if (s3d->is_float) {
- float *rect_left = s3d->rectf.left;
- float *rect_right = s3d->rectf.right;
- const float *rect_from = s3d->rectf.stereo;
-
- switch (mode) {
- case S3D_INTERLACE_ROW:
- {
- char i = (char) swap;
- for (y = 0; y < height; y++) {
- const float *from = rect_from + stride_from * y * channels;
- float *to[2] = {
- rect_left + stride_to * y * channels,
- rect_right + stride_to * y * channels,
- };
- memcpy(to[i], from, sizeof(float) * channels * stride_to);
- i = !i;
- }
- break;
- }
- case S3D_INTERLACE_COLUMN:
- {
- if (channels == 1) {
- for (y = 0; y < height; y++) {
- const float *from = rect_from + stride_from * y;
- float *to[2] = {
- rect_left + stride_to * y,
- rect_right + stride_to * y,
- };
-
- char i = (char) swap;
- for (x = 0; x < width; x++, from += 1, to[0] += 1, to[1] += 1) {
- to[i][0] = from[0];
- i = !i;
- }
- }
- }
- else if (channels == 3) {
- for (y = 0; y < height; y++) {
- const float *from = rect_from + stride_from * y * 3;
- float *to[2] = {
- rect_left + stride_to * y * 3,
- rect_right + stride_to * y * 3,
- };
-
- char i = (char) swap;
- for (x = 0; x < width; x++, from += 3, to[0] += 3, to[1] += 3) {
- copy_v3_v3(to[i], from);
- i = !i;
- }
- }
- }
- else if (channels == 4) {
- for (y = 0; y < height; y++) {
- const float *from = rect_from + stride_from * y * channels;
- float *to[2] = {
- rect_left + stride_to * y * channels,
- rect_right + stride_to * y * channels,
- };
-
- char i = (char) swap;
- for (x = 0; x < width; x++, from += 4, to[0] += 4, to[1] += 4) {
- copy_v4_v4(to[i], from);
- i = !i;
- }
- }
- }
- break;
- }
- case S3D_INTERLACE_CHECKERBOARD:
- {
- if (channels == 1) {
- char i = (char) swap;
- for (y = 0; y < height; y++) {
- const float *from = rect_from + stride_from * y;
- float *to[2] = {
- rect_left + stride_to * y,
- rect_right + stride_to * y,
- };
- char j = i;
- for (x = 0; x < width; x++, from += 1, to[0] += 1, to[1] += 1) {
- to[j][0] = from[0];
- j = !j;
- }
- i = !i;
- }
- }
- else if (channels == 3) {
- char i = (char) swap;
- for (y = 0; y < height; y++) {
- const float *from = rect_from + stride_from * y * 3;
- float *to[2] = {
- rect_left + stride_to * y * 3,
- rect_right + stride_to * y * 3,
- };
- char j = i;
- for (x = 0; x < width; x++, from += 3, to[0] += 3, to[1] += 3) {
- copy_v3_v3(to[j], from);
- j = !j;
- }
- i = !i;
- }
- }
- else if (channels == 4) {
- char i = (char) swap;
- for (y = 0; y < height; y++) {
- const float *from = rect_from + stride_from * y * 4;
- float *to[2] = {
- rect_left + stride_to * y * 4,
- rect_right + stride_to * y * 4,
- };
- char j = i;
- for (x = 0; x < width; x++, from += 4, to[0] += 4, to[1] += 4) {
- copy_v4_v4(to[j], from);
- j = !j;
- }
- i = !i;
- }
- }
- break;
- }
- default:
- {
- break;
- }
- }
- }
- else {
- uchar *rect_left = s3d->rect.right;
- uchar *rect_right = s3d->rect.left;
- const uchar *rect_from = s3d->rect.stereo;
-
- switch (mode) {
- case S3D_INTERLACE_ROW:
- {
- char i = (char) swap;
- for (y = 0; y < height; y++) {
- const uchar *from = rect_from + stride_from * y * channels;
- uchar *to[2] = {
- rect_left + stride_to * y * channels,
- rect_right + stride_to * y * channels,
- };
- memcpy(to[i], from, sizeof(uchar) * channels * stride_to);
- i = !i;
- }
- break;
- }
- case S3D_INTERLACE_COLUMN:
- {
- if (channels == 1) {
- for (y = 0; y < height; y++) {
- const uchar *from = rect_from + stride_from * y;
- uchar *to[2] = {
- rect_left + stride_to * y,
- rect_right + stride_to * y,
- };
- char i = (char) swap;
- for (x = 0; x < width; x++, from += 1, to[0] += 1, to[1] += 1) {
- to[i][0] = from[0];
- i = !i;
- }
- }
- }
- else if (channels == 3) {
- for (y = 0; y < height; y++) {
- const uchar *from = rect_from + stride_from * y * 3;
- uchar *to[2] = {
- rect_left + stride_to * y * 3,
- rect_right + stride_to * y * 3,
- };
- char i = (char) swap;
- for (x = 0; x < width; x++, from += 3, to[0] += 3, to[1] += 3) {
- copy_v3_v3_uchar(to[i], from);
- i = !i;
- }
- }
- }
- else if (channels == 4) {
- for (y = 0; y < height; y++) {
- const uchar *from = rect_from + stride_from * y * 4;
- uchar *to[2] = {
- rect_left + stride_to * y * 4,
- rect_right + stride_to * y * 4,
- };
- char i = (char) swap;
- for (x = 0; x < width; x++, from += 4, to[0] += 4, to[1] += 4) {
- copy_v4_v4_uchar(to[i], from);
- i = !i;
- }
- }
- }
- break;
- }
- case S3D_INTERLACE_CHECKERBOARD:
- {
- if (channels == 1) {
- char i = (char) swap;
- for (y = 0; y < height; y++) {
- const uchar *from = rect_from + stride_from * y;
- uchar *to[2] = {
- rect_left + stride_to * y,
- rect_right + stride_to * y,
- };
- char j = i;
- for (x = 0; x < width; x++, from += 1, to[0] += 1, to[1] += 1) {
- to[j][0] = from[0];
- j = !j;
- }
- i = !i;
- }
- }
- else if (channels == 3) {
- char i = (char) swap;
- for (y = 0; y < height; y++) {
- const uchar *from = rect_from + stride_from * y * 3;
- uchar *to[2] = {
- rect_left + stride_to * y * 3,
- rect_right + stride_to * y * 3,
- };
- char j = i;
- for (x = 0; x < width; x++, from += 3, to[0] += 3, to[1] += 3) {
- copy_v3_v3_uchar(to[j], from);
- j = !j;
- }
- i = !i;
- }
- }
- else if (channels == 4) {
- char i = (char) swap;
- for (y = 0; y < height; y++) {
- const uchar *from = rect_from + stride_from * y * 4;
- uchar *to[2] = {
- rect_left + stride_to * y * 4,
- rect_right + stride_to * y * 4,
- };
- char j = i;
- for (x = 0; x < width; x++, from += 4, to[0] += 4, to[1] += 4) {
- copy_v4_v4_uchar(to[j], from);
- j = !j;
- }
- i = !i;
- }
- }
- break;
- }
- default:
- {
- break;
- }
- }
- }
+ int x, y;
+ size_t width = s3d->x;
+ size_t height = s3d->y;
+ const size_t channels = s3d->channels;
+
+ const int stride_from = width;
+ const int stride_to = width;
+
+ if (s3d->is_float) {
+ float *rect_left = s3d->rectf.left;
+ float *rect_right = s3d->rectf.right;
+ const float *rect_from = s3d->rectf.stereo;
+
+ switch (mode) {
+ case S3D_INTERLACE_ROW: {
+ char i = (char)swap;
+ for (y = 0; y < height; y++) {
+ const float *from = rect_from + stride_from * y * channels;
+ float *to[2] = {
+ rect_left + stride_to * y * channels,
+ rect_right + stride_to * y * channels,
+ };
+ memcpy(to[i], from, sizeof(float) * channels * stride_to);
+ i = !i;
+ }
+ break;
+ }
+ case S3D_INTERLACE_COLUMN: {
+ if (channels == 1) {
+ for (y = 0; y < height; y++) {
+ const float *from = rect_from + stride_from * y;
+ float *to[2] = {
+ rect_left + stride_to * y,
+ rect_right + stride_to * y,
+ };
+
+ char i = (char)swap;
+ for (x = 0; x < width; x++, from += 1, to[0] += 1, to[1] += 1) {
+ to[i][0] = from[0];
+ i = !i;
+ }
+ }
+ }
+ else if (channels == 3) {
+ for (y = 0; y < height; y++) {
+ const float *from = rect_from + stride_from * y * 3;
+ float *to[2] = {
+ rect_left + stride_to * y * 3,
+ rect_right + stride_to * y * 3,
+ };
+
+ char i = (char)swap;
+ for (x = 0; x < width; x++, from += 3, to[0] += 3, to[1] += 3) {
+ copy_v3_v3(to[i], from);
+ i = !i;
+ }
+ }
+ }
+ else if (channels == 4) {
+ for (y = 0; y < height; y++) {
+ const float *from = rect_from + stride_from * y * channels;
+ float *to[2] = {
+ rect_left + stride_to * y * channels,
+ rect_right + stride_to * y * channels,
+ };
+
+ char i = (char)swap;
+ for (x = 0; x < width; x++, from += 4, to[0] += 4, to[1] += 4) {
+ copy_v4_v4(to[i], from);
+ i = !i;
+ }
+ }
+ }
+ break;
+ }
+ case S3D_INTERLACE_CHECKERBOARD: {
+ if (channels == 1) {
+ char i = (char)swap;
+ for (y = 0; y < height; y++) {
+ const float *from = rect_from + stride_from * y;
+ float *to[2] = {
+ rect_left + stride_to * y,
+ rect_right + stride_to * y,
+ };
+ char j = i;
+ for (x = 0; x < width; x++, from += 1, to[0] += 1, to[1] += 1) {
+ to[j][0] = from[0];
+ j = !j;
+ }
+ i = !i;
+ }
+ }
+ else if (channels == 3) {
+ char i = (char)swap;
+ for (y = 0; y < height; y++) {
+ const float *from = rect_from + stride_from * y * 3;
+ float *to[2] = {
+ rect_left + stride_to * y * 3,
+ rect_right + stride_to * y * 3,
+ };
+ char j = i;
+ for (x = 0; x < width; x++, from += 3, to[0] += 3, to[1] += 3) {
+ copy_v3_v3(to[j], from);
+ j = !j;
+ }
+ i = !i;
+ }
+ }
+ else if (channels == 4) {
+ char i = (char)swap;
+ for (y = 0; y < height; y++) {
+ const float *from = rect_from + stride_from * y * 4;
+ float *to[2] = {
+ rect_left + stride_to * y * 4,
+ rect_right + stride_to * y * 4,
+ };
+ char j = i;
+ for (x = 0; x < width; x++, from += 4, to[0] += 4, to[1] += 4) {
+ copy_v4_v4(to[j], from);
+ j = !j;
+ }
+ i = !i;
+ }
+ }
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ }
+ else {
+ uchar *rect_left = s3d->rect.right;
+ uchar *rect_right = s3d->rect.left;
+ const uchar *rect_from = s3d->rect.stereo;
+
+ switch (mode) {
+ case S3D_INTERLACE_ROW: {
+ char i = (char)swap;
+ for (y = 0; y < height; y++) {
+ const uchar *from = rect_from + stride_from * y * channels;
+ uchar *to[2] = {
+ rect_left + stride_to * y * channels,
+ rect_right + stride_to * y * channels,
+ };
+ memcpy(to[i], from, sizeof(uchar) * channels * stride_to);
+ i = !i;
+ }
+ break;
+ }
+ case S3D_INTERLACE_COLUMN: {
+ if (channels == 1) {
+ for (y = 0; y < height; y++) {
+ const uchar *from = rect_from + stride_from * y;
+ uchar *to[2] = {
+ rect_left + stride_to * y,
+ rect_right + stride_to * y,
+ };
+ char i = (char)swap;
+ for (x = 0; x < width; x++, from += 1, to[0] += 1, to[1] += 1) {
+ to[i][0] = from[0];
+ i = !i;
+ }
+ }
+ }
+ else if (channels == 3) {
+ for (y = 0; y < height; y++) {
+ const uchar *from = rect_from + stride_from * y * 3;
+ uchar *to[2] = {
+ rect_left + stride_to * y * 3,
+ rect_right + stride_to * y * 3,
+ };
+ char i = (char)swap;
+ for (x = 0; x < width; x++, from += 3, to[0] += 3, to[1] += 3) {
+ copy_v3_v3_uchar(to[i], from);
+ i = !i;
+ }
+ }
+ }
+ else if (channels == 4) {
+ for (y = 0; y < height; y++) {
+ const uchar *from = rect_from + stride_from * y * 4;
+ uchar *to[2] = {
+ rect_left + stride_to * y * 4,
+ rect_right + stride_to * y * 4,
+ };
+ char i = (char)swap;
+ for (x = 0; x < width; x++, from += 4, to[0] += 4, to[1] += 4) {
+ copy_v4_v4_uchar(to[i], from);
+ i = !i;
+ }
+ }
+ }
+ break;
+ }
+ case S3D_INTERLACE_CHECKERBOARD: {
+ if (channels == 1) {
+ char i = (char)swap;
+ for (y = 0; y < height; y++) {
+ const uchar *from = rect_from + stride_from * y;
+ uchar *to[2] = {
+ rect_left + stride_to * y,
+ rect_right + stride_to * y,
+ };
+ char j = i;
+ for (x = 0; x < width; x++, from += 1, to[0] += 1, to[1] += 1) {
+ to[j][0] = from[0];
+ j = !j;
+ }
+ i = !i;
+ }
+ }
+ else if (channels == 3) {
+ char i = (char)swap;
+ for (y = 0; y < height; y++) {
+ const uchar *from = rect_from + stride_from * y * 3;
+ uchar *to[2] = {
+ rect_left + stride_to * y * 3,
+ rect_right + stride_to * y * 3,
+ };
+ char j = i;
+ for (x = 0; x < width; x++, from += 3, to[0] += 3, to[1] += 3) {
+ copy_v3_v3_uchar(to[j], from);
+ j = !j;
+ }
+ i = !i;
+ }
+ }
+ else if (channels == 4) {
+ char i = (char)swap;
+ for (y = 0; y < height; y++) {
+ const uchar *from = rect_from + stride_from * y * 4;
+ uchar *to[2] = {
+ rect_left + stride_to * y * 4,
+ rect_right + stride_to * y * 4,
+ };
+ char j = i;
+ for (x = 0; x < width; x++, from += 4, to[0] += 4, to[1] += 4) {
+ copy_v4_v4_uchar(to[j], from);
+ j = !j;
+ }
+ i = !i;
+ }
+ }
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ }
}
/* stereo input (s3d->rectf.stereo) is always unsqueezed */
static void imb_stereo3d_read_sidebyside(Stereo3DData *s3d, const bool crosseyed)
{
- int y;
- size_t width = s3d->x;
- size_t height = s3d->y;
- const size_t channels = s3d->channels;
-
- const int stride_from = width * 2;
- const int stride_to = width;
-
- const int l = (int) crosseyed;
- const int r = !l;
-
- if (s3d->is_float) {
- float *rect_left = s3d->rectf.left;
- float *rect_right = s3d->rectf.right;
- const float *rect_from = s3d->rectf.stereo;
-
- for (y = 0; y < height; y++) {
- const float *from = rect_from + stride_from * y * channels;
- float *to[2] = {
- rect_left + stride_to * y * channels,
- rect_right + stride_to * y * channels,
- };
-
- memcpy(to[l], from, sizeof(float) * channels * stride_to);
- memcpy(to[r], from + channels * stride_to, sizeof(float) * channels * stride_to);
- }
- }
- else {
- uchar *rect_left = s3d->rect.left;
- uchar *rect_right = s3d->rect.right;
- const uchar *rect_from = s3d->rect.stereo;
-
- /* always RGBA input/output */
- for (y = 0; y < height; y++) {
- const uchar *from = rect_from + stride_from * y * channels;
- uchar *to[2] = {
- rect_left + stride_to * y * channels,
- rect_right + stride_to * y * channels,
- };
-
- memcpy(to[l], from, sizeof(uchar) * channels * stride_to);
- memcpy(to[r], from + channels * stride_to, sizeof(uchar) * channels * stride_to);
- }
- }
+ int y;
+ size_t width = s3d->x;
+ size_t height = s3d->y;
+ const size_t channels = s3d->channels;
+
+ const int stride_from = width * 2;
+ const int stride_to = width;
+
+ const int l = (int)crosseyed;
+ const int r = !l;
+
+ if (s3d->is_float) {
+ float *rect_left = s3d->rectf.left;
+ float *rect_right = s3d->rectf.right;
+ const float *rect_from = s3d->rectf.stereo;
+
+ for (y = 0; y < height; y++) {
+ const float *from = rect_from + stride_from * y * channels;
+ float *to[2] = {
+ rect_left + stride_to * y * channels,
+ rect_right + stride_to * y * channels,
+ };
+
+ memcpy(to[l], from, sizeof(float) * channels * stride_to);
+ memcpy(to[r], from + channels * stride_to, sizeof(float) * channels * stride_to);
+ }
+ }
+ else {
+ uchar *rect_left = s3d->rect.left;
+ uchar *rect_right = s3d->rect.right;
+ const uchar *rect_from = s3d->rect.stereo;
+
+ /* always RGBA input/output */
+ for (y = 0; y < height; y++) {
+ const uchar *from = rect_from + stride_from * y * channels;
+ uchar *to[2] = {
+ rect_left + stride_to * y * channels,
+ rect_right + stride_to * y * channels,
+ };
+
+ memcpy(to[l], from, sizeof(uchar) * channels * stride_to);
+ memcpy(to[r], from + channels * stride_to, sizeof(uchar) * channels * stride_to);
+ }
+ }
}
/* stereo input (s3d->rectf.stereo) is always unsqueezed */
static void imb_stereo3d_read_topbottom(Stereo3DData *s3d)
{
- int y;
- size_t width = s3d->x;
- size_t height = s3d->y;
- const size_t channels = s3d->channels;
-
- const int stride_from = width;
- const int stride_to = width;
-
- if (s3d->is_float) {
- float *rect_left = s3d->rectf.left;
- float *rect_right = s3d->rectf.right;
- const float *rect_from = s3d->rectf.stereo;
-
- for (y = 0; y < height; y++) {
- const float *from = rect_from + stride_from * y * channels;
- float *to[2] = {
- rect_left + stride_to * y * channels,
- rect_right + stride_to * y * channels,
- };
-
- memcpy(to[1], from, sizeof(float) * channels * stride_to);
- memcpy(to[0], from + channels * height * stride_to, sizeof(float) * channels * stride_to);
- }
- }
- else {
- uchar *rect_left = s3d->rect.left;
- uchar *rect_right = s3d->rect.right;
- const uchar *rect_from = s3d->rect.stereo;
-
- for (y = 0; y < height; y++) {
- const uchar *from = rect_from + stride_from * y * channels;
- uchar *to[2] = {
- rect_left + stride_to * y * channels,
- rect_right + stride_to * y * channels,
- };
-
- memcpy(to[1], from, sizeof(uchar) * channels * stride_to);
- memcpy(to[0], from + channels * height * stride_to, sizeof(uchar) * channels * stride_to);
- }
- }
+ int y;
+ size_t width = s3d->x;
+ size_t height = s3d->y;
+ const size_t channels = s3d->channels;
+
+ const int stride_from = width;
+ const int stride_to = width;
+
+ if (s3d->is_float) {
+ float *rect_left = s3d->rectf.left;
+ float *rect_right = s3d->rectf.right;
+ const float *rect_from = s3d->rectf.stereo;
+
+ for (y = 0; y < height; y++) {
+ const float *from = rect_from + stride_from * y * channels;
+ float *to[2] = {
+ rect_left + stride_to * y * channels,
+ rect_right + stride_to * y * channels,
+ };
+
+ memcpy(to[1], from, sizeof(float) * channels * stride_to);
+ memcpy(to[0], from + channels * height * stride_to, sizeof(float) * channels * stride_to);
+ }
+ }
+ else {
+ uchar *rect_left = s3d->rect.left;
+ uchar *rect_right = s3d->rect.right;
+ const uchar *rect_from = s3d->rect.stereo;
+
+ for (y = 0; y < height; y++) {
+ const uchar *from = rect_from + stride_from * y * channels;
+ uchar *to[2] = {
+ rect_left + stride_to * y * channels,
+ rect_right + stride_to * y * channels,
+ };
+
+ memcpy(to[1], from, sizeof(uchar) * channels * stride_to);
+ memcpy(to[0], from + channels * height * stride_to, sizeof(uchar) * channels * stride_to);
+ }
+ }
}
-
/*************************** preparing to call the read functions **************************/
/* reading a stereo encoded ibuf (*left) and generating two ibufs from it (*left and *right) */
-void IMB_ImBufFromStereo3d(
- Stereo3dFormat *s3d, ImBuf *ibuf_stereo3d,
- ImBuf **r_ibuf_left, ImBuf **r_ibuf_right)
+void IMB_ImBufFromStereo3d(Stereo3dFormat *s3d,
+ ImBuf *ibuf_stereo3d,
+ ImBuf **r_ibuf_left,
+ ImBuf **r_ibuf_right)
{
- Stereo3DData s3d_data = {{NULL}};
- ImBuf *ibuf_left, *ibuf_right;
- size_t width, height;
- const bool is_float = (ibuf_stereo3d->rect_float != NULL);
-
- IMB_stereo3d_read_dimensions(
- s3d->display_mode, ((s3d->flag & S3D_SQUEEZED_FRAME) == 0), ibuf_stereo3d->x, ibuf_stereo3d->y,
- &width, &height);
-
- ibuf_left = IMB_allocImBuf(width, height, ibuf_stereo3d->planes, (is_float ? IB_rectfloat : IB_rect));
- ibuf_right = IMB_allocImBuf(width, height, ibuf_stereo3d->planes, (is_float ? IB_rectfloat : IB_rect));
-
- ibuf_left->flags = ibuf_stereo3d->flags;
- ibuf_right->flags = ibuf_stereo3d->flags;
-
- /* we always work with unsqueezed formats */
- IMB_stereo3d_write_dimensions(
- s3d->display_mode, ((s3d->flag & S3D_SQUEEZED_FRAME) == 0), ibuf_stereo3d->x, ibuf_stereo3d->y,
- &width, &height);
- imb_stereo3d_unsqueeze_ImBuf(ibuf_stereo3d, s3d, width, height);
-
- imb_stereo3d_data_initialize(
- &s3d_data, is_float, ibuf_left->x, ibuf_left->y, 4,
- (int *)ibuf_left->rect, (int *)ibuf_right->rect, (int *)ibuf_stereo3d->rect,
- ibuf_left->rect_float, ibuf_right->rect_float, ibuf_stereo3d->rect_float);
-
- imb_stereo3d_read_doit(&s3d_data, s3d);
-
- if (ibuf_stereo3d->flags & (IB_zbuf | IB_zbuffloat)) {
- if (is_float) {
- addzbuffloatImBuf(ibuf_left);
- addzbuffloatImBuf(ibuf_right);
- }
- else {
- addzbufImBuf(ibuf_left);
- addzbufImBuf(ibuf_right);
- }
-
- imb_stereo3d_data_initialize(
- &s3d_data, is_float, ibuf_left->x, ibuf_left->y, 1,
- (int *)ibuf_left->zbuf, (int *)ibuf_right->zbuf, (int *)ibuf_stereo3d->zbuf,
- ibuf_left->zbuf_float, ibuf_right->zbuf_float, ibuf_stereo3d->zbuf_float);
-
- imb_stereo3d_read_doit(&s3d_data, s3d);
- }
-
- IMB_freeImBuf(ibuf_stereo3d);
-
- *r_ibuf_left = ibuf_left;
- *r_ibuf_right = ibuf_right;
+ Stereo3DData s3d_data = {{NULL}};
+ ImBuf *ibuf_left, *ibuf_right;
+ size_t width, height;
+ const bool is_float = (ibuf_stereo3d->rect_float != NULL);
+
+ IMB_stereo3d_read_dimensions(s3d->display_mode,
+ ((s3d->flag & S3D_SQUEEZED_FRAME) == 0),
+ ibuf_stereo3d->x,
+ ibuf_stereo3d->y,
+ &width,
+ &height);
+
+ ibuf_left = IMB_allocImBuf(
+ width, height, ibuf_stereo3d->planes, (is_float ? IB_rectfloat : IB_rect));
+ ibuf_right = IMB_allocImBuf(
+ width, height, ibuf_stereo3d->planes, (is_float ? IB_rectfloat : IB_rect));
+
+ ibuf_left->flags = ibuf_stereo3d->flags;
+ ibuf_right->flags = ibuf_stereo3d->flags;
+
+ /* we always work with unsqueezed formats */
+ IMB_stereo3d_write_dimensions(s3d->display_mode,
+ ((s3d->flag & S3D_SQUEEZED_FRAME) == 0),
+ ibuf_stereo3d->x,
+ ibuf_stereo3d->y,
+ &width,
+ &height);
+ imb_stereo3d_unsqueeze_ImBuf(ibuf_stereo3d, s3d, width, height);
+
+ imb_stereo3d_data_initialize(&s3d_data,
+ is_float,
+ ibuf_left->x,
+ ibuf_left->y,
+ 4,
+ (int *)ibuf_left->rect,
+ (int *)ibuf_right->rect,
+ (int *)ibuf_stereo3d->rect,
+ ibuf_left->rect_float,
+ ibuf_right->rect_float,
+ ibuf_stereo3d->rect_float);
+
+ imb_stereo3d_read_doit(&s3d_data, s3d);
+
+ if (ibuf_stereo3d->flags & (IB_zbuf | IB_zbuffloat)) {
+ if (is_float) {
+ addzbuffloatImBuf(ibuf_left);
+ addzbuffloatImBuf(ibuf_right);
+ }
+ else {
+ addzbufImBuf(ibuf_left);
+ addzbufImBuf(ibuf_right);
+ }
+
+ imb_stereo3d_data_initialize(&s3d_data,
+ is_float,
+ ibuf_left->x,
+ ibuf_left->y,
+ 1,
+ (int *)ibuf_left->zbuf,
+ (int *)ibuf_right->zbuf,
+ (int *)ibuf_stereo3d->zbuf,
+ ibuf_left->zbuf_float,
+ ibuf_right->zbuf_float,
+ ibuf_stereo3d->zbuf_float);
+
+ imb_stereo3d_read_doit(&s3d_data, s3d);
+ }
+
+ IMB_freeImBuf(ibuf_stereo3d);
+
+ *r_ibuf_left = ibuf_left;
+ *r_ibuf_right = ibuf_right;
}
static void imb_stereo3d_read_doit(Stereo3DData *s3d_data, Stereo3dFormat *s3d)
{
- switch (s3d->display_mode) {
- case S3D_DISPLAY_ANAGLYPH:
- imb_stereo3d_read_anaglyph(s3d_data, s3d->anaglyph_type);
- break;
- case S3D_DISPLAY_INTERLACE:
- imb_stereo3d_read_interlace(s3d_data, s3d->interlace_type, (s3d->flag & S3D_INTERLACE_SWAP) != 0);
- break;
- case S3D_DISPLAY_SIDEBYSIDE:
- imb_stereo3d_read_sidebyside(s3d_data, (s3d->flag & S3D_SIDEBYSIDE_CROSSEYED) != 0);
- break;
- case S3D_DISPLAY_TOPBOTTOM:
- imb_stereo3d_read_topbottom(s3d_data);
- break;
- default:
- break;
- }
+ switch (s3d->display_mode) {
+ case S3D_DISPLAY_ANAGLYPH:
+ imb_stereo3d_read_anaglyph(s3d_data, s3d->anaglyph_type);
+ break;
+ case S3D_DISPLAY_INTERLACE:
+ imb_stereo3d_read_interlace(
+ s3d_data, s3d->interlace_type, (s3d->flag & S3D_INTERLACE_SWAP) != 0);
+ break;
+ case S3D_DISPLAY_SIDEBYSIDE:
+ imb_stereo3d_read_sidebyside(s3d_data, (s3d->flag & S3D_SIDEBYSIDE_CROSSEYED) != 0);
+ break;
+ case S3D_DISPLAY_TOPBOTTOM:
+ imb_stereo3d_read_topbottom(s3d_data);
+ break;
+ default:
+ break;
+ }
}
diff --git a/source/blender/imbuf/intern/targa.c b/source/blender/imbuf/intern/targa.c
index fa477037f72..c80e3a0c07d 100644
--- a/source/blender/imbuf/intern/targa.c
+++ b/source/blender/imbuf/intern/targa.c
@@ -21,7 +21,6 @@
* \ingroup imbuf
*/
-
#ifdef WIN32
# include <io.h>
#endif
@@ -47,659 +46,706 @@
/***/
typedef struct TARGA {
- unsigned char numid;
- unsigned char maptyp;
- unsigned char imgtyp;
- short maporig;
- short mapsize;
- unsigned char mapbits;
- short xorig;
- short yorig;
- short xsize;
- short ysize;
- unsigned char pixsize;
- unsigned char imgdes;
+ unsigned char numid;
+ unsigned char maptyp;
+ unsigned char imgtyp;
+ short maporig;
+ short mapsize;
+ unsigned char mapbits;
+ short xorig;
+ short yorig;
+ short xsize;
+ short ysize;
+ unsigned char pixsize;
+ unsigned char imgdes;
} TARGA;
/***/
static int tga_out1(unsigned int data, FILE *file)
{
- uchar *p;
+ uchar *p;
- p = (uchar *) &data;
- if (putc(p[0], file) == EOF) return EOF;
- return ~EOF;
+ p = (uchar *)&data;
+ if (putc(p[0], file) == EOF)
+ return EOF;
+ return ~EOF;
}
static int tga_out2(unsigned int data, FILE *file)
{
- uchar *p;
-
- p = (uchar *) &data;
- if (putc(p[0], file) == EOF) return EOF;
- if (putc(p[1], file) == EOF) return EOF;
- return ~EOF;
+ uchar *p;
+
+ p = (uchar *)&data;
+ if (putc(p[0], file) == EOF)
+ return EOF;
+ if (putc(p[1], file) == EOF)
+ return EOF;
+ return ~EOF;
}
-
static int tga_out3(unsigned int data, FILE *file)
{
- uchar *p;
-
- p = (uchar *) &data;
- if (putc(p[2], file) == EOF) return EOF;
- if (putc(p[1], file) == EOF) return EOF;
- if (putc(p[0], file) == EOF) return EOF;
- return ~EOF;
+ uchar *p;
+
+ p = (uchar *)&data;
+ if (putc(p[2], file) == EOF)
+ return EOF;
+ if (putc(p[1], file) == EOF)
+ return EOF;
+ if (putc(p[0], file) == EOF)
+ return EOF;
+ return ~EOF;
}
-
static int tga_out4(unsigned int data, FILE *file)
{
- uchar *p;
-
- p = (uchar *) &data;
- /* order = bgra */
- if (putc(p[2], file) == EOF) return EOF;
- if (putc(p[1], file) == EOF) return EOF;
- if (putc(p[0], file) == EOF) return EOF;
- if (putc(p[3], file) == EOF) return EOF;
- return ~EOF;
+ uchar *p;
+
+ p = (uchar *)&data;
+ /* order = bgra */
+ if (putc(p[2], file) == EOF)
+ return EOF;
+ if (putc(p[1], file) == EOF)
+ return EOF;
+ if (putc(p[0], file) == EOF)
+ return EOF;
+ if (putc(p[3], file) == EOF)
+ return EOF;
+ return ~EOF;
}
static bool makebody_tga(ImBuf *ibuf, FILE *file, int (*out)(unsigned int, FILE *))
{
- register int last, this;
- register int copy, bytes;
- register unsigned int *rect, *rectstart, *temp;
- int y;
-
- for (y = 0; y < ibuf->y; y++) {
- bytes = ibuf->x - 1;
- rectstart = rect = ibuf->rect + (y * ibuf->x);
- last = *rect++;
- this = *rect++;
- copy = last ^ this;
- while (bytes > 0) {
- if (copy) {
- do {
- last = this;
- this = *rect++;
- if (last == this) {
- if (this == rect[-3]) { /* three the same? */
- bytes--; /* set bytes */
- break;
- }
- }
- } while (--bytes != 0);
-
- copy = rect - rectstart;
- copy--;
- if (bytes) copy -= 2;
-
- temp = rect;
- rect = rectstart;
-
- while (copy) {
- last = copy;
- if (copy >= 128) last = 128;
- copy -= last;
- if (fputc(last - 1, file) == EOF) return 0;
- do {
- if (out(*rect++, file) == EOF) return 0;
- } while (--last != 0);
- }
- rectstart = rect;
- rect = temp;
- last = this;
-
- copy = 0;
- }
- else {
- while (*rect++ == this) { /* seek for first different byte */
- if (--bytes == 0) break; /* oor end of line */
- }
- rect--;
- copy = rect - rectstart;
- rectstart = rect;
- bytes--;
- this = *rect++;
-
- while (copy) {
- if (copy > 128) {
- if (fputc(255, file) == EOF) return 0;
- copy -= 128;
- }
- else {
- if (copy == 1) {
- if (fputc(0, file) == EOF) return 0;
- }
- else if (fputc(127 + copy, file) == EOF) return 0;
- copy = 0;
- }
- if (out(last, file) == EOF) return 0;
- }
- copy = 1;
- }
- }
- }
- return 1;
+ register int last, this;
+ register int copy, bytes;
+ register unsigned int *rect, *rectstart, *temp;
+ int y;
+
+ for (y = 0; y < ibuf->y; y++) {
+ bytes = ibuf->x - 1;
+ rectstart = rect = ibuf->rect + (y * ibuf->x);
+ last = *rect++;
+ this = *rect++;
+ copy = last ^ this;
+ while (bytes > 0) {
+ if (copy) {
+ do {
+ last = this;
+ this = *rect++;
+ if (last == this) {
+ if (this == rect[-3]) { /* three the same? */
+ bytes--; /* set bytes */
+ break;
+ }
+ }
+ } while (--bytes != 0);
+
+ copy = rect - rectstart;
+ copy--;
+ if (bytes)
+ copy -= 2;
+
+ temp = rect;
+ rect = rectstart;
+
+ while (copy) {
+ last = copy;
+ if (copy >= 128)
+ last = 128;
+ copy -= last;
+ if (fputc(last - 1, file) == EOF)
+ return 0;
+ do {
+ if (out(*rect++, file) == EOF)
+ return 0;
+ } while (--last != 0);
+ }
+ rectstart = rect;
+ rect = temp;
+ last = this;
+
+ copy = 0;
+ }
+ else {
+ while (*rect++ == this) { /* seek for first different byte */
+ if (--bytes == 0)
+ break; /* oor end of line */
+ }
+ rect--;
+ copy = rect - rectstart;
+ rectstart = rect;
+ bytes--;
+ this = *rect++;
+
+ while (copy) {
+ if (copy > 128) {
+ if (fputc(255, file) == EOF)
+ return 0;
+ copy -= 128;
+ }
+ else {
+ if (copy == 1) {
+ if (fputc(0, file) == EOF)
+ return 0;
+ }
+ else if (fputc(127 + copy, file) == EOF)
+ return 0;
+ copy = 0;
+ }
+ if (out(last, file) == EOF)
+ return 0;
+ }
+ copy = 1;
+ }
+ }
+ }
+ return 1;
}
static bool dumptarga(struct ImBuf *ibuf, FILE *file)
{
- int size;
- uchar *rect;
-
- if (ibuf == NULL) return 0;
- if (ibuf->rect == NULL) return 0;
-
- size = ibuf->x * ibuf->y;
- rect = (uchar *) ibuf->rect;
-
- if (ibuf->planes <= 8) {
- while (size > 0) {
- if (putc(*rect, file) == EOF) return 0;
- size--;
- rect += 4;
- }
- }
- else if (ibuf->planes <= 16) {
- while (size > 0) {
- putc(rect[0], file);
- if (putc(rect[1], file) == EOF) return 0;
- size--;
- rect += 4;
- }
- }
- else if (ibuf->planes <= 24) {
- while (size > 0) {
- putc(rect[2], file);
- putc(rect[1], file);
- if (putc(rect[0], file) == EOF) return 0;
- size--;
- rect += 4;
- }
- }
- else if (ibuf->planes <= 32) {
- while (size > 0) {
- putc(rect[2], file);
- putc(rect[1], file);
- putc(rect[0], file);
- if (putc(rect[3], file) == EOF) return 0;
- size--;
- rect += 4;
- }
- }
- else {
- return 0;
- }
-
- return 1;
+ int size;
+ uchar *rect;
+
+ if (ibuf == NULL)
+ return 0;
+ if (ibuf->rect == NULL)
+ return 0;
+
+ size = ibuf->x * ibuf->y;
+ rect = (uchar *)ibuf->rect;
+
+ if (ibuf->planes <= 8) {
+ while (size > 0) {
+ if (putc(*rect, file) == EOF)
+ return 0;
+ size--;
+ rect += 4;
+ }
+ }
+ else if (ibuf->planes <= 16) {
+ while (size > 0) {
+ putc(rect[0], file);
+ if (putc(rect[1], file) == EOF)
+ return 0;
+ size--;
+ rect += 4;
+ }
+ }
+ else if (ibuf->planes <= 24) {
+ while (size > 0) {
+ putc(rect[2], file);
+ putc(rect[1], file);
+ if (putc(rect[0], file) == EOF)
+ return 0;
+ size--;
+ rect += 4;
+ }
+ }
+ else if (ibuf->planes <= 32) {
+ while (size > 0) {
+ putc(rect[2], file);
+ putc(rect[1], file);
+ putc(rect[0], file);
+ if (putc(rect[3], file) == EOF)
+ return 0;
+ size--;
+ rect += 4;
+ }
+ }
+ else {
+ return 0;
+ }
+
+ return 1;
}
-
int imb_savetarga(struct ImBuf *ibuf, const char *name, int flags)
{
- char buf[20] = {0};
- FILE *fildes;
- bool ok = false;
-
- (void)flags; /* unused */
-
- buf[16] = (ibuf->planes + 0x7) & ~0x7;
- if (ibuf->planes > 8) {
- buf[2] = 10;
- }
- else {
- buf[2] = 11;
- }
-
- if (ibuf->foptions.flag & RAWTGA) buf[2] &= ~8;
-
- buf[8] = 0;
- buf[9] = 0;
- buf[10] = 0;
- buf[11] = 0;
-
- buf[12] = ibuf->x & 0xff;
- buf[13] = ibuf->x >> 8;
- buf[14] = ibuf->y & 0xff;
- buf[15] = ibuf->y >> 8;
-
- /* Don't forget to indicate that your 32 bit
- * targa uses 8 bits for the alpha channel! */
- if (ibuf->planes == 32) {
- buf[17] |= 0x08;
- }
- fildes = BLI_fopen(name, "wb");
- if (!fildes) return 0;
-
- if (fwrite(buf, 1, 18, fildes) != 18) {
- fclose(fildes);
- return 0;
- }
-
- if (ibuf->foptions.flag & RAWTGA) {
- ok = dumptarga(ibuf, fildes);
- }
- else {
- switch ((ibuf->planes + 7) >> 3) {
- case 1:
- ok = makebody_tga(ibuf, fildes, tga_out1);
- break;
- case 2:
- ok = makebody_tga(ibuf, fildes, tga_out2);
- break;
- case 3:
- ok = makebody_tga(ibuf, fildes, tga_out3);
- break;
- case 4:
- ok = makebody_tga(ibuf, fildes, tga_out4);
- break;
- }
- }
-
- fclose(fildes);
- return ok;
+ char buf[20] = {0};
+ FILE *fildes;
+ bool ok = false;
+
+ (void)flags; /* unused */
+
+ buf[16] = (ibuf->planes + 0x7) & ~0x7;
+ if (ibuf->planes > 8) {
+ buf[2] = 10;
+ }
+ else {
+ buf[2] = 11;
+ }
+
+ if (ibuf->foptions.flag & RAWTGA)
+ buf[2] &= ~8;
+
+ buf[8] = 0;
+ buf[9] = 0;
+ buf[10] = 0;
+ buf[11] = 0;
+
+ buf[12] = ibuf->x & 0xff;
+ buf[13] = ibuf->x >> 8;
+ buf[14] = ibuf->y & 0xff;
+ buf[15] = ibuf->y >> 8;
+
+ /* Don't forget to indicate that your 32 bit
+ * targa uses 8 bits for the alpha channel! */
+ if (ibuf->planes == 32) {
+ buf[17] |= 0x08;
+ }
+ fildes = BLI_fopen(name, "wb");
+ if (!fildes)
+ return 0;
+
+ if (fwrite(buf, 1, 18, fildes) != 18) {
+ fclose(fildes);
+ return 0;
+ }
+
+ if (ibuf->foptions.flag & RAWTGA) {
+ ok = dumptarga(ibuf, fildes);
+ }
+ else {
+ switch ((ibuf->planes + 7) >> 3) {
+ case 1:
+ ok = makebody_tga(ibuf, fildes, tga_out1);
+ break;
+ case 2:
+ ok = makebody_tga(ibuf, fildes, tga_out2);
+ break;
+ case 3:
+ ok = makebody_tga(ibuf, fildes, tga_out3);
+ break;
+ case 4:
+ ok = makebody_tga(ibuf, fildes, tga_out4);
+ break;
+ }
+ }
+
+ fclose(fildes);
+ return ok;
}
-
static int checktarga(TARGA *tga, const unsigned char *mem)
{
- tga->numid = mem[0];
- tga->maptyp = mem[1];
- tga->imgtyp = mem[2];
-
- tga->maporig = GSS(mem + 3);
- tga->mapsize = GSS(mem + 5);
- tga->mapbits = mem[7];
- tga->xorig = GSS(mem + 8);
- tga->yorig = GSS(mem + 10);
- tga->xsize = GSS(mem + 12);
- tga->ysize = GSS(mem + 14);
- tga->pixsize = mem[16];
- tga->imgdes = mem[17];
-
- if (tga->maptyp > 1) return 0;
- switch (tga->imgtyp) {
- case 1: /* raw cmap */
- case 2: /* raw rgb */
- case 3: /* raw b&w */
- case 9: /* cmap */
- case 10: /* rgb */
- case 11: /* b&w */
- break;
- default:
- return 0;
- }
- if (tga->mapsize && tga->mapbits > 32) return 0;
- if (tga->xsize <= 0) return 0;
- if (tga->ysize <= 0) return 0;
- if (tga->pixsize > 32) return 0;
- if (tga->pixsize == 0) return 0;
- return 1;
+ tga->numid = mem[0];
+ tga->maptyp = mem[1];
+ tga->imgtyp = mem[2];
+
+ tga->maporig = GSS(mem + 3);
+ tga->mapsize = GSS(mem + 5);
+ tga->mapbits = mem[7];
+ tga->xorig = GSS(mem + 8);
+ tga->yorig = GSS(mem + 10);
+ tga->xsize = GSS(mem + 12);
+ tga->ysize = GSS(mem + 14);
+ tga->pixsize = mem[16];
+ tga->imgdes = mem[17];
+
+ if (tga->maptyp > 1)
+ return 0;
+ switch (tga->imgtyp) {
+ case 1: /* raw cmap */
+ case 2: /* raw rgb */
+ case 3: /* raw b&w */
+ case 9: /* cmap */
+ case 10: /* rgb */
+ case 11: /* b&w */
+ break;
+ default:
+ return 0;
+ }
+ if (tga->mapsize && tga->mapbits > 32)
+ return 0;
+ if (tga->xsize <= 0)
+ return 0;
+ if (tga->ysize <= 0)
+ return 0;
+ if (tga->pixsize > 32)
+ return 0;
+ if (tga->pixsize == 0)
+ return 0;
+ return 1;
}
int imb_is_a_targa(const unsigned char *buf)
{
- TARGA tga;
+ TARGA tga;
- return checktarga(&tga, buf);
+ return checktarga(&tga, buf);
}
static void complete_partial_load(struct ImBuf *ibuf, unsigned int *rect)
{
- int size = (ibuf->x * ibuf->y) - (rect - ibuf->rect);
- if (size) {
- printf("decodetarga: incomplete file, %.1f%% missing\n", 100 * ((float)size / (ibuf->x * ibuf->y)));
-
- /* not essential but makes displaying partially rendered TGA's less ugly */
- memset(rect, 0, size);
- }
- else {
- /* shouldn't happen */
- printf("decodetarga: incomplete file, all pixels written\n");
- }
+ int size = (ibuf->x * ibuf->y) - (rect - ibuf->rect);
+ if (size) {
+ printf("decodetarga: incomplete file, %.1f%% missing\n",
+ 100 * ((float)size / (ibuf->x * ibuf->y)));
+
+ /* not essential but makes displaying partially rendered TGA's less ugly */
+ memset(rect, 0, size);
+ }
+ else {
+ /* shouldn't happen */
+ printf("decodetarga: incomplete file, all pixels written\n");
+ }
}
static void decodetarga(struct ImBuf *ibuf, const unsigned char *mem, size_t mem_size, int psize)
{
- const unsigned char *mem_end = mem + mem_size;
- int count, col, size;
- unsigned int *rect;
- uchar *cp = (uchar *) &col;
-
- if (ibuf == NULL) return;
- if (ibuf->rect == NULL) return;
-
- size = ibuf->x * ibuf->y;
- rect = ibuf->rect;
-
- /* set alpha */
- cp[0] = 0xff;
- cp[1] = cp[2] = 0;
-
- while (size > 0) {
- count = *mem++;
-
- if (mem > mem_end)
- goto partial_load;
-
- if (count >= 128) {
- /*if (count == 128) printf("TARGA: 128 in file !\n");*/
- count -= 127;
-
- if (psize & 2) {
- if (psize & 1) {
- /* order = bgra */
- cp[0] = mem[3];
- cp[1] = mem[0];
- cp[2] = mem[1];
- cp[3] = mem[2];
- /*col = (mem[3] << 24) + (mem[0] << 16) + (mem[1] << 8) + mem[2];*/
- mem += 4;
- }
- else {
- cp[1] = mem[0];
- cp[2] = mem[1];
- cp[3] = mem[2];
- /*col = 0xff000000 + (mem[0] << 16) + (mem[1] << 8) + mem[2];*/
- mem += 3;
- }
- }
- else {
- if (psize & 1) {
- cp[0] = mem[0];
- cp[1] = mem[1];
- mem += 2;
- }
- else {
- col = *mem++;
- }
- }
-
- size -= count;
- if (size >= 0) {
- while (count > 0) {
- *rect++ = col;
- count--;
- }
- }
- }
- else {
- count++;
- size -= count;
- if (size >= 0) {
- while (count > 0) {
- if (psize & 2) {
- if (psize & 1) {
- /* order = bgra */
- cp[0] = mem[3];
- cp[1] = mem[0];
- cp[2] = mem[1];
- cp[3] = mem[2];
- /*col = (mem[3] << 24) + (mem[0] << 16) + (mem[1] << 8) + mem[2];*/
- mem += 4;
- }
- else {
- cp[1] = mem[0];
- cp[2] = mem[1];
- cp[3] = mem[2];
- /*col = 0xff000000 + (mem[0] << 16) + (mem[1] << 8) + mem[2];*/
- mem += 3;
- }
- }
- else {
- if (psize & 1) {
- cp[0] = mem[0];
- cp[1] = mem[1];
- mem += 2;
- }
- else {
- col = *mem++;
- }
- }
- *rect++ = col;
- count--;
-
- if (mem > mem_end)
- goto partial_load;
- }
-
- if (mem > mem_end)
- goto partial_load;
- }
- }
- }
- if (size) {
- printf("decodetarga: count would overwrite %d pixels\n", -size);
- }
- return;
+ const unsigned char *mem_end = mem + mem_size;
+ int count, col, size;
+ unsigned int *rect;
+ uchar *cp = (uchar *)&col;
+
+ if (ibuf == NULL)
+ return;
+ if (ibuf->rect == NULL)
+ return;
+
+ size = ibuf->x * ibuf->y;
+ rect = ibuf->rect;
+
+ /* set alpha */
+ cp[0] = 0xff;
+ cp[1] = cp[2] = 0;
+
+ while (size > 0) {
+ count = *mem++;
+
+ if (mem > mem_end)
+ goto partial_load;
+
+ if (count >= 128) {
+ /*if (count == 128) printf("TARGA: 128 in file !\n");*/
+ count -= 127;
+
+ if (psize & 2) {
+ if (psize & 1) {
+ /* order = bgra */
+ cp[0] = mem[3];
+ cp[1] = mem[0];
+ cp[2] = mem[1];
+ cp[3] = mem[2];
+ /*col = (mem[3] << 24) + (mem[0] << 16) + (mem[1] << 8) + mem[2];*/
+ mem += 4;
+ }
+ else {
+ cp[1] = mem[0];
+ cp[2] = mem[1];
+ cp[3] = mem[2];
+ /*col = 0xff000000 + (mem[0] << 16) + (mem[1] << 8) + mem[2];*/
+ mem += 3;
+ }
+ }
+ else {
+ if (psize & 1) {
+ cp[0] = mem[0];
+ cp[1] = mem[1];
+ mem += 2;
+ }
+ else {
+ col = *mem++;
+ }
+ }
+
+ size -= count;
+ if (size >= 0) {
+ while (count > 0) {
+ *rect++ = col;
+ count--;
+ }
+ }
+ }
+ else {
+ count++;
+ size -= count;
+ if (size >= 0) {
+ while (count > 0) {
+ if (psize & 2) {
+ if (psize & 1) {
+ /* order = bgra */
+ cp[0] = mem[3];
+ cp[1] = mem[0];
+ cp[2] = mem[1];
+ cp[3] = mem[2];
+ /*col = (mem[3] << 24) + (mem[0] << 16) + (mem[1] << 8) + mem[2];*/
+ mem += 4;
+ }
+ else {
+ cp[1] = mem[0];
+ cp[2] = mem[1];
+ cp[3] = mem[2];
+ /*col = 0xff000000 + (mem[0] << 16) + (mem[1] << 8) + mem[2];*/
+ mem += 3;
+ }
+ }
+ else {
+ if (psize & 1) {
+ cp[0] = mem[0];
+ cp[1] = mem[1];
+ mem += 2;
+ }
+ else {
+ col = *mem++;
+ }
+ }
+ *rect++ = col;
+ count--;
+
+ if (mem > mem_end)
+ goto partial_load;
+ }
+
+ if (mem > mem_end)
+ goto partial_load;
+ }
+ }
+ }
+ if (size) {
+ printf("decodetarga: count would overwrite %d pixels\n", -size);
+ }
+ return;
partial_load:
- complete_partial_load(ibuf, rect);
+ complete_partial_load(ibuf, rect);
}
static void ldtarga(struct ImBuf *ibuf, const unsigned char *mem, size_t mem_size, int psize)
{
- const unsigned char *mem_end = mem + mem_size;
- int col, size;
- unsigned int *rect;
- uchar *cp = (uchar *) &col;
-
- if (ibuf == NULL) return;
- if (ibuf->rect == NULL) return;
-
- size = ibuf->x * ibuf->y;
- rect = ibuf->rect;
-
- /* set alpha */
- cp[0] = 0xff;
- cp[1] = cp[2] = 0;
-
- while (size > 0) {
- if (mem > mem_end)
- goto partial_load;
-
- if (psize & 2) {
- if (psize & 1) {
- /* order = bgra */
- cp[0] = mem[3];
- cp[1] = mem[0];
- cp[2] = mem[1];
- cp[3] = mem[2];
- /*col = (mem[3] << 24) + (mem[0] << 16) + (mem[1] << 8) + mem[2];*/
- mem += 4;
- }
- else {
- /* set alpha for 24 bits colors */
- cp[1] = mem[0];
- cp[2] = mem[1];
- cp[3] = mem[2];
- /*col = 0xff000000 + (mem[0] << 16) + (mem[1] << 8) + mem[2];*/
- mem += 3;
- }
- }
- else {
- if (psize & 1) {
- cp[0] = mem[0];
- cp[1] = mem[1];
- mem += 2;
- }
- else {
- col = *mem++;
- }
- }
- *rect++ = col;
- size--;
- }
- return;
+ const unsigned char *mem_end = mem + mem_size;
+ int col, size;
+ unsigned int *rect;
+ uchar *cp = (uchar *)&col;
+
+ if (ibuf == NULL)
+ return;
+ if (ibuf->rect == NULL)
+ return;
+
+ size = ibuf->x * ibuf->y;
+ rect = ibuf->rect;
+
+ /* set alpha */
+ cp[0] = 0xff;
+ cp[1] = cp[2] = 0;
+
+ while (size > 0) {
+ if (mem > mem_end)
+ goto partial_load;
+
+ if (psize & 2) {
+ if (psize & 1) {
+ /* order = bgra */
+ cp[0] = mem[3];
+ cp[1] = mem[0];
+ cp[2] = mem[1];
+ cp[3] = mem[2];
+ /*col = (mem[3] << 24) + (mem[0] << 16) + (mem[1] << 8) + mem[2];*/
+ mem += 4;
+ }
+ else {
+ /* set alpha for 24 bits colors */
+ cp[1] = mem[0];
+ cp[2] = mem[1];
+ cp[3] = mem[2];
+ /*col = 0xff000000 + (mem[0] << 16) + (mem[1] << 8) + mem[2];*/
+ mem += 3;
+ }
+ }
+ else {
+ if (psize & 1) {
+ cp[0] = mem[0];
+ cp[1] = mem[1];
+ mem += 2;
+ }
+ else {
+ col = *mem++;
+ }
+ }
+ *rect++ = col;
+ size--;
+ }
+ return;
partial_load:
- complete_partial_load(ibuf, rect);
+ complete_partial_load(ibuf, rect);
}
-
-ImBuf *imb_loadtarga(const unsigned char *mem, size_t mem_size, int flags, char colorspace[IM_MAX_SPACE])
+ImBuf *imb_loadtarga(const unsigned char *mem,
+ size_t mem_size,
+ int flags,
+ char colorspace[IM_MAX_SPACE])
{
- TARGA tga;
- struct ImBuf *ibuf;
- int count, size;
- unsigned int *rect, *cmap = NULL /*, mincol = 0*/, cmap_max = 0;
- int32_t cp_data;
- uchar *cp = (uchar *) &cp_data;
-
- if (checktarga(&tga, mem) == 0) {
- return NULL;
- }
-
- colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE);
-
- if (flags & IB_test) ibuf = IMB_allocImBuf(tga.xsize, tga.ysize, tga.pixsize, 0);
- else ibuf = IMB_allocImBuf(tga.xsize, tga.ysize, (tga.pixsize + 0x7) & ~0x7, IB_rect);
-
- if (ibuf == NULL) return NULL;
- ibuf->ftype = IMB_FTYPE_TGA;
- if (tga.imgtyp < 4)
- ibuf->foptions.flag |= RAWTGA;
- mem = mem + 18 + tga.numid;
-
- cp[0] = 0xff;
- cp[1] = cp[2] = 0;
-
- if (tga.mapsize) {
- /* load color map */
- /*mincol = tga.maporig;*/ /*UNUSED*/
- cmap_max = tga.mapsize;
- cmap = MEM_callocN(sizeof(unsigned int) * cmap_max, "targa cmap");
-
- for (count = 0; count < cmap_max; count++) {
- switch (tga.mapbits >> 3) {
- case 4:
- cp[0] = mem[3];
- cp[1] = mem[0];
- cp[2] = mem[1];
- cp[3] = mem[2];
- mem += 4;
- break;
- case 3:
- cp[1] = mem[0];
- cp[2] = mem[1];
- cp[3] = mem[2];
- mem += 3;
- break;
- case 2:
- cp[1] = mem[1];
- cp[0] = mem[0];
- mem += 2;
- break;
- case 1:
- cp_data = *mem++;
- break;
- }
- cmap[count] = cp_data;
- }
-
- size = 0;
- for (int cmap_index = cmap_max - 1; cmap_index > 0; cmap_index >>= 1) {
- size++;
- }
- ibuf->planes = size;
-
- if (tga.mapbits != 32) { /* set alpha bits */
- cmap[0] &= BIG_LONG(0x00ffffffl);
- }
- }
-
- if (flags & IB_test) {
- if (cmap) {
- MEM_freeN(cmap);
- }
- return ibuf;
- }
-
- if (tga.imgtyp != 1 && tga.imgtyp != 9) { /* happens sometimes (beuh) */
- if (cmap) {
- MEM_freeN(cmap);
- cmap = NULL;
- }
- }
-
- switch (tga.imgtyp) {
- case 1:
- case 2:
- case 3:
- if (tga.pixsize <= 8) ldtarga(ibuf, mem, mem_size, 0);
- else if (tga.pixsize <= 16) ldtarga(ibuf, mem, mem_size, 1);
- else if (tga.pixsize <= 24) ldtarga(ibuf, mem, mem_size, 2);
- else if (tga.pixsize <= 32) ldtarga(ibuf, mem, mem_size, 3);
- break;
- case 9:
- case 10:
- case 11:
- if (tga.pixsize <= 8) decodetarga(ibuf, mem, mem_size, 0);
- else if (tga.pixsize <= 16) decodetarga(ibuf, mem, mem_size, 1);
- else if (tga.pixsize <= 24) decodetarga(ibuf, mem, mem_size, 2);
- else if (tga.pixsize <= 32) decodetarga(ibuf, mem, mem_size, 3);
- break;
- }
-
- if (cmap) {
- /* apply color map */
- rect = ibuf->rect;
- for (size = ibuf->x * ibuf->y; size > 0; --size, ++rect) {
- int cmap_index = *rect;
- if (cmap_index >= 0 && cmap_index < cmap_max) {
- *rect = cmap[cmap_index];
- }
- }
-
- MEM_freeN(cmap);
- }
-
- if (tga.pixsize == 16) {
- unsigned int col;
- rect = ibuf->rect;
- for (size = ibuf->x * ibuf->y; size > 0; --size, ++rect) {
- col = *rect;
- cp = (uchar *)rect;
- mem = (uchar *)&col;
-
- cp[3] = ((mem[1] << 1) & 0xf8);
- cp[2] = ((mem[0] & 0xe0) >> 2) + ((mem[1] & 0x03) << 6);
- cp[1] = ((mem[0] << 3) & 0xf8);
- cp[1] += cp[1] >> 5;
- cp[2] += cp[2] >> 5;
- cp[3] += cp[3] >> 5;
- cp[0] = 0xff;
- }
- ibuf->planes = 24;
- }
-
- if (tga.imgtyp == 3 || tga.imgtyp == 11) {
- uchar *crect;
- unsigned int *lrect, col;
-
- crect = (uchar *) ibuf->rect;
- lrect = (unsigned int *) ibuf->rect;
-
- for (size = ibuf->x * ibuf->y; size > 0; size--) {
- col = *lrect++;
-
- crect[0] = 255;
- crect[1] = crect[2] = crect[3] = col;
- crect += 4;
- }
- }
-
- if (tga.imgdes & 0x20) {
- IMB_flipy(ibuf);
- }
-
- if (ibuf->rect)
- IMB_convert_rgba_to_abgr(ibuf);
-
- return ibuf;
+ TARGA tga;
+ struct ImBuf *ibuf;
+ int count, size;
+ unsigned int *rect, *cmap = NULL /*, mincol = 0*/, cmap_max = 0;
+ int32_t cp_data;
+ uchar *cp = (uchar *)&cp_data;
+
+ if (checktarga(&tga, mem) == 0) {
+ return NULL;
+ }
+
+ colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE);
+
+ if (flags & IB_test)
+ ibuf = IMB_allocImBuf(tga.xsize, tga.ysize, tga.pixsize, 0);
+ else
+ ibuf = IMB_allocImBuf(tga.xsize, tga.ysize, (tga.pixsize + 0x7) & ~0x7, IB_rect);
+
+ if (ibuf == NULL)
+ return NULL;
+ ibuf->ftype = IMB_FTYPE_TGA;
+ if (tga.imgtyp < 4)
+ ibuf->foptions.flag |= RAWTGA;
+ mem = mem + 18 + tga.numid;
+
+ cp[0] = 0xff;
+ cp[1] = cp[2] = 0;
+
+ if (tga.mapsize) {
+ /* load color map */
+ /*mincol = tga.maporig;*/ /*UNUSED*/
+ cmap_max = tga.mapsize;
+ cmap = MEM_callocN(sizeof(unsigned int) * cmap_max, "targa cmap");
+
+ for (count = 0; count < cmap_max; count++) {
+ switch (tga.mapbits >> 3) {
+ case 4:
+ cp[0] = mem[3];
+ cp[1] = mem[0];
+ cp[2] = mem[1];
+ cp[3] = mem[2];
+ mem += 4;
+ break;
+ case 3:
+ cp[1] = mem[0];
+ cp[2] = mem[1];
+ cp[3] = mem[2];
+ mem += 3;
+ break;
+ case 2:
+ cp[1] = mem[1];
+ cp[0] = mem[0];
+ mem += 2;
+ break;
+ case 1:
+ cp_data = *mem++;
+ break;
+ }
+ cmap[count] = cp_data;
+ }
+
+ size = 0;
+ for (int cmap_index = cmap_max - 1; cmap_index > 0; cmap_index >>= 1) {
+ size++;
+ }
+ ibuf->planes = size;
+
+ if (tga.mapbits != 32) { /* set alpha bits */
+ cmap[0] &= BIG_LONG(0x00ffffffl);
+ }
+ }
+
+ if (flags & IB_test) {
+ if (cmap) {
+ MEM_freeN(cmap);
+ }
+ return ibuf;
+ }
+
+ if (tga.imgtyp != 1 && tga.imgtyp != 9) { /* happens sometimes (beuh) */
+ if (cmap) {
+ MEM_freeN(cmap);
+ cmap = NULL;
+ }
+ }
+
+ switch (tga.imgtyp) {
+ case 1:
+ case 2:
+ case 3:
+ if (tga.pixsize <= 8)
+ ldtarga(ibuf, mem, mem_size, 0);
+ else if (tga.pixsize <= 16)
+ ldtarga(ibuf, mem, mem_size, 1);
+ else if (tga.pixsize <= 24)
+ ldtarga(ibuf, mem, mem_size, 2);
+ else if (tga.pixsize <= 32)
+ ldtarga(ibuf, mem, mem_size, 3);
+ break;
+ case 9:
+ case 10:
+ case 11:
+ if (tga.pixsize <= 8)
+ decodetarga(ibuf, mem, mem_size, 0);
+ else if (tga.pixsize <= 16)
+ decodetarga(ibuf, mem, mem_size, 1);
+ else if (tga.pixsize <= 24)
+ decodetarga(ibuf, mem, mem_size, 2);
+ else if (tga.pixsize <= 32)
+ decodetarga(ibuf, mem, mem_size, 3);
+ break;
+ }
+
+ if (cmap) {
+ /* apply color map */
+ rect = ibuf->rect;
+ for (size = ibuf->x * ibuf->y; size > 0; --size, ++rect) {
+ int cmap_index = *rect;
+ if (cmap_index >= 0 && cmap_index < cmap_max) {
+ *rect = cmap[cmap_index];
+ }
+ }
+
+ MEM_freeN(cmap);
+ }
+
+ if (tga.pixsize == 16) {
+ unsigned int col;
+ rect = ibuf->rect;
+ for (size = ibuf->x * ibuf->y; size > 0; --size, ++rect) {
+ col = *rect;
+ cp = (uchar *)rect;
+ mem = (uchar *)&col;
+
+ cp[3] = ((mem[1] << 1) & 0xf8);
+ cp[2] = ((mem[0] & 0xe0) >> 2) + ((mem[1] & 0x03) << 6);
+ cp[1] = ((mem[0] << 3) & 0xf8);
+ cp[1] += cp[1] >> 5;
+ cp[2] += cp[2] >> 5;
+ cp[3] += cp[3] >> 5;
+ cp[0] = 0xff;
+ }
+ ibuf->planes = 24;
+ }
+
+ if (tga.imgtyp == 3 || tga.imgtyp == 11) {
+ uchar *crect;
+ unsigned int *lrect, col;
+
+ crect = (uchar *)ibuf->rect;
+ lrect = (unsigned int *)ibuf->rect;
+
+ for (size = ibuf->x * ibuf->y; size > 0; size--) {
+ col = *lrect++;
+
+ crect[0] = 255;
+ crect[1] = crect[2] = crect[3] = col;
+ crect += 4;
+ }
+ }
+
+ if (tga.imgdes & 0x20) {
+ IMB_flipy(ibuf);
+ }
+
+ if (ibuf->rect)
+ IMB_convert_rgba_to_abgr(ibuf);
+
+ return ibuf;
}
diff --git a/source/blender/imbuf/intern/thumbs.c b/source/blender/imbuf/intern/thumbs.c
index 6c71aa06583..fc5bfe42d60 100644
--- a/source/blender/imbuf/intern/thumbs.c
+++ b/source/blender/imbuf/intern/thumbs.c
@@ -36,7 +36,7 @@
#include "BLI_threads.h"
#include BLI_SYSTEM_PID_H
-#include "DNA_space_types.h" /* For FILE_MAX_LIBEXTRA */
+#include "DNA_space_types.h" /* For FILE_MAX_LIBEXTRA */
#include "BLO_readfile.h"
@@ -53,13 +53,13 @@
#include <stdio.h>
#ifdef WIN32
- /* Need to include windows.h so _WIN32_IE is defined. */
+/* Need to include windows.h so _WIN32_IE is defined. */
# include <windows.h>
# ifndef _WIN32_IE
- /* Minimal requirements for SHGetSpecialFolderPath on MINGW MSVC has this defined already. */
+/* Minimal requirements for SHGetSpecialFolderPath on MINGW MSVC has this defined already. */
# define _WIN32_IE 0x0400
# endif
- /* For SHGetSpecialFolderPath, has to be done before BLI_winstuff
+/* For SHGetSpecialFolderPath, has to be done before BLI_winstuff
* because 'near' is disabled through BLI_windstuff */
# include <shlobj.h>
# include <direct.h> /* chdir */
@@ -68,7 +68,7 @@
#endif
#if defined(WIN32) || defined(__APPLE__)
- /* pass */
+/* pass */
#else
# define USE_FREEDESKTOP
#endif
@@ -84,554 +84,665 @@
static bool get_thumb_dir(char *dir, ThumbSize size)
{
- char *s = dir;
- const char *subdir;
+ char *s = dir;
+ const char *subdir;
#ifdef WIN32
- wchar_t dir_16[MAX_PATH];
- /* yes, applications shouldn't store data there, but so does GIMP :)*/
- SHGetSpecialFolderPathW(0, dir_16, CSIDL_PROFILE, 0);
- conv_utf_16_to_8(dir_16, dir, FILE_MAX);
- s += strlen(dir);
+ wchar_t dir_16[MAX_PATH];
+ /* yes, applications shouldn't store data there, but so does GIMP :)*/
+ SHGetSpecialFolderPathW(0, dir_16, CSIDL_PROFILE, 0);
+ conv_utf_16_to_8(dir_16, dir, FILE_MAX);
+ s += strlen(dir);
#else
-#if defined(USE_FREEDESKTOP)
- const char *home_cache = BLI_getenv("XDG_CACHE_HOME");
- const char *home = home_cache ? home_cache : BLI_getenv("HOME");
-#else
- const char *home = BLI_getenv("HOME");
-#endif
- if (!home) return 0;
- s += BLI_strncpy_rlen(s, home, FILE_MAX);
-
-#ifdef USE_FREEDESKTOP
- if (!home_cache) {
- s += BLI_strncpy_rlen(s, "/.cache", FILE_MAX - (s - dir));
- }
-#endif
+# if defined(USE_FREEDESKTOP)
+ const char *home_cache = BLI_getenv("XDG_CACHE_HOME");
+ const char *home = home_cache ? home_cache : BLI_getenv("HOME");
+# else
+ const char *home = BLI_getenv("HOME");
+# endif
+ if (!home)
+ return 0;
+ s += BLI_strncpy_rlen(s, home, FILE_MAX);
+
+# ifdef USE_FREEDESKTOP
+ if (!home_cache) {
+ s += BLI_strncpy_rlen(s, "/.cache", FILE_MAX - (s - dir));
+ }
+# endif
#endif
- switch (size) {
- case THB_NORMAL:
- subdir = "/" THUMBNAILS "/normal/";
- break;
- case THB_LARGE:
- subdir = "/" THUMBNAILS "/large/";
- break;
- case THB_FAIL:
- subdir = "/" THUMBNAILS "/fail/blender/";
- break;
- default:
- return 0; /* unknown size */
- }
-
- s += BLI_strncpy_rlen(s, subdir, FILE_MAX - (s - dir));
- (void)s;
-
- return 1;
+ switch (size) {
+ case THB_NORMAL:
+ subdir = "/" THUMBNAILS "/normal/";
+ break;
+ case THB_LARGE:
+ subdir = "/" THUMBNAILS "/large/";
+ break;
+ case THB_FAIL:
+ subdir = "/" THUMBNAILS "/fail/blender/";
+ break;
+ default:
+ return 0; /* unknown size */
+ }
+
+ s += BLI_strncpy_rlen(s, subdir, FILE_MAX - (s - dir));
+ (void)s;
+
+ return 1;
}
#undef THUMBNAILS
-
/** ----- begin of adapted code from glib ---
* The following code is adapted from function g_escape_uri_string from the gnome glib
* Source: http://svn.gnome.org/viewcvs/glib/trunk/glib/gconvert.c?view=markup
* released under the Gnu General Public License.
*/
typedef enum {
- UNSAFE_ALL = 0x1, /* Escape all unsafe characters */
- UNSAFE_ALLOW_PLUS = 0x2, /* Allows '+' */
- UNSAFE_PATH = 0x8, /* Allows '/', '&', '=', ':', '@', '+', '$' and ',' */
- UNSAFE_HOST = 0x10, /* Allows '/' and ':' and '@' */
- UNSAFE_SLASHES = 0x20, /* Allows all characters except for '/' and '%' */
+ UNSAFE_ALL = 0x1, /* Escape all unsafe characters */
+ UNSAFE_ALLOW_PLUS = 0x2, /* Allows '+' */
+ UNSAFE_PATH = 0x8, /* Allows '/', '&', '=', ':', '@', '+', '$' and ',' */
+ UNSAFE_HOST = 0x10, /* Allows '/' and ':' and '@' */
+ UNSAFE_SLASHES = 0x20, /* Allows all characters except for '/' and '%' */
} UnsafeCharacterSet;
static const unsigned char acceptable[96] = {
- /* A table of the ASCII chars from space (32) to DEL (127) */
- /* ! " # $ % & ' ( ) * + , - . / */
- 0x00,0x3F,0x20,0x20,0x28,0x00,0x2C,0x3F,0x3F,0x3F,0x3F,0x2A,0x28,0x3F,0x3F,0x1C,
- /* 0 1 2 3 4 5 6 7 8 9 : ; < = > ? */
- 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x38,0x20,0x20,0x2C,0x20,0x20,
- /* @ A B C D E F G H I J K L M N O */
- 0x38,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,
- /* P Q R S T U V W X Y Z [ \ ] ^ _ */
- 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x20,0x20,0x20,0x20,0x3F,
- /* ` a b c d e f g h i j k l m n o */
- 0x20,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,
- /* p q r s t u v w x y z { | } ~ DEL */
- 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x20,0x20,0x20,0x3F,0x20,
+ /* A table of the ASCII chars from space (32) to DEL (127) */
+ /* ! " # $ % & ' ( ) * + , - . / */
+ 0x00,
+ 0x3F,
+ 0x20,
+ 0x20,
+ 0x28,
+ 0x00,
+ 0x2C,
+ 0x3F,
+ 0x3F,
+ 0x3F,
+ 0x3F,
+ 0x2A,
+ 0x28,
+ 0x3F,
+ 0x3F,
+ 0x1C,
+ /* 0 1 2 3 4 5 6 7 8 9 : ; < = > ? */
+ 0x3F,
+ 0x3F,
+ 0x3F,
+ 0x3F,
+ 0x3F,
+ 0x3F,
+ 0x3F,
+ 0x3F,
+ 0x3F,
+ 0x3F,
+ 0x38,
+ 0x20,
+ 0x20,
+ 0x2C,
+ 0x20,
+ 0x20,
+ /* @ A B C D E F G H I J K L M N O */
+ 0x38,
+ 0x3F,
+ 0x3F,
+ 0x3F,
+ 0x3F,
+ 0x3F,
+ 0x3F,
+ 0x3F,
+ 0x3F,
+ 0x3F,
+ 0x3F,
+ 0x3F,
+ 0x3F,
+ 0x3F,
+ 0x3F,
+ 0x3F,
+ /* P Q R S T U V W X Y Z [ \ ] ^ _ */
+ 0x3F,
+ 0x3F,
+ 0x3F,
+ 0x3F,
+ 0x3F,
+ 0x3F,
+ 0x3F,
+ 0x3F,
+ 0x3F,
+ 0x3F,
+ 0x3F,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x3F,
+ /* ` a b c d e f g h i j k l m n o */
+ 0x20,
+ 0x3F,
+ 0x3F,
+ 0x3F,
+ 0x3F,
+ 0x3F,
+ 0x3F,
+ 0x3F,
+ 0x3F,
+ 0x3F,
+ 0x3F,
+ 0x3F,
+ 0x3F,
+ 0x3F,
+ 0x3F,
+ 0x3F,
+ /* p q r s t u v w x y z { | } ~ DEL */
+ 0x3F,
+ 0x3F,
+ 0x3F,
+ 0x3F,
+ 0x3F,
+ 0x3F,
+ 0x3F,
+ 0x3F,
+ 0x3F,
+ 0x3F,
+ 0x3F,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x3F,
+ 0x20,
};
static const char hex[17] = "0123456789abcdef";
/* Note: This escape function works on file: URIs, but if you want to
* escape something else, please read RFC-2396 */
-static void escape_uri_string(const char *string, char *escaped_string, int escaped_string_size, UnsafeCharacterSet mask)
+static void escape_uri_string(const char *string,
+ char *escaped_string,
+ int escaped_string_size,
+ UnsafeCharacterSet mask)
{
-#define ACCEPTABLE(a) ((a) >= 32 && (a) < 128 && (acceptable[(a) - 32] & use_mask))
-
- const char *p;
- char *q;
- int c;
- UnsafeCharacterSet use_mask;
- use_mask = mask;
-
- BLI_assert(escaped_string_size > 0);
-
- /* space for \0 */
- escaped_string_size -= 1;
-
- for (q = escaped_string, p = string; (*p != '\0') && escaped_string_size; p++) {
- c = (unsigned char) *p;
-
- if (!ACCEPTABLE(c)) {
- if (escaped_string_size < 3) {
- break;
- }
-
- *q++ = '%'; /* means hex coming */
- *q++ = hex[c >> 4];
- *q++ = hex[c & 15];
- escaped_string_size -= 3;
- }
- else {
- *q++ = *p;
- escaped_string_size -= 1;
- }
- }
-
- *q = '\0';
+#define ACCEPTABLE(a) ((a) >= 32 && (a) < 128 && (acceptable[(a)-32] & use_mask))
+
+ const char *p;
+ char *q;
+ int c;
+ UnsafeCharacterSet use_mask;
+ use_mask = mask;
+
+ BLI_assert(escaped_string_size > 0);
+
+ /* space for \0 */
+ escaped_string_size -= 1;
+
+ for (q = escaped_string, p = string; (*p != '\0') && escaped_string_size; p++) {
+ c = (unsigned char)*p;
+
+ if (!ACCEPTABLE(c)) {
+ if (escaped_string_size < 3) {
+ break;
+ }
+
+ *q++ = '%'; /* means hex coming */
+ *q++ = hex[c >> 4];
+ *q++ = hex[c & 15];
+ escaped_string_size -= 3;
+ }
+ else {
+ *q++ = *p;
+ escaped_string_size -= 1;
+ }
+ }
+
+ *q = '\0';
}
/** ----- end of adapted code from glib --- */
static bool thumbhash_from_path(const char *UNUSED(path), ThumbSource source, char *r_hash)
{
- switch (source) {
- case THB_SOURCE_FONT:
- return IMB_thumb_load_font_get_hash(r_hash);
- default:
- r_hash[0] = '\0';
- return false;
- }
+ switch (source) {
+ case THB_SOURCE_FONT:
+ return IMB_thumb_load_font_get_hash(r_hash);
+ default:
+ r_hash[0] = '\0';
+ return false;
+ }
}
static bool uri_from_filename(const char *path, char *uri)
{
- char orig_uri[URI_MAX];
- const char *dirstart = path;
+ char orig_uri[URI_MAX];
+ const char *dirstart = path;
#ifdef WIN32
- {
- char vol[3];
-
- BLI_strncpy(orig_uri, "file:///", FILE_MAX);
- if (strlen(path) < 2 && path[1] != ':') {
- /* not a correct absolute path */
- return 0;
- }
- /* on windows, using always uppercase drive/volume letter in uri */
- vol[0] = (unsigned char)toupper(path[0]);
- vol[1] = ':';
- vol[2] = '\0';
- strcat(orig_uri, vol);
- dirstart += 2;
- }
- strcat(orig_uri, dirstart);
- BLI_str_replace_char(orig_uri, '\\', '/');
+ {
+ char vol[3];
+
+ BLI_strncpy(orig_uri, "file:///", FILE_MAX);
+ if (strlen(path) < 2 && path[1] != ':') {
+ /* not a correct absolute path */
+ return 0;
+ }
+ /* on windows, using always uppercase drive/volume letter in uri */
+ vol[0] = (unsigned char)toupper(path[0]);
+ vol[1] = ':';
+ vol[2] = '\0';
+ strcat(orig_uri, vol);
+ dirstart += 2;
+ }
+ strcat(orig_uri, dirstart);
+ BLI_str_replace_char(orig_uri, '\\', '/');
#else
- BLI_snprintf(orig_uri, URI_MAX, "file://%s", dirstart);
+ BLI_snprintf(orig_uri, URI_MAX, "file://%s", dirstart);
#endif
- escape_uri_string(orig_uri, uri, URI_MAX, UNSAFE_PATH);
+ escape_uri_string(orig_uri, uri, URI_MAX, UNSAFE_PATH);
- return 1;
+ return 1;
}
static bool thumbpathname_from_uri(
- const char *uri, char *r_path, const int path_len, char *r_name, int name_len, ThumbSize size)
+ const char *uri, char *r_path, const int path_len, char *r_name, int name_len, ThumbSize size)
{
- char name_buff[40];
-
- if (r_path && !r_name) {
- r_name = name_buff;
- name_len = sizeof(name_buff);
- }
-
- if (r_name) {
- char hexdigest[33];
- unsigned char digest[16];
- BLI_hash_md5_buffer(uri, strlen(uri), digest);
- hexdigest[0] = '\0';
- BLI_snprintf(r_name, name_len, "%s.png", BLI_hash_md5_to_hexdigest(digest, hexdigest));
-// printf("%s: '%s' --> '%s'\n", __func__, uri, r_name);
- }
-
- if (r_path) {
- char tmppath[FILE_MAX];
-
- if (get_thumb_dir(tmppath, size)) {
- BLI_snprintf(r_path, path_len, "%s%s", tmppath, r_name);
-// printf("%s: '%s' --> '%s'\n", __func__, uri, r_path);
- return true;
- }
- }
- return false;
+ char name_buff[40];
+
+ if (r_path && !r_name) {
+ r_name = name_buff;
+ name_len = sizeof(name_buff);
+ }
+
+ if (r_name) {
+ char hexdigest[33];
+ unsigned char digest[16];
+ BLI_hash_md5_buffer(uri, strlen(uri), digest);
+ hexdigest[0] = '\0';
+ BLI_snprintf(r_name, name_len, "%s.png", BLI_hash_md5_to_hexdigest(digest, hexdigest));
+ // printf("%s: '%s' --> '%s'\n", __func__, uri, r_name);
+ }
+
+ if (r_path) {
+ char tmppath[FILE_MAX];
+
+ if (get_thumb_dir(tmppath, size)) {
+ BLI_snprintf(r_path, path_len, "%s%s", tmppath, r_name);
+ // printf("%s: '%s' --> '%s'\n", __func__, uri, r_path);
+ return true;
+ }
+ }
+ return false;
}
static void thumbname_from_uri(const char *uri, char *thumb, const int thumb_len)
{
- thumbpathname_from_uri(uri, NULL, 0, thumb, thumb_len, THB_FAIL);
+ thumbpathname_from_uri(uri, NULL, 0, thumb, thumb_len, THB_FAIL);
}
static bool thumbpath_from_uri(const char *uri, char *path, const int path_len, ThumbSize size)
{
- return thumbpathname_from_uri(uri, path, path_len, NULL, 0, size);
+ return thumbpathname_from_uri(uri, path, path_len, NULL, 0, size);
}
void IMB_thumb_makedirs(void)
{
- char tpath[FILE_MAX];
-#if 0 /* UNUSED */
- if (get_thumb_dir(tpath, THB_NORMAL)) {
- BLI_dir_create_recursive(tpath);
- }
+ char tpath[FILE_MAX];
+#if 0 /* UNUSED */
+ if (get_thumb_dir(tpath, THB_NORMAL)) {
+ BLI_dir_create_recursive(tpath);
+ }
#endif
- if (get_thumb_dir(tpath, THB_LARGE)) {
- BLI_dir_create_recursive(tpath);
- }
- if (get_thumb_dir(tpath, THB_FAIL)) {
- BLI_dir_create_recursive(tpath);
- }
+ if (get_thumb_dir(tpath, THB_LARGE)) {
+ BLI_dir_create_recursive(tpath);
+ }
+ if (get_thumb_dir(tpath, THB_FAIL)) {
+ BLI_dir_create_recursive(tpath);
+ }
}
/* create thumbnail for file and returns new imbuf for thumbnail */
-static ImBuf *thumb_create_ex(
- const char *file_path, const char *uri, const char *thumb, const bool use_hash, const char *hash,
- const char *blen_group, const char *blen_id,
- ThumbSize size, ThumbSource source, ImBuf *img)
+static ImBuf *thumb_create_ex(const char *file_path,
+ const char *uri,
+ const char *thumb,
+ const bool use_hash,
+ const char *hash,
+ const char *blen_group,
+ const char *blen_id,
+ ThumbSize size,
+ ThumbSource source,
+ ImBuf *img)
{
- char desc[URI_MAX + 22];
- char tpath[FILE_MAX];
- char tdir[FILE_MAX];
- char temp[FILE_MAX];
- char mtime[40] = "0"; /* in case we can't stat the file */
- char cwidth[40] = "0"; /* in case images have no data */
- char cheight[40] = "0";
- short tsize = 128;
- short ex, ey;
- float scaledx, scaledy;
- BLI_stat_t info;
-
- switch (size) {
- case THB_NORMAL:
- tsize = PREVIEW_RENDER_DEFAULT_HEIGHT;
- break;
- case THB_LARGE:
- tsize = PREVIEW_RENDER_DEFAULT_HEIGHT * 2;
- break;
- case THB_FAIL:
- tsize = 1;
- break;
- default:
- return NULL; /* unknown size */
- }
-
- /* exception, skip images over 100mb */
- if (source == THB_SOURCE_IMAGE) {
- const size_t file_size = BLI_file_size(file_path);
- if (file_size != -1 && file_size > THUMB_SIZE_MAX) {
- // printf("file too big: %d, skipping %s\n", (int)size, file_path);
- return NULL;
- }
- }
-
- if (get_thumb_dir(tdir, size)) {
- BLI_snprintf(tpath, FILE_MAX, "%s%s", tdir, thumb);
-// thumb[8] = '\0'; /* shorten for tempname, not needed anymore */
- BLI_snprintf(temp, FILE_MAX, "%sblender_%d_%s.png", tdir, abs(getpid()), thumb);
- if (BLI_path_ncmp(file_path, tdir, sizeof(tdir)) == 0) {
- return NULL;
- }
- if (size == THB_FAIL) {
- img = IMB_allocImBuf(1, 1, 32, IB_rect | IB_metadata);
- if (!img) return NULL;
- }
- else {
- if (ELEM(source, THB_SOURCE_IMAGE, THB_SOURCE_BLEND, THB_SOURCE_FONT)) {
- /* only load if we didn't give an image */
- if (img == NULL) {
- switch (source) {
- case THB_SOURCE_IMAGE:
- img = IMB_loadiffname(file_path, IB_rect | IB_metadata, NULL);
- break;
- case THB_SOURCE_BLEND:
- img = IMB_thumb_load_blend(file_path, blen_group, blen_id);
- break;
- case THB_SOURCE_FONT:
- img = IMB_thumb_load_font(file_path, tsize, tsize);
- break;
- default:
- BLI_assert(0); /* This should never happen */
- }
- }
-
- if (img != NULL) {
- if (BLI_stat(file_path, &info) != -1) {
- BLI_snprintf(mtime, sizeof(mtime), "%ld", (long int)info.st_mtime);
- }
- BLI_snprintf(cwidth, sizeof(cwidth), "%d", img->x);
- BLI_snprintf(cheight, sizeof(cheight), "%d", img->y);
- }
- }
- else if (THB_SOURCE_MOVIE == source) {
- struct anim *anim = NULL;
- anim = IMB_open_anim(file_path, IB_rect | IB_metadata, 0, NULL);
- if (anim != NULL) {
- img = IMB_anim_absolute(anim, 0, IMB_TC_NONE, IMB_PROXY_NONE);
- if (img == NULL) {
- printf("not an anim; %s\n", file_path);
- }
- else {
- IMB_freeImBuf(img);
- img = IMB_anim_previewframe(anim);
- }
- IMB_free_anim(anim);
- }
- if (BLI_stat(file_path, &info) != -1) {
- BLI_snprintf(mtime, sizeof(mtime), "%ld", (long int)info.st_mtime);
- }
- }
- if (!img) return NULL;
-
- if (img->x > img->y) {
- scaledx = (float)tsize;
- scaledy = ( (float)img->y / (float)img->x) * tsize;
- }
- else {
- scaledy = (float)tsize;
- scaledx = ( (float)img->x / (float)img->y) * tsize;
- }
- ex = (short)scaledx;
- ey = (short)scaledy;
-
- /* save some time by only scaling byte buf */
- if (img->rect_float) {
- if (img->rect == NULL) {
- IMB_rect_from_float(img);
- }
-
- imb_freerectfloatImBuf(img);
- }
-
- IMB_scaleImBuf(img, ex, ey);
- }
- BLI_snprintf(desc, sizeof(desc), "Thumbnail for %s", uri);
- 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_set_field(img->metadata, "X-Blender::Hash", hash);
- }
- if (ELEM(source, THB_SOURCE_IMAGE, THB_SOURCE_BLEND, THB_SOURCE_FONT)) {
- 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;
-
- /* If we generated from a 16bit PNG e.g., we have a float rect, not a byte one - fix this. */
- IMB_rect_from_float(img);
- imb_freerectfloatImBuf(img);
-
- if (IMB_saveiff(img, temp, IB_rect | IB_metadata)) {
+ char desc[URI_MAX + 22];
+ char tpath[FILE_MAX];
+ char tdir[FILE_MAX];
+ char temp[FILE_MAX];
+ char mtime[40] = "0"; /* in case we can't stat the file */
+ char cwidth[40] = "0"; /* in case images have no data */
+ char cheight[40] = "0";
+ short tsize = 128;
+ short ex, ey;
+ float scaledx, scaledy;
+ BLI_stat_t info;
+
+ switch (size) {
+ case THB_NORMAL:
+ tsize = PREVIEW_RENDER_DEFAULT_HEIGHT;
+ break;
+ case THB_LARGE:
+ tsize = PREVIEW_RENDER_DEFAULT_HEIGHT * 2;
+ break;
+ case THB_FAIL:
+ tsize = 1;
+ break;
+ default:
+ return NULL; /* unknown size */
+ }
+
+ /* exception, skip images over 100mb */
+ if (source == THB_SOURCE_IMAGE) {
+ const size_t file_size = BLI_file_size(file_path);
+ if (file_size != -1 && file_size > THUMB_SIZE_MAX) {
+ // printf("file too big: %d, skipping %s\n", (int)size, file_path);
+ return NULL;
+ }
+ }
+
+ if (get_thumb_dir(tdir, size)) {
+ BLI_snprintf(tpath, FILE_MAX, "%s%s", tdir, thumb);
+ // thumb[8] = '\0'; /* shorten for tempname, not needed anymore */
+ BLI_snprintf(temp, FILE_MAX, "%sblender_%d_%s.png", tdir, abs(getpid()), thumb);
+ if (BLI_path_ncmp(file_path, tdir, sizeof(tdir)) == 0) {
+ return NULL;
+ }
+ if (size == THB_FAIL) {
+ img = IMB_allocImBuf(1, 1, 32, IB_rect | IB_metadata);
+ if (!img)
+ return NULL;
+ }
+ else {
+ if (ELEM(source, THB_SOURCE_IMAGE, THB_SOURCE_BLEND, THB_SOURCE_FONT)) {
+ /* only load if we didn't give an image */
+ if (img == NULL) {
+ switch (source) {
+ case THB_SOURCE_IMAGE:
+ img = IMB_loadiffname(file_path, IB_rect | IB_metadata, NULL);
+ break;
+ case THB_SOURCE_BLEND:
+ img = IMB_thumb_load_blend(file_path, blen_group, blen_id);
+ break;
+ case THB_SOURCE_FONT:
+ img = IMB_thumb_load_font(file_path, tsize, tsize);
+ break;
+ default:
+ BLI_assert(0); /* This should never happen */
+ }
+ }
+
+ if (img != NULL) {
+ if (BLI_stat(file_path, &info) != -1) {
+ BLI_snprintf(mtime, sizeof(mtime), "%ld", (long int)info.st_mtime);
+ }
+ BLI_snprintf(cwidth, sizeof(cwidth), "%d", img->x);
+ BLI_snprintf(cheight, sizeof(cheight), "%d", img->y);
+ }
+ }
+ else if (THB_SOURCE_MOVIE == source) {
+ struct anim *anim = NULL;
+ anim = IMB_open_anim(file_path, IB_rect | IB_metadata, 0, NULL);
+ if (anim != NULL) {
+ img = IMB_anim_absolute(anim, 0, IMB_TC_NONE, IMB_PROXY_NONE);
+ if (img == NULL) {
+ printf("not an anim; %s\n", file_path);
+ }
+ else {
+ IMB_freeImBuf(img);
+ img = IMB_anim_previewframe(anim);
+ }
+ IMB_free_anim(anim);
+ }
+ if (BLI_stat(file_path, &info) != -1) {
+ BLI_snprintf(mtime, sizeof(mtime), "%ld", (long int)info.st_mtime);
+ }
+ }
+ if (!img)
+ return NULL;
+
+ if (img->x > img->y) {
+ scaledx = (float)tsize;
+ scaledy = ((float)img->y / (float)img->x) * tsize;
+ }
+ else {
+ scaledy = (float)tsize;
+ scaledx = ((float)img->x / (float)img->y) * tsize;
+ }
+ ex = (short)scaledx;
+ ey = (short)scaledy;
+
+ /* save some time by only scaling byte buf */
+ if (img->rect_float) {
+ if (img->rect == NULL) {
+ IMB_rect_from_float(img);
+ }
+
+ imb_freerectfloatImBuf(img);
+ }
+
+ IMB_scaleImBuf(img, ex, ey);
+ }
+ BLI_snprintf(desc, sizeof(desc), "Thumbnail for %s", uri);
+ 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_set_field(img->metadata, "X-Blender::Hash", hash);
+ }
+ if (ELEM(source, THB_SOURCE_IMAGE, THB_SOURCE_BLEND, THB_SOURCE_FONT)) {
+ 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;
+
+ /* If we generated from a 16bit PNG e.g., we have a float rect, not a byte one - fix this. */
+ IMB_rect_from_float(img);
+ imb_freerectfloatImBuf(img);
+
+ if (IMB_saveiff(img, temp, IB_rect | IB_metadata)) {
#ifndef WIN32
- chmod(temp, S_IRUSR | S_IWUSR);
+ chmod(temp, S_IRUSR | S_IWUSR);
#endif
- // printf("%s saving thumb: '%s'\n", __func__, tpath);
+ // printf("%s saving thumb: '%s'\n", __func__, tpath);
- BLI_rename(temp, tpath);
- }
- }
- return img;
+ BLI_rename(temp, tpath);
+ }
+ }
+ return img;
}
-static ImBuf *thumb_create_or_fail(
- const char *file_path, const char *uri, const char *thumb, const bool use_hash, const char *hash,
- const char *blen_group, const char *blen_id, ThumbSize size, ThumbSource source)
+static ImBuf *thumb_create_or_fail(const char *file_path,
+ const char *uri,
+ const char *thumb,
+ const bool use_hash,
+ const char *hash,
+ const char *blen_group,
+ const char *blen_id,
+ ThumbSize size,
+ ThumbSource source)
{
- ImBuf *img = thumb_create_ex(file_path, uri, thumb, use_hash, hash, blen_group, blen_id, size, source, NULL);
-
- if (!img) {
- /* thumb creation failed, write fail thumb */
- img = thumb_create_ex(file_path, uri, thumb, use_hash, hash, blen_group, blen_id, THB_FAIL, source, NULL);
- if (img) {
- /* we don't need failed thumb anymore */
- IMB_freeImBuf(img);
- img = NULL;
- }
- }
-
- return img;
+ ImBuf *img = thumb_create_ex(
+ file_path, uri, thumb, use_hash, hash, blen_group, blen_id, size, source, NULL);
+
+ if (!img) {
+ /* thumb creation failed, write fail thumb */
+ img = thumb_create_ex(
+ file_path, uri, thumb, use_hash, hash, blen_group, blen_id, THB_FAIL, source, NULL);
+ if (img) {
+ /* we don't need failed thumb anymore */
+ IMB_freeImBuf(img);
+ img = NULL;
+ }
+ }
+
+ return img;
}
ImBuf *IMB_thumb_create(const char *path, ThumbSize size, ThumbSource source, ImBuf *img)
{
- char uri[URI_MAX] = "";
- char thumb_name[40];
+ char uri[URI_MAX] = "";
+ char thumb_name[40];
- if (!uri_from_filename(path, uri)) {
- return NULL;
- }
- thumbname_from_uri(uri, thumb_name, sizeof(thumb_name));
+ if (!uri_from_filename(path, uri)) {
+ return NULL;
+ }
+ thumbname_from_uri(uri, thumb_name, sizeof(thumb_name));
- return thumb_create_ex(path, uri, thumb_name, false, THUMB_DEFAULT_HASH, NULL, NULL, size, source, img);
+ return thumb_create_ex(
+ path, uri, thumb_name, false, THUMB_DEFAULT_HASH, NULL, NULL, size, source, img);
}
/* read thumbnail for file and returns new imbuf for thumbnail */
ImBuf *IMB_thumb_read(const char *path, ThumbSize size)
{
- char thumb[FILE_MAX];
- char uri[URI_MAX];
- ImBuf *img = NULL;
-
- if (!uri_from_filename(path, uri)) {
- return NULL;
- }
- if (thumbpath_from_uri(uri, thumb, sizeof(thumb), size)) {
- img = IMB_loadiffname(thumb, IB_rect | IB_metadata, NULL);
- }
-
- return img;
+ char thumb[FILE_MAX];
+ char uri[URI_MAX];
+ ImBuf *img = NULL;
+
+ if (!uri_from_filename(path, uri)) {
+ return NULL;
+ }
+ if (thumbpath_from_uri(uri, thumb, sizeof(thumb), size)) {
+ img = IMB_loadiffname(thumb, IB_rect | IB_metadata, NULL);
+ }
+
+ return img;
}
/* delete all thumbs for the file */
void IMB_thumb_delete(const char *path, ThumbSize size)
{
- char thumb[FILE_MAX];
- char uri[URI_MAX];
-
- if (!uri_from_filename(path, uri)) {
- return;
- }
- if (thumbpath_from_uri(uri, thumb, sizeof(thumb), size)) {
- if (BLI_path_ncmp(path, thumb, sizeof(thumb)) == 0) {
- return;
- }
- if (BLI_exists(thumb)) {
- BLI_delete(thumb, false, false);
- }
- }
+ char thumb[FILE_MAX];
+ char uri[URI_MAX];
+
+ if (!uri_from_filename(path, uri)) {
+ return;
+ }
+ if (thumbpath_from_uri(uri, thumb, sizeof(thumb), size)) {
+ if (BLI_path_ncmp(path, thumb, sizeof(thumb)) == 0) {
+ return;
+ }
+ if (BLI_exists(thumb)) {
+ BLI_delete(thumb, false, false);
+ }
+ }
}
-
/* create the thumb if necessary and manage failed and old thumbs */
ImBuf *IMB_thumb_manage(const char *org_path, ThumbSize size, ThumbSource source)
{
- char thumb_path[FILE_MAX];
- char thumb_name[40];
- char uri[URI_MAX];
- char path_buff[FILE_MAX_LIBEXTRA];
- const char *file_path;
- const char *path;
- BLI_stat_t st;
- ImBuf *img = NULL;
- char *blen_group = NULL, *blen_id = NULL;
-
- path = file_path = org_path;
- if (source == THB_SOURCE_BLEND) {
- if (BLO_library_path_explode(path, path_buff, &blen_group, &blen_id)) {
- if (blen_group) {
- if (!blen_id) {
- /* No preview for blen groups */
- return NULL;
- }
- file_path = path_buff; /* path needs to be a valid file! */
- }
- }
- }
-
- if (BLI_stat(file_path, &st) == -1) {
- return NULL;
- }
- if (!uri_from_filename(path, uri)) {
- return NULL;
- }
- if (thumbpath_from_uri(uri, thumb_path, sizeof(thumb_path), THB_FAIL)) {
- /* failure thumb exists, don't try recreating */
- if (BLI_exists(thumb_path)) {
- /* clear out of date fail case (note for blen IDs we use blender file itself here) */
- if (BLI_file_older(thumb_path, file_path)) {
- BLI_delete(thumb_path, false, false);
- }
- else {
- return NULL;
- }
- }
- }
-
- if (thumbpathname_from_uri(uri, thumb_path, sizeof(thumb_path), thumb_name, sizeof(thumb_name), size)) {
- if (BLI_path_ncmp(path, thumb_path, sizeof(thumb_path)) == 0) {
- img = IMB_loadiffname(path, IB_rect, NULL);
- }
- else {
- img = IMB_loadiffname(thumb_path, IB_rect | IB_metadata, NULL);
- if (img) {
- bool regenerate = false;
-
- char mtime[40];
- char thumb_hash[33];
- char thumb_hash_curr[33];
-
- const bool use_hash = thumbhash_from_path(file_path, source, thumb_hash);
-
- if (IMB_metadata_get_field(img->metadata, "Thumb::MTime", mtime, sizeof(mtime))) {
- regenerate = (st.st_mtime != atol(mtime));
- }
- else {
- /* illegal thumb, regenerate it! */
- regenerate = true;
- }
-
- if (use_hash && !regenerate) {
- 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 {
- regenerate = true;
- }
- }
-
- if (regenerate) {
- /* recreate all thumbs */
- IMB_freeImBuf(img);
- img = NULL;
- IMB_thumb_delete(path, THB_NORMAL);
- IMB_thumb_delete(path, THB_LARGE);
- IMB_thumb_delete(path, THB_FAIL);
- img = thumb_create_or_fail(
- file_path, uri, thumb_name, use_hash, thumb_hash, blen_group, blen_id, size, source);
- }
- }
- else {
- char thumb_hash[33];
- const bool use_hash = thumbhash_from_path(file_path, source, thumb_hash);
-
- img = thumb_create_or_fail(
- file_path, uri, thumb_name, use_hash, thumb_hash, blen_group, blen_id, size, source);
- }
- }
- }
-
- /* Our imbuf **must** have a valid rect (i.e. 8-bits/channels) data, we rely on this in draw code.
- * However, in some cases we may end loading 16bits PNGs, which generated float buffers.
- * This should be taken care of in generation step, but add also a safeguard here! */
- if (img) {
- IMB_rect_from_float(img);
- imb_freerectfloatImBuf(img);
- }
-
- return img;
+ char thumb_path[FILE_MAX];
+ char thumb_name[40];
+ char uri[URI_MAX];
+ char path_buff[FILE_MAX_LIBEXTRA];
+ const char *file_path;
+ const char *path;
+ BLI_stat_t st;
+ ImBuf *img = NULL;
+ char *blen_group = NULL, *blen_id = NULL;
+
+ path = file_path = org_path;
+ if (source == THB_SOURCE_BLEND) {
+ if (BLO_library_path_explode(path, path_buff, &blen_group, &blen_id)) {
+ if (blen_group) {
+ if (!blen_id) {
+ /* No preview for blen groups */
+ return NULL;
+ }
+ file_path = path_buff; /* path needs to be a valid file! */
+ }
+ }
+ }
+
+ if (BLI_stat(file_path, &st) == -1) {
+ return NULL;
+ }
+ if (!uri_from_filename(path, uri)) {
+ return NULL;
+ }
+ if (thumbpath_from_uri(uri, thumb_path, sizeof(thumb_path), THB_FAIL)) {
+ /* failure thumb exists, don't try recreating */
+ if (BLI_exists(thumb_path)) {
+ /* clear out of date fail case (note for blen IDs we use blender file itself here) */
+ if (BLI_file_older(thumb_path, file_path)) {
+ BLI_delete(thumb_path, false, false);
+ }
+ else {
+ return NULL;
+ }
+ }
+ }
+
+ if (thumbpathname_from_uri(
+ uri, thumb_path, sizeof(thumb_path), thumb_name, sizeof(thumb_name), size)) {
+ if (BLI_path_ncmp(path, thumb_path, sizeof(thumb_path)) == 0) {
+ img = IMB_loadiffname(path, IB_rect, NULL);
+ }
+ else {
+ img = IMB_loadiffname(thumb_path, IB_rect | IB_metadata, NULL);
+ if (img) {
+ bool regenerate = false;
+
+ char mtime[40];
+ char thumb_hash[33];
+ char thumb_hash_curr[33];
+
+ const bool use_hash = thumbhash_from_path(file_path, source, thumb_hash);
+
+ if (IMB_metadata_get_field(img->metadata, "Thumb::MTime", mtime, sizeof(mtime))) {
+ regenerate = (st.st_mtime != atol(mtime));
+ }
+ else {
+ /* illegal thumb, regenerate it! */
+ regenerate = true;
+ }
+
+ if (use_hash && !regenerate) {
+ 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 {
+ regenerate = true;
+ }
+ }
+
+ if (regenerate) {
+ /* recreate all thumbs */
+ IMB_freeImBuf(img);
+ img = NULL;
+ IMB_thumb_delete(path, THB_NORMAL);
+ IMB_thumb_delete(path, THB_LARGE);
+ IMB_thumb_delete(path, THB_FAIL);
+ img = thumb_create_or_fail(
+ file_path, uri, thumb_name, use_hash, thumb_hash, blen_group, blen_id, size, source);
+ }
+ }
+ else {
+ char thumb_hash[33];
+ const bool use_hash = thumbhash_from_path(file_path, source, thumb_hash);
+
+ img = thumb_create_or_fail(
+ file_path, uri, thumb_name, use_hash, thumb_hash, blen_group, blen_id, size, source);
+ }
+ }
+ }
+
+ /* Our imbuf **must** have a valid rect (i.e. 8-bits/channels) data, we rely on this in draw code.
+ * However, in some cases we may end loading 16bits PNGs, which generated float buffers.
+ * This should be taken care of in generation step, but add also a safeguard here! */
+ if (img) {
+ IMB_rect_from_float(img);
+ imb_freerectfloatImBuf(img);
+ }
+
+ return img;
}
/* ***** Threading ***** */
@@ -641,71 +752,71 @@ ImBuf *IMB_thumb_manage(const char *org_path, ThumbSize size, ThumbSource source
*/
static struct IMBThumbLocks {
- GSet *locked_paths;
- int lock_counter;
- ThreadCondition cond;
+ GSet *locked_paths;
+ int lock_counter;
+ ThreadCondition cond;
} thumb_locks = {0};
void IMB_thumb_locks_acquire(void)
{
- BLI_thread_lock(LOCK_IMAGE);
-
- if (thumb_locks.lock_counter == 0) {
- BLI_assert(thumb_locks.locked_paths == NULL);
- thumb_locks.locked_paths = BLI_gset_str_new(__func__);
- BLI_condition_init(&thumb_locks.cond);
- }
- thumb_locks.lock_counter++;
-
- BLI_assert(thumb_locks.locked_paths != NULL);
- BLI_assert(thumb_locks.lock_counter > 0);
- BLI_thread_unlock(LOCK_IMAGE);
+ BLI_thread_lock(LOCK_IMAGE);
+
+ if (thumb_locks.lock_counter == 0) {
+ BLI_assert(thumb_locks.locked_paths == NULL);
+ thumb_locks.locked_paths = BLI_gset_str_new(__func__);
+ BLI_condition_init(&thumb_locks.cond);
+ }
+ thumb_locks.lock_counter++;
+
+ BLI_assert(thumb_locks.locked_paths != NULL);
+ BLI_assert(thumb_locks.lock_counter > 0);
+ BLI_thread_unlock(LOCK_IMAGE);
}
void IMB_thumb_locks_release(void)
{
- BLI_thread_lock(LOCK_IMAGE);
- BLI_assert((thumb_locks.locked_paths != NULL) && (thumb_locks.lock_counter > 0));
+ BLI_thread_lock(LOCK_IMAGE);
+ BLI_assert((thumb_locks.locked_paths != NULL) && (thumb_locks.lock_counter > 0));
- thumb_locks.lock_counter--;
- if (thumb_locks.lock_counter == 0) {
- BLI_gset_free(thumb_locks.locked_paths, MEM_freeN);
- thumb_locks.locked_paths = NULL;
- BLI_condition_end(&thumb_locks.cond);
- }
+ thumb_locks.lock_counter--;
+ if (thumb_locks.lock_counter == 0) {
+ BLI_gset_free(thumb_locks.locked_paths, MEM_freeN);
+ thumb_locks.locked_paths = NULL;
+ BLI_condition_end(&thumb_locks.cond);
+ }
- BLI_thread_unlock(LOCK_IMAGE);
+ BLI_thread_unlock(LOCK_IMAGE);
}
void IMB_thumb_path_lock(const char *path)
{
- void *key = BLI_strdup(path);
+ void *key = BLI_strdup(path);
- BLI_thread_lock(LOCK_IMAGE);
- BLI_assert((thumb_locks.locked_paths != NULL) && (thumb_locks.lock_counter > 0));
+ BLI_thread_lock(LOCK_IMAGE);
+ BLI_assert((thumb_locks.locked_paths != NULL) && (thumb_locks.lock_counter > 0));
- if (thumb_locks.locked_paths) {
- while (!BLI_gset_add(thumb_locks.locked_paths, key)) {
- BLI_condition_wait_global_mutex(&thumb_locks.cond, LOCK_IMAGE);
- }
- }
+ if (thumb_locks.locked_paths) {
+ while (!BLI_gset_add(thumb_locks.locked_paths, key)) {
+ BLI_condition_wait_global_mutex(&thumb_locks.cond, LOCK_IMAGE);
+ }
+ }
- BLI_thread_unlock(LOCK_IMAGE);
+ BLI_thread_unlock(LOCK_IMAGE);
}
void IMB_thumb_path_unlock(const char *path)
{
- const void *key = path;
+ const void *key = path;
- BLI_thread_lock(LOCK_IMAGE);
- BLI_assert((thumb_locks.locked_paths != NULL) && (thumb_locks.lock_counter > 0));
+ BLI_thread_lock(LOCK_IMAGE);
+ BLI_assert((thumb_locks.locked_paths != NULL) && (thumb_locks.lock_counter > 0));
- if (thumb_locks.locked_paths) {
- if (!BLI_gset_remove(thumb_locks.locked_paths, key, MEM_freeN)) {
- BLI_assert(0);
- }
- BLI_condition_notify_all(&thumb_locks.cond);
- }
+ if (thumb_locks.locked_paths) {
+ if (!BLI_gset_remove(thumb_locks.locked_paths, key, MEM_freeN)) {
+ BLI_assert(0);
+ }
+ BLI_condition_notify_all(&thumb_locks.cond);
+ }
- BLI_thread_unlock(LOCK_IMAGE);
+ BLI_thread_unlock(LOCK_IMAGE);
}
diff --git a/source/blender/imbuf/intern/thumbs_blend.c b/source/blender/imbuf/intern/thumbs_blend.c
index 92005371c2a..20a419d1a16 100644
--- a/source/blender/imbuf/intern/thumbs_blend.c
+++ b/source/blender/imbuf/intern/thumbs_blend.c
@@ -18,13 +18,12 @@
* \ingroup imbuf
*/
-
#include <stdlib.h>
#include <string.h>
#include "BLI_utildefines.h"
#include "BLI_linklist.h"
-#include "BLI_listbase.h" /* Needed due to import of BLO_readfile.h */
+#include "BLI_listbase.h" /* Needed due to import of BLO_readfile.h */
#include "BLO_blend_defs.h"
#include "BLO_readfile.h"
@@ -33,7 +32,7 @@
#include "BKE_icons.h"
#include "BKE_main.h"
-#include "DNA_ID.h" /* For preview images... */
+#include "DNA_ID.h" /* For preview images... */
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
@@ -43,70 +42,70 @@
ImBuf *IMB_thumb_load_blend(const char *blen_path, const char *blen_group, const char *blen_id)
{
- ImBuf *ima = NULL;
-
- if (blen_group && blen_id) {
- LinkNode *ln, *names, *lp, *previews = NULL;
- struct BlendHandle *libfiledata = BLO_blendhandle_from_file(blen_path, NULL);
- int idcode = BKE_idcode_from_name(blen_group);
- int i, nprevs, nnames;
-
- if (libfiledata == NULL) {
- return ima;
- }
-
- /* Note: we should handle all previews for a same group at once, would avoid reopening .blend file
- * for each and every ID. However, this adds some complexity, so keep it for later. */
- names = BLO_blendhandle_get_datablock_names(libfiledata, idcode, &nnames);
- previews = BLO_blendhandle_get_previews(libfiledata, idcode, &nprevs);
-
- BLO_blendhandle_close(libfiledata);
-
- if (!previews || (nnames != nprevs)) {
- if (previews != 0) {
- /* No previews at all is not a bug! */
- printf("%s: error, found %d items, %d previews\n", __func__, nnames, nprevs);
- }
- BLI_linklist_free(previews, BKE_previewimg_freefunc);
- BLI_linklist_free(names, free);
- return ima;
- }
-
- for (i = 0, ln = names, lp = previews; i < nnames; i++, ln = ln->next, lp = lp->next) {
- const char *blockname = ln->link;
- PreviewImage *img = lp->link;
-
- if (STREQ(blockname, blen_id)) {
- if (img) {
- unsigned int w = img->w[ICON_SIZE_PREVIEW];
- unsigned int h = img->h[ICON_SIZE_PREVIEW];
- unsigned int *rect = img->rect[ICON_SIZE_PREVIEW];
-
- if (w > 0 && h > 0 && rect) {
- /* first allocate imbuf for copying preview into it */
- ima = IMB_allocImBuf(w, h, 32, IB_rect);
- memcpy(ima->rect, rect, w * h * sizeof(unsigned int));
- }
- }
- break;
- }
- }
-
- BLI_linklist_free(previews, BKE_previewimg_freefunc);
- BLI_linklist_free(names, free);
- }
- else {
- BlendThumbnail *data;
-
- data = BLO_thumbnail_from_file(blen_path);
- ima = BKE_main_thumbnail_to_imbuf(NULL, data);
-
- if (data) {
- MEM_freeN(data);
- }
- }
-
- return ima;
+ ImBuf *ima = NULL;
+
+ if (blen_group && blen_id) {
+ LinkNode *ln, *names, *lp, *previews = NULL;
+ struct BlendHandle *libfiledata = BLO_blendhandle_from_file(blen_path, NULL);
+ int idcode = BKE_idcode_from_name(blen_group);
+ int i, nprevs, nnames;
+
+ if (libfiledata == NULL) {
+ return ima;
+ }
+
+ /* Note: we should handle all previews for a same group at once, would avoid reopening .blend file
+ * for each and every ID. However, this adds some complexity, so keep it for later. */
+ names = BLO_blendhandle_get_datablock_names(libfiledata, idcode, &nnames);
+ previews = BLO_blendhandle_get_previews(libfiledata, idcode, &nprevs);
+
+ BLO_blendhandle_close(libfiledata);
+
+ if (!previews || (nnames != nprevs)) {
+ if (previews != 0) {
+ /* No previews at all is not a bug! */
+ printf("%s: error, found %d items, %d previews\n", __func__, nnames, nprevs);
+ }
+ BLI_linklist_free(previews, BKE_previewimg_freefunc);
+ BLI_linklist_free(names, free);
+ return ima;
+ }
+
+ for (i = 0, ln = names, lp = previews; i < nnames; i++, ln = ln->next, lp = lp->next) {
+ const char *blockname = ln->link;
+ PreviewImage *img = lp->link;
+
+ if (STREQ(blockname, blen_id)) {
+ if (img) {
+ unsigned int w = img->w[ICON_SIZE_PREVIEW];
+ unsigned int h = img->h[ICON_SIZE_PREVIEW];
+ unsigned int *rect = img->rect[ICON_SIZE_PREVIEW];
+
+ if (w > 0 && h > 0 && rect) {
+ /* first allocate imbuf for copying preview into it */
+ ima = IMB_allocImBuf(w, h, 32, IB_rect);
+ memcpy(ima->rect, rect, w * h * sizeof(unsigned int));
+ }
+ }
+ break;
+ }
+ }
+
+ BLI_linklist_free(previews, BKE_previewimg_freefunc);
+ BLI_linklist_free(names, free);
+ }
+ else {
+ BlendThumbnail *data;
+
+ data = BLO_thumbnail_from_file(blen_path);
+ ima = BKE_main_thumbnail_to_imbuf(NULL, data);
+
+ if (data) {
+ MEM_freeN(data);
+ }
+ }
+
+ return ima;
}
/* add a fake passepartout overlay to a byte buffer, use for blend file thumbnails */
@@ -114,54 +113,55 @@ ImBuf *IMB_thumb_load_blend(const char *blen_path, const char *blen_group, const
void IMB_thumb_overlay_blend(unsigned int *thumb, int width, int height, float aspect)
{
- unsigned char *px = (unsigned char *)thumb;
- int margin_l = MARGIN;
- int margin_b = MARGIN;
- int margin_r = width - MARGIN;
- int margin_t = height - MARGIN;
-
- if (aspect < 1.0f) {
- margin_l = (int)((width - ((float)width * aspect)) / 2.0f);
- margin_l += MARGIN;
- CLAMP(margin_l, MARGIN, (width / 2));
- margin_r = width - margin_l;
- }
- else if (aspect > 1.0f) {
- margin_b = (int)((height - ((float)height / aspect)) / 2.0f);
- margin_b += MARGIN;
- CLAMP(margin_b, MARGIN, (height / 2));
- margin_t = height - margin_b;
- }
-
- {
- int x, y;
- int stride_x = (margin_r - margin_l) - 2;
-
- for (y = 0; y < height; y++) {
- for (x = 0; x < width; x++, px += 4) {
- int hline = 0, vline = 0;
- if ((x > margin_l && x < margin_r) && (y > margin_b && y < margin_t)) {
- /* interior. skip */
- x += stride_x;
- px += stride_x * 4;
- }
- else if ((hline = (((x == margin_l || x == margin_r)) && y >= margin_b && y <= margin_t)) ||
- (vline = (((y == margin_b || y == margin_t)) && x >= margin_l && x <= margin_r)))
- {
- /* dashed line */
- if ((hline && y % 2) || (vline && x % 2)) {
- px[0] = px[1] = px[2] = 0;
- px[3] = 255;
- }
- }
- else {
- /* outside, fill in alpha, like passepartout */
- px[0] *= 0.5f;
- px[1] *= 0.5f;
- px[2] *= 0.5f;
- px[3] = (px[3] * 0.5f) + 96;
- }
- }
- }
- }
+ unsigned char *px = (unsigned char *)thumb;
+ int margin_l = MARGIN;
+ int margin_b = MARGIN;
+ int margin_r = width - MARGIN;
+ int margin_t = height - MARGIN;
+
+ if (aspect < 1.0f) {
+ margin_l = (int)((width - ((float)width * aspect)) / 2.0f);
+ margin_l += MARGIN;
+ CLAMP(margin_l, MARGIN, (width / 2));
+ margin_r = width - margin_l;
+ }
+ else if (aspect > 1.0f) {
+ margin_b = (int)((height - ((float)height / aspect)) / 2.0f);
+ margin_b += MARGIN;
+ CLAMP(margin_b, MARGIN, (height / 2));
+ margin_t = height - margin_b;
+ }
+
+ {
+ int x, y;
+ int stride_x = (margin_r - margin_l) - 2;
+
+ for (y = 0; y < height; y++) {
+ for (x = 0; x < width; x++, px += 4) {
+ int hline = 0, vline = 0;
+ if ((x > margin_l && x < margin_r) && (y > margin_b && y < margin_t)) {
+ /* interior. skip */
+ x += stride_x;
+ px += stride_x * 4;
+ }
+ else if ((hline = (((x == margin_l || x == margin_r)) && y >= margin_b &&
+ y <= margin_t)) ||
+ (vline = (((y == margin_b || y == margin_t)) && x >= margin_l &&
+ x <= margin_r))) {
+ /* dashed line */
+ if ((hline && y % 2) || (vline && x % 2)) {
+ px[0] = px[1] = px[2] = 0;
+ px[3] = 255;
+ }
+ }
+ else {
+ /* outside, fill in alpha, like passepartout */
+ px[0] *= 0.5f;
+ px[1] *= 0.5f;
+ px[2] *= 0.5f;
+ px[3] = (px[3] * 0.5f) + 96;
+ }
+ }
+ }
+ }
}
diff --git a/source/blender/imbuf/intern/thumbs_font.c b/source/blender/imbuf/intern/thumbs_font.c
index ec45749e513..1213927d329 100644
--- a/source/blender/imbuf/intern/thumbs_font.c
+++ b/source/blender/imbuf/intern/thumbs_font.c
@@ -28,7 +28,6 @@
#include "IMB_thumbs.h"
-
/* XXX, bad level call */
#include "../../blenfont/BLF_api.h"
#include "../../blentranslation/BLT_translation.h"
@@ -44,51 +43,57 @@ static const char *thumb_str[] = {
struct ImBuf *IMB_thumb_load_font(const char *filename, unsigned int x, unsigned int y)
{
- const int font_size = y / 4;
+ const int font_size = y / 4;
- struct ImBuf *ibuf;
- float font_color[4];
+ struct ImBuf *ibuf;
+ float font_color[4];
- /* create a white image (theme color is used for drawing) */
- font_color[0] = font_color[1] = font_color[2] = 1.0f;
+ /* create a white image (theme color is used for drawing) */
+ font_color[0] = font_color[1] = font_color[2] = 1.0f;
- /* fill with zero alpha */
- font_color[3] = 0.0f;
+ /* fill with zero alpha */
+ font_color[3] = 0.0f;
- ibuf = IMB_allocImBuf(x, y, 32, IB_rect | IB_metadata);
- IMB_rectfill(ibuf, font_color);
+ ibuf = IMB_allocImBuf(x, y, 32, IB_rect | IB_metadata);
+ IMB_rectfill(ibuf, font_color);
- /* draw with full alpha */
- font_color[3] = 1.0f;
+ /* draw with full alpha */
+ font_color[3] = 1.0f;
- BLF_thumb_preview(
- filename, thumb_str, ARRAY_SIZE(thumb_str),
- font_color, font_size,
- (unsigned char *)ibuf->rect, ibuf->x, ibuf->y, ibuf->channels);
+ BLF_thumb_preview(filename,
+ thumb_str,
+ ARRAY_SIZE(thumb_str),
+ font_color,
+ font_size,
+ (unsigned char *)ibuf->rect,
+ ibuf->x,
+ ibuf->y,
+ ibuf->channels);
- return ibuf;
+ return ibuf;
}
bool IMB_thumb_load_font_get_hash(char *r_hash)
{
- char buf[1024];
- char *str = buf;
- size_t len = 0;
+ char buf[1024];
+ char *str = buf;
+ size_t len = 0;
- int draw_str_lines = ARRAY_SIZE(thumb_str);
- int i;
+ int draw_str_lines = ARRAY_SIZE(thumb_str);
+ int i;
- unsigned char digest[16];
+ unsigned char digest[16];
- len += BLI_strncpy_rlen(str + len, THUMB_DEFAULT_HASH, sizeof(buf) - len);
+ len += BLI_strncpy_rlen(str + len, THUMB_DEFAULT_HASH, sizeof(buf) - len);
- for (i = 0; (i < draw_str_lines) && (len < sizeof(buf)); i++) {
- len += BLI_strncpy_rlen(str + len, BLT_translate_do(BLT_I18NCONTEXT_DEFAULT, thumb_str[i]), sizeof(buf) - len);
- }
+ for (i = 0; (i < draw_str_lines) && (len < sizeof(buf)); i++) {
+ len += BLI_strncpy_rlen(
+ str + len, BLT_translate_do(BLT_I18NCONTEXT_DEFAULT, thumb_str[i]), sizeof(buf) - len);
+ }
- BLI_hash_md5_buffer(str, len, digest);
- r_hash[0] = '\0';
- BLI_hash_md5_to_hexdigest(digest, r_hash);
+ BLI_hash_md5_buffer(str, len, digest);
+ r_hash[0] = '\0';
+ BLI_hash_md5_to_hexdigest(digest, r_hash);
- return true;
+ return true;
}
diff --git a/source/blender/imbuf/intern/tiff.c b/source/blender/imbuf/intern/tiff.c
index 928f1ef7a54..1f2b63a3749 100644
--- a/source/blender/imbuf/intern/tiff.c
+++ b/source/blender/imbuf/intern/tiff.c
@@ -18,7 +18,6 @@
* \ingroup imbuf
*/
-
/**
* Provides TIFF file loading and saving for Blender, via libtiff.
*
@@ -55,7 +54,7 @@
#include "tiffio.h"
#ifdef WIN32
-#include "utfconv.h"
+# include "utfconv.h"
#endif
/***********************
@@ -64,42 +63,38 @@
/* Reading and writing of an in-memory TIFF file. */
static tsize_t imb_tiff_ReadProc(thandle_t handle, tdata_t data, tsize_t n);
static tsize_t imb_tiff_WriteProc(thandle_t handle, tdata_t data, tsize_t n);
-static toff_t imb_tiff_SeekProc(thandle_t handle, toff_t ofs, int whence);
-static int imb_tiff_CloseProc(thandle_t handle);
-static toff_t imb_tiff_SizeProc(thandle_t handle);
-static int imb_tiff_DummyMapProc(thandle_t fd, tdata_t *pbase, toff_t *psize);
-static void imb_tiff_DummyUnmapProc(thandle_t fd, tdata_t base, toff_t size);
-
+static toff_t imb_tiff_SeekProc(thandle_t handle, toff_t ofs, int whence);
+static int imb_tiff_CloseProc(thandle_t handle);
+static toff_t imb_tiff_SizeProc(thandle_t handle);
+static int imb_tiff_DummyMapProc(thandle_t fd, tdata_t *pbase, toff_t *psize);
+static void imb_tiff_DummyUnmapProc(thandle_t fd, tdata_t base, toff_t size);
/* Structure for in-memory TIFF file. */
typedef struct ImbTIFFMemFile {
- const unsigned char *mem; /* Location of first byte of TIFF file. */
- toff_t offset; /* Current offset within the file. */
- tsize_t size; /* Size of the TIFF file. */
+ const unsigned char *mem; /* Location of first byte of TIFF file. */
+ toff_t offset; /* Current offset within the file. */
+ tsize_t size; /* Size of the TIFF file. */
} ImbTIFFMemFile;
#define IMB_TIFF_GET_MEMFILE(x) ((ImbTIFFMemFile *)(x))
-
-
/*****************************
* Function implementations. *
*****************************/
-
static void imb_tiff_DummyUnmapProc(thandle_t fd, tdata_t base, toff_t size)
{
- (void)fd;
- (void)base;
- (void)size;
+ (void)fd;
+ (void)base;
+ (void)size;
}
static int imb_tiff_DummyMapProc(thandle_t fd, tdata_t *pbase, toff_t *psize)
{
- (void)fd;
- (void)pbase;
- (void)psize;
+ (void)fd;
+ (void)pbase;
+ (void)psize;
- return (0);
+ return (0);
}
/**
@@ -114,40 +109,38 @@ static int imb_tiff_DummyMapProc(thandle_t fd, tdata_t *pbase, toff_t *psize)
*/
static tsize_t imb_tiff_ReadProc(thandle_t handle, tdata_t data, tsize_t n)
{
- tsize_t nRemaining, nCopy;
- ImbTIFFMemFile *mfile;
- void *srcAddr;
-
- /* get the pointer to the in-memory file */
- mfile = IMB_TIFF_GET_MEMFILE(handle);
- if (!mfile || !mfile->mem) {
- fprintf(stderr, "imb_tiff_ReadProc: !mfile || !mfile->mem!\n");
- return 0;
- }
-
- /* find the actual number of bytes to read (copy) */
- nCopy = n;
- if ((tsize_t)mfile->offset >= mfile->size)
- nRemaining = 0;
- else
- nRemaining = mfile->size - mfile->offset;
-
- if (nCopy > nRemaining)
- nCopy = nRemaining;
-
- /* on EOF, return immediately and read (copy) nothing */
- if (nCopy <= 0)
- return (0);
-
- /* all set -> do the read (copy) */
- srcAddr = (void *)(&(mfile->mem[mfile->offset]));
- memcpy((void *)data, srcAddr, nCopy);
- mfile->offset += nCopy; /* advance file ptr by copied bytes */
- return nCopy;
+ tsize_t nRemaining, nCopy;
+ ImbTIFFMemFile *mfile;
+ void *srcAddr;
+
+ /* get the pointer to the in-memory file */
+ mfile = IMB_TIFF_GET_MEMFILE(handle);
+ if (!mfile || !mfile->mem) {
+ fprintf(stderr, "imb_tiff_ReadProc: !mfile || !mfile->mem!\n");
+ return 0;
+ }
+
+ /* find the actual number of bytes to read (copy) */
+ nCopy = n;
+ if ((tsize_t)mfile->offset >= mfile->size)
+ nRemaining = 0;
+ else
+ nRemaining = mfile->size - mfile->offset;
+
+ if (nCopy > nRemaining)
+ nCopy = nRemaining;
+
+ /* on EOF, return immediately and read (copy) nothing */
+ if (nCopy <= 0)
+ return (0);
+
+ /* all set -> do the read (copy) */
+ srcAddr = (void *)(&(mfile->mem[mfile->offset]));
+ memcpy((void *)data, srcAddr, nCopy);
+ mfile->offset += nCopy; /* advance file ptr by copied bytes */
+ return nCopy;
}
-
-
/**
* Writes data to an in-memory TIFF file.
*
@@ -156,16 +149,14 @@ static tsize_t imb_tiff_ReadProc(thandle_t handle, tdata_t data, tsize_t n)
*/
static tsize_t imb_tiff_WriteProc(thandle_t handle, tdata_t data, tsize_t n)
{
- (void)handle;
- (void)data;
- (void)n;
+ (void)handle;
+ (void)data;
+ (void)n;
- printf("imb_tiff_WriteProc: this function should not be called.\n");
- return (-1);
+ printf("imb_tiff_WriteProc: this function should not be called.\n");
+ return (-1);
}
-
-
/**
* Seeks to a new location in an in-memory TIFF file.
*
@@ -182,39 +173,37 @@ static tsize_t imb_tiff_WriteProc(thandle_t handle, tdata_t data, tsize_t n)
*/
static toff_t imb_tiff_SeekProc(thandle_t handle, toff_t ofs, int whence)
{
- ImbTIFFMemFile *mfile;
- toff_t new_offset;
-
- /* get the pointer to the in-memory file */
- mfile = IMB_TIFF_GET_MEMFILE(handle);
- if (!mfile || !mfile->mem) {
- fprintf(stderr, "imb_tiff_SeekProc: !mfile || !mfile->mem!\n");
- return (-1);
- }
-
- /* find the location we plan to seek to */
- switch (whence) {
- case SEEK_SET:
- new_offset = ofs;
- break;
- case SEEK_CUR:
- new_offset = mfile->offset + ofs;
- break;
- default:
- /* no other types are supported - return an error */
- fprintf(stderr,
- "imb_tiff_SeekProc: "
- "Unsupported TIFF SEEK type.\n");
- return (-1);
- }
-
- /* set the new location */
- mfile->offset = new_offset;
- return mfile->offset;
+ ImbTIFFMemFile *mfile;
+ toff_t new_offset;
+
+ /* get the pointer to the in-memory file */
+ mfile = IMB_TIFF_GET_MEMFILE(handle);
+ if (!mfile || !mfile->mem) {
+ fprintf(stderr, "imb_tiff_SeekProc: !mfile || !mfile->mem!\n");
+ return (-1);
+ }
+
+ /* find the location we plan to seek to */
+ switch (whence) {
+ case SEEK_SET:
+ new_offset = ofs;
+ break;
+ case SEEK_CUR:
+ new_offset = mfile->offset + ofs;
+ break;
+ default:
+ /* no other types are supported - return an error */
+ fprintf(stderr,
+ "imb_tiff_SeekProc: "
+ "Unsupported TIFF SEEK type.\n");
+ return (-1);
+ }
+
+ /* set the new location */
+ mfile->offset = new_offset;
+ return mfile->offset;
}
-
-
/**
* Closes (virtually) an in-memory TIFF file.
*
@@ -229,25 +218,23 @@ static toff_t imb_tiff_SeekProc(thandle_t handle, toff_t ofs, int whence)
*/
static int imb_tiff_CloseProc(thandle_t handle)
{
- ImbTIFFMemFile *mfile;
+ ImbTIFFMemFile *mfile;
- /* get the pointer to the in-memory file */
- mfile = IMB_TIFF_GET_MEMFILE(handle);
- if (!mfile || !mfile->mem) {
- fprintf(stderr, "imb_tiff_CloseProc: !mfile || !mfile->mem!\n");
- return (0);
- }
+ /* get the pointer to the in-memory file */
+ mfile = IMB_TIFF_GET_MEMFILE(handle);
+ if (!mfile || !mfile->mem) {
+ fprintf(stderr, "imb_tiff_CloseProc: !mfile || !mfile->mem!\n");
+ return (0);
+ }
- /* virtually close the file */
- mfile->mem = NULL;
- mfile->offset = 0;
- mfile->size = 0;
+ /* virtually close the file */
+ mfile->mem = NULL;
+ mfile->offset = 0;
+ mfile->size = 0;
- return (0);
+ return (0);
}
-
-
/**
* Returns the size of an in-memory TIFF file in bytes.
*
@@ -255,31 +242,36 @@ static int imb_tiff_CloseProc(thandle_t handle)
*/
static toff_t imb_tiff_SizeProc(thandle_t handle)
{
- ImbTIFFMemFile *mfile;
+ ImbTIFFMemFile *mfile;
- /* get the pointer to the in-memory file */
- mfile = IMB_TIFF_GET_MEMFILE(handle);
- if (!mfile || !mfile->mem) {
- fprintf(stderr, "imb_tiff_SizeProc: !mfile || !mfile->mem!\n");
- return (0);
- }
+ /* get the pointer to the in-memory file */
+ mfile = IMB_TIFF_GET_MEMFILE(handle);
+ if (!mfile || !mfile->mem) {
+ fprintf(stderr, "imb_tiff_SizeProc: !mfile || !mfile->mem!\n");
+ return (0);
+ }
- /* return the size */
- return (toff_t)(mfile->size);
+ /* return the size */
+ return (toff_t)(mfile->size);
}
static TIFF *imb_tiff_client_open(ImbTIFFMemFile *memFile, const unsigned char *mem, size_t size)
{
- /* open the TIFF client layer interface to the in-memory file */
- memFile->mem = mem;
- memFile->offset = 0;
- memFile->size = size;
-
- return TIFFClientOpen("(Blender TIFF Interface Layer)",
- "r", (thandle_t)(memFile),
- imb_tiff_ReadProc, imb_tiff_WriteProc,
- imb_tiff_SeekProc, imb_tiff_CloseProc,
- imb_tiff_SizeProc, imb_tiff_DummyMapProc, imb_tiff_DummyUnmapProc);
+ /* open the TIFF client layer interface to the in-memory file */
+ memFile->mem = mem;
+ memFile->offset = 0;
+ memFile->size = size;
+
+ return TIFFClientOpen("(Blender TIFF Interface Layer)",
+ "r",
+ (thandle_t)(memFile),
+ imb_tiff_ReadProc,
+ imb_tiff_WriteProc,
+ imb_tiff_SeekProc,
+ imb_tiff_CloseProc,
+ imb_tiff_SizeProc,
+ imb_tiff_DummyMapProc,
+ imb_tiff_DummyUnmapProc);
}
/**
@@ -297,70 +289,76 @@ static TIFF *imb_tiff_client_open(ImbTIFFMemFile *memFile, const unsigned char *
* AFAICT, libtiff doesn't provide a method to do this automatically, and
* hence my manual comparison. - Jonathan Merritt (lancelet) 4th Sept 2005.
*/
-#define IMB_TIFF_NCB 4 /* number of comparison bytes used */
+#define IMB_TIFF_NCB 4 /* number of comparison bytes used */
int imb_is_a_tiff(const unsigned char *mem)
{
- char big_endian[IMB_TIFF_NCB] = { 0x4d, 0x4d, 0x00, 0x2a };
- char lil_endian[IMB_TIFF_NCB] = { 0x49, 0x49, 0x2a, 0x00 };
+ char big_endian[IMB_TIFF_NCB] = {0x4d, 0x4d, 0x00, 0x2a};
+ char lil_endian[IMB_TIFF_NCB] = {0x49, 0x49, 0x2a, 0x00};
- return ((memcmp(big_endian, mem, IMB_TIFF_NCB) == 0) ||
- (memcmp(lil_endian, mem, IMB_TIFF_NCB) == 0));
+ return ((memcmp(big_endian, mem, IMB_TIFF_NCB) == 0) ||
+ (memcmp(lil_endian, mem, IMB_TIFF_NCB) == 0));
}
-static void scanline_contig_16bit(float *rectf, const unsigned short *sbuf, int scanline_w, int spp)
+static void scanline_contig_16bit(float *rectf,
+ const unsigned short *sbuf,
+ int scanline_w,
+ int spp)
{
- int i;
- for (i = 0; i < scanline_w; i++) {
- rectf[i * 4 + 0] = sbuf[i * spp + 0] / 65535.0;
- rectf[i * 4 + 1] = (spp >= 3) ? sbuf[i * spp + 1] / 65535.0 : sbuf[i * spp + 0] / 65535.0;
- rectf[i * 4 + 2] = (spp >= 3) ? sbuf[i * spp + 2] / 65535.0 : sbuf[i * spp + 0] / 65535.0;
- rectf[i * 4 + 3] = (spp == 4) ? (sbuf[i * spp + 3] / 65535.0) : 1.0;
- }
+ int i;
+ for (i = 0; i < scanline_w; i++) {
+ rectf[i * 4 + 0] = sbuf[i * spp + 0] / 65535.0;
+ rectf[i * 4 + 1] = (spp >= 3) ? sbuf[i * spp + 1] / 65535.0 : sbuf[i * spp + 0] / 65535.0;
+ rectf[i * 4 + 2] = (spp >= 3) ? sbuf[i * spp + 2] / 65535.0 : sbuf[i * spp + 0] / 65535.0;
+ rectf[i * 4 + 3] = (spp == 4) ? (sbuf[i * spp + 3] / 65535.0) : 1.0;
+ }
}
static void scanline_contig_32bit(float *rectf, const float *fbuf, int scanline_w, int spp)
{
- int i;
- for (i = 0; i < scanline_w; i++) {
- rectf[i * 4 + 0] = fbuf[i * spp + 0];
- rectf[i * 4 + 1] = (spp >= 3) ? fbuf[i * spp + 1] : fbuf[i * spp + 0];
- rectf[i * 4 + 2] = (spp >= 3) ? fbuf[i * spp + 2] : fbuf[i * spp + 0];
- rectf[i * 4 + 3] = (spp == 4) ? fbuf[i * spp + 3] : 1.0f;
- }
+ int i;
+ for (i = 0; i < scanline_w; i++) {
+ rectf[i * 4 + 0] = fbuf[i * spp + 0];
+ rectf[i * 4 + 1] = (spp >= 3) ? fbuf[i * spp + 1] : fbuf[i * spp + 0];
+ rectf[i * 4 + 2] = (spp >= 3) ? fbuf[i * spp + 2] : fbuf[i * spp + 0];
+ rectf[i * 4 + 3] = (spp == 4) ? fbuf[i * spp + 3] : 1.0f;
+ }
}
-static void scanline_separate_16bit(float *rectf, const unsigned short *sbuf, int scanline_w, int chan)
+static void scanline_separate_16bit(float *rectf,
+ const unsigned short *sbuf,
+ int scanline_w,
+ int chan)
{
- int i;
- for (i = 0; i < scanline_w; i++)
- rectf[i * 4 + chan] = sbuf[i] / 65535.0;
+ int i;
+ for (i = 0; i < scanline_w; i++)
+ rectf[i * 4 + chan] = sbuf[i] / 65535.0;
}
static void scanline_separate_32bit(float *rectf, const float *fbuf, int scanline_w, int chan)
{
- int i;
- for (i = 0; i < scanline_w; i++)
- rectf[i * 4 + chan] = fbuf[i];
+ int i;
+ for (i = 0; i < scanline_w; i++)
+ rectf[i * 4 + chan] = fbuf[i];
}
static void imb_read_tiff_resolution(ImBuf *ibuf, TIFF *image)
{
- uint16 unit;
- float xres;
- float yres;
-
- TIFFGetFieldDefaulted(image, TIFFTAG_RESOLUTIONUNIT, &unit);
- TIFFGetFieldDefaulted(image, TIFFTAG_XRESOLUTION, &xres);
- TIFFGetFieldDefaulted(image, TIFFTAG_YRESOLUTION, &yres);
-
- if (unit == RESUNIT_CENTIMETER) {
- ibuf->ppm[0] = (double)xres * 100.0;
- ibuf->ppm[1] = (double)yres * 100.0;
- }
- else {
- ibuf->ppm[0] = (double)xres / 0.0254;
- ibuf->ppm[1] = (double)yres / 0.0254;
- }
+ uint16 unit;
+ float xres;
+ float yres;
+
+ TIFFGetFieldDefaulted(image, TIFFTAG_RESOLUTIONUNIT, &unit);
+ TIFFGetFieldDefaulted(image, TIFFTAG_XRESOLUTION, &xres);
+ TIFFGetFieldDefaulted(image, TIFFTAG_YRESOLUTION, &yres);
+
+ if (unit == RESUNIT_CENTIMETER) {
+ ibuf->ppm[0] = (double)xres * 100.0;
+ ibuf->ppm[1] = (double)yres * 100.0;
+ }
+ else {
+ ibuf->ppm[0] = (double)xres / 0.0254;
+ ibuf->ppm[1] = (double)yres / 0.0254;
+ }
}
/*
@@ -370,147 +368,144 @@ static void imb_read_tiff_resolution(ImBuf *ibuf, TIFF *image)
*/
static int imb_read_tiff_pixels(ImBuf *ibuf, TIFF *image)
{
- ImBuf *tmpibuf = NULL;
- int success = 0;
- short bitspersample, spp, config;
- size_t scanline;
- int ib_flag = 0, row, chan;
- float *fbuf = NULL;
- unsigned short *sbuf = NULL;
-
- TIFFGetField(image, TIFFTAG_BITSPERSAMPLE, &bitspersample);
- TIFFGetField(image, TIFFTAG_SAMPLESPERPIXEL, &spp); /* number of 'channels' */
- TIFFGetField(image, TIFFTAG_PLANARCONFIG, &config);
-
- if (spp == 4) {
- /* HACK: this is really tricky hack, which is only needed to force libtiff
- * do not touch RGB channels when there's alpha channel present
- * The thing is: libtiff will premul RGB if alpha mode is set to
- * unassociated, which really conflicts with blender's assumptions
- *
- * Alternative would be to unpremul after load, but it'll be really
- * lossy and unwanted behavior
- *
- * So let's keep this thing here for until proper solution is found (sergey)
- */
-
- unsigned short extraSampleTypes[1];
- extraSampleTypes[0] = EXTRASAMPLE_ASSOCALPHA;
- TIFFSetField(image, TIFFTAG_EXTRASAMPLES, 1, extraSampleTypes);
- }
-
- imb_read_tiff_resolution(ibuf, image);
-
- scanline = TIFFScanlineSize(image);
-
- if (bitspersample == 32) {
- ib_flag = IB_rectfloat;
- fbuf = (float *)_TIFFmalloc(scanline);
- if (!fbuf) {
- goto cleanup;
- }
- }
- else if (bitspersample == 16) {
- ib_flag = IB_rectfloat;
- sbuf = (unsigned short *)_TIFFmalloc(scanline);
- if (!sbuf) {
- goto cleanup;
- }
- }
- else {
- ib_flag = IB_rect;
- }
-
- tmpibuf = IMB_allocImBuf(ibuf->x, ibuf->y, ibuf->planes, ib_flag);
- if (!tmpibuf) {
- goto cleanup;
- }
-
- /* simple RGBA image */
- if (!(bitspersample == 32 || bitspersample == 16)) {
- success |= TIFFReadRGBAImage(image, ibuf->x, ibuf->y, tmpibuf->rect, 0);
- }
- /* contiguous channels: RGBRGBRGB */
- else if (config == PLANARCONFIG_CONTIG) {
- for (row = 0; row < ibuf->y; row++) {
- size_t ib_offset = (size_t)ibuf->x * 4 * ((size_t)ibuf->y - ((size_t)row + 1));
-
- if (bitspersample == 32) {
- success |= TIFFReadScanline(image, fbuf, row, 0);
- scanline_contig_32bit(tmpibuf->rect_float + ib_offset, fbuf, ibuf->x, spp);
-
- }
- else if (bitspersample == 16) {
- success |= TIFFReadScanline(image, sbuf, row, 0);
- scanline_contig_16bit(tmpibuf->rect_float + ib_offset, sbuf, ibuf->x, spp);
- }
- }
- /* separate channels: RRRGGGBBB */
- }
- else if (config == PLANARCONFIG_SEPARATE) {
-
- /* imbufs always have 4 channels of data, so we iterate over all of them
- * but only fill in from the TIFF scanline where necessary. */
- for (chan = 0; chan < 4; chan++) {
- for (row = 0; row < ibuf->y; row++) {
- size_t ib_offset = (size_t)ibuf->x * 4 * ((size_t)ibuf->y - ((size_t)row + 1));
-
- if (bitspersample == 32) {
- if (chan == 3 && spp == 3) /* fill alpha if only RGB TIFF */
- copy_vn_fl(fbuf, ibuf->x, 1.0f);
- else if (chan >= spp) /* for grayscale, duplicate first channel into G and B */
- success |= TIFFReadScanline(image, fbuf, row, 0);
- else
- success |= TIFFReadScanline(image, fbuf, row, chan);
- scanline_separate_32bit(tmpibuf->rect_float + ib_offset, fbuf, ibuf->x, chan);
-
- }
- else if (bitspersample == 16) {
- if (chan == 3 && spp == 3) /* fill alpha if only RGB TIFF */
- copy_vn_ushort(sbuf, ibuf->x, 65535);
- else if (chan >= spp) /* for grayscale, duplicate first channel into G and B */
- success |= TIFFReadScanline(image, fbuf, row, 0);
- else
- success |= TIFFReadScanline(image, sbuf, row, chan);
- scanline_separate_16bit(tmpibuf->rect_float + ib_offset, sbuf, ibuf->x, chan);
-
- }
- }
- }
- }
-
- if (success) {
- /* Code seems to be not needed for 16 bits tif, on PPC G5 OSX (ton) */
- if (bitspersample < 16)
- if (ENDIAN_ORDER == B_ENDIAN)
- IMB_convert_rgba_to_abgr(tmpibuf);
-
- /* assign rect last */
- if (tmpibuf->rect_float)
- ibuf->rect_float = tmpibuf->rect_float;
- else
- ibuf->rect = tmpibuf->rect;
- ibuf->mall |= ib_flag;
- ibuf->flags |= ib_flag;
-
- tmpibuf->mall &= ~ib_flag;
- }
+ ImBuf *tmpibuf = NULL;
+ int success = 0;
+ short bitspersample, spp, config;
+ size_t scanline;
+ int ib_flag = 0, row, chan;
+ float *fbuf = NULL;
+ unsigned short *sbuf = NULL;
+
+ TIFFGetField(image, TIFFTAG_BITSPERSAMPLE, &bitspersample);
+ TIFFGetField(image, TIFFTAG_SAMPLESPERPIXEL, &spp); /* number of 'channels' */
+ TIFFGetField(image, TIFFTAG_PLANARCONFIG, &config);
+
+ if (spp == 4) {
+ /* HACK: this is really tricky hack, which is only needed to force libtiff
+ * do not touch RGB channels when there's alpha channel present
+ * The thing is: libtiff will premul RGB if alpha mode is set to
+ * unassociated, which really conflicts with blender's assumptions
+ *
+ * Alternative would be to unpremul after load, but it'll be really
+ * lossy and unwanted behavior
+ *
+ * So let's keep this thing here for until proper solution is found (sergey)
+ */
+
+ unsigned short extraSampleTypes[1];
+ extraSampleTypes[0] = EXTRASAMPLE_ASSOCALPHA;
+ TIFFSetField(image, TIFFTAG_EXTRASAMPLES, 1, extraSampleTypes);
+ }
+
+ imb_read_tiff_resolution(ibuf, image);
+
+ scanline = TIFFScanlineSize(image);
+
+ if (bitspersample == 32) {
+ ib_flag = IB_rectfloat;
+ fbuf = (float *)_TIFFmalloc(scanline);
+ if (!fbuf) {
+ goto cleanup;
+ }
+ }
+ else if (bitspersample == 16) {
+ ib_flag = IB_rectfloat;
+ sbuf = (unsigned short *)_TIFFmalloc(scanline);
+ if (!sbuf) {
+ goto cleanup;
+ }
+ }
+ else {
+ ib_flag = IB_rect;
+ }
+
+ tmpibuf = IMB_allocImBuf(ibuf->x, ibuf->y, ibuf->planes, ib_flag);
+ if (!tmpibuf) {
+ goto cleanup;
+ }
+
+ /* simple RGBA image */
+ if (!(bitspersample == 32 || bitspersample == 16)) {
+ success |= TIFFReadRGBAImage(image, ibuf->x, ibuf->y, tmpibuf->rect, 0);
+ }
+ /* contiguous channels: RGBRGBRGB */
+ else if (config == PLANARCONFIG_CONTIG) {
+ for (row = 0; row < ibuf->y; row++) {
+ size_t ib_offset = (size_t)ibuf->x * 4 * ((size_t)ibuf->y - ((size_t)row + 1));
+
+ if (bitspersample == 32) {
+ success |= TIFFReadScanline(image, fbuf, row, 0);
+ scanline_contig_32bit(tmpibuf->rect_float + ib_offset, fbuf, ibuf->x, spp);
+ }
+ else if (bitspersample == 16) {
+ success |= TIFFReadScanline(image, sbuf, row, 0);
+ scanline_contig_16bit(tmpibuf->rect_float + ib_offset, sbuf, ibuf->x, spp);
+ }
+ }
+ /* separate channels: RRRGGGBBB */
+ }
+ else if (config == PLANARCONFIG_SEPARATE) {
+
+ /* imbufs always have 4 channels of data, so we iterate over all of them
+ * but only fill in from the TIFF scanline where necessary. */
+ for (chan = 0; chan < 4; chan++) {
+ for (row = 0; row < ibuf->y; row++) {
+ size_t ib_offset = (size_t)ibuf->x * 4 * ((size_t)ibuf->y - ((size_t)row + 1));
+
+ if (bitspersample == 32) {
+ if (chan == 3 && spp == 3) /* fill alpha if only RGB TIFF */
+ copy_vn_fl(fbuf, ibuf->x, 1.0f);
+ else if (chan >= spp) /* for grayscale, duplicate first channel into G and B */
+ success |= TIFFReadScanline(image, fbuf, row, 0);
+ else
+ success |= TIFFReadScanline(image, fbuf, row, chan);
+ scanline_separate_32bit(tmpibuf->rect_float + ib_offset, fbuf, ibuf->x, chan);
+ }
+ else if (bitspersample == 16) {
+ if (chan == 3 && spp == 3) /* fill alpha if only RGB TIFF */
+ copy_vn_ushort(sbuf, ibuf->x, 65535);
+ else if (chan >= spp) /* for grayscale, duplicate first channel into G and B */
+ success |= TIFFReadScanline(image, fbuf, row, 0);
+ else
+ success |= TIFFReadScanline(image, sbuf, row, chan);
+ scanline_separate_16bit(tmpibuf->rect_float + ib_offset, sbuf, ibuf->x, chan);
+ }
+ }
+ }
+ }
+
+ if (success) {
+ /* Code seems to be not needed for 16 bits tif, on PPC G5 OSX (ton) */
+ if (bitspersample < 16)
+ if (ENDIAN_ORDER == B_ENDIAN)
+ IMB_convert_rgba_to_abgr(tmpibuf);
+
+ /* assign rect last */
+ if (tmpibuf->rect_float)
+ ibuf->rect_float = tmpibuf->rect_float;
+ else
+ ibuf->rect = tmpibuf->rect;
+ ibuf->mall |= ib_flag;
+ ibuf->flags |= ib_flag;
+
+ tmpibuf->mall &= ~ib_flag;
+ }
cleanup:
- if (bitspersample == 32)
- _TIFFfree(fbuf);
- else if (bitspersample == 16)
- _TIFFfree(sbuf);
+ if (bitspersample == 32)
+ _TIFFfree(fbuf);
+ else if (bitspersample == 16)
+ _TIFFfree(sbuf);
- IMB_freeImBuf(tmpibuf);
+ IMB_freeImBuf(tmpibuf);
- return success;
+ return success;
}
void imb_inittiff(void)
{
- if (!(G.debug & G_DEBUG))
- TIFFSetErrorHandler(NULL);
+ if (!(G.debug & G_DEBUG))
+ TIFFSetErrorHandler(NULL);
}
/**
@@ -522,165 +517,177 @@ void imb_inittiff(void)
*
* \return: A newly allocated ImBuf structure if successful, otherwise NULL.
*/
-ImBuf *imb_loadtiff(const unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE])
+ImBuf *imb_loadtiff(const unsigned char *mem,
+ size_t size,
+ int flags,
+ char colorspace[IM_MAX_SPACE])
{
- TIFF *image = NULL;
- ImBuf *ibuf = NULL, *hbuf;
- ImbTIFFMemFile memFile;
- uint32 width, height;
- char *format = NULL;
- int level;
- short spp;
- int ib_depth;
- int found;
-
- /* check whether or not we have a TIFF file */
- if (size < IMB_TIFF_NCB) {
- fprintf(stderr, "imb_loadtiff: size < IMB_TIFF_NCB\n");
- return NULL;
- }
- if (imb_is_a_tiff(mem) == 0)
- return NULL;
-
- /* both 8 and 16 bit PNGs are default to standard byte colorspace */
- colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE);
-
- image = imb_tiff_client_open(&memFile, mem, size);
-
- if (image == NULL) {
- printf("imb_loadtiff: could not open TIFF IO layer.\n");
- return NULL;
- }
-
- /* allocate the image buffer */
- TIFFGetField(image, TIFFTAG_IMAGEWIDTH, &width);
- TIFFGetField(image, TIFFTAG_IMAGELENGTH, &height);
- TIFFGetField(image, TIFFTAG_SAMPLESPERPIXEL, &spp);
-
- ib_depth = (spp == 3) ? 24 : 32;
-
- ibuf = IMB_allocImBuf(width, height, ib_depth, 0);
- if (ibuf) {
- ibuf->ftype = IMB_FTYPE_TIF;
- }
- else {
- fprintf(stderr,
- "imb_loadtiff: could not allocate memory for TIFF "
- "image.\n");
- TIFFClose(image);
- return NULL;
- }
-
- /* get alpha mode from file header */
- if (flags & IB_alphamode_detect) {
- if (spp == 4) {
- unsigned short extra, *extraSampleTypes;
-
- found = TIFFGetField(image, TIFFTAG_EXTRASAMPLES, &extra, &extraSampleTypes);
-
- if (found && (extraSampleTypes[0] == EXTRASAMPLE_ASSOCALPHA)) {
- ibuf->flags |= IB_alphamode_premul;
- }
- }
- }
-
- /* if testing, we're done */
- if (flags & IB_test) {
- TIFFClose(image);
- return ibuf;
- }
-
- /* detect if we are reading a tiled/mipmapped texture, in that case
- * we don't read pixels but leave it to the cache to load tiles */
- if (flags & IB_tilecache) {
- format = NULL;
- TIFFGetField(image, TIFFTAG_PIXAR_TEXTUREFORMAT, &format);
-
- if (format && STREQ(format, "Plain Texture") && TIFFIsTiled(image)) {
- int numlevel = TIFFNumberOfDirectories(image);
-
- /* create empty mipmap levels in advance */
- for (level = 0; level < numlevel; level++) {
- if (!TIFFSetDirectory(image, level))
- break;
-
- if (level > 0) {
- width = (width > 1) ? width / 2 : 1;
- height = (height > 1) ? height / 2 : 1;
-
- hbuf = IMB_allocImBuf(width, height, 32, 0);
- hbuf->miplevel = level;
- hbuf->ftype = ibuf->ftype;
- ibuf->mipmap[level - 1] = hbuf;
- }
- else
- hbuf = ibuf;
-
- hbuf->flags |= IB_tilecache;
-
- TIFFGetField(image, TIFFTAG_TILEWIDTH, &hbuf->tilex);
- TIFFGetField(image, TIFFTAG_TILELENGTH, &hbuf->tiley);
-
- hbuf->xtiles = ceil(hbuf->x / (float)hbuf->tilex);
- hbuf->ytiles = ceil(hbuf->y / (float)hbuf->tiley);
-
- imb_addtilesImBuf(hbuf);
-
- ibuf->miptot++;
- }
- }
- }
-
- /* read pixels */
- if (!(ibuf->flags & IB_tilecache) && !imb_read_tiff_pixels(ibuf, image)) {
- fprintf(stderr, "imb_loadtiff: Failed to read tiff image.\n");
- TIFFClose(image);
- return NULL;
- }
-
- /* close the client layer interface to the in-memory file */
- TIFFClose(image);
-
- /* return successfully */
- return ibuf;
+ TIFF *image = NULL;
+ ImBuf *ibuf = NULL, *hbuf;
+ ImbTIFFMemFile memFile;
+ uint32 width, height;
+ char *format = NULL;
+ int level;
+ short spp;
+ int ib_depth;
+ int found;
+
+ /* check whether or not we have a TIFF file */
+ if (size < IMB_TIFF_NCB) {
+ fprintf(stderr, "imb_loadtiff: size < IMB_TIFF_NCB\n");
+ return NULL;
+ }
+ if (imb_is_a_tiff(mem) == 0)
+ return NULL;
+
+ /* both 8 and 16 bit PNGs are default to standard byte colorspace */
+ colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE);
+
+ image = imb_tiff_client_open(&memFile, mem, size);
+
+ if (image == NULL) {
+ printf("imb_loadtiff: could not open TIFF IO layer.\n");
+ return NULL;
+ }
+
+ /* allocate the image buffer */
+ TIFFGetField(image, TIFFTAG_IMAGEWIDTH, &width);
+ TIFFGetField(image, TIFFTAG_IMAGELENGTH, &height);
+ TIFFGetField(image, TIFFTAG_SAMPLESPERPIXEL, &spp);
+
+ ib_depth = (spp == 3) ? 24 : 32;
+
+ ibuf = IMB_allocImBuf(width, height, ib_depth, 0);
+ if (ibuf) {
+ ibuf->ftype = IMB_FTYPE_TIF;
+ }
+ else {
+ fprintf(stderr,
+ "imb_loadtiff: could not allocate memory for TIFF "
+ "image.\n");
+ TIFFClose(image);
+ return NULL;
+ }
+
+ /* get alpha mode from file header */
+ if (flags & IB_alphamode_detect) {
+ if (spp == 4) {
+ unsigned short extra, *extraSampleTypes;
+
+ found = TIFFGetField(image, TIFFTAG_EXTRASAMPLES, &extra, &extraSampleTypes);
+
+ if (found && (extraSampleTypes[0] == EXTRASAMPLE_ASSOCALPHA)) {
+ ibuf->flags |= IB_alphamode_premul;
+ }
+ }
+ }
+
+ /* if testing, we're done */
+ if (flags & IB_test) {
+ TIFFClose(image);
+ return ibuf;
+ }
+
+ /* detect if we are reading a tiled/mipmapped texture, in that case
+ * we don't read pixels but leave it to the cache to load tiles */
+ if (flags & IB_tilecache) {
+ format = NULL;
+ TIFFGetField(image, TIFFTAG_PIXAR_TEXTUREFORMAT, &format);
+
+ if (format && STREQ(format, "Plain Texture") && TIFFIsTiled(image)) {
+ int numlevel = TIFFNumberOfDirectories(image);
+
+ /* create empty mipmap levels in advance */
+ for (level = 0; level < numlevel; level++) {
+ if (!TIFFSetDirectory(image, level))
+ break;
+
+ if (level > 0) {
+ width = (width > 1) ? width / 2 : 1;
+ height = (height > 1) ? height / 2 : 1;
+
+ hbuf = IMB_allocImBuf(width, height, 32, 0);
+ hbuf->miplevel = level;
+ hbuf->ftype = ibuf->ftype;
+ ibuf->mipmap[level - 1] = hbuf;
+ }
+ else
+ hbuf = ibuf;
+
+ hbuf->flags |= IB_tilecache;
+
+ TIFFGetField(image, TIFFTAG_TILEWIDTH, &hbuf->tilex);
+ TIFFGetField(image, TIFFTAG_TILELENGTH, &hbuf->tiley);
+
+ hbuf->xtiles = ceil(hbuf->x / (float)hbuf->tilex);
+ hbuf->ytiles = ceil(hbuf->y / (float)hbuf->tiley);
+
+ imb_addtilesImBuf(hbuf);
+
+ ibuf->miptot++;
+ }
+ }
+ }
+
+ /* read pixels */
+ if (!(ibuf->flags & IB_tilecache) && !imb_read_tiff_pixels(ibuf, image)) {
+ fprintf(stderr, "imb_loadtiff: Failed to read tiff image.\n");
+ TIFFClose(image);
+ return NULL;
+ }
+
+ /* close the client layer interface to the in-memory file */
+ TIFFClose(image);
+
+ /* return successfully */
+ return ibuf;
}
-void imb_loadtiletiff(ImBuf *ibuf, const unsigned char *mem, size_t size, int tx, int ty, unsigned int *rect)
+void imb_loadtiletiff(
+ ImBuf *ibuf, const unsigned char *mem, size_t size, int tx, int ty, unsigned int *rect)
{
- TIFF *image = NULL;
- uint32 width, height;
- ImbTIFFMemFile memFile;
-
- image = imb_tiff_client_open(&memFile, mem, size);
-
- if (image == NULL) {
- printf("imb_loadtiff: could not open TIFF IO layer for loading mipmap level.\n");
- return;
- }
-
- if (TIFFSetDirectory(image, ibuf->miplevel)) { /* allocate the image buffer */
- TIFFGetField(image, TIFFTAG_IMAGEWIDTH, &width);
- TIFFGetField(image, TIFFTAG_IMAGELENGTH, &height);
-
- if (width == ibuf->x && height == ibuf->y) {
- if (rect) {
- /* tiff pixels are bottom to top, tiles are top to bottom */
- if (TIFFReadRGBATile(image, tx * ibuf->tilex, (ibuf->ytiles - 1 - ty) * ibuf->tiley, rect) == 1) {
- if (ibuf->tiley > ibuf->y)
- memmove(rect, rect + ibuf->tilex * (ibuf->tiley - ibuf->y), sizeof(int) * ibuf->tilex * ibuf->y);
- }
- else
- printf("imb_loadtiff: failed to read tiff tile at mipmap level %d\n", ibuf->miplevel);
- }
- }
- else
- printf("imb_loadtiff: mipmap level %d has unexpected size %ux%u instead of %dx%d\n", ibuf->miplevel, width, height, ibuf->x, ibuf->y);
- }
- else
- printf("imb_loadtiff: could not find mipmap level %d\n", ibuf->miplevel);
-
- /* close the client layer interface to the in-memory file */
- TIFFClose(image);
+ TIFF *image = NULL;
+ uint32 width, height;
+ ImbTIFFMemFile memFile;
+
+ image = imb_tiff_client_open(&memFile, mem, size);
+
+ if (image == NULL) {
+ printf("imb_loadtiff: could not open TIFF IO layer for loading mipmap level.\n");
+ return;
+ }
+
+ if (TIFFSetDirectory(image, ibuf->miplevel)) { /* allocate the image buffer */
+ TIFFGetField(image, TIFFTAG_IMAGEWIDTH, &width);
+ TIFFGetField(image, TIFFTAG_IMAGELENGTH, &height);
+
+ if (width == ibuf->x && height == ibuf->y) {
+ if (rect) {
+ /* tiff pixels are bottom to top, tiles are top to bottom */
+ if (TIFFReadRGBATile(
+ image, tx * ibuf->tilex, (ibuf->ytiles - 1 - ty) * ibuf->tiley, rect) == 1) {
+ if (ibuf->tiley > ibuf->y)
+ memmove(rect,
+ rect + ibuf->tilex * (ibuf->tiley - ibuf->y),
+ sizeof(int) * ibuf->tilex * ibuf->y);
+ }
+ else
+ printf("imb_loadtiff: failed to read tiff tile at mipmap level %d\n", ibuf->miplevel);
+ }
+ }
+ else
+ printf("imb_loadtiff: mipmap level %d has unexpected size %ux%u instead of %dx%d\n",
+ ibuf->miplevel,
+ width,
+ height,
+ ibuf->x,
+ ibuf->y);
+ }
+ else
+ printf("imb_loadtiff: could not find mipmap level %d\n", ibuf->miplevel);
+
+ /* close the client layer interface to the in-memory file */
+ TIFFClose(image);
}
/**
@@ -701,210 +708,202 @@ void imb_loadtiletiff(ImBuf *ibuf, const unsigned char *mem, size_t size, int tx
int imb_savetiff(ImBuf *ibuf, const char *name, int flags)
{
- TIFF *image = NULL;
- uint16 samplesperpixel, bitspersample;
- size_t npixels;
- unsigned char *pixels = NULL;
- unsigned char *from = NULL, *to = NULL;
- unsigned short *pixels16 = NULL, *to16 = NULL;
- float *fromf = NULL;
- float xres, yres;
- int x, y, from_i, to_i, i;
- int compress_mode = COMPRESSION_NONE;
-
- /* check for a valid number of bytes per pixel. Like the PNG writer,
- * the TIFF writer supports 1, 3 or 4 bytes per pixel, corresponding
- * to gray, RGB, RGBA respectively. */
- samplesperpixel = (uint16)((ibuf->planes + 7) >> 3);
- if ((samplesperpixel > 4) || (samplesperpixel == 2)) {
- fprintf(stderr,
- "imb_savetiff: unsupported number of bytes per "
- "pixel: %d\n", samplesperpixel);
- return (0);
- }
-
- if ((ibuf->foptions.flag & TIF_16BIT) && ibuf->rect_float)
- bitspersample = 16;
- else
- bitspersample = 8;
-
- if (ibuf->foptions.flag & TIF_COMPRESS_DEFLATE)
- compress_mode = COMPRESSION_DEFLATE;
- else if (ibuf->foptions.flag & TIF_COMPRESS_LZW)
- compress_mode = COMPRESSION_LZW;
- else if (ibuf->foptions.flag & TIF_COMPRESS_PACKBITS)
- compress_mode = COMPRESSION_PACKBITS;
-
- /* open TIFF file for writing */
- if (flags & IB_mem) {
- /* bork at the creation of a TIFF in memory */
- fprintf(stderr,
- "imb_savetiff: creation of in-memory TIFF files is "
- "not yet supported.\n");
- return (0);
- }
- else {
- /* create image as a file */
+ TIFF *image = NULL;
+ uint16 samplesperpixel, bitspersample;
+ size_t npixels;
+ unsigned char *pixels = NULL;
+ unsigned char *from = NULL, *to = NULL;
+ unsigned short *pixels16 = NULL, *to16 = NULL;
+ float *fromf = NULL;
+ float xres, yres;
+ int x, y, from_i, to_i, i;
+ int compress_mode = COMPRESSION_NONE;
+
+ /* check for a valid number of bytes per pixel. Like the PNG writer,
+ * the TIFF writer supports 1, 3 or 4 bytes per pixel, corresponding
+ * to gray, RGB, RGBA respectively. */
+ samplesperpixel = (uint16)((ibuf->planes + 7) >> 3);
+ if ((samplesperpixel > 4) || (samplesperpixel == 2)) {
+ fprintf(stderr,
+ "imb_savetiff: unsupported number of bytes per "
+ "pixel: %d\n",
+ samplesperpixel);
+ return (0);
+ }
+
+ if ((ibuf->foptions.flag & TIF_16BIT) && ibuf->rect_float)
+ bitspersample = 16;
+ else
+ bitspersample = 8;
+
+ if (ibuf->foptions.flag & TIF_COMPRESS_DEFLATE)
+ compress_mode = COMPRESSION_DEFLATE;
+ else if (ibuf->foptions.flag & TIF_COMPRESS_LZW)
+ compress_mode = COMPRESSION_LZW;
+ else if (ibuf->foptions.flag & TIF_COMPRESS_PACKBITS)
+ compress_mode = COMPRESSION_PACKBITS;
+
+ /* open TIFF file for writing */
+ if (flags & IB_mem) {
+ /* bork at the creation of a TIFF in memory */
+ fprintf(stderr,
+ "imb_savetiff: creation of in-memory TIFF files is "
+ "not yet supported.\n");
+ return (0);
+ }
+ else {
+ /* create image as a file */
#ifdef WIN32
- wchar_t *wname = alloc_utf16_from_8(name, 0);
- image = TIFFOpenW(wname, "w");
- free(wname);
+ wchar_t *wname = alloc_utf16_from_8(name, 0);
+ image = TIFFOpenW(wname, "w");
+ free(wname);
#else
- image = TIFFOpen(name, "w");
+ image = TIFFOpen(name, "w");
#endif
- }
- if (image == NULL) {
- fprintf(stderr,
- "imb_savetiff: could not open TIFF for writing.\n");
- return (0);
- }
-
- /* allocate array for pixel data */
- npixels = ibuf->x * ibuf->y;
- if (bitspersample == 16)
- pixels16 = (unsigned short *)_TIFFmalloc(npixels *
- samplesperpixel * sizeof(unsigned short));
- else
- pixels = (unsigned char *)_TIFFmalloc(npixels *
- samplesperpixel * sizeof(unsigned char));
-
- if (pixels == NULL && pixels16 == NULL) {
- fprintf(stderr,
- "imb_savetiff: could not allocate pixels array.\n");
- TIFFClose(image);
- return (0);
- }
-
- /* setup pointers */
- if (bitspersample == 16) {
- fromf = ibuf->rect_float;
- to16 = pixels16;
- }
- else {
- from = (unsigned char *)ibuf->rect;
- to = pixels;
- }
-
- /* setup samples per pixel */
- TIFFSetField(image, TIFFTAG_BITSPERSAMPLE, bitspersample);
- TIFFSetField(image, TIFFTAG_SAMPLESPERPIXEL, samplesperpixel);
-
- if (samplesperpixel == 4) {
- unsigned short extraSampleTypes[1];
-
- if (bitspersample == 16)
- extraSampleTypes[0] = EXTRASAMPLE_ASSOCALPHA;
- else
- extraSampleTypes[0] = EXTRASAMPLE_UNASSALPHA;
-
- /* RGBA images */
- TIFFSetField(image, TIFFTAG_EXTRASAMPLES, 1,
- extraSampleTypes);
- TIFFSetField(image, TIFFTAG_PHOTOMETRIC,
- PHOTOMETRIC_RGB);
- }
- else if (samplesperpixel == 3) {
- /* RGB images */
- TIFFSetField(image, TIFFTAG_PHOTOMETRIC,
- PHOTOMETRIC_RGB);
- }
- else if (samplesperpixel == 1) {
- /* grayscale images, 1 channel */
- TIFFSetField(image, TIFFTAG_PHOTOMETRIC,
- PHOTOMETRIC_MINISBLACK);
- }
-
- /* copy pixel data. While copying, we flip the image vertically. */
- const int channels_in_float = ibuf->channels ? ibuf->channels : 4;
- for (x = 0; x < ibuf->x; x++) {
- for (y = 0; y < ibuf->y; y++) {
- from_i = ((size_t)channels_in_float) * (y * ibuf->x + x);
- to_i = samplesperpixel * ((ibuf->y - y - 1) * ibuf->x + x);
-
- if (pixels16) {
- /* convert from float source */
- float rgb[4];
-
- if (channels_in_float == 3 || channels_in_float == 4) {
- if (ibuf->float_colorspace ||
- (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA))
- {
- /* Float buffer was managed already, no need in color
- * space conversion.
- */
- copy_v3_v3(rgb, &fromf[from_i]);
- }
- else {
- /* Standard linear-to-srgb conversion if float buffer
- * wasn't managed.
- */
- linearrgb_to_srgb_v3_v3(rgb, &fromf[from_i]);
- }
- if (channels_in_float == 4) {
- rgb[3] = fromf[from_i + 3];
- }
- else {
- rgb[3] = 1.0f;
- }
- }
- else {
- if (ibuf->float_colorspace ||
- (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA))
- {
- rgb[0] = fromf[from_i];
- }
- else {
- rgb[0] = linearrgb_to_srgb(fromf[from_i]);
- }
- rgb[1] = rgb[2] = rgb[0];
- rgb[3] = 1.0f;
- }
-
- for (i = 0; i < samplesperpixel; i++, to_i++)
- to16[to_i] = unit_float_to_ushort_clamp(rgb[i]);
- }
- else {
- for (i = 0; i < samplesperpixel; i++, to_i++, from_i++)
- to[to_i] = from[from_i];
- }
- }
- }
-
- /* write the actual TIFF file */
- TIFFSetField(image, TIFFTAG_IMAGEWIDTH, ibuf->x);
- TIFFSetField(image, TIFFTAG_IMAGELENGTH, ibuf->y);
- TIFFSetField(image, TIFFTAG_ROWSPERSTRIP, ibuf->y);
- TIFFSetField(image, TIFFTAG_COMPRESSION, compress_mode);
- TIFFSetField(image, TIFFTAG_FILLORDER, FILLORDER_MSB2LSB);
- TIFFSetField(image, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
-
-
- if (ibuf->ppm[0] > 0.0 && ibuf->ppm[1] > 0.0) {
- xres = (float)(ibuf->ppm[0] * 0.0254);
- yres = (float)(ibuf->ppm[1] * 0.0254);
- }
- else {
- xres = yres = IMB_DPI_DEFAULT;
- }
-
- TIFFSetField(image, TIFFTAG_XRESOLUTION, xres);
- TIFFSetField(image, TIFFTAG_YRESOLUTION, yres);
- TIFFSetField(image, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);
- if (TIFFWriteEncodedStrip(image, 0,
- (bitspersample == 16) ? (unsigned char *)pixels16 : pixels,
- (size_t)ibuf->x * ibuf->y * samplesperpixel * bitspersample / 8) == -1)
- {
- fprintf(stderr,
- "imb_savetiff: Could not write encoded TIFF.\n");
- TIFFClose(image);
- if (pixels) _TIFFfree(pixels);
- if (pixels16) _TIFFfree(pixels16);
- return (1);
- }
-
- /* close the TIFF file */
- TIFFClose(image);
- if (pixels) _TIFFfree(pixels);
- if (pixels16) _TIFFfree(pixels16);
- return (1);
+ }
+ if (image == NULL) {
+ fprintf(stderr, "imb_savetiff: could not open TIFF for writing.\n");
+ return (0);
+ }
+
+ /* allocate array for pixel data */
+ npixels = ibuf->x * ibuf->y;
+ if (bitspersample == 16)
+ pixels16 = (unsigned short *)_TIFFmalloc(npixels * samplesperpixel * sizeof(unsigned short));
+ else
+ pixels = (unsigned char *)_TIFFmalloc(npixels * samplesperpixel * sizeof(unsigned char));
+
+ if (pixels == NULL && pixels16 == NULL) {
+ fprintf(stderr, "imb_savetiff: could not allocate pixels array.\n");
+ TIFFClose(image);
+ return (0);
+ }
+
+ /* setup pointers */
+ if (bitspersample == 16) {
+ fromf = ibuf->rect_float;
+ to16 = pixels16;
+ }
+ else {
+ from = (unsigned char *)ibuf->rect;
+ to = pixels;
+ }
+
+ /* setup samples per pixel */
+ TIFFSetField(image, TIFFTAG_BITSPERSAMPLE, bitspersample);
+ TIFFSetField(image, TIFFTAG_SAMPLESPERPIXEL, samplesperpixel);
+
+ if (samplesperpixel == 4) {
+ unsigned short extraSampleTypes[1];
+
+ if (bitspersample == 16)
+ extraSampleTypes[0] = EXTRASAMPLE_ASSOCALPHA;
+ else
+ extraSampleTypes[0] = EXTRASAMPLE_UNASSALPHA;
+
+ /* RGBA images */
+ TIFFSetField(image, TIFFTAG_EXTRASAMPLES, 1, extraSampleTypes);
+ TIFFSetField(image, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
+ }
+ else if (samplesperpixel == 3) {
+ /* RGB images */
+ TIFFSetField(image, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
+ }
+ else if (samplesperpixel == 1) {
+ /* grayscale images, 1 channel */
+ TIFFSetField(image, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
+ }
+
+ /* copy pixel data. While copying, we flip the image vertically. */
+ const int channels_in_float = ibuf->channels ? ibuf->channels : 4;
+ for (x = 0; x < ibuf->x; x++) {
+ for (y = 0; y < ibuf->y; y++) {
+ from_i = ((size_t)channels_in_float) * (y * ibuf->x + x);
+ to_i = samplesperpixel * ((ibuf->y - y - 1) * ibuf->x + x);
+
+ if (pixels16) {
+ /* convert from float source */
+ float rgb[4];
+
+ if (channels_in_float == 3 || channels_in_float == 4) {
+ if (ibuf->float_colorspace || (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA)) {
+ /* Float buffer was managed already, no need in color
+ * space conversion.
+ */
+ copy_v3_v3(rgb, &fromf[from_i]);
+ }
+ else {
+ /* Standard linear-to-srgb conversion if float buffer
+ * wasn't managed.
+ */
+ linearrgb_to_srgb_v3_v3(rgb, &fromf[from_i]);
+ }
+ if (channels_in_float == 4) {
+ rgb[3] = fromf[from_i + 3];
+ }
+ else {
+ rgb[3] = 1.0f;
+ }
+ }
+ else {
+ if (ibuf->float_colorspace || (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA)) {
+ rgb[0] = fromf[from_i];
+ }
+ else {
+ rgb[0] = linearrgb_to_srgb(fromf[from_i]);
+ }
+ rgb[1] = rgb[2] = rgb[0];
+ rgb[3] = 1.0f;
+ }
+
+ for (i = 0; i < samplesperpixel; i++, to_i++)
+ to16[to_i] = unit_float_to_ushort_clamp(rgb[i]);
+ }
+ else {
+ for (i = 0; i < samplesperpixel; i++, to_i++, from_i++)
+ to[to_i] = from[from_i];
+ }
+ }
+ }
+
+ /* write the actual TIFF file */
+ TIFFSetField(image, TIFFTAG_IMAGEWIDTH, ibuf->x);
+ TIFFSetField(image, TIFFTAG_IMAGELENGTH, ibuf->y);
+ TIFFSetField(image, TIFFTAG_ROWSPERSTRIP, ibuf->y);
+ TIFFSetField(image, TIFFTAG_COMPRESSION, compress_mode);
+ TIFFSetField(image, TIFFTAG_FILLORDER, FILLORDER_MSB2LSB);
+ TIFFSetField(image, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
+
+ if (ibuf->ppm[0] > 0.0 && ibuf->ppm[1] > 0.0) {
+ xres = (float)(ibuf->ppm[0] * 0.0254);
+ yres = (float)(ibuf->ppm[1] * 0.0254);
+ }
+ else {
+ xres = yres = IMB_DPI_DEFAULT;
+ }
+
+ TIFFSetField(image, TIFFTAG_XRESOLUTION, xres);
+ TIFFSetField(image, TIFFTAG_YRESOLUTION, yres);
+ TIFFSetField(image, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);
+ if (TIFFWriteEncodedStrip(image,
+ 0,
+ (bitspersample == 16) ? (unsigned char *)pixels16 : pixels,
+ (size_t)ibuf->x * ibuf->y * samplesperpixel * bitspersample / 8) ==
+ -1) {
+ fprintf(stderr, "imb_savetiff: Could not write encoded TIFF.\n");
+ TIFFClose(image);
+ if (pixels)
+ _TIFFfree(pixels);
+ if (pixels16)
+ _TIFFfree(pixels16);
+ return (1);
+ }
+
+ /* close the TIFF file */
+ TIFFClose(image);
+ if (pixels)
+ _TIFFfree(pixels);
+ if (pixels16)
+ _TIFFfree(pixels16);
+ return (1);
}
diff --git a/source/blender/imbuf/intern/util.c b/source/blender/imbuf/intern/util.c
index ba541dc6e91..50aaa16c3fe 100644
--- a/source/blender/imbuf/intern/util.c
+++ b/source/blender/imbuf/intern/util.c
@@ -22,7 +22,6 @@
* \ingroup imbuf
*/
-
#ifdef _WIN32
# include <io.h>
#endif
@@ -41,9 +40,9 @@
#include "IMB_anim.h"
#ifdef WITH_FFMPEG
-# include "BLI_string.h" /* BLI_vsnprintf */
+# include "BLI_string.h" /* BLI_vsnprintf */
-# include "BKE_global.h" /* G.debug */
+# include "BKE_global.h" /* G.debug */
# include <libavcodec/avcodec.h>
# include <libavformat/avformat.h>
@@ -56,338 +55,327 @@
#define UTIL_DEBUG 0
const char *imb_ext_image[] = {
- ".png",
- ".tga",
- ".bmp",
- ".jpg", ".jpeg",
- ".sgi", ".rgb", ".rgba",
+ ".png", ".tga", ".bmp", ".jpg", ".jpeg", ".sgi", ".rgb", ".rgba",
#ifdef WITH_TIFF
- ".tif", ".tiff", ".tx",
+ ".tif", ".tiff", ".tx",
#endif
#ifdef WITH_OPENJPEG
- ".jp2",
- ".j2c",
+ ".jp2", ".j2c",
#endif
#ifdef WITH_HDR
- ".hdr",
+ ".hdr",
#endif
#ifdef WITH_DDS
- ".dds",
+ ".dds",
#endif
#ifdef WITH_CINEON
- ".dpx",
- ".cin",
+ ".dpx", ".cin",
#endif
#ifdef WITH_OPENEXR
- ".exr",
+ ".exr",
#endif
#ifdef WITH_OPENIMAGEIO
- ".psd", ".pdd", ".psb",
+ ".psd", ".pdd", ".psb",
#endif
- NULL,
+ NULL,
};
const char *imb_ext_image_filepath_only[] = {
#ifdef WITH_OPENIMAGEIO
- ".psd", ".pdd", ".psb",
+ ".psd",
+ ".pdd",
+ ".psb",
#endif
- NULL,
+ NULL,
};
const char *imb_ext_movie[] = {
- ".avi",
- ".flc",
- ".mov",
- ".movie",
- ".mp4",
- ".m4v",
- ".m2v",
- ".m2t",
- ".m2ts",
- ".mts",
- ".ts",
- ".mv",
- ".avs",
- ".wmv",
- ".ogv",
- ".ogg",
- ".r3d",
- ".dv",
- ".mpeg",
- ".mpg",
- ".mpg2",
- ".vob",
- ".mkv",
- ".flv",
- ".divx",
- ".xvid",
- ".mxf",
- ".webm",
- NULL,
+ ".avi", ".flc", ".mov", ".movie", ".mp4", ".m4v", ".m2v", ".m2t", ".m2ts", ".mts",
+ ".ts", ".mv", ".avs", ".wmv", ".ogv", ".ogg", ".r3d", ".dv", ".mpeg", ".mpg",
+ ".mpg2", ".vob", ".mkv", ".flv", ".divx", ".xvid", ".mxf", ".webm", NULL,
};
/* sort of wrong being here... */
const char *imb_ext_audio[] = {
- ".wav",
- ".ogg",
- ".oga",
- ".mp3",
- ".mp2",
- ".ac3",
- ".aac",
- ".flac",
- ".wma",
- ".eac3",
- ".aif",
- ".aiff",
- ".m4a",
- ".mka",
- NULL,
+ ".wav",
+ ".ogg",
+ ".oga",
+ ".mp3",
+ ".mp2",
+ ".ac3",
+ ".aac",
+ ".flac",
+ ".wma",
+ ".eac3",
+ ".aif",
+ ".aiff",
+ ".m4a",
+ ".mka",
+ NULL,
};
int IMB_ispic_type(const char *name)
{
- /* increased from 32 to 64 because of the bitmaps header size */
+ /* increased from 32 to 64 because of the bitmaps header size */
#define HEADER_SIZE 64
- unsigned char buf[HEADER_SIZE];
- const ImFileType *type;
- BLI_stat_t st;
- int fp;
+ unsigned char buf[HEADER_SIZE];
+ const ImFileType *type;
+ BLI_stat_t st;
+ int fp;
- BLI_assert(!BLI_path_is_rel(name));
+ BLI_assert(!BLI_path_is_rel(name));
- if (UTIL_DEBUG) printf("%s: loading %s\n", __func__, name);
+ if (UTIL_DEBUG)
+ printf("%s: loading %s\n", __func__, name);
- if (BLI_stat(name, &st) == -1)
- return false;
- if (((st.st_mode) & S_IFMT) != S_IFREG)
- return false;
+ if (BLI_stat(name, &st) == -1)
+ return false;
+ if (((st.st_mode) & S_IFMT) != S_IFREG)
+ return false;
- if ((fp = BLI_open(name, O_BINARY | O_RDONLY, 0)) == -1)
- return false;
+ if ((fp = BLI_open(name, O_BINARY | O_RDONLY, 0)) == -1)
+ return false;
- memset(buf, 0, sizeof(buf));
- if (read(fp, buf, HEADER_SIZE) <= 0) {
- close(fp);
- return false;
- }
+ memset(buf, 0, sizeof(buf));
+ if (read(fp, buf, HEADER_SIZE) <= 0) {
+ close(fp);
+ return false;
+ }
- close(fp);
+ close(fp);
- /* XXX move this exception */
- if ((BIG_LONG(((int *)buf)[0]) & 0xfffffff0) == 0xffd8ffe0)
- return IMB_FTYPE_JPG;
+ /* XXX move this exception */
+ if ((BIG_LONG(((int *)buf)[0]) & 0xfffffff0) == 0xffd8ffe0)
+ return IMB_FTYPE_JPG;
- for (type = IMB_FILE_TYPES; type < IMB_FILE_TYPES_LAST; type++) {
- if (type->is_a) {
- if (type->is_a(buf)) {
- return type->filetype;
- }
- }
- else if (type->is_a_filepath) {
- if (type->is_a_filepath(name)) {
- return type->filetype;
- }
- }
- }
+ for (type = IMB_FILE_TYPES; type < IMB_FILE_TYPES_LAST; type++) {
+ if (type->is_a) {
+ if (type->is_a(buf)) {
+ return type->filetype;
+ }
+ }
+ else if (type->is_a_filepath) {
+ if (type->is_a_filepath(name)) {
+ return type->filetype;
+ }
+ }
+ }
- return 0;
+ return 0;
#undef HEADER_SIZE
}
bool IMB_ispic(const char *name)
{
- return (IMB_ispic_type(name) != 0);
+ return (IMB_ispic_type(name) != 0);
}
static int isavi(const char *name)
{
#ifdef WITH_AVI
- return AVI_is_avi(name);
+ return AVI_is_avi(name);
#else
- (void)name;
- return false;
+ (void)name;
+ return false;
#endif
}
#ifdef WITH_FFMPEG
/* BLI_vsnprintf in ffmpeg_log_callback() causes invalid warning */
-#ifdef __GNUC__
-# pragma GCC diagnostic push
-# pragma GCC diagnostic ignored "-Wmissing-format-attribute"
-#endif
+# ifdef __GNUC__
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wmissing-format-attribute"
+# endif
static char ffmpeg_last_error[1024];
static void ffmpeg_log_callback(void *ptr, int level, const char *format, va_list arg)
{
- if (ELEM(level, AV_LOG_FATAL, AV_LOG_ERROR)) {
- size_t n;
- va_list args_cpy;
-
- va_copy(args_cpy, arg);
- n = BLI_vsnprintf(ffmpeg_last_error, sizeof(ffmpeg_last_error), format, args_cpy);
- va_end(args_cpy);
-
- /* strip trailing \n */
- ffmpeg_last_error[n - 1] = '\0';
- }
-
- if (G.debug & G_DEBUG_FFMPEG) {
- /* call default logger to print all message to console */
- av_log_default_callback(ptr, level, format, arg);
- }
+ if (ELEM(level, AV_LOG_FATAL, AV_LOG_ERROR)) {
+ size_t n;
+ va_list args_cpy;
+
+ va_copy(args_cpy, arg);
+ n = BLI_vsnprintf(ffmpeg_last_error, sizeof(ffmpeg_last_error), format, args_cpy);
+ va_end(args_cpy);
+
+ /* strip trailing \n */
+ ffmpeg_last_error[n - 1] = '\0';
+ }
+
+ if (G.debug & G_DEBUG_FFMPEG) {
+ /* call default logger to print all message to console */
+ av_log_default_callback(ptr, level, format, arg);
+ }
}
-#ifdef __GNUC__
-# pragma GCC diagnostic pop
-#endif
+# ifdef __GNUC__
+# pragma GCC diagnostic pop
+# endif
void IMB_ffmpeg_init(void)
{
- av_register_all();
- avdevice_register_all();
+ av_register_all();
+ avdevice_register_all();
- ffmpeg_last_error[0] = '\0';
+ ffmpeg_last_error[0] = '\0';
- if (G.debug & G_DEBUG_FFMPEG)
- av_log_set_level(AV_LOG_DEBUG);
+ if (G.debug & G_DEBUG_FFMPEG)
+ av_log_set_level(AV_LOG_DEBUG);
- /* set own callback which could store last error to report to UI */
- av_log_set_callback(ffmpeg_log_callback);
+ /* set own callback which could store last error to report to UI */
+ av_log_set_callback(ffmpeg_log_callback);
}
const char *IMB_ffmpeg_last_error(void)
{
- return ffmpeg_last_error;
+ return ffmpeg_last_error;
}
static int isffmpeg(const char *filename)
{
- AVFormatContext *pFormatCtx = NULL;
- unsigned int i;
- int videoStream;
- AVCodec *pCodec;
- AVCodecContext *pCodecCtx;
-
- if (BLI_path_extension_check_n(
- filename,
- ".swf", ".jpg", ".png", ".dds", ".tga", ".bmp", ".tif", ".exr", ".cin", ".wav", NULL))
- {
- return 0;
- }
-
- if (avformat_open_input(&pFormatCtx, filename, NULL, NULL) != 0) {
- if (UTIL_DEBUG) fprintf(stderr, "isffmpeg: av_open_input_file failed\n");
- return 0;
- }
-
- if (avformat_find_stream_info(pFormatCtx, NULL) < 0) {
- if (UTIL_DEBUG) fprintf(stderr, "isffmpeg: avformat_find_stream_info failed\n");
- avformat_close_input(&pFormatCtx);
- return 0;
- }
-
- if (UTIL_DEBUG) av_dump_format(pFormatCtx, 0, filename, 0);
-
-
- /* Find the first video stream */
- videoStream = -1;
- for (i = 0; i < pFormatCtx->nb_streams; i++)
- if (pFormatCtx->streams[i] &&
- pFormatCtx->streams[i]->codec &&
- (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO))
- {
- videoStream = i;
- break;
- }
-
- if (videoStream == -1) {
- avformat_close_input(&pFormatCtx);
- return 0;
- }
-
- pCodecCtx = pFormatCtx->streams[videoStream]->codec;
-
- /* Find the decoder for the video stream */
- pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
- if (pCodec == NULL) {
- avformat_close_input(&pFormatCtx);
- return 0;
- }
-
- if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0) {
- avformat_close_input(&pFormatCtx);
- return 0;
- }
-
- avcodec_close(pCodecCtx);
- avformat_close_input(&pFormatCtx);
-
- return 1;
+ AVFormatContext *pFormatCtx = NULL;
+ unsigned int i;
+ int videoStream;
+ AVCodec *pCodec;
+ AVCodecContext *pCodecCtx;
+
+ if (BLI_path_extension_check_n(filename,
+ ".swf",
+ ".jpg",
+ ".png",
+ ".dds",
+ ".tga",
+ ".bmp",
+ ".tif",
+ ".exr",
+ ".cin",
+ ".wav",
+ NULL)) {
+ return 0;
+ }
+
+ if (avformat_open_input(&pFormatCtx, filename, NULL, NULL) != 0) {
+ if (UTIL_DEBUG)
+ fprintf(stderr, "isffmpeg: av_open_input_file failed\n");
+ return 0;
+ }
+
+ if (avformat_find_stream_info(pFormatCtx, NULL) < 0) {
+ if (UTIL_DEBUG)
+ fprintf(stderr, "isffmpeg: avformat_find_stream_info failed\n");
+ avformat_close_input(&pFormatCtx);
+ return 0;
+ }
+
+ if (UTIL_DEBUG)
+ av_dump_format(pFormatCtx, 0, filename, 0);
+
+ /* Find the first video stream */
+ videoStream = -1;
+ for (i = 0; i < pFormatCtx->nb_streams; i++)
+ if (pFormatCtx->streams[i] && pFormatCtx->streams[i]->codec &&
+ (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)) {
+ videoStream = i;
+ break;
+ }
+
+ if (videoStream == -1) {
+ avformat_close_input(&pFormatCtx);
+ return 0;
+ }
+
+ pCodecCtx = pFormatCtx->streams[videoStream]->codec;
+
+ /* Find the decoder for the video stream */
+ pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
+ if (pCodec == NULL) {
+ avformat_close_input(&pFormatCtx);
+ return 0;
+ }
+
+ if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0) {
+ avformat_close_input(&pFormatCtx);
+ return 0;
+ }
+
+ avcodec_close(pCodecCtx);
+ avformat_close_input(&pFormatCtx);
+
+ return 1;
}
#endif
int imb_get_anim_type(const char *name)
{
- int type;
- BLI_stat_t st;
+ int type;
+ BLI_stat_t st;
- BLI_assert(!BLI_path_is_rel(name));
+ BLI_assert(!BLI_path_is_rel(name));
- if (UTIL_DEBUG) printf("%s: %s\n", __func__, name);
+ if (UTIL_DEBUG)
+ printf("%s: %s\n", __func__, name);
#ifndef _WIN32
-# ifdef WITH_FFMPEG
- /* stat test below fails on large files > 4GB */
- if (isffmpeg(name)) return (ANIM_FFMPEG);
-# endif
- if (BLI_stat(name, &st) == -1) return(0);
- if (((st.st_mode) & S_IFMT) != S_IFREG) return(0);
-
- if (isavi(name)) return (ANIM_AVI);
-
- if (ismovie(name)) return (ANIM_MOVIE);
+# ifdef WITH_FFMPEG
+ /* stat test below fails on large files > 4GB */
+ if (isffmpeg(name))
+ return (ANIM_FFMPEG);
+# endif
+ if (BLI_stat(name, &st) == -1)
+ return (0);
+ if (((st.st_mode) & S_IFMT) != S_IFREG)
+ return (0);
+
+ if (isavi(name))
+ return (ANIM_AVI);
+
+ if (ismovie(name))
+ return (ANIM_MOVIE);
#else
- if (BLI_stat(name, &st) == -1) return(0);
- if (((st.st_mode) & S_IFMT) != S_IFREG) return(0);
-
- if (ismovie(name)) return (ANIM_MOVIE);
-# ifdef WITH_FFMPEG
- if (isffmpeg(name)) return (ANIM_FFMPEG);
-# endif
-
-
- if (isavi(name)) return (ANIM_AVI);
+ if (BLI_stat(name, &st) == -1)
+ return (0);
+ if (((st.st_mode) & S_IFMT) != S_IFREG)
+ return (0);
+
+ if (ismovie(name))
+ return (ANIM_MOVIE);
+# ifdef WITH_FFMPEG
+ if (isffmpeg(name))
+ return (ANIM_FFMPEG);
+# endif
+
+ if (isavi(name))
+ return (ANIM_AVI);
#endif
- type = IMB_ispic(name);
- if (type) {
- return ANIM_SEQUENCE;
- }
+ type = IMB_ispic(name);
+ if (type) {
+ return ANIM_SEQUENCE;
+ }
- return ANIM_NONE;
+ return ANIM_NONE;
}
bool IMB_isanim(const char *filename)
{
- int type;
+ int type;
- type = imb_get_anim_type(filename);
+ type = imb_get_anim_type(filename);
- return (type && type != ANIM_SEQUENCE);
+ return (type && type != ANIM_SEQUENCE);
}
bool IMB_isfloat(ImBuf *ibuf)
{
- const ImFileType *type;
-
- for (type = IMB_FILE_TYPES; type < IMB_FILE_TYPES_LAST; type++) {
- if (type->ftype(type, ibuf)) {
- return (type->flag & IM_FTYPE_FLOAT) != 0;
- }
- }
- return false;
+ const ImFileType *type;
+
+ for (type = IMB_FILE_TYPES; type < IMB_FILE_TYPES_LAST; type++) {
+ if (type->ftype(type, ibuf)) {
+ return (type->flag & IM_FTYPE_FLOAT) != 0;
+ }
+ }
+ return false;
}
diff --git a/source/blender/imbuf/intern/writeimage.c b/source/blender/imbuf/intern/writeimage.c
index d6f2f801725..e93df7b73ba 100644
--- a/source/blender/imbuf/intern/writeimage.c
+++ b/source/blender/imbuf/intern/writeimage.c
@@ -22,7 +22,6 @@
* \ingroup imbuf
*/
-
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
@@ -39,53 +38,54 @@
static bool prepare_write_imbuf(const ImFileType *type, ImBuf *ibuf)
{
- return IMB_prepare_write_ImBuf((type->flag & IM_FTYPE_FLOAT), ibuf);
+ return IMB_prepare_write_ImBuf((type->flag & IM_FTYPE_FLOAT), ibuf);
}
short IMB_saveiff(struct ImBuf *ibuf, const char *name, int flags)
{
- const ImFileType *type;
+ const ImFileType *type;
- errno = 0;
+ errno = 0;
- BLI_assert(!BLI_path_is_rel(name));
+ BLI_assert(!BLI_path_is_rel(name));
- if (ibuf == NULL) return (false);
- ibuf->flags = flags;
+ if (ibuf == NULL)
+ return (false);
+ ibuf->flags = flags;
- for (type = IMB_FILE_TYPES; type < IMB_FILE_TYPES_LAST; type++) {
- if (type->save && type->ftype(type, ibuf)) {
- short result = false;
+ for (type = IMB_FILE_TYPES; type < IMB_FILE_TYPES_LAST; type++) {
+ if (type->save && type->ftype(type, ibuf)) {
+ short result = false;
- prepare_write_imbuf(type, ibuf);
+ prepare_write_imbuf(type, ibuf);
- result = type->save(ibuf, name, flags);
+ result = type->save(ibuf, name, flags);
- return result;
- }
- }
+ return result;
+ }
+ }
- fprintf(stderr, "Couldn't save picture.\n");
+ fprintf(stderr, "Couldn't save picture.\n");
- return false;
+ return false;
}
bool IMB_prepare_write_ImBuf(const bool isfloat, ImBuf *ibuf)
{
- bool changed = false;
-
- if (isfloat) {
- /* pass */
- }
- else {
- if (ibuf->rect == NULL && ibuf->rect_float) {
- ibuf->rect_colorspace = colormanage_colorspace_get_roled(COLOR_ROLE_DEFAULT_BYTE);
- IMB_rect_from_float(ibuf);
- if (ibuf->rect != NULL) {
- changed = true;
- }
- }
- }
-
- return changed;
+ bool changed = false;
+
+ if (isfloat) {
+ /* pass */
+ }
+ else {
+ if (ibuf->rect == NULL && ibuf->rect_float) {
+ ibuf->rect_colorspace = colormanage_colorspace_get_roled(COLOR_ROLE_DEFAULT_BYTE);
+ IMB_rect_from_float(ibuf);
+ if (ibuf->rect != NULL) {
+ changed = true;
+ }
+ }
+ }
+
+ return changed;
}