diff options
Diffstat (limited to 'source/blender/imbuf')
31 files changed, 694 insertions, 540 deletions
diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h index 839b0b12b83..957352595ed 100644 --- a/source/blender/imbuf/IMB_imbuf.h +++ b/source/blender/imbuf/IMB_imbuf.h @@ -466,27 +466,29 @@ void IMB_scaleImBuf_threaded(struct ImBuf *ibuf, unsigned int newx, unsigned int * * \attention Defined in writeimage.c */ -short IMB_saveiff(struct ImBuf *ibuf, const char *filepath, int flags); +bool IMB_saveiff(struct ImBuf *ibuf, const char *filepath, int flags); 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); +bool IMB_ispic(const char *filepath); +bool IMB_ispic_type_matches(const char *filepath, int filetype); +int IMB_ispic_type_from_memory(const unsigned char *buf, const size_t buf_size); +int IMB_ispic_type(const char *filepath); /** * * \attention Defined in util.c */ -bool IMB_isanim(const char *name); +bool IMB_isanim(const char *filepath); /** * * \attention Defined in util.c */ -int imb_get_anim_type(const char *name); +int imb_get_anim_type(const char *filepath); /** * @@ -684,6 +686,8 @@ void IMB_rectfill_area(struct ImBuf *ibuf, int x2, int y2, struct ColorManagedDisplay *display); +void IMB_rectfill_area_replace( + const struct ImBuf *ibuf, const float col[4], int x1, int y1, int x2, int y2); void IMB_rectfill_alpha(struct ImBuf *ibuf, const float value); /* This should not be here, really, diff --git a/source/blender/imbuf/IMB_imbuf_types.h b/source/blender/imbuf/IMB_imbuf_types.h index 98e9c34a4ff..4bb3ea500fa 100644 --- a/source/blender/imbuf/IMB_imbuf_types.h +++ b/source/blender/imbuf/IMB_imbuf_types.h @@ -69,7 +69,7 @@ typedef struct DDSData { * See T46524. */ /** #ImBuf.ftype flag, main image types. */ -enum eImbTypes { +enum eImbFileType { IMB_FTYPE_PNG = 1, IMB_FTYPE_TGA = 2, IMB_FTYPE_JPG = 3, @@ -98,6 +98,9 @@ enum eImbTypes { #endif }; +/* Only for readability. */ +#define IMB_FTYPE_NONE 0 + /* ibuf->foptions flag, type specific options. * Some formats include compression rations on some bits */ @@ -243,7 +246,7 @@ typedef struct ImBuf { /* file information */ /** file type we are going to save as */ - enum eImbTypes ftype; + enum eImbFileType ftype; /** file format specific flags */ ImbFormatOptions foptions; /** filename associated with this image */ diff --git a/source/blender/imbuf/intern/IMB_filetype.h b/source/blender/imbuf/intern/IMB_filetype.h index 93a3a98c3d1..c8f6135f330 100644 --- a/source/blender/imbuf/intern/IMB_filetype.h +++ b/source/blender/imbuf/intern/IMB_filetype.h @@ -29,18 +29,27 @@ struct ImBuf; #define IM_FTYPE_FLOAT 1 typedef struct ImFileType { + /** Optional, called once when initializing. */ void (*init)(void); + /** Optional, called once when exiting. */ void (*exit)(void); - int (*is_a)(const unsigned char *buf); - int (*is_a_filepath)(const char *filepath); - int (*ftype)(const struct ImFileType *type, const struct ImBuf *ibuf); + /** + * Check if the data matches this file types 'magic', + * \note that this may only read in a small part of the files header, + * see: #IMB_ispic_type for details. + */ + bool (*is_a)(const unsigned char *buf, const size_t size); + + /** Load an image from memory. */ struct ImBuf *(*load)(const unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE]); + /** Load an image from a file. */ struct ImBuf *(*load_filepath)(const char *filepath, int flags, char colorspace[IM_MAX_SPACE]); - int (*save)(struct ImBuf *ibuf, const char *filepath, int flags); + /** Save to a file (or memory if #IB_mem is set in `flags` and the format supports it). */ + bool (*save)(struct ImBuf *ibuf, const char *filepath, int flags); void (*load_tile)(struct ImBuf *ibuf, const unsigned char *mem, size_t size, @@ -49,13 +58,19 @@ typedef struct ImFileType { unsigned int *rect); int flag; + + /** #eImbFileType */ int filetype; + int default_save_role; } ImFileType; extern const ImFileType IMB_FILE_TYPES[]; extern const ImFileType *IMB_FILE_TYPES_LAST; +const ImFileType *IMB_file_type_from_ftype(int ftype); +const ImFileType *IMB_file_type_from_ibuf(const struct ImBuf *ibuf); + void imb_filetypes_init(void); void imb_filetypes_exit(void); @@ -68,31 +83,31 @@ void imb_tile_cache_tile_free(struct ImBuf *ibuf, int tx, int ty); /* Type Specific Functions */ /* png */ -int imb_is_a_png(const unsigned char *mem); +bool imb_is_a_png(const unsigned char *mem, const size_t size); 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 *filepath, int flags); +bool imb_savepng(struct ImBuf *ibuf, const char *filepath, int flags); /* targa */ -int imb_is_a_targa(const unsigned char *buf); +bool imb_is_a_targa(const unsigned char *buf, const size_t size); 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 *filepath, int flags); +bool imb_savetarga(struct ImBuf *ibuf, const char *filepath, int flags); /* iris */ -int imb_is_a_iris(const unsigned char *mem); +bool imb_is_a_iris(const unsigned char *mem, const size_t size); 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 *filepath, int flags); +bool imb_saveiris(struct ImBuf *ibuf, const char *filepath, int flags); /* jp2 */ -int imb_is_a_jp2(const unsigned char *buf); +bool imb_is_a_jp2(const unsigned char *buf, const size_t size); struct ImBuf *imb_load_jp2(const unsigned char *mem, size_t size, int flags, @@ -100,55 +115,55 @@ struct ImBuf *imb_load_jp2(const unsigned char *mem, struct ImBuf *imb_load_jp2_filepath(const char *filepath, int flags, char colorspace[IM_MAX_SPACE]); -int imb_save_jp2(struct ImBuf *ibuf, const char *filepath, int flags); +bool imb_save_jp2(struct ImBuf *ibuf, const char *filepath, int flags); /* jpeg */ -int imb_is_a_jpeg(const unsigned char *mem); -int imb_savejpeg(struct ImBuf *ibuf, const char *filepath, int flags); +bool imb_is_a_jpeg(const unsigned char *mem, const size_t size); +bool imb_savejpeg(struct ImBuf *ibuf, const char *filepath, int flags); 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); +bool imb_is_a_bmp(const unsigned char *buf, const size_t size); 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 *filepath, int flags); +bool imb_savebmp(struct ImBuf *ibuf, const char *filepath, int flags); /* cineon */ -int imb_is_cineon(const unsigned char *buf); -int imb_save_cineon(struct ImBuf *buf, const char *filepath, int flags); +bool imb_is_a_cineon(const unsigned char *buf, const size_t size); +bool imb_save_cineon(struct ImBuf *buf, const char *filepath, int flags); 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 *filepath, int flags); +bool imb_is_a_dpx(const unsigned char *buf, const size_t size); +bool imb_save_dpx(struct ImBuf *buf, const char *filepath, int flags); 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); +bool imb_is_a_hdr(const unsigned char *buf, const size_t size); 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 *filepath, int flags); +bool imb_savehdr(struct ImBuf *ibuf, const char *filepath, int flags); /* tiff */ void imb_inittiff(void); -int imb_is_a_tiff(const unsigned char *buf); +bool imb_is_a_tiff(const unsigned char *buf, const size_t size); 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 *filepath, int flags); +bool imb_savetiff(struct ImBuf *ibuf, const char *filepath, int flags); diff --git a/source/blender/imbuf/intern/bmp.c b/source/blender/imbuf/intern/bmp.c index ab818d451d6..58ce02f28ae 100644 --- a/source/blender/imbuf/intern/bmp.c +++ b/source/blender/imbuf/intern/bmp.c @@ -72,43 +72,43 @@ typedef struct BMPHEADER { CHECK_HEADER_FIELD(_mem, "CI") || CHECK_HEADER_FIELD(_mem, "CP") || \ CHECK_HEADER_FIELD(_mem, "IC") || CHECK_HEADER_FIELD(_mem, "PT")) -static int checkbmp(const uchar *mem) +static bool checkbmp(const uchar *mem, const size_t size) { + if (size < BMP_FILEHEADER_SIZE) { + return false; + } + + if (!CHECK_HEADER_FIELD_BMP(mem)) { + return false; + } - int ret_val = 0; + bool ok = false; BMPINFOHEADER bmi; uint u; - if (mem) { - if (CHECK_HEADER_FIELD_BMP(mem)) { - /* skip fileheader */ - mem += BMP_FILEHEADER_SIZE; - } - else { - return 0; - } + /* skip fileheader */ + mem += BMP_FILEHEADER_SIZE; - /* for systems where an int needs to be 4 bytes aligned */ - memcpy(&bmi, mem, sizeof(bmi)); + /* 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; - } + 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) { + ok = true; } } } - return ret_val; + return ok; } -int imb_is_a_bmp(const uchar *buf) +bool imb_is_a_bmp(const uchar *buf, size_t size) { - return checkbmp(buf); + return checkbmp(buf, size); } ImBuf *imb_bmp_decode(const uchar *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE]) @@ -124,7 +124,7 @@ ImBuf *imb_bmp_decode(const uchar *mem, size_t size, int flags, char colorspace[ (void)size; /* unused */ - if (checkbmp(mem) == 0) { + if (checkbmp(mem, size) == 0) { return NULL; } @@ -296,12 +296,12 @@ static int putShortLSB(ushort us, FILE *ofile) } /* Found write info at http://users.ece.gatech.edu/~slabaugh/personal/c/bitmapUnix.c */ -int imb_savebmp(ImBuf *ibuf, const char *filepath, int UNUSED(flags)) +bool imb_savebmp(ImBuf *ibuf, const char *filepath, int UNUSED(flags)) { BMPINFOHEADER infoheader; const size_t bytes_per_pixel = (ibuf->planes + 7) >> 3; - BLI_assert(bytes_per_pixel == 1 || bytes_per_pixel == 3); + BLI_assert(ELEM(bytes_per_pixel, 1, 3)); const size_t pad_bytes_per_scanline = (4 - ibuf->x * bytes_per_pixel % 4) % 4; const size_t bytesize = (ibuf->x * bytes_per_pixel + pad_bytes_per_scanline) * ibuf->y; diff --git a/source/blender/imbuf/intern/cineon/cineon_dpx.c b/source/blender/imbuf/intern/cineon/cineon_dpx.c index eeccadf56c1..de54e6dab9d 100644 --- a/source/blender/imbuf/intern/cineon/cineon_dpx.c +++ b/source/blender/imbuf/intern/cineon/cineon_dpx.c @@ -183,14 +183,14 @@ static int imb_save_dpx_cineon(ImBuf *ibuf, const char *filename, int use_cineon return rvalue; } -int imb_save_cineon(struct ImBuf *buf, const char *filepath, int flags) +bool imb_save_cineon(struct ImBuf *buf, const char *filepath, int flags) { return imb_save_dpx_cineon(buf, filepath, 1, flags); } -int imb_is_cineon(const unsigned char *buf) +bool imb_is_a_cineon(const unsigned char *buf, size_t size) { - return logImageIsCineon(buf); + return logImageIsCineon(buf, size); } ImBuf *imb_load_cineon(const unsigned char *mem, @@ -198,20 +198,20 @@ ImBuf *imb_load_cineon(const unsigned char *mem, int flags, char colorspace[IM_MAX_SPACE]) { - if (imb_is_cineon(mem)) { + if (imb_is_a_cineon(mem, size)) { return imb_load_dpx_cineon(mem, size, 1, flags, colorspace); } return NULL; } -int imb_save_dpx(struct ImBuf *buf, const char *filepath, int flags) +bool imb_save_dpx(struct ImBuf *buf, const char *filepath, int flags) { return imb_save_dpx_cineon(buf, filepath, 0, flags); } -int imb_is_dpx(const unsigned char *buf) +bool imb_is_a_dpx(const unsigned char *buf, size_t size) { - return logImageIsDpx(buf); + return logImageIsDpx(buf, size); } ImBuf *imb_load_dpx(const unsigned char *mem, @@ -219,7 +219,7 @@ ImBuf *imb_load_dpx(const unsigned char *mem, int flags, char colorspace[IM_MAX_SPACE]) { - if (imb_is_dpx(mem)) { + if (imb_is_a_dpx(mem, size)) { return imb_load_dpx_cineon(mem, size, 0, flags, colorspace); } return NULL; diff --git a/source/blender/imbuf/intern/cineon/dpxlib.c b/source/blender/imbuf/intern/cineon/dpxlib.c index 73003265d8d..b7a15812547 100644 --- a/source/blender/imbuf/intern/cineon/dpxlib.c +++ b/source/blender/imbuf/intern/cineon/dpxlib.c @@ -277,9 +277,7 @@ LogImageFile *dpxOpen(const unsigned char *byteStuff, int fromMemory, size_t buf } 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 (!ELEM(dpx->element[i].bitsPerSample, 1, 8, 10, 12, 16)) { if (verbose) { printf("DPX: Unsupported bitsPerSample for elements %d: %d\n", i, @@ -348,8 +346,7 @@ LogImageFile *dpxOpen(const unsigned char *byteStuff, int fromMemory, size_t buf 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) { + if (ELEM(dpx->element[i].transfer, transfer_PrintingDensity, transfer_Logarithmic)) { dpx->element[i].refHighQuantity = 2.048f; } else { diff --git a/source/blender/imbuf/intern/cineon/logImageCore.c b/source/blender/imbuf/intern/cineon/logImageCore.c index 446f360a3e7..2d42609fdf5 100644 --- a/source/blender/imbuf/intern/cineon/logImageCore.c +++ b/source/blender/imbuf/intern/cineon/logImageCore.c @@ -96,15 +96,23 @@ void logImageSetVerbose(int verbosity) * IO stuff */ -int logImageIsDpx(const void *buffer) +int logImageIsDpx(const void *buffer, const unsigned int size) { - unsigned int magicNum = *(unsigned int *)buffer; + unsigned int magicNum; + if (size < sizeof(magicNum)) { + return 0; + } + magicNum = *(unsigned int *)buffer; return (magicNum == DPX_FILE_MAGIC || magicNum == swap_uint(DPX_FILE_MAGIC, 1)); } -int logImageIsCineon(const void *buffer) +int logImageIsCineon(const void *buffer, const unsigned int size) { - unsigned int magicNum = *(unsigned int *)buffer; + unsigned int magicNum; + if (size < sizeof(magicNum)) { + return 0; + } + magicNum = *(unsigned int *)buffer; return (magicNum == CINEON_FILE_MAGIC || magicNum == swap_uint(CINEON_FILE_MAGIC, 1)); } @@ -119,17 +127,17 @@ LogImageFile *logImageOpenFromFile(const char *filename, int cineon) return NULL; } - if (fread(&magicNum, sizeof(unsigned int), 1, f) != 1) { + if (fread(&magicNum, sizeof(magicNum), 1, f) != 1) { fclose(f); return NULL; } fclose(f); - if (logImageIsDpx(&magicNum)) { + if (logImageIsDpx(&magicNum, sizeof(magicNum))) { return dpxOpen((const unsigned char *)filename, 0, 0); } - if (logImageIsCineon(&magicNum)) { + if (logImageIsCineon(&magicNum, sizeof(magicNum))) { return cineonOpen((const unsigned char *)filename, 0, 0); } @@ -138,10 +146,10 @@ LogImageFile *logImageOpenFromFile(const char *filename, int cineon) LogImageFile *logImageOpenFromMemory(const unsigned char *buffer, unsigned int size) { - if (logImageIsDpx(buffer)) { + if (logImageIsDpx(buffer, size)) { return dpxOpen(buffer, 1, size); } - if (logImageIsCineon(buffer)) { + if (logImageIsCineon(buffer, size)) { return cineonOpen(buffer, 1, size); } @@ -215,7 +223,7 @@ size_t getRowLength(size_t width, LogImageElement logElement) if (logElement.packing == 0) { return ((width * logElement.depth * 10 - 1) / 32 + 1) * 4; } - else if (logElement.packing == 1 || logElement.packing == 2) { + else if (ELEM(logElement.packing, 1, 2)) { return ((width * logElement.depth - 1) / 3 + 1) * 4; } break; @@ -223,7 +231,7 @@ size_t getRowLength(size_t width, LogImageElement logElement) if (logElement.packing == 0) { return ((width * logElement.depth * 12 - 1) / 32 + 1) * 4; } - else if (logElement.packing == 1 || logElement.packing == 2) { + else if (ELEM(logElement.packing, 1, 2)) { return width * logElement.depth * 2; } break; @@ -442,8 +450,7 @@ int logImageGetDataRGBA(LogImageFile *logImage, float *data, int dataIsLinearRGB 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) { + if (!ELEM(logImage->element[i].descriptor, descriptor_Depth, descriptor_Composite)) { /* Allocate memory */ elementData[i] = imb_alloc_pixels( logImage->width, logImage->height, logImage->element[i].depth, sizeof(float), __func__); @@ -680,7 +687,7 @@ static int logImageElementGetData(LogImageFile *logImage, LogImageElement logEle if (logElement.packing == 0) { return logImageElementGetData10Packed(logImage, logElement, data); } - else if (logElement.packing == 1 || logElement.packing == 2) { + else if (ELEM(logElement.packing, 1, 2)) { return logImageElementGetData10(logImage, logElement, data); } break; @@ -689,7 +696,7 @@ static int logImageElementGetData(LogImageFile *logImage, LogImageElement logEle if (logElement.packing == 0) { return logImageElementGetData12Packed(logImage, logElement, data); } - else if (logElement.packing == 1 || logElement.packing == 2) { + else if (ELEM(logElement.packing, 1, 2)) { return logImageElementGetData12(logImage, logElement, data); } break; diff --git a/source/blender/imbuf/intern/cineon/logImageCore.h b/source/blender/imbuf/intern/cineon/logImageCore.h index a2d50f21a98..c2704a086b6 100644 --- a/source/blender/imbuf/intern/cineon/logImageCore.h +++ b/source/blender/imbuf/intern/cineon/logImageCore.h @@ -181,8 +181,8 @@ enum descriptor { /* int functions return 0 for OK */ void logImageSetVerbose(int verbosity); -int logImageIsDpx(const void *buffer); -int logImageIsCineon(const void *buffer); +int logImageIsDpx(const void *buffer, unsigned int size); +int logImageIsCineon(const void *buffer, unsigned int size); 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); diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c index 7847ae83c19..2c95d49612f 100644 --- a/source/blender/imbuf/intern/colormanagement.c +++ b/source/blender/imbuf/intern/colormanagement.c @@ -54,10 +54,11 @@ #include "BKE_context.h" #include "BKE_image.h" #include "BKE_main.h" -#include "BKE_sequencer.h" #include "RNA_define.h" +#include "SEQ_sequencer.h" + #include <ocio_capi.h> /* -------------------------------------------------------------------- */ @@ -2615,7 +2616,6 @@ ImBuf *IMB_colormanagement_imbuf_for_write(ImBuf *ibuf, 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 @@ -2628,13 +2628,10 @@ ImBuf *IMB_colormanagement_imbuf_for_write(ImBuf *ibuf, * 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; + const ImFileType *type = IMB_file_type_from_ibuf(colormanaged_ibuf); + if (type != NULL) { + if ((type->save != NULL) && (type->flag & IM_FTYPE_FLOAT) == 0) { + make_byte = true; } } @@ -3237,14 +3234,11 @@ void IMB_colormanagement_colorspace_from_ibuf_ftype( } /* 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; - - role_colorspace = IMB_colormanagement_role_colorspace_name_get(type->default_save_role); - + const ImFileType *type = IMB_file_type_from_ibuf(ibuf); + if (type != NULL) { + if (type->save != NULL) { + const char *role_colorspace = IMB_colormanagement_role_colorspace_name_get( + type->default_save_role); BLI_strncpy(colorspace_settings->name, role_colorspace, sizeof(colorspace_settings->name)); } } diff --git a/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp b/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp index 3e459934db7..37e30d30e2c 100644 --- a/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp +++ b/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp @@ -1130,7 +1130,7 @@ void *DirectDrawSurface::readData(uint &rsize) if (stream.failed) { free(data); - data = NULL; + data = nullptr; rsize = 0; } diff --git a/source/blender/imbuf/intern/dds/Image.cpp b/source/blender/imbuf/intern/dds/Image.cpp index 4cfd7178f29..7958a586c7d 100644 --- a/source/blender/imbuf/intern/dds/Image.cpp +++ b/source/blender/imbuf/intern/dds/Image.cpp @@ -32,7 +32,7 @@ #include <stdio.h> /* printf */ -Image::Image() : m_width(0), m_height(0), m_format(Format_RGB), m_data(NULL) +Image::Image() : m_width(0), m_height(0), m_format(Format_RGB), m_data(nullptr) { } @@ -52,7 +52,7 @@ void Image::allocate(uint w, uint h) void Image::free() { delete[] m_data; - m_data = NULL; + m_data = nullptr; } uint Image::width() const diff --git a/source/blender/imbuf/intern/dds/dds_api.cpp b/source/blender/imbuf/intern/dds/dds_api.cpp index 1d29dd4a26b..804d8130b4c 100644 --- a/source/blender/imbuf/intern/dds/dds_api.cpp +++ b/source/blender/imbuf/intern/dds/dds_api.cpp @@ -42,16 +42,16 @@ extern "C" { -int imb_save_dds(struct ImBuf *ibuf, const char *name, int /*flags*/) +bool imb_save_dds(struct ImBuf *ibuf, const char *name, int /*flags*/) { - return 0; /* todo: finish this function */ + return false; /* todo: finish this function */ /* check image buffer */ - if (ibuf == 0) { - return 0; + if (ibuf == nullptr) { + return false; } - if (ibuf->rect == 0) { - return 0; + if (ibuf->rect == nullptr) { + return false; } /* open file for writing */ @@ -69,21 +69,24 @@ int imb_save_dds(struct ImBuf *ibuf, const char *name, int /*flags*/) fildes << "DDS "; fildes.close(); - return 1; + return true; } -int imb_is_a_dds(const unsigned char *mem) /* note: use at most first 32 bytes */ +bool imb_is_a_dds(const unsigned char *mem, const size_t size) { + if (size < 8) { + return false; + } /* 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; + return false; } /* header.size == 124 */ if ((mem[4] != 124) || mem[5] || mem[6] || mem[7]) { - return 0; + return false; } - return 1; + return true; } struct ImBuf *imb_load_dds(const unsigned char *mem, @@ -91,7 +94,7 @@ struct ImBuf *imb_load_dds(const unsigned char *mem, int flags, char colorspace[IM_MAX_SPACE]) { - struct ImBuf *ibuf = NULL; + struct ImBuf *ibuf = nullptr; DirectDrawSurface dds((unsigned char *)mem, size); /* reads header */ unsigned char bits_per_pixel; unsigned int *rect; @@ -100,7 +103,7 @@ struct ImBuf *imb_load_dds(const unsigned char *mem, int col; unsigned char *cp = (unsigned char *)&col; Color32 pixel; - Color32 *pixels = 0; + Color32 *pixels = nullptr; /* 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 @@ -108,28 +111,28 @@ struct ImBuf *imb_load_dds(const unsigned char *mem, */ colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE); - if (!imb_is_a_dds(mem)) { - return 0; + if (!imb_is_a_dds(mem, size)) { + return nullptr; } /* 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; + return nullptr; } printf("DDS: not valid; header follows\n"); dds.printInfo(); - return 0; + return nullptr; } if (!dds.isSupported()) { printf("DDS: format not supported\n"); - return 0; + return nullptr; } if ((dds.width() > 65535) || (dds.height() > 65535)) { printf("DDS: dimensions too large\n"); - return 0; + return nullptr; } /* convert DDS into ImBuf */ @@ -148,8 +151,8 @@ struct ImBuf *imb_load_dds(const unsigned char *mem, } } ibuf = IMB_allocImBuf(dds.width(), dds.height(), bits_per_pixel, 0); - if (ibuf == 0) { - return 0; /* memory allocation failed */ + if (ibuf == nullptr) { + return nullptr; /* memory allocation failed */ } ibuf->ftype = IMB_FTYPE_DDS; @@ -160,7 +163,7 @@ struct ImBuf *imb_load_dds(const unsigned char *mem, if (!imb_addrectImBuf(ibuf)) { return ibuf; } - if (ibuf->rect == 0) { + if (ibuf->rect == nullptr) { return ibuf; } @@ -188,7 +191,7 @@ struct ImBuf *imb_load_dds(const unsigned char *mem, } } else { - ibuf->dds_data.data = NULL; + ibuf->dds_data.data = nullptr; ibuf->dds_data.size = 0; } diff --git a/source/blender/imbuf/intern/dds/dds_api.h b/source/blender/imbuf/intern/dds/dds_api.h index 930205c9efb..931c4f267f9 100644 --- a/source/blender/imbuf/intern/dds/dds_api.h +++ b/source/blender/imbuf/intern/dds/dds_api.h @@ -26,8 +26,8 @@ extern "C" { #endif -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); +bool imb_is_a_dds(const unsigned char *mem, const size_t size); +bool 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, diff --git a/source/blender/imbuf/intern/filetype.c b/source/blender/imbuf/intern/filetype.c index 5aa588da36d..b1fe557a9bf 100644 --- a/source/blender/imbuf/intern/filetype.c +++ b/source/blender/imbuf/intern/filetype.c @@ -40,192 +40,197 @@ # include "dds/dds_api.h" #endif -static int imb_ftype_default(const ImFileType *type, const ImBuf *ibuf) -{ - return (ibuf->ftype == type->filetype); -} -static int imb_ftype_iris(const ImFileType *type, const ImBuf *ibuf) -{ - (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}, + { + .init = NULL, + .exit = NULL, + .is_a = imb_is_a_jpeg, + .load = imb_load_jpeg, + .load_filepath = NULL, + .save = imb_savejpeg, + .load_tile = NULL, + .flag = 0, + .filetype = IMB_FTYPE_JPG, + .default_save_role = COLOR_ROLE_DEFAULT_BYTE, + }, + { + .init = NULL, + .exit = NULL, + .is_a = imb_is_a_png, + .load = imb_loadpng, + .load_filepath = NULL, + .save = imb_savepng, + .load_tile = NULL, + .flag = 0, + .filetype = IMB_FTYPE_PNG, + .default_save_role = COLOR_ROLE_DEFAULT_BYTE, + }, + { + .init = NULL, + .exit = NULL, + .is_a = imb_is_a_bmp, + .load = imb_bmp_decode, + .load_filepath = NULL, + .save = imb_savebmp, + .load_tile = NULL, + .flag = 0, + .filetype = IMB_FTYPE_BMP, + .default_save_role = COLOR_ROLE_DEFAULT_BYTE, + }, + { + .init = NULL, + .exit = NULL, + .is_a = imb_is_a_targa, + .load = imb_loadtarga, + .load_filepath = NULL, + .save = imb_savetarga, + .load_tile = NULL, + .flag = 0, + .filetype = IMB_FTYPE_TGA, + .default_save_role = COLOR_ROLE_DEFAULT_BYTE, + }, + { + .init = NULL, + .exit = NULL, + .is_a = imb_is_a_iris, + .load = imb_loadiris, + .load_filepath = NULL, + .save = imb_saveiris, + .load_tile = NULL, + .flag = 0, + .filetype = IMB_FTYPE_IMAGIC, + .default_save_role = 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}, + { + .init = NULL, + .exit = NULL, + .is_a = imb_is_a_dpx, + .load = imb_load_dpx, + .load_filepath = NULL, + .save = imb_save_dpx, + .load_tile = NULL, + .flag = IM_FTYPE_FLOAT, + .filetype = IMB_FTYPE_DPX, + .default_save_role = COLOR_ROLE_DEFAULT_FLOAT, + }, + { + .init = NULL, + .exit = NULL, + .is_a = imb_is_a_cineon, + .load = imb_load_cineon, + .load_filepath = NULL, + .save = imb_save_cineon, + .load_tile = NULL, + .flag = IM_FTYPE_FLOAT, + .filetype = IMB_FTYPE_CINEON, + .default_save_role = 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}, + { + .init = imb_inittiff, + .exit = NULL, + .is_a = imb_is_a_tiff, + .load = imb_loadtiff, + .load_filepath = NULL, + .save = imb_savetiff, + .load_tile = imb_loadtiletiff, + .flag = 0, + .filetype = IMB_FTYPE_TIF, + .default_save_role = 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}, + { + .init = NULL, + .exit = NULL, + .is_a = imb_is_a_hdr, + .load = imb_loadhdr, + .load_filepath = NULL, + .save = imb_savehdr, + .load_tile = NULL, + .flag = IM_FTYPE_FLOAT, + .filetype = IMB_FTYPE_RADHDR, + .default_save_role = 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}, + { + .init = imb_initopenexr, + .exit = imb_exitopenexr, + .is_a = imb_is_a_openexr, + .load = imb_load_openexr, + .load_filepath = NULL, + .save = imb_save_openexr, + .load_tile = NULL, + .flag = IM_FTYPE_FLOAT, + .filetype = IMB_FTYPE_OPENEXR, + .default_save_role = 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}, + { + .init = NULL, + .exit = NULL, + .is_a = imb_is_a_jp2, + .load = imb_load_jp2, + .load_filepath = NULL, + .save = imb_save_jp2, + .load_tile = NULL, + .flag = IM_FTYPE_FLOAT, + .filetype = IMB_FTYPE_JP2, + .default_save_role = 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}, + { + .init = NULL, + .exit = NULL, + .is_a = imb_is_a_dds, + .load = imb_load_dds, + .load_filepath = NULL, + .save = NULL, + .load_tile = NULL, + .flag = 0, + .filetype = IMB_FTYPE_DDS, + .default_save_role = 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}, + { + .init = NULL, + .exit = NULL, + .is_a = imb_is_a_photoshop, + .load = NULL, + .load_filepath = imb_load_photoshop, + .save = NULL, + .load_tile = NULL, + .flag = IM_FTYPE_FLOAT, + .filetype = IMB_FTYPE_PSD, + .default_save_role = COLOR_ROLE_DEFAULT_FLOAT, + }, #endif - {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0}, + {NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0}, }; const ImFileType *IMB_FILE_TYPES_LAST = &IMB_FILE_TYPES[ARRAY_SIZE(IMB_FILE_TYPES) - 1]; +const ImFileType *IMB_file_type_from_ftype(int ftype) +{ + for (const ImFileType *type = IMB_FILE_TYPES; type < IMB_FILE_TYPES_LAST; type++) { + if (ftype == type->filetype) { + return type; + } + } + return NULL; +} + +const ImFileType *IMB_file_type_from_ibuf(const ImBuf *ibuf) +{ + return IMB_file_type_from_ftype(ibuf->ftype); +} + void imb_filetypes_init(void) { const ImFileType *type; diff --git a/source/blender/imbuf/intern/indexer.c b/source/blender/imbuf/intern/indexer.c index 76717bef537..b5b8cd4a580 100644 --- a/source/blender/imbuf/intern/indexer.c +++ b/source/blender/imbuf/intern/indexer.c @@ -1218,8 +1218,11 @@ IndexBuildContext *IMB_anim_index_rebuild_context(struct anim *anim, } void IMB_anim_index_rebuild(struct IndexBuildContext *context, + /* NOLINTNEXTLINE: readability-non-const-parameter. */ short *stop, + /* NOLINTNEXTLINE: readability-non-const-parameter. */ short *do_update, + /* NOLINTNEXTLINE: readability-non-const-parameter. */ float *progress) { switch (context->anim_type) { diff --git a/source/blender/imbuf/intern/iris.c b/source/blender/imbuf/intern/iris.c index 12c4c63849c..112b95bf1a1 100644 --- a/source/blender/imbuf/intern/iris.c +++ b/source/blender/imbuf/intern/iris.c @@ -243,8 +243,11 @@ static void test_endian_zbuf(struct ImBuf *ibuf) /* this one is only def-ed once, strangely... */ #define GSS(x) (((uchar *)(x))[1] << 8 | ((uchar *)(x))[0]) -int imb_is_a_iris(const uchar *mem) +bool imb_is_a_iris(const uchar *mem, size_t size) { + if (size < 2) { + return false; + } return ((GS(mem) == IMAGIC) || (GSS(mem) == IMAGIC)); } @@ -271,7 +274,7 @@ struct ImBuf *imb_loadiris(const uchar *mem, size_t size, int flags, char colors return NULL; } - if (!imb_is_a_iris(mem)) { + if (!imb_is_a_iris(mem, size)) { return NULL; } @@ -286,7 +289,7 @@ struct ImBuf *imb_loadiris(const uchar *mem, size_t size, int flags, char colors rle = ISRLE(image.type); bpp = BPP(image.type); - if (bpp != 1 && bpp != 2) { + if (!ELEM(bpp, 1, 2)) { fprintf(stderr, "longimagedata: image must have 1 or 2 byte per pix chan\n"); return NULL; } @@ -807,7 +810,7 @@ fail: * Added: zbuf write */ -static int output_iris(uint *lptr, int xsize, int ysize, int zsize, const char *name, int *zptr) +static bool output_iris(uint *lptr, int xsize, int ysize, int zsize, const char *name, int *zptr) { FILE *outf; IMAGE *image; @@ -969,10 +972,9 @@ static int compressrow(uchar *lbuf, uchar *rlebuf, int z, int cnt) return optr - (uchar *)rlebuf; } -int imb_saveiris(struct ImBuf *ibuf, const char *filepath, int flags) +bool imb_saveiris(struct ImBuf *ibuf, const char *filepath, int flags) { short zsize; - int ret; zsize = (ibuf->planes + 7) >> 3; if (flags & IB_zbuf && ibuf->zbuf != NULL) { @@ -982,11 +984,11 @@ int imb_saveiris(struct ImBuf *ibuf, const char *filepath, int flags) IMB_convert_rgba_to_abgr(ibuf); test_endian_zbuf(ibuf); - ret = output_iris(ibuf->rect, ibuf->x, ibuf->y, zsize, filepath, ibuf->zbuf); + const bool ok = output_iris(ibuf->rect, ibuf->x, ibuf->y, zsize, filepath, ibuf->zbuf); /* restore! Quite clumsy, 2 times a switch... maybe better a malloc ? */ IMB_convert_rgba_to_abgr(ibuf); test_endian_zbuf(ibuf); - return ret; + return ok; } diff --git a/source/blender/imbuf/intern/jp2.c b/source/blender/imbuf/intern/jp2.c index c7e4fe45a26..e19589317d7 100644 --- a/source/blender/imbuf/intern/jp2.c +++ b/source/blender/imbuf/intern/jp2.c @@ -58,31 +58,38 @@ enum { DCP_CINEMA4K = 4, }; -static bool check_jp2(const unsigned char *mem) /* J2K_CFMT */ +static bool check_jp2(const unsigned char *mem, const size_t size) /* J2K_CFMT */ { + if (size < sizeof(JP2_HEAD)) { + return false; + } return memcmp(JP2_HEAD, mem, sizeof(JP2_HEAD)) ? 0 : 1; } -static bool check_j2k(const unsigned char *mem) /* J2K_CFMT */ +static bool check_j2k(const unsigned char *mem, const size_t size) /* J2K_CFMT */ { + if (size < sizeof(J2K_HEAD)) { + return false; + } return memcmp(J2K_HEAD, mem, sizeof(J2K_HEAD)) ? 0 : 1; } -static OPJ_CODEC_FORMAT format_from_header(const unsigned char mem[JP2_FILEHEADER_SIZE]) +static OPJ_CODEC_FORMAT format_from_header(const unsigned char mem[JP2_FILEHEADER_SIZE], + const size_t size) { - if (check_jp2(mem)) { + if (check_jp2(mem, size)) { return OPJ_CODEC_JP2; } - if (check_j2k(mem)) { + if (check_j2k(mem, size)) { return OPJ_CODEC_J2K; } return OPJ_CODEC_UNKNOWN; } -int imb_is_a_jp2(const unsigned char *buf) +bool imb_is_a_jp2(const unsigned char *buf, size_t size) { - return (check_jp2(buf) || check_j2k(buf)); + return (check_jp2(buf, size) || check_j2k(buf, size)); } /** @@ -126,6 +133,7 @@ static void info_callback(const char *msg, void *client_data) } \ (void)0 +/* -------------------------------------------------------------------- */ /** \name Buffer Stream * \{ */ @@ -217,6 +225,7 @@ static opj_stream_t *opj_stream_create_from_buffer(struct BufInfo *p_file, /** \} */ +/* -------------------------------------------------------------------- */ /** \name File Stream * \{ */ @@ -315,7 +324,7 @@ ImBuf *imb_load_jp2(const unsigned char *mem, int flags, char colorspace[IM_MAX_SPACE]) { - const OPJ_CODEC_FORMAT format = (size > JP2_FILEHEADER_SIZE) ? format_from_header(mem) : + const OPJ_CODEC_FORMAT format = (size > JP2_FILEHEADER_SIZE) ? format_from_header(mem, size) : OPJ_CODEC_UNKNOWN; struct BufInfo buf_wrapper = { .buf = mem, @@ -346,7 +355,7 @@ ImBuf *imb_load_jp2_filepath(const char *filepath, int flags, char colorspace[IM fseek(p_file, 0, SEEK_SET); - const OPJ_CODEC_FORMAT format = format_from_header(mem); + const OPJ_CODEC_FORMAT format = format_from_header(mem, sizeof(mem)); ImBuf *ibuf = imb_load_jp2_stream(stream, format, flags, colorspace); opj_stream_destroy(stream); return ibuf; @@ -1192,22 +1201,22 @@ static opj_image_t *ibuftoimage(ImBuf *ibuf, opj_cparameters_t *parameters) return image; } -int imb_save_jp2_stream(struct ImBuf *ibuf, opj_stream_t *stream, int flags); +bool 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) +bool 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); + const bool ok = imb_save_jp2_stream(ibuf, stream, flags); opj_stream_destroy(stream); - return ret; + return ok; } /* 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)) +bool imb_save_jp2_stream(struct ImBuf *ibuf, opj_stream_t *stream, int UNUSED(flags)) { int quality = ibuf->foptions.quality; @@ -1228,7 +1237,7 @@ int imb_save_jp2_stream(struct ImBuf *ibuf, opj_stream_t *stream, int UNUSED(fla image = ibuftoimage(ibuf, ¶meters); opj_codec_t *codec = NULL; - int ok = false; + bool ok = false; /* JP2 format output */ { /* get a JP2 compressor handle */ diff --git a/source/blender/imbuf/intern/jpeg.c b/source/blender/imbuf/intern/jpeg.c index 525284bd867..93cdbbb1407 100644 --- a/source/blender/imbuf/intern/jpeg.c +++ b/source/blender/imbuf/intern/jpeg.c @@ -57,12 +57,13 @@ static ImBuf *ibJpegImageFromCinfo(struct jpeg_decompress_struct *cinfo, int fla static const uchar jpeg_default_quality = 75; static uchar ibuf_quality; -int imb_is_a_jpeg(const unsigned char *mem) +bool imb_is_a_jpeg(const unsigned char *mem, const size_t size) { - if ((mem[0] == 0xFF) && (mem[1] == 0xD8)) { - return 1; + const char magic[2] = {0xFF, 0xD8}; + if (size < sizeof(magic)) { + return false; } - return 0; + return memcmp(mem, magic, sizeof(magic)) == 0; } /*---------------------------------------------------------- @@ -246,7 +247,7 @@ static boolean handle_app1(j_decompress_ptr cinfo) INPUT_BYTE(cinfo, neogeo[i], return false); } length = 0; - if (STREQLEN(neogeo, "NeoGeo", 6)) { + if (STRPREFIX(neogeo, "NeoGeo")) { struct NeoGeo_Word *neogeo_word = (struct NeoGeo_Word *)(neogeo + 6); ibuf_quality = neogeo_word->quality; } @@ -362,7 +363,7 @@ static ImBuf *ibJpegImageFromCinfo(struct jpeg_decompress_struct *cinfo, int fla * That is why we need split it to the * common key/value here. */ - if (!STREQLEN(str, "Blender", 7)) { + if (!STRPREFIX(str, "Blender")) { /* * Maybe the file have text that * we don't know "what it's", in that @@ -429,7 +430,7 @@ ImBuf *imb_load_jpeg(const unsigned char *buffer, struct my_error_mgr jerr; ImBuf *ibuf; - if (!imb_is_a_jpeg(buffer)) { + if (!imb_is_a_jpeg(buffer, size)) { return NULL; } @@ -608,7 +609,7 @@ static int init_jpeg(FILE *outfile, struct jpeg_compress_struct *cinfo, struct I return 0; } -static int save_stdjpeg(const char *name, struct ImBuf *ibuf) +static bool save_stdjpeg(const char *name, struct ImBuf *ibuf) { FILE *outfile; struct jpeg_compress_struct _cinfo, *cinfo = &_cinfo; @@ -642,7 +643,7 @@ static int save_stdjpeg(const char *name, struct ImBuf *ibuf) return 1; } -int imb_savejpeg(struct ImBuf *ibuf, const char *filepath, int flags) +bool imb_savejpeg(struct ImBuf *ibuf, const char *filepath, int flags) { ibuf->flags = flags; diff --git a/source/blender/imbuf/intern/oiio/openimageio_api.cpp b/source/blender/imbuf/intern/oiio/openimageio_api.cpp index 71774b335d7..1e8c3c25778 100644 --- a/source/blender/imbuf/intern/oiio/openimageio_api.cpp +++ b/source/blender/imbuf/intern/oiio/openimageio_api.cpp @@ -101,7 +101,7 @@ static ImBuf *imb_oiio_load_image( IMB_freeImBuf(ibuf); } - return NULL; + return nullptr; } } catch (const std::exception &exc) { @@ -110,7 +110,7 @@ static ImBuf *imb_oiio_load_image( IMB_freeImBuf(ibuf); } - return NULL; + return nullptr; } /* ImBuf always needs 4 channels */ @@ -141,7 +141,7 @@ static ImBuf *imb_oiio_load_image_float( IMB_freeImBuf(ibuf); } - return NULL; + return nullptr; } } catch (const std::exception &exc) { @@ -150,7 +150,7 @@ static ImBuf *imb_oiio_load_image_float( IMB_freeImBuf(ibuf); } - return NULL; + return nullptr; } /* ImBuf always needs 4 channels */ @@ -163,16 +163,13 @@ static ImBuf *imb_oiio_load_image_float( extern "C" { -int imb_is_a_photoshop(const char *filename) +bool imb_is_a_photoshop(const unsigned char *mem, size_t size) { - const char *photoshop_extension[] = { - ".psd", - ".pdd", - ".psb", - NULL, - }; - - return BLI_path_extension_check_array(filename, photoshop_extension); + const unsigned char magic[4] = {'8', 'B', 'P', 'S'}; + if (size < sizeof(magic)) { + return false; + } + return memcmp(magic, mem, sizeof(magic)) == 0; } int imb_save_photoshop(struct ImBuf *ibuf, const char * /*name*/, int flags) @@ -190,7 +187,7 @@ int imb_save_photoshop(struct ImBuf *ibuf, const char * /*name*/, int flags) struct ImBuf *imb_load_photoshop(const char *filename, int flags, char colorspace[IM_MAX_SPACE]) { - struct ImBuf *ibuf = NULL; + struct ImBuf *ibuf = nullptr; int width, height, components; bool is_float, is_alpha, is_half; int basesize; @@ -198,8 +195,8 @@ struct ImBuf *imb_load_photoshop(const char *filename, int flags, char colorspac const bool is_colorspace_manually_set = (colorspace[0] != '\0'); /* load image from file through OIIO */ - if (imb_is_a_photoshop(filename) == 0) { - return NULL; + if (IMB_ispic_type_matches(filename, IMB_FTYPE_PSD) == 0) { + return nullptr; } colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE); @@ -208,7 +205,7 @@ struct ImBuf *imb_load_photoshop(const char *filename, int flags, char colorspac if (!in) { std::cerr << __func__ << ": ImageInput::create() failed:" << std::endl << OIIO_NAMESPACE::geterror() << std::endl; - return NULL; + return nullptr; } ImageSpec spec, config; @@ -217,7 +214,7 @@ struct ImBuf *imb_load_photoshop(const char *filename, int flags, char colorspac if (!in->open(filename, spec, config)) { std::cerr << __func__ << ": ImageInput::open() failed:" << std::endl << in->geterror() << std::endl; - return NULL; + return nullptr; } if (!is_colorspace_manually_set) { @@ -248,7 +245,7 @@ struct ImBuf *imb_load_photoshop(const char *filename, int flags, char colorspac if (in) { in->close(); } - return NULL; + return nullptr; } if (is_float) { @@ -263,7 +260,7 @@ struct ImBuf *imb_load_photoshop(const char *filename, int flags, char colorspac } if (!ibuf) { - return NULL; + return nullptr; } /* ImBuf always needs 4 channels */ @@ -281,7 +278,7 @@ struct ImBuf *imb_load_photoshop(const char *filename, int flags, char colorspac IMB_freeImBuf(ibuf); } - return NULL; + return nullptr; } } diff --git a/source/blender/imbuf/intern/oiio/openimageio_api.h b/source/blender/imbuf/intern/oiio/openimageio_api.h index 3f5f234099c..659050cdb00 100644 --- a/source/blender/imbuf/intern/oiio/openimageio_api.h +++ b/source/blender/imbuf/intern/oiio/openimageio_api.h @@ -31,7 +31,7 @@ extern "C" { struct ImBuf; -int imb_is_a_photoshop(const char *name); +bool imb_is_a_photoshop(const unsigned char *mem, const size_t size); int imb_save_photoshop(struct ImBuf *ibuf, const char *name, int flags); diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp index ca70ec633c1..56188fbe98a 100644 --- a/source/blender/imbuf/intern/openexr/openexr_api.cpp +++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp @@ -330,8 +330,12 @@ extern "C" { * Test presence of OpenEXR file. * \param mem: pointer to loaded OpenEXR bitstream */ -int imb_is_a_openexr(const unsigned char *mem) +bool imb_is_a_openexr(const unsigned char *mem, const size_t size) { + /* No define is exposed for this size. */ + if (size < 4) { + return false; + } return Imf::isImfMagic((const char *)mem); } @@ -407,10 +411,10 @@ 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 bool is_zbuf = (flags & IB_zbuffloat) && ibuf->zbuf_float != nullptr; /* summarize */ const int width = ibuf->x; const int height = ibuf->y; - OStream *file_stream = NULL; + OStream *file_stream = nullptr; try { Header header(width, height); @@ -514,10 +518,10 @@ static bool imb_save_openexr_float(ImBuf *ibuf, const char *name, const int flag { 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 bool is_zbuf = (flags & IB_zbuffloat) && ibuf->zbuf_float != nullptr; /* summarize */ const int width = ibuf->x; const int height = ibuf->y; - OStream *file_stream = NULL; + OStream *file_stream = nullptr; try { Header header(width, height); @@ -551,7 +555,7 @@ static bool imb_save_openexr_float(ImBuf *ibuf, const char *name, const int flag int ystride = -xstride * width; /* last scanline, stride negative */ - float *rect[4] = {NULL, NULL, NULL, NULL}; + float *rect[4] = {nullptr, nullptr, nullptr, nullptr}; 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]; @@ -586,7 +590,7 @@ static bool imb_save_openexr_float(ImBuf *ibuf, const char *name, const int flag return true; } -int imb_save_openexr(struct ImBuf *ibuf, const char *name, int flags) +bool imb_save_openexr(struct ImBuf *ibuf, const char *name, int flags) { if (flags & IB_mem) { imb_addencodedbufferImBuf(ibuf); @@ -594,15 +598,15 @@ int imb_save_openexr(struct ImBuf *ibuf, const char *name, int flags) } if (ibuf->foptions.flag & OPENEXR_HALF) { - return (int)imb_save_openexr_half(ibuf, name, flags); + return imb_save_openexr_half(ibuf, name, flags); } /* 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); + if (ibuf->rect_float == nullptr) { + return imb_save_openexr_half(ibuf, name, flags); } - return (int)imb_save_openexr_float(ibuf, name, flags); + return imb_save_openexr_float(ibuf, name, flags); } /* ******* Nicer API, MultiLayer and with Tile file support ************************************ */ @@ -614,7 +618,7 @@ int imb_save_openexr(struct ImBuf *ibuf, const char *name, int flags) * - separated with a dot: the Layer name (like "Light1" or "Walls" or "Characters") */ -static ListBase exrhandles = {NULL, NULL}; +static ListBase exrhandles = {nullptr, nullptr}; typedef struct ExrHandle { struct ExrHandle *next, *prev; @@ -691,7 +695,7 @@ void *IMB_exr_get_handle_name(const char *name) { ExrHandle *data = (ExrHandle *)BLI_rfindstring(&exrhandles, name, offsetof(ExrHandle, name)); - if (data == NULL) { + if (data == nullptr) { data = (ExrHandle *)IMB_exr_get_handle(); BLI_strncpy(data->name, name, strlen(name) + 1); } @@ -754,8 +758,8 @@ static void imb_exr_insert_view_name(char *name_full, const char *passname, cons { BLI_assert(!ELEM(name_full, passname, viewname)); - if (viewname == NULL || viewname[0] == '\0') { - BLI_strncpy(name_full, passname, sizeof(((ExrChannel *)NULL)->name)); + if (viewname == nullptr || viewname[0] == '\0') { + BLI_strncpy(name_full, passname, sizeof(((ExrChannel *)nullptr)->name)); return; } @@ -882,11 +886,11 @@ int IMB_exr_begin_write(void *handle, delete data->ofile; delete data->ofile_stream; - data->ofile = NULL; - data->ofile_stream = NULL; + data->ofile = nullptr; + data->ofile_stream = nullptr; } - return (data->ofile != NULL); + return (data->ofile != nullptr); } /* only used for writing temp. render results (not image files) @@ -951,8 +955,8 @@ void IMB_exrtile_begin_write( delete data->mpofile; delete data->ofile_stream; - data->mpofile = NULL; - data->ofile_stream = NULL; + data->mpofile = nullptr; + data->ofile_stream = nullptr; } } @@ -973,8 +977,8 @@ int IMB_exr_begin_read(void *handle, const char *filename, int *width, int *heig delete data->ifile; delete data->ifile_stream; - data->ifile = NULL; - data->ifile_stream = NULL; + data->ifile = nullptr; + data->ifile_stream = nullptr; } if (data->ifile) { @@ -988,8 +992,14 @@ int IMB_exr_begin_read(void *handle, const char *filename, int *width, int *heig 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); + IMB_exr_add_channel(data, + nullptr, + channels[i].name.c_str(), + channels[i].view.c_str(), + 0, + 0, + nullptr, + false); echan = (ExrChannel *)data->channels.last; echan->m->name = channels[i].name; @@ -1074,7 +1084,7 @@ float *IMB_exr_channel_rect(void *handle, return echan->rect; } - return NULL; + return nullptr; } void IMB_exr_clear_channels(void *handle) @@ -1097,7 +1107,7 @@ void IMB_exr_write_channels(void *handle) if (data->channels.first) { const size_t num_pixels = ((size_t)data->width) * data->height; - half *rect_half = NULL, *current_rect_half = NULL; + half *rect_half = nullptr, *current_rect_half = nullptr; /* We allocate teporary storage for half pixels for all the channels at once. */ if (data->num_half_channels != 0) { @@ -1138,7 +1148,7 @@ void IMB_exr_write_channels(void *handle) std::cerr << "OpenEXR-writePixels: ERROR: " << exc.what() << std::endl; } /* Free temporary buffers. */ - if (rect_half != NULL) { + if (rect_half != nullptr) { MEM_freeN(rect_half); } } @@ -1210,7 +1220,7 @@ void IMB_exr_read_channels(void *handle) "BlenderMultiChannel"); /* 'previous multilayer attribute, flipped. */ - short flip = (ta && STREQLEN(ta->value().c_str(), "Blender V2.43", 13)); + short flip = (ta && STRPREFIX(ta->value().c_str(), "Blender V2.43")); exr_printf( "\nIMB_exr_read_channels\n%s %-6s %-22s " @@ -1323,7 +1333,7 @@ void IMB_exr_multilayer_convert(void *handle, pass->totchan, pass->chan_id, pass->view); - pass->rect = NULL; + pass->rect = nullptr; } } } @@ -1343,11 +1353,11 @@ void IMB_exr_close(void *handle) delete data->ofile_stream; delete data->multiView; - data->ifile = NULL; - data->ifile_stream = NULL; - data->ofile = NULL; - data->mpofile = NULL; - data->ofile_stream = NULL; + data->ifile = nullptr; + data->ifile_stream = nullptr; + data->ofile = nullptr; + data->mpofile = nullptr; + data->ofile_stream = nullptr; for (chan = (ExrChannel *)data->channels.first; chan; chan = chan->next) { delete chan->m; @@ -1491,7 +1501,7 @@ static ExrLayer *imb_exr_get_layer(ListBase *lb, char *layname) { ExrLayer *lay = (ExrLayer *)BLI_findstring(lb, layname, offsetof(ExrLayer, name)); - if (lay == NULL) { + if (lay == nullptr) { lay = (ExrLayer *)MEM_callocN(sizeof(ExrLayer), "exr layer"); BLI_addtail(lb, lay); BLI_strncpy(lay->name, layname, EXR_LAY_MAXNAME); @@ -1504,7 +1514,7 @@ static ExrPass *imb_exr_get_pass(ListBase *lb, char *passname) { ExrPass *pass = (ExrPass *)BLI_findstring(lb, passname, offsetof(ExrPass, name)); - if (pass == NULL) { + if (pass == nullptr) { pass = (ExrPass *)MEM_callocN(sizeof(ExrPass), "exr pass"); if (STREQ(passname, "Combined")) { @@ -1546,7 +1556,7 @@ static ExrHandle *imb_exr_begin_read_mem(IStream &file_stream, 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); + data, nullptr, channels[i].name.c_str(), channels[i].view.c_str(), 0, 0, nullptr, false); echan = (ExrChannel *)data->channels.last; echan->m->name = channels[i].name; @@ -1588,7 +1598,7 @@ static ExrHandle *imb_exr_begin_read_mem(IStream &file_stream, if (echan) { printf("error, too many channels in one pass: %s\n", echan->m->name.c_str()); IMB_exr_close(data); - return NULL; + return nullptr; } /* with some heuristics, try to merge the channels in buffers */ @@ -1610,7 +1620,7 @@ static ExrHandle *imb_exr_begin_read_mem(IStream &file_stream, memset(lookup, 0, sizeof(lookup)); /* we can have RGB(A), XYZ(W), UVA */ - if (pass->totchan == 3 || pass->totchan == 4) { + if (ELEM(pass->totchan, 3, 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; @@ -1723,7 +1733,7 @@ static int exr_has_rgb(MultiPartInputFile &file, const char *rgb_channels[3]) { /* Common names for RGB-like channels in order. */ static const char *channel_names[] = { - "R", "Red", "G", "Green", "B", "Blue", "AR", "RA", "AG", "GA", "AB", "BA", NULL}; + "R", "Red", "G", "Green", "B", "Blue", "AR", "RA", "AG", "GA", "AB", "BA", nullptr}; const Header &header = file.header(0); int num_channels = 0; @@ -1746,26 +1756,26 @@ static bool exr_has_luma(MultiPartInputFile &file) * optionally it could be also channels for chromas called BY and RY. */ const Header &header = file.header(0); - return header.channels().findChannel("Y") != NULL; + return header.channels().findChannel("Y") != nullptr; } static bool exr_has_chroma(MultiPartInputFile &file) { const Header &header = file.header(0); - return header.channels().findChannel("BY") != NULL && - header.channels().findChannel("RY") != NULL; + return header.channels().findChannel("BY") != nullptr && + header.channels().findChannel("RY") != nullptr; } static bool exr_has_zbuffer(MultiPartInputFile &file) { const Header &header = file.header(0); - return !(header.channels().findChannel("Z") == NULL); + return !(header.channels().findChannel("Z") == nullptr); } static bool exr_has_alpha(MultiPartInputFile &file) { const Header &header = file.header(0); - return !(header.channels().findChannel("A") == NULL); + return !(header.channels().findChannel("A") == nullptr); } static bool exr_is_half_float(MultiPartInputFile &file) @@ -1895,12 +1905,12 @@ struct ImBuf *imb_load_openexr(const unsigned char *mem, int flags, char colorspace[IM_MAX_SPACE]) { - struct ImBuf *ibuf = NULL; - IMemStream *membuf = NULL; - MultiPartInputFile *file = NULL; + struct ImBuf *ibuf = nullptr; + IMemStream *membuf = nullptr; + MultiPartInputFile *file = nullptr; - if (imb_is_a_openexr(mem) == 0) { - return NULL; + if (imb_is_a_openexr(mem, size) == 0) { + return nullptr; } colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_FLOAT); @@ -1918,7 +1928,7 @@ struct ImBuf *imb_load_openexr(const unsigned char *mem, // 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 */ + if (false) { /* debug */ exr_print_filecontents(*file); } @@ -2084,7 +2094,7 @@ struct ImBuf *imb_load_openexr(const unsigned char *mem, delete file; delete membuf; - return 0; + return nullptr; } } diff --git a/source/blender/imbuf/intern/openexr/openexr_api.h b/source/blender/imbuf/intern/openexr/openexr_api.h index 73db146849b..940715690a7 100644 --- a/source/blender/imbuf/intern/openexr/openexr_api.h +++ b/source/blender/imbuf/intern/openexr/openexr_api.h @@ -32,9 +32,9 @@ extern "C" { void imb_initopenexr(void); void imb_exitopenexr(void); -int imb_is_a_openexr(const unsigned char *mem); +bool imb_is_a_openexr(const unsigned char *mem, const size_t size); -int imb_save_openexr(struct ImBuf *ibuf, const char *name, int flags); +bool 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); diff --git a/source/blender/imbuf/intern/openexr/openexr_stub.cpp b/source/blender/imbuf/intern/openexr/openexr_stub.cpp index bfc4291c7b1..51bc2094053 100644 --- a/source/blender/imbuf/intern/openexr/openexr_stub.cpp +++ b/source/blender/imbuf/intern/openexr/openexr_stub.cpp @@ -26,11 +26,11 @@ void *IMB_exr_get_handle(void) { - return NULL; + return nullptr; } void *IMB_exr_get_handle_name(const char * /*name*/) { - return NULL; + return nullptr; } void IMB_exr_add_channel(void * /*handle*/, const char * /*layname*/, @@ -82,7 +82,7 @@ float *IMB_exr_channel_rect(void * /*handle*/, const char * /*passname*/, const char * /*view*/) { - return NULL; + return nullptr; } void IMB_exr_read_channels(void * /*handle*/) diff --git a/source/blender/imbuf/intern/png.c b/source/blender/imbuf/intern/png.c index 0104d7e2f17..60fc2ac0867 100644 --- a/source/blender/imbuf/intern/png.c +++ b/source/blender/imbuf/intern/png.c @@ -59,19 +59,21 @@ BLI_INLINE unsigned short UPSAMPLE_8_TO_16(const unsigned char _val) return (_val << 8) + _val; } -int imb_is_a_png(const unsigned char *mem) +bool imb_is_a_png(const unsigned char *mem, size_t size) { - int ret_val = 0; + const int num_to_check = 8; + if (size < num_to_check) { + return false; + } + bool ok = false; - 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. */ + ok = !png_sig_cmp((png_bytep)mem, 0, num_to_check); #else - ret_val = !png_sig_cmp(mem, 0, 8); + ok = !png_sig_cmp(mem, 0, num_to_check); #endif - } - return ret_val; + return ok; } static void Flush(png_structp png_ptr) @@ -119,7 +121,7 @@ BLI_INLINE unsigned short ftoshort(float val) return unit_float_to_ushort_clamp(val); } -int imb_savepng(struct ImBuf *ibuf, const char *filepath, int flags) +bool imb_savepng(struct ImBuf *ibuf, const char *filepath, int flags) { png_structp png_ptr; png_infop info_ptr; @@ -522,7 +524,7 @@ static void imb_png_warning(png_structp UNUSED(png_ptr), png_const_charp message * 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)) { + if ((G.debug & G_DEBUG) == 0 && STRPREFIX(message, "iCCP")) { return; } fprintf(stderr, "libpng warning: %s\n", message); @@ -550,7 +552,7 @@ ImBuf *imb_loadpng(const unsigned char *mem, size_t size, int flags, char colors float *to_float; unsigned int channels; - if (imb_is_a_png(mem) == 0) { + if (imb_is_a_png(mem, size) == 0) { return NULL; } diff --git a/source/blender/imbuf/intern/radiance_hdr.c b/source/blender/imbuf/intern/radiance_hdr.c index 21709fa8603..285b18595f7 100644 --- a/source/blender/imbuf/intern/radiance_hdr.c +++ b/source/blender/imbuf/intern/radiance_hdr.c @@ -197,17 +197,22 @@ static void FLOAT2RGBE(const fCOLOR fcol, RGBE rgbe) /* ImBuf read */ -int imb_is_a_hdr(const unsigned char *buf) +bool imb_is_a_hdr(const unsigned char *buf, const size_t size) { - /* 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 (memcmp((char *)buf, "#?", 2) == 0) { - return 1; + /* NOTE: `#?RADIANCE` is used by other programs such as `ImageMagik`, + * Although there are some files in the wild that only use `#?` (from looking online). + * If this is ever a problem we could check for the longer header since this is part of the spec. + * + * We could check `32-bit_rle_rgbe` or `32-bit_rle_xyze` too since this is part of the format. + * Currently this isn't needed. + * + * See: http://paulbourke.net/dataformats/pic/ + */ + const unsigned char magic[2] = {'#', '?'}; + if (size < sizeof(magic)) { + return false; } - // if (strstr((char *)buf, "32-bit_rle_rgbe")) return 1; - return 0; + return memcmp(buf, magic, sizeof(magic)) == 0; } struct ImBuf *imb_loadhdr(const unsigned char *mem, @@ -224,7 +229,7 @@ struct ImBuf *imb_loadhdr(const unsigned char *mem, const unsigned char *ptr, *mem_eof = mem + size; char oriY[80], oriX[80]; - if (imb_is_a_hdr((void *)mem)) { + if (imb_is_a_hdr(mem, size)) { colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_FLOAT); /* find empty line, next line is resolution info */ @@ -329,9 +334,9 @@ static int fwritecolrs( 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; + fcol[RED] = (float)ibufscan[j] / 255.0f; + fcol[GRN] = (float)((channels >= 2) ? ibufscan[j + 1] : ibufscan[j]) / 255.0f; + fcol[BLU] = (float)((channels >= 3) ? ibufscan[j + 2] : ibufscan[j]) / 255.0f; } FLOAT2RGBE(fcol, rgbe); COPY_RGBE(rgbe, rgbe_scan[i]); @@ -409,7 +414,7 @@ static void writeHeader(FILE *file, int width, int height) fputc(10, file); } -int imb_savehdr(struct ImBuf *ibuf, const char *filepath, int flags) +bool imb_savehdr(struct ImBuf *ibuf, const char *filepath, int flags) { FILE *file = BLI_fopen(filepath, "wb"); float *fp = NULL; diff --git a/source/blender/imbuf/intern/readimage.c b/source/blender/imbuf/intern/readimage.c index 8b322eaf052..f0daa4543e1 100644 --- a/source/blender/imbuf/intern/readimage.c +++ b/source/blender/imbuf/intern/readimage.c @@ -282,7 +282,6 @@ ImBuf *IMB_testiffname(const char *filepath, int flags) static void imb_loadtilefile(ImBuf *ibuf, int file, int tx, int ty, unsigned int *rect) { - const ImFileType *type; unsigned char *mem; size_t size; @@ -301,8 +300,9 @@ static void imb_loadtilefile(ImBuf *ibuf, int file, int tx, int ty, unsigned int return; } - for (type = IMB_FILE_TYPES; type < IMB_FILE_TYPES_LAST; type++) { - if (type->load_tile && type->ftype(type, ibuf)) { + const ImFileType *type = IMB_file_type_from_ibuf(ibuf); + if (type != NULL) { + if (type->load_tile != NULL) { type->load_tile(ibuf, mem, size, tx, ty, rect); } } diff --git a/source/blender/imbuf/intern/rectop.c b/source/blender/imbuf/intern/rectop.c index 8b4f33bb306..6ae93def50f 100644 --- a/source/blender/imbuf/intern/rectop.c +++ b/source/blender/imbuf/intern/rectop.c @@ -1069,8 +1069,11 @@ void IMB_rectblend_threaded(ImBuf *dbuf, } } -/* fill */ - +/** + * Replace pixels of entire image with solid color. + * \param ibuf: An image to be filled with color. It must be 4 channel image. + * \param col: RGBA color, which is assigned directly to both byte (via scaling) and float buffers. + */ void IMB_rectfill(ImBuf *drect, const float col[4]) { int num; @@ -1103,6 +1106,61 @@ void IMB_rectfill(ImBuf *drect, const float col[4]) } } +/** + * Replace pixels of image area with solid color. + * \param ibuf: an image to be filled with color. It must be 4 channel image. + * \param col: RGBA color, which is assigned directly to both byte (via scaling) and float buffers. + * \param x1, y1, x2, y2: (x1, y1) defines starting point of the rectangular area to be filled, + * (x2, y2) is the end point. Note that values are allowed to be loosely ordered, which means that + * x2 is allowed to be lower than x1, as well as y2 is allowed to be lower than y1. No matter the + * order the area between x1 and x2, and y1 and y2 is filled. + */ +void IMB_rectfill_area_replace( + const ImBuf *ibuf, const float col[4], int x1, int y1, int x2, int y2) +{ + /* Sanity checks. */ + BLI_assert(ibuf->channels == 4); + + if (ibuf->channels != 4) { + return; + } + + int width = ibuf->x; + int height = ibuf->y; + 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; + } + + unsigned char col_char[4] = {col[0] * 255, col[1] * 255, col[2] * 255, col[3] * 255}; + + for (int y = y1; y < y2; y++) { + for (int x = x1; x < x2; x++) { + size_t offset = ((size_t)ibuf->x) * y * 4 + 4 * x; + + if (ibuf->rect) { + unsigned char *rrect = (unsigned char *)ibuf->rect + offset; + memcpy(rrect, &col_char, sizeof(unsigned char) * 4); + } + + if (ibuf->rect_float) { + float *rrectf = ibuf->rect_float + offset; + memcpy(rrectf, &col, sizeof(float) * 4); + } + } + } +} + void buf_rectfill_area(unsigned char *rect, float *rectf, int width, @@ -1214,6 +1272,21 @@ void buf_rectfill_area(unsigned char *rect, } } +/** + * Blend pixels of image area with solid color. + * + * For images with `uchar` buffer use color matching image color-space. + * For images with float buffer use color display color-space. + * If display color-space can not be referenced, use color in SRGB color-space. + * + * \param ibuf: an image to be filled with color. It must be 4 channel image. + * \param col: RGBA color. + * \param x1, y1, x2, y2: (x1, y1) defines starting point of the rectangular area to be filled, + * (x2, y2) is the end point. Note that values are allowed to be loosely ordered, which means that + * x2 is allowed to be lower than x1, as well as y2 is allowed to be lower than y1. No matter the + * order the area between x1 and x2, and y1 and y2 is filled. + * \param display: color-space reference for display space. + */ void IMB_rectfill_area(ImBuf *ibuf, const float col[4], int x1, diff --git a/source/blender/imbuf/intern/targa.c b/source/blender/imbuf/intern/targa.c index 5f373e4bd3a..a9833623250 100644 --- a/source/blender/imbuf/intern/targa.c +++ b/source/blender/imbuf/intern/targa.c @@ -60,6 +60,14 @@ typedef struct TARGA { unsigned char imgdes; } TARGA; +/** + * On-disk header size. + * + * \note In theory it's possible padding would make the struct and on-disk size differ, + * so use a constant instead of `sizeof(TARGA)`. + */ +#define TARGA_HEADER_SIZE 18 + /***/ static int tga_out1(unsigned int data, FILE *file) @@ -286,14 +294,12 @@ static bool dumptarga(struct ImBuf *ibuf, FILE *file) return 1; } -int imb_savetarga(struct ImBuf *ibuf, const char *filepath, int flags) +bool imb_savetarga(struct ImBuf *ibuf, const char *filepath, int UNUSED(flags)) { - char buf[20] = {0}; + char buf[TARGA_HEADER_SIZE] = {0}; FILE *fildes; bool ok = false; - (void)flags; /* unused */ - buf[16] = (ibuf->planes + 0x7) & ~0x7; if (ibuf->planes > 8) { buf[2] = 10; @@ -326,7 +332,7 @@ int imb_savetarga(struct ImBuf *ibuf, const char *filepath, int flags) return 0; } - if (fwrite(buf, 1, 18, fildes) != 18) { + if (fwrite(buf, 1, TARGA_HEADER_SIZE, fildes) != TARGA_HEADER_SIZE) { fclose(fildes); return 0; } @@ -355,8 +361,12 @@ int imb_savetarga(struct ImBuf *ibuf, const char *filepath, int flags) return ok; } -static int checktarga(TARGA *tga, const unsigned char *mem) +static bool checktarga(TARGA *tga, const unsigned char *mem, const size_t size) { + if (size < TARGA_HEADER_SIZE) { + return false; + } + tga->numid = mem[0]; tga->maptyp = mem[1]; tga->imgtyp = mem[2]; @@ -372,7 +382,7 @@ static int checktarga(TARGA *tga, const unsigned char *mem) tga->imgdes = mem[17]; if (tga->maptyp > 1) { - return 0; + return false; } switch (tga->imgtyp) { case 1: /* raw cmap */ @@ -383,31 +393,31 @@ static int checktarga(TARGA *tga, const unsigned char *mem) case 11: /* b&w */ break; default: - return 0; + return false; } if (tga->mapsize && tga->mapbits > 32) { - return 0; + return false; } if (tga->xsize <= 0) { - return 0; + return false; } if (tga->ysize <= 0) { - return 0; + return false; } if (tga->pixsize > 32) { - return 0; + return false; } if (tga->pixsize == 0) { - return 0; + return false; } - return 1; + return true; } -int imb_is_a_targa(const unsigned char *buf) +bool imb_is_a_targa(const unsigned char *buf, size_t size) { TARGA tga; - return checktarga(&tga, buf); + return checktarga(&tga, buf, size); } static void complete_partial_load(struct ImBuf *ibuf, unsigned int *rect) @@ -627,7 +637,7 @@ ImBuf *imb_loadtarga(const unsigned char *mem, int32_t cp_data; uchar *cp = (uchar *)&cp_data; - if (checktarga(&tga, mem) == 0) { + if (checktarga(&tga, mem, mem_size) == 0) { return NULL; } @@ -647,7 +657,7 @@ ImBuf *imb_loadtarga(const unsigned char *mem, if (tga.imgtyp < 4) { ibuf->foptions.flag |= RAWTGA; } - mem = mem + 18 + tga.numid; + mem = mem + TARGA_HEADER_SIZE + tga.numid; cp[0] = 0xff; cp[1] = cp[2] = 0; @@ -703,7 +713,7 @@ ImBuf *imb_loadtarga(const unsigned char *mem, return ibuf; } - if (tga.imgtyp != 1 && tga.imgtyp != 9) { /* happens sometimes (beuh) */ + if (!ELEM(tga.imgtyp, 1, 9)) { /* happens sometimes (beuh) */ if (cmap) { MEM_freeN(cmap); cmap = NULL; @@ -777,7 +787,7 @@ ImBuf *imb_loadtarga(const unsigned char *mem, ibuf->planes = 24; } - if (tga.imgtyp == 3 || tga.imgtyp == 11) { + if (ELEM(tga.imgtyp, 3, 11)) { uchar *crect; unsigned int *lrect, col; diff --git a/source/blender/imbuf/intern/tiff.c b/source/blender/imbuf/intern/tiff.c index cd0b012d809..587d6ad9e7e 100644 --- a/source/blender/imbuf/intern/tiff.c +++ b/source/blender/imbuf/intern/tiff.c @@ -316,10 +316,13 @@ static TIFF *imb_tiff_client_open(ImbTIFFMemFile *memFile, const unsigned char * * hence my manual comparison. - Jonathan Merritt (lancelet) 4th Sept 2005. */ #define IMB_TIFF_NCB 4 /* number of comparison bytes used */ -int imb_is_a_tiff(const unsigned char *buf) +bool imb_is_a_tiff(const unsigned char *buf, size_t size) { const char big_endian[IMB_TIFF_NCB] = {0x4d, 0x4d, 0x00, 0x2a}; const char lil_endian[IMB_TIFF_NCB] = {0x49, 0x49, 0x2a, 0x00}; + if (size < IMB_TIFF_NCB) { + return false; + } return ((memcmp(big_endian, buf, IMB_TIFF_NCB) == 0) || (memcmp(lil_endian, buf, IMB_TIFF_NCB) == 0)); @@ -578,7 +581,7 @@ ImBuf *imb_loadtiff(const unsigned char *mem, fprintf(stderr, "imb_loadtiff: size < IMB_TIFF_NCB\n"); return NULL; } - if (imb_is_a_tiff(mem) == 0) { + if (imb_is_a_tiff(mem, size) == 0) { return NULL; } @@ -759,8 +762,7 @@ void imb_loadtiletiff( * * \return 1 if the function is successful, 0 on failure. */ - -int imb_savetiff(ImBuf *ibuf, const char *filepath, int flags) +bool imb_savetiff(ImBuf *ibuf, const char *filepath, int flags) { TIFF *image = NULL; uint16 samplesperpixel, bitspersample; @@ -888,7 +890,7 @@ int imb_savetiff(ImBuf *ibuf, const char *filepath, int flags) /* convert from float source */ float rgb[4]; - if (channels_in_float == 3 || channels_in_float == 4) { + if (ELEM(channels_in_float, 3, 4)) { if (ibuf->float_colorspace || (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA)) { /* Float buffer was managed already, no need in color * space conversion. diff --git a/source/blender/imbuf/intern/util.c b/source/blender/imbuf/intern/util.c index 64b03f332a8..64dad5de902 100644 --- a/source/blender/imbuf/intern/util.c +++ b/source/blender/imbuf/intern/util.c @@ -117,75 +117,94 @@ const char *imb_ext_audio[] = { 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; +static ssize_t imb_ispic_read_header_from_filepath(const char *filepath, + unsigned char buf[HEADER_SIZE]) +{ BLI_stat_t st; int fp; - BLI_assert(!BLI_path_is_rel(name)); + BLI_assert(!BLI_path_is_rel(filepath)); if (UTIL_DEBUG) { - printf("%s: loading %s\n", __func__, name); + printf("%s: loading %s\n", __func__, filepath); } - if (BLI_stat(name, &st) == -1) { - return false; + if (BLI_stat(filepath, &st) == -1) { + return -1; } if (((st.st_mode) & S_IFMT) != S_IFREG) { - return false; + return -1; } - if ((fp = BLI_open(name, O_BINARY | O_RDONLY, 0)) == -1) { - return false; + if ((fp = BLI_open(filepath, O_BINARY | O_RDONLY, 0)) == -1) { + return -1; } - memset(buf, 0, sizeof(buf)); - if (read(fp, buf, HEADER_SIZE) <= 0) { - close(fp); - return false; - } + const ssize_t size = read(fp, buf, HEADER_SIZE); close(fp); + return size; +} - /* 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)) { +int IMB_ispic_type_from_memory(const unsigned char *buf, const size_t buf_size) +{ + for (const ImFileType *type = IMB_FILE_TYPES; type < IMB_FILE_TYPES_LAST; type++) { + if (type->is_a != NULL) { + if (type->is_a(buf, buf_size)) { return type->filetype; } } } - return 0; + return IMB_FTYPE_NONE; +} -#undef HEADER_SIZE +int IMB_ispic_type(const char *filepath) +{ + unsigned char buf[HEADER_SIZE]; + const ssize_t buf_size = imb_ispic_read_header_from_filepath(filepath, buf); + if (buf_size <= 0) { + return IMB_FTYPE_NONE; + } + return IMB_ispic_type_from_memory(buf, (size_t)buf_size); +} + +bool IMB_ispic_type_matches(const char *filepath, int filetype) +{ + unsigned char buf[HEADER_SIZE]; + const ssize_t buf_size = imb_ispic_read_header_from_filepath(filepath, buf); + if (buf_size <= 0) { + return false; + } + + const ImFileType *type = IMB_file_type_from_ftype(filetype); + if (type != NULL) { + /* Requesting to load a type that can't check it's own header doesn't make sense. + * Keep the check for developers. */ + BLI_assert(type->is_a != NULL); + if (type->is_a != NULL) { + return type->is_a(buf, (size_t)buf_size); + } + } + return false; } -bool IMB_ispic(const char *name) +#undef HEADER_SIZE + +bool IMB_ispic(const char *filepath) { - return (IMB_ispic_type(name) != 0); + return (IMB_ispic_type(filepath) != IMB_FTYPE_NONE); } -static int isavi(const char *name) +static bool isavi(const char *filepath) { #ifdef WITH_AVI - return AVI_is_avi(name); + return AVI_is_avi(filepath); #else - (void)name; + (void)filepath; return false; #endif } @@ -244,7 +263,7 @@ const char *IMB_ffmpeg_last_error(void) return ffmpeg_last_error; } -static int isffmpeg(const char *filename) +static int isffmpeg(const char *filepath) { AVFormatContext *pFormatCtx = NULL; unsigned int i; @@ -252,7 +271,7 @@ static int isffmpeg(const char *filename) AVCodec *pCodec; AVCodecContext *pCodecCtx; - if (BLI_path_extension_check_n(filename, + if (BLI_path_extension_check_n(filepath, ".swf", ".jpg", ".jp2", @@ -269,7 +288,7 @@ static int isffmpeg(const char *filename) return 0; } - if (avformat_open_input(&pFormatCtx, filename, NULL, NULL) != 0) { + if (avformat_open_input(&pFormatCtx, filepath, NULL, NULL) != 0) { if (UTIL_DEBUG) { fprintf(stderr, "isffmpeg: av_open_input_file failed\n"); } @@ -285,7 +304,7 @@ static int isffmpeg(const char *filename) } if (UTIL_DEBUG) { - av_dump_format(pFormatCtx, 0, filename, 0); + av_dump_format(pFormatCtx, 0, filepath, 0); } /* Find the first video stream */ @@ -324,83 +343,82 @@ static int isffmpeg(const char *filename) } #endif -int imb_get_anim_type(const char *name) +int imb_get_anim_type(const char *filepath) { - int type; BLI_stat_t st; - BLI_assert(!BLI_path_is_rel(name)); + BLI_assert(!BLI_path_is_rel(filepath)); if (UTIL_DEBUG) { - printf("%s: %s\n", __func__, name); + printf("%s: %s\n", __func__, filepath); } #ifndef _WIN32 # ifdef WITH_FFMPEG /* stat test below fails on large files > 4GB */ - if (isffmpeg(name)) { + if (isffmpeg(filepath)) { return ANIM_FFMPEG; } # endif - if (BLI_stat(name, &st) == -1) { + if (BLI_stat(filepath, &st) == -1) { return 0; } if (((st.st_mode) & S_IFMT) != S_IFREG) { return 0; } - if (isavi(name)) { + if (isavi(filepath)) { return ANIM_AVI; } - if (ismovie(name)) { + if (ismovie(filepath)) { return ANIM_MOVIE; } -#else - if (BLI_stat(name, &st) == -1) { +#else /* !_WIN32 */ + if (BLI_stat(filepath, &st) == -1) { return 0; } if (((st.st_mode) & S_IFMT) != S_IFREG) { return 0; } - if (ismovie(name)) { + if (ismovie(filepath)) { return ANIM_MOVIE; } # ifdef WITH_FFMPEG - if (isffmpeg(name)) { + if (isffmpeg(filepath)) { return ANIM_FFMPEG; } # endif - if (isavi(name)) { + if (isavi(filepath)) { return ANIM_AVI; } -#endif - type = IMB_ispic(name); - if (type) { +#endif /* !_WIN32 */ + + /* Assume a single image is part of an image sequence. */ + if (IMB_ispic(filepath)) { return ANIM_SEQUENCE; } return ANIM_NONE; } -bool IMB_isanim(const char *filename) +bool IMB_isanim(const char *filepath) { int type; - type = imb_get_anim_type(filename); + type = imb_get_anim_type(filepath); return (type && type != ANIM_SEQUENCE); } bool IMB_isfloat(const 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; + const ImFileType *type = IMB_file_type_from_ibuf(ibuf); + if (type != NULL) { + if (type->flag & IM_FTYPE_FLOAT) { + return true; } } return false; diff --git a/source/blender/imbuf/intern/writeimage.c b/source/blender/imbuf/intern/writeimage.c index e321470559a..f21d274f8fd 100644 --- a/source/blender/imbuf/intern/writeimage.c +++ b/source/blender/imbuf/intern/writeimage.c @@ -41,10 +41,8 @@ static bool prepare_write_imbuf(const ImFileType *type, ImBuf *ibuf) return IMB_prepare_write_ImBuf((type->flag & IM_FTYPE_FLOAT), ibuf); } -short IMB_saveiff(struct ImBuf *ibuf, const char *filepath, int flags) +bool IMB_saveiff(struct ImBuf *ibuf, const char *filepath, int flags) { - const ImFileType *type; - errno = 0; BLI_assert(!BLI_path_is_rel(filepath)); @@ -54,15 +52,11 @@ short IMB_saveiff(struct ImBuf *ibuf, const char *filepath, int flags) } ibuf->flags = flags; - for (type = IMB_FILE_TYPES; type < IMB_FILE_TYPES_LAST; type++) { - if (type->save && type->ftype(type, ibuf)) { - short result = false; - + const ImFileType *type = IMB_file_type_from_ibuf(ibuf); + if (type != NULL) { + if (type->save != NULL) { prepare_write_imbuf(type, ibuf); - - result = type->save(ibuf, filepath, flags); - - return result; + return type->save(ibuf, filepath, flags); } } |