[#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.
This commit is contained in:
Campbell Barton 2009-01-23 21:08:01 +00:00
parent 8a95c67a50
commit 55150edc92
16 changed files with 175 additions and 5 deletions

@ -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'

@ -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

@ -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'

@ -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'

@ -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;

@ -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

@ -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)

@ -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) {

@ -68,6 +68,10 @@
#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")

@ -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);

@ -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

@ -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')

@ -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");

@ -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")

@ -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:

@ -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 {