From 55150edc925e7d74398f39d5bf46212200f53324 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 23 Jan 2009 21:08:01 +0000 Subject: [#18164] jpeg2000 patch, with some fixes from Peter too. Support for jpeg2000 and writing DCI Cinema standard files. Notes * 12 and 16bit channel depths are converted from/to blenders float buffer. * Grayscale/RGB with alpha supported. * Theres an option to save color channels as YCC rather then RGB. * Quality 100 saves lossless * The UI is a bit weired because of the DCI standards need to be given to the encoder. --- source/blender/blenkernel/SConscript | 3 ++ source/blender/blenkernel/intern/image.c | 36 +++++++++++++++++++++ source/blender/blenpluginapi/iff.h | 5 +++ source/blender/imbuf/IMB_imbuf_types.h | 10 ++++++ source/blender/imbuf/intern/readimage.c | 11 ++++++- source/blender/imbuf/intern/util.c | 16 +++++++++- source/blender/imbuf/intern/writeimage.c | 8 +++++ source/blender/makesdna/DNA_scene_types.h | 12 +++++++ source/blender/src/SConscript | 3 ++ source/blender/src/buttons_scene.c | 53 ++++++++++++++++++++++++++++++- source/blender/src/filelist.c | 7 ++++ source/blender/src/writeimage.c | 5 +++ 12 files changed, 166 insertions(+), 3 deletions(-) (limited to 'source/blender') diff --git a/source/blender/blenkernel/SConscript b/source/blender/blenkernel/SConscript index 4ab7d4a6792..fb67c855b81 100644 --- a/source/blender/blenkernel/SConscript +++ b/source/blender/blenkernel/SConscript @@ -42,6 +42,9 @@ if env['WITH_BF_VERSE']: if env['WITH_BF_OPENEXR']: defs += ' WITH_OPENEXR' +if env['WITH_BF_OPENJPEG']: + defs += ' WITH_OPENJPEG' + if env['WITH_BF_DDS']: defs += ' WITH_DDS' diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index d5166fc7a83..e817c38618f 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -767,6 +767,10 @@ int BKE_imtype_to_ftype(int imtype) return RAWTGA; else if(imtype==R_HAMX) return AN_hamx; +#ifdef WITH_OPENJPEG + else if(imtype==R_JP2) + return JP2; +#endif else return JPG|90; } @@ -801,6 +805,10 @@ int BKE_ftype_to_imtype(int ftype) return R_RAWTGA; else if(ftype == AN_hamx) return R_HAMX; +#ifdef WITH_OPENJPEG + else if(ftype & JP2) + return R_JP2; +#endif else return R_JPEG90; } @@ -877,6 +885,12 @@ void BKE_add_image_extension(char *string, int imtype) if(!BLI_testextensie(string, ".tga")) extension= ".tga"; } +#ifdef WITH_OPENJPEG + else if(imtype==R_JP2) { + if(!BLI_testextensie(string, ".jp2")) + extension= ".jp2"; + } +#endif else { // R_MOVIE, R_AVICODEC, R_AVIRAW, R_AVIJPEG, R_JPEG90, R_QUICKTIME etc if(!( BLI_testextensie(string, ".jpg") || BLI_testextensie(string, ".jpeg"))) extension= ".jpg"; @@ -1220,6 +1234,28 @@ int BKE_write_ibuf(ImBuf *ibuf, char *name, int imtype, int subimtype, int quali else if(imtype==R_HAMX) { ibuf->ftype= AN_hamx; } +#ifdef WITH_OPENJPEG + else if(imtype==R_JP2) { + if(quality < 10) quality= 90; + ibuf->ftype= JP2|quality; + + if (subimtype & R_JPEG2K_16BIT) { + ibuf->ftype |= JP2_16BIT; + } else if (subimtype & R_JPEG2K_12BIT) { + ibuf->ftype |= JP2_12BIT; + } + + if (subimtype & R_JPEG2K_YCC) { + ibuf->ftype |= JP2_YCC; + } + + if (subimtype & R_JPEG2K_CINE_PRESET) { + ibuf->ftype |= JP2_CINE; + if (subimtype & R_JPEG2K_CINE_48FPS) + ibuf->ftype |= JP2_CINE_48FPS; + } + } +#endif else { /* R_JPEG90, R_MOVIE, etc. default we save jpegs */ if(quality < 10) quality= 90; diff --git a/source/blender/blenpluginapi/iff.h b/source/blender/blenpluginapi/iff.h index 92cbd7dd093..e7f328d870f 100644 --- a/source/blender/blenpluginapi/iff.h +++ b/source/blender/blenpluginapi/iff.h @@ -56,6 +56,10 @@ #endif #define RADHDR (1<<24) +#ifdef WITH_OPENJPEG +#define JP2 (1 << 18) +#endif + #define RAWTGA (TGA | 1) #define JPG_STD (JPG | (0 << 8)) @@ -113,6 +117,7 @@ #define IS_tim(x) (x->ftype & TIM) #define IS_tiff(x) (x->ftype & TIFF) #define IS_openexr(x) (x->ftype & OPENEXR) +#define IS_jp2(x) (x->ftype & JP2) #define IMAGIC 0732 diff --git a/source/blender/imbuf/IMB_imbuf_types.h b/source/blender/imbuf/IMB_imbuf_types.h index 73ef83393b0..eadd7affe6a 100644 --- a/source/blender/imbuf/IMB_imbuf_types.h +++ b/source/blender/imbuf/IMB_imbuf_types.h @@ -181,6 +181,15 @@ typedef enum { #define DDS (1 << 19) #endif +#ifdef WITH_OPENJPEG +#define JP2 (1 << 18) +#define JP2_12BIT (1 << 17) +#define JP2_16BIT (1 << 16) +#define JP2_YCC (1 << 15) +#define JP2_CINE (1 << 14) +#define JP2_CINE_48FPS (1 << 13) +#endif + #define RAWTGA (TGA | 1) #define JPG_STD (JPG | (0 << 8)) @@ -217,6 +226,7 @@ typedef enum { #define IS_tga(x) (x->ftype & TGA) #define IS_png(x) (x->ftype & PNG) #define IS_openexr(x) (x->ftype & OPENEXR) +#define IS_jp2(x) (x->ftype & JP2) #define IS_cineon(x) (x->ftype & CINEON) #define IS_dpx(x) (x->ftype & DPX) #define IS_bmp(x) (x->ftype & BMP) diff --git a/source/blender/imbuf/intern/readimage.c b/source/blender/imbuf/intern/readimage.c index 05e7921665b..6df92f69fff 100644 --- a/source/blender/imbuf/intern/readimage.c +++ b/source/blender/imbuf/intern/readimage.c @@ -58,6 +58,10 @@ #include "IMB_dpxcineon.h" #include "BKE_global.h" +#ifdef WITH_OPENJPEG +#include "IMB_jp2.h" +#endif + #ifdef WITH_OPENEXR #include "openexr/openexr_api.h" #endif @@ -161,11 +165,16 @@ ImBuf *IMB_ibImageFromMemory(int *mem, int size, int flags) { if (ibuf) return (ibuf); #endif +#ifdef WITH_OPENJPEG + ibuf = imb_jp2_decode((uchar *)mem, size, flags); + if (ibuf) return (ibuf); +#endif + #ifdef WITH_DDS ibuf = imb_load_dds((uchar *)mem, size, flags); if (ibuf) return (ibuf); #endif - + #ifdef WITH_QUICKTIME #if defined(_WIN32) || defined (__APPLE__) if(G.have_quicktime) { diff --git a/source/blender/imbuf/intern/util.c b/source/blender/imbuf/intern/util.c index cf8c0978c66..15d1d031dbd 100644 --- a/source/blender/imbuf/intern/util.c +++ b/source/blender/imbuf/intern/util.c @@ -68,6 +68,10 @@ #include "quicktime_import.h" #endif +#ifdef WITH_OPENJPEG +#include "IMB_jp2.h" +#endif + #ifdef WITH_FFMPEG #include #include @@ -140,7 +144,11 @@ static int IMB_ispic_name(char *name) /* if (imb_is_a_bmp(buf)) return(BMP); */ - + +#ifdef WITH_OPENJPEG + if (imb_is_a_jp2(buf)) return(JP2); +#endif + #ifdef WITH_QUICKTIME #if defined(_WIN32) || defined(__APPLE__) if(G.have_quicktime) { @@ -190,6 +198,9 @@ int IMB_ispic(char *filename) || BLI_testextensie(filename, ".cin") #ifdef WITH_BF_OPENEXR || BLI_testextensie(filename, ".exr") +#endif +#ifdef WITH_BF_OPENJPEG + || BLI_testextensie(filename, ".jp2") #endif || BLI_testextensie(filename, ".sgi")) { return IMB_ispic_name(filename); @@ -210,6 +221,9 @@ int IMB_ispic(char *filename) #endif #ifdef WITH_BF_OPENEXR || BLI_testextensie(filename, ".exr") +#endif +#ifdef WITH_BF_OPENJPEG + || BLI_testextensie(filename, ".jp2") #endif || BLI_testextensie(filename, ".iff") || BLI_testextensie(filename, ".lbm") diff --git a/source/blender/imbuf/intern/writeimage.c b/source/blender/imbuf/intern/writeimage.c index 5a4f83a473b..5df0595d97f 100644 --- a/source/blender/imbuf/intern/writeimage.c +++ b/source/blender/imbuf/intern/writeimage.c @@ -55,6 +55,9 @@ #include "IMB_bmp.h" #include "IMB_tiff.h" #include "IMB_radiance_hdr.h" +#ifdef WITH_OPENJPEG +#include "IMB_jp2.h" +#endif #ifdef WITH_OPENEXR #include "openexr/openexr_api.h" #endif @@ -129,6 +132,11 @@ short IMB_saveiff(struct ImBuf *ibuf, char *name, int flags) if (IS_dpx(ibuf)) { return imb_save_dpx(ibuf, name, flags); } +#ifdef WITH_OPENJPEG + if (IS_jp2(ibuf)) { + return imb_savejp2(ibuf, name, flags); + } +#endif file = open(name, O_BINARY | O_RDWR | O_CREAT | O_TRUNC, 0666); if (file < 0) return (FALSE); diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index f92311312fa..09c2344d53a 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -310,6 +310,10 @@ typedef struct RenderData { /* cineon */ short cineonwhite, cineonblack; float cineongamma; + + /* jpeg2000 */ + short jp2_preset, jp2_depth; + int rpad3; } RenderData; /* control render convert and shading engine */ @@ -692,6 +696,7 @@ typedef struct Scene { #define R_DPX 27 #define R_MULTILAYER 28 #define R_DDS 29 +#define R_JP2 30 /* subimtype, flag options for imtype */ #define R_OPENEXR_HALF 1 @@ -700,6 +705,13 @@ typedef struct Scene { #define R_CINEON_LOG 8 #define R_TIFF_16BIT 16 +#define R_JPEG2K_12BIT 32 /* Jpeg2000 */ +#define R_JPEG2K_16BIT 64 +#define R_JPEG2K_YCC 128 /* when disabled use RGB */ +#define R_JPEG2K_CINE_PRESET 256 +#define R_JPEG2K_CINE_48FPS 512 + + /* bake_mode: same as RE_BAKE_xxx defines */ /* bake_flag: */ #define R_BAKE_CLEAR 1 diff --git a/source/blender/src/SConscript b/source/blender/src/SConscript index 451afc9b244..384ad1b1bf2 100644 --- a/source/blender/src/SConscript +++ b/source/blender/src/SConscript @@ -53,6 +53,9 @@ if env['WITH_BF_INTERNATIONAL']: if env['WITH_BF_OPENEXR']: defs.append('WITH_OPENEXR') +if env['WITH_BF_OPENJPEG']: + defs.append('WITH_OPENJPEG') + if env['WITH_BF_DDS']: defs.append('WITH_DDS') diff --git a/source/blender/src/buttons_scene.c b/source/blender/src/buttons_scene.c index ea7411af621..376a57b11e9 100644 --- a/source/blender/src/buttons_scene.c +++ b/source/blender/src/buttons_scene.c @@ -1956,7 +1956,6 @@ static char *imagetype_pup(void) char appendstring[1024]; strcpy(formatstring, "Save image as: %%t|%s %%x%d|%s %%x%d|%s %%x%d|%s %%x%d|%s %%x%d|%s %%x%d|%s %%x%d"); - #ifdef __sgi strcat(formatstring, "|%s %%x%d"); // add space for Movie #endif @@ -1967,6 +1966,10 @@ static char *imagetype_pup(void) strcat(formatstring, "|%s %%x%d"); // add space for DDS #endif */ +#ifdef WITH_OPENJPEG + strcat(formatstring, "|%s %%x%d"); // add space for JP2 +#endif + strcat(formatstring, "|%s %%x%d"); // add space for BMP strcat(formatstring, "|%s %%x%d"); // add space for Radiance HDR strcat(formatstring, "|%s %%x%d"); // add space for Cineon @@ -2008,6 +2011,9 @@ static char *imagetype_pup(void) "DDS", R_DDS, #endif */ +#ifdef WITH_OPENJPEG + "Jpeg 2000", R_JP2, +#endif "BMP", R_BMP, "Jpeg", R_JPEG90, "HamX", R_HAMX, @@ -2015,6 +2021,7 @@ static char *imagetype_pup(void) "Radiance HDR", R_RADHDR, "Cineon", R_CINEON, "DPX", R_DPX + #ifdef __sgi ,"Movie", R_MOVIE #endif @@ -2036,6 +2043,9 @@ static char *imagetype_pup(void) /*#ifdef WITH_DDS "DDS", R_DDS, #endif*/ +#ifdef WITH_OPENJPEG + "Jpeg 2000", R_JP2, +#endif "BMP", R_BMP, "Jpeg", R_JPEG90, "HamX", R_HAMX, @@ -2043,6 +2053,8 @@ static char *imagetype_pup(void) "Radiance HDR", R_RADHDR, "Cineon", R_CINEON, "DPX", R_DPX + + #ifdef __sgi ,"Movie", R_MOVIE #endif @@ -3152,6 +3164,45 @@ static void render_panel_format(void) uiDefButS(block, NUM,B_DIFF, "Q:", 892,yofs,74,20, &G.scene->r.quality, 10.0, 100.0, 0, 0, "Quality setting for JPEG images, AVI Jpeg and SGI movies"); } + +#ifdef WITH_OPENJPEG + if (G.scene->r.imtype == R_JP2) { + + uiDefButS(block, MENU,B_REDR, + "Preset %t|No Preset %x0|" + "Cinema 24fps 2048x1080%x1|" + "Cinema 48fps 2048x1080%x2|" + "Cinema 24fps 4096x2160%x3|" + "Cine-Scope 24fps 2048x858%x4|" + "Cine-Scope 48fps 2048x858%x5|" + "Cine-Flat 24fps 1998x1080%x6|" + "Cine-Flat 48fps 1998x1080%x7", + 892,yofs+44,G.scene->r.jp2_preset?227:110,20, &G.scene->r.jp2_preset, 0, 0, 0, 0, "Use a DCI Standard preset for saving jpeg2000"); + + if (G.scene->r.jp2_preset==0) { + uiBlockBeginAlign(block); + uiDefButS(block, ROW,B_REDR,"8", 1007,yofs+44,20,20, &G.scene->r.jp2_depth,1.0,8.0, 0, 0,""); + uiDefButS(block, ROW,B_REDR,"12",1007+20,yofs+44,25,20, &G.scene->r.jp2_depth,1.0,12.0, 0, 0,""); + uiDefButS(block, ROW,B_REDR,"16", 1007+45,yofs+44,25,20, &G.scene->r.jp2_depth,1.0,16.0, 0, 0,""); + uiDefButBitS(block, TOG, R_JPEG2K_YCC, B_REDR,"YCC",1007+70,yofs+44,42,20, &G.scene->r.subimtype, 0, 0, 0, 0, "Save luminance-chrominance-chrominance instead of RGB color channels "); + uiBlockEndAlign(block); + } + + G.scene->r.subimtype &= ~(R_JPEG2K_12BIT|R_JPEG2K_16BIT | R_JPEG2K_CINE_PRESET|R_JPEG2K_CINE_48FPS); + if (G.scene->r.jp2_depth==12) G.scene->r.subimtype |= R_JPEG2K_12BIT; + if (G.scene->r.jp2_depth==16) G.scene->r.subimtype |= R_JPEG2K_16BIT; + + if (G.scene->r.jp2_preset==1) G.scene->r.subimtype |= R_JPEG2K_CINE_PRESET; + if (G.scene->r.jp2_preset==2) G.scene->r.subimtype |= R_JPEG2K_CINE_PRESET|R_JPEG2K_CINE_48FPS; + if (G.scene->r.jp2_preset==3) G.scene->r.subimtype |= R_JPEG2K_CINE_PRESET; + if (G.scene->r.jp2_preset==4) G.scene->r.subimtype |= R_JPEG2K_CINE_PRESET; + if (G.scene->r.jp2_preset==5) G.scene->r.subimtype |= R_JPEG2K_CINE_PRESET|R_JPEG2K_CINE_48FPS; + if (G.scene->r.jp2_preset==6) G.scene->r.subimtype |= R_JPEG2K_CINE_PRESET; + if (G.scene->r.jp2_preset==7) G.scene->r.subimtype |= R_JPEG2K_CINE_PRESET|R_JPEG2K_CINE_48FPS; + + } +#endif + uiDefButS(block, NUM,B_FRAMEMAP,"FPS:", 968,yofs,75,20, &G.scene->r.frs_sec, 1.0, 120.0, 100.0, 0, "Frames per second"); uiDefButF(block, NUM,B_FRAMEMAP,"/", 1043,yofs,75,20, &G.scene->r.frs_sec_base, 1.0, 120.0, 0.1, 3, "Frames per second base"); diff --git a/source/blender/src/filelist.c b/source/blender/src/filelist.c index c2c0f00885f..008bcbe147d 100644 --- a/source/blender/src/filelist.c +++ b/source/blender/src/filelist.c @@ -678,6 +678,9 @@ void BIF_filelist_setfiletypes(struct FileList* filelist, short has_quicktime) if( BLI_testextensie(file->relname, ".int") || BLI_testextensie(file->relname, ".inta") || BLI_testextensie(file->relname, ".jpg") +#ifdef WITH_OPENJPEG + || BLI_testextensie(file->relname, ".jp2") +#endif || BLI_testextensie(file->relname, ".jpeg") || BLI_testextensie(file->relname, ".tga") || BLI_testextensie(file->relname, ".rgb") @@ -721,6 +724,10 @@ void BIF_filelist_setfiletypes(struct FileList* filelist, short has_quicktime) if(BLI_testextensie(file->relname, ".int") || BLI_testextensie(file->relname, ".inta") || BLI_testextensie(file->relname, ".jpg") + || BLI_testextensie(file->relname, ".jpeg") +#ifdef WITH_OPENJPEG + || BLI_testextensie(file->relname, ".jp2") +#endif || BLI_testextensie(file->relname, ".tga") || BLI_testextensie(file->relname, ".rgb") || BLI_testextensie(file->relname, ".rgba") diff --git a/source/blender/src/writeimage.c b/source/blender/src/writeimage.c index b21c14bed35..a611353026e 100644 --- a/source/blender/src/writeimage.c +++ b/source/blender/src/writeimage.c @@ -190,6 +190,11 @@ void save_image_filesel_str(char *str) case R_MULTILAYER: strcpy(str, "Save Multi Layer EXR"); break; +#ifdef WITH_OPENJPEG + case R_JP2: + strcpy(str, "Save JPEG2000"); + break; +#endif /* default we save jpeg, also for all movie formats */ case R_JPEG90: case R_MOVIE: -- cgit v1.2.3