[#18164] jpeg2000 patch, with some fixes from Peter too.
authorCampbell Barton <ideasman42@gmail.com>
Fri, 23 Jan 2009 21:08:01 +0000 (21:08 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Fri, 23 Jan 2009 21:08:01 +0000 (21:08 +0000)
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.

16 files changed:
config/irix6-config.py
config/linux2-config.py
config/win32-vc-config.py
source/blender/blenkernel/SConscript
source/blender/blenkernel/intern/image.c
source/blender/blenpluginapi/iff.h
source/blender/imbuf/IMB_imbuf_types.h
source/blender/imbuf/intern/readimage.c
source/blender/imbuf/intern/util.c
source/blender/imbuf/intern/writeimage.c
source/blender/makesdna/DNA_scene_types.h
source/blender/src/SConscript
source/blender/src/buttons_scene.c
source/blender/src/filelist.c
source/blender/src/writeimage.c
source/creator/creator.c

index 2485c02e0950da2e51d8e5548fe1615ccc146e6e..81a301fbb038eb1ff1a25333bb8297688d84194d 100644 (file)
@@ -159,7 +159,7 @@ BF_OGG_LIB = 'ogg vorbis theoraenc theoradec'
 WITH_BF_OPENJPEG = 'false' 
 BF_OPENJPEG = '#extern/libopenjpeg'
 BF_OPENJPEG_LIB = ''
-BF_OPENJPEG_INC = '${BF_OPENJPEG}/include'
+BF_OPENJPEG_INC = '${BF_OPENJPEG}'
 BF_OPENJPEG_LIBPATH='${BF_OPENJPEG}/lib'
 
 WITH_BF_REDCODE = 'false'  
index a1f979d26daf23a7292e55fabebcb04e06bbc8c1..6ba3052048d088d3d229ac745e7e3129035527fb 100644 (file)
@@ -157,7 +157,7 @@ BF_OGG_LIB = 'ogg vorbis theoraenc theoradec'
 WITH_BF_OPENJPEG = True 
 BF_OPENJPEG = '#extern/libopenjpeg'
 BF_OPENJPEG_LIB = ''
-BF_OPENJPEG_INC = '${BF_OPENJPEG}/include'
+BF_OPENJPEG_INC = '${BF_OPENJPEG}'
 BF_OPENJPEG_LIBPATH='${BF_OPENJPEG}/lib'
 
 WITH_BF_REDCODE = False  
index d7165401705d9872ed79a4f0b1738a5c81521b6f..d4e9fa9b30ebad942b8998d4a48d69a6c3d12752 100644 (file)
@@ -153,6 +153,10 @@ BF_QUICKTIME_LIB = 'qtmlClient'
 BF_QUICKTIME_LIBPATH = '${BF_QUICKTIME}/Libraries'
 
 WITH_BF_OPENJPEG = True 
+BF_OPENJPEG = '#extern/libopenjpeg'
+BF_OPENJPEG_LIB = ''
+BF_OPENJPEG_INC = '${BF_OPENJPEG}'
+BF_OPENJPEG_LIBPATH='${BF_OPENJPEG}/lib'
 
 WITH_BF_REDCODE = False  
 BF_REDCODE_INC = '#extern'
index 4ab7d4a679250239b10f82db5cb2213895826128..fb67c855b81876eb159ca621887f22c1db6d5c87 100644 (file)
@@ -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'
 
index d5166fc7a838d49075edf8c501eb3407f5e3ff55..e817c38618f3a2e389e7fe7202675aa2553d64db 100644 (file)
@@ -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;
index 92cbd7dd0939ce347544bd636436700053ff388d..e7f328d870f8084f97b8d99417fffb85522f7e64 100644 (file)
 #endif
 #define RADHDR  (1<<24)
 
+#ifdef WITH_OPENJPEG
+#define JP2                            (1 << 18)
+#endif
+
 #define RAWTGA (TGA | 1)
 
 #define JPG_STD        (JPG | (0 << 8))
 #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
index 73ef83393b02234adfda0c77f66974018803ab47..eadd7affe6aa2577766a975726eaa5955efc9318 100644 (file)
@@ -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)
index 05e7921665bc2707fbda9fe2f59602a0bb52c976..6df92f69fffee8e0947b33ab456b8ef8bc6ea450 100644 (file)
 #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) {
index cf8c0978c669ab49f05e3f85aa532b0d5e337639..15d1d031dbd658fe9f876a1b18d9bfca4b61777f 100644 (file)
 #include "quicktime_import.h"
 #endif
 
+#ifdef WITH_OPENJPEG
+#include "IMB_jp2.h"
+#endif
+
 #ifdef WITH_FFMPEG
 #include <ffmpeg/avcodec.h>
 #include <ffmpeg/avformat.h>
@@ -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")
index 5a4f83a473baa6875109549bbd938b31e71b6a90..5df0595d97fb8f01c19db64bd5f20a505cd08b58 100644 (file)
@@ -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);
 
index f92311312fa88e56deafddd6a9adb95d6929b447..09c2344d53acc6abebf6370f4f99251deeaa794c 100644 (file)
@@ -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
index 451afc9b244118a0213df7c8902c40594c57b162..384ad1b1bf261723475153125d0b55fdd3cd3b2a 100644 (file)
@@ -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')
 
index ea7411af621aa1cdf29beef26cf4effc8ba665d1..376a57b11e9430c64204d3bed9eaab89f20eb05d 100644 (file)
@@ -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");
 
index c2c0f00885f80ebf00d8c449a0c3a5335d693fe4..008bcbe147d47842a78fdbc1bd52d663ae78adfb 100644 (file)
@@ -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")
index b21c14bed35c47157a8802f6b617cd7c8f28e1c9..a611353026ec4b5ea000374363a55360d1af5eec 100644 (file)
@@ -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:
index 9d6841c3708f0cd2e6248887903641b07b864803..5c0ca9e07ff77a3a960f912a6611dace7b62ff21 100644 (file)
@@ -776,6 +776,9 @@ int main(int argc, char **argv)
                                                else if (!strcmp(argv[a],"FRAMESERVER")) G.scene->r.imtype = R_FRAMESERVER;
                                                else if (!strcmp(argv[a],"CINEON")) G.scene->r.imtype = R_CINEON;
                                                else if (!strcmp(argv[a],"DPX")) G.scene->r.imtype = R_DPX;
+#if WITH_OPENJPEG
+                                               else if (!strcmp(argv[a],"JP2")) G.scene->r.imtype = R_JP2;
+#endif
                                                else printf("\nError: Format from '-F' not known or not compiled in this release.\n");
                                        }
                                } else {