diff options
Diffstat (limited to 'libopenjpeg/opj_convert.c')
| -rw-r--r-- | libopenjpeg/opj_convert.c | 315 |
1 files changed, 315 insertions, 0 deletions
diff --git a/libopenjpeg/opj_convert.c b/libopenjpeg/opj_convert.c new file mode 100644 index 00000000..33216655 --- /dev/null +++ b/libopenjpeg/opj_convert.c @@ -0,0 +1,315 @@ +#include "opj_includes.h" +#include "opj_convert.h" +/* + * The yuv code is based on cinelerra-VERSION/quicktime/rtjpeg_core.c +*/ +#define KcrR 76284 +#define KcrG 53281 +#define KcbG 25625 +#define KcbB 132252 +#define Ky 76284 + +static void opj_convert_yuv444(opj_image_t *img) +{ + int *d0, *d1, *d2, *red, *green, *blue; + const int *sY, *sCb, *sCr; + int maxw, maxh, max, i; + int R, G, B, C, D, E; + int shiftR, shiftG, shiftB; + int addR, addG, addB; + + maxw = img->comps[0].w; maxh = img->comps[0].h; + max = maxw * maxh; + + sY = img->comps[0].data; + sCb = img->comps[1].data; + sCr = img->comps[2].data; + + if(img->comps[0].prec > 8) + shiftR = img->comps[0].prec - 8; + else + shiftR = 0; + + if(img->comps[1].prec > 8) + shiftG = img->comps[1].prec - 8; + else + shiftG = 0; + + if(img->comps[2].prec > 8) + shiftB = img->comps[2].prec - 8; + else + shiftB = 0; + + addR = (img->comps[0].sgnd ? 1 << (img->comps[0].prec - 1) : 0); + addG = (img->comps[1].sgnd ? 1 << (img->comps[1].prec - 1) : 0); + addB = (img->comps[2].sgnd ? 1 << (img->comps[2].prec - 1) : 0); + + d0 = red = (int*)opj_malloc(sizeof(int) * max); + d1 = green = (int*)opj_malloc(sizeof(int) * max); + d2 = blue = (int*)opj_malloc(sizeof(int) * max); + + for(i = 0; i < max; ++i) + { + C = ((*sY++ + addR) >> shiftR) - 16; + D = ((*sCb++ + addG) >> shiftG) - 128; + E = ((*sCr++ + addB) >> shiftB) - 128; + + + R = (298 * C + 409 * E + 128)>>8; + if(R < 0) R = 0; else if(R > 255) R = 255; + + G = (298 * C - 100 * D - 208 * E + 128)>>8; + if(G < 0) G = 0; else if(G > 255) G = 255; + + B = (298 * C + 516 * D + 128)>>8; + if(B < 0) B = 0; else if(B > 255) B = 255; + + *d0++ = R; *d1++ = G; *d2++ = B; + + } + opj_free(img->comps[0].data); img->comps[0].data = red; + opj_free(img->comps[1].data); img->comps[1].data = green; + opj_free(img->comps[2].data); img->comps[2].data = blue; + + img->comps[0].prec = 8; img->comps[1].prec = 8; img->comps[2].prec = 8; +}/* opj_convert_yuv444() */ + +static void yuv422rgb(int *src_y, int *src_cb, int *src_cr, int *red, + int *green, int *blue, int width, int height) +{ + int i, j, tmp; + int y, crR, crG, cbG, cbB; + + for(i=0; i<height; i++) + { + for(j=0; j<width; j+=2) + { + crR=(*src_cr - 128)*KcrR; + crG=(*src_cr - 128)*KcrG; ++src_cr; + cbG=(*src_cb - 128)*KcbG; + cbB=(*src_cb - 128)*KcbB; ++src_cb; + + y=(src_y[j]-16)*Ky; + + tmp=(y+crR)>>16; + if(tmp < 0) tmp = 0; else if(tmp > 255) tmp = 255; + *red++ = tmp; + + tmp=(y-crG-cbG)>>16; + if(tmp < 0) tmp = 0; else if(tmp > 255) tmp = 255; + *green++ = tmp; + + tmp=(y+cbB)>>16; + if(tmp < 0) tmp = 0; else if(tmp > 255) tmp = 255; + *blue = tmp; + + y=(src_y[j+1]-16)*Ky; + + tmp=(y+crR)>>16; + if(tmp < 0) tmp = 0; else if(tmp > 255) tmp = 255; + *red++ = tmp; + + tmp=(y-crG-cbG)>>16; + if(tmp < 0) tmp = 0; else if(tmp > 255) tmp = 255; + *green++ = tmp; + + tmp=(y+cbB)>>16; + if(tmp < 0) tmp = 0; else if(tmp > 255) tmp = 255; + *blue++ = tmp; + } + src_y += width; + } +}/* yuv422rgb() */ + +static void yuv420rgb(const int *src_y, const int *src_cb, + const int *src_cr, int *red, int *green, int *blue, + int width, int height) +{ + int *red_e, *green_e, *blue_e, *red_o, *green_o, *blue_o; + int y, crR, crG, cbG, cbB, i, j, tmp; + int yskip; + + yskip = width; + red_e = red; green_e = green; blue_e = blue; + red_o = red + width; green_o = green + width; blue_o = blue + width; + + for(i=0; i < (height>>1); i++) + { + for(j=0; j < width; j+=2) + { + crR=(*src_cr-128)*KcrR; + crG=(*(src_cr++)-128)*KcrG; + cbG=(*src_cb-128)*KcbG; + cbB=(*(src_cb++)-128)*KcbB; + + y=(src_y[j]-16)*Ky; + + tmp=(y+crR)>>16; + if(tmp < 0) tmp = 0; else if(tmp > 255) tmp = 255; + *red_e++ = tmp;//*(bufoute++)=(tmp>255)?255:((tmp<0)?0:tmp); + + tmp=(y-crG-cbG)>>16; + if(tmp < 0) tmp = 0; else if(tmp > 255) tmp = 255; + *green_e++ = tmp;//*(bufoute++)=(tmp>255)?255:((tmp<0)?0:tmp); + + tmp=(y+cbB)>>16; + if(tmp < 0) tmp = 0; else if(tmp > 255) tmp = 255; + *blue_e++ = tmp;//*(bufoute++)=(tmp>255)?255:((tmp<0)?0:tmp); + + y=(src_y[j+1]-16)*Ky; + + tmp=(y+crR)>>16; + if(tmp < 0) tmp = 0; else if(tmp > 255) tmp = 255; + *red_e++ = tmp;//*(bufoute++)=(tmp>255)?255:((tmp<0)?0:tmp); + + tmp=(y-crG-cbG)>>16; + if(tmp < 0) tmp = 0; else if(tmp > 255) tmp = 255; + *green_e++ = tmp;//*(bufoute++)=(tmp>255)?255:((tmp<0)?0:tmp); + + tmp=(y+cbB)>>16; + if(tmp < 0) tmp = 0; else if(tmp > 255) tmp = 255; + *blue_e++ = tmp;//*(bufoute++)=(tmp>255)?255:((tmp<0)?0:tmp); + + y=(src_y[j+yskip]-16)*Ky; + + tmp=(y+crR)>>16; + if(tmp < 0) tmp = 0; else if(tmp > 255) tmp = 255; + *red_o++ = tmp;//*(bufouto++)=(tmp>255)?255:((tmp<0)?0:tmp); + + tmp=(y-crG-cbG)>>16; + if(tmp < 0) tmp = 0; else if(tmp > 255) tmp = 255; + *green_o++ = tmp;//*(bufouto++)=(tmp>255)?255:((tmp<0)?0:tmp); + + tmp=(y+cbB)>>16; + if(tmp < 0) tmp = 0; else if(tmp > 255) tmp = 255; + *blue_o++ = tmp;//*(bufouto++)=(tmp>255)?255:((tmp<0)?0:tmp); + + y=(src_y[j+1+yskip]-16)*Ky; + + tmp=(y+crR)>>16; + if(tmp < 0) tmp = 0; else if(tmp > 255) tmp = 255; + *red_o++ = tmp;//*(bufouto++)=(tmp>255)?255:((tmp<0)?0:tmp); + + tmp=(y-crG-cbG)>>16; + if(tmp < 0) tmp = 0; else if(tmp > 255) tmp = 255; + *green_o++ = tmp;//*(bufouto++)=(tmp>255)?255:((tmp<0)?0:tmp); + + tmp=(y+cbB)>>16; + if(tmp < 0) tmp = 0; else if(tmp > 255) tmp = 255; + *blue_o++ = tmp;//*(bufouto++)=(tmp>255)?255:((tmp<0)?0:tmp); + + } + red_e += width; green_e += width; blue_e += width; + red_o += width; green_o += width; blue_o += width; + src_y += width<<1; + } +}/* yuv420rgb() */ + +static void opj_convert_yuv422(opj_image_t *img) +{ + int *y, *cb, *cr, *red, *green, *blue; + int maxy, maxw, maxh; + + maxw = img->comps[0].w; maxh = img->comps[0].h; + maxy = maxw * maxh; + + y = img->comps[0].data; + cb = img->comps[1].data; + cr = img->comps[2].data; + +//YUV422 -> YUV444 -> RGB + red = (int*)opj_calloc(sizeof(int), maxy); + green = (int*)opj_calloc(sizeof(int), maxy); + blue = (int*)opj_calloc(sizeof(int), maxy); + + yuv422rgb(y, cb, cr, red, green, blue, maxw, maxh); + + opj_free(img->comps[0].data); img->comps[0].data = red; + opj_free(img->comps[1].data); img->comps[1].data = green; + opj_free(img->comps[2].data); img->comps[2].data = blue; + + img->comps[1].w = maxw; img->comps[2].h = maxh; + img->comps[1].dx = img->comps[0].dx; + img->comps[2].dx = img->comps[0].dx; + img->comps[1].dy = img->comps[0].dy; + img->comps[2].dy = img->comps[0].dy; + + img->comps[0].prec = 8; img->comps[1].prec = 8; img->comps[2].prec = 8; +} + +static void opj_convert_yuv420(opj_image_t *img) +{ + int *y, *cb, *cr, *red, *green, *blue; + int maxy, maxw, maxh; + + maxw = img->comps[0].w; maxh = img->comps[0].h; + maxy = maxw * maxh; + + y = img->comps[0].data; + cb = img->comps[1].data; + cr = img->comps[2].data; + +//YUV420 -> YUV422 -> YUV444 -> RGB + red = (int*)opj_calloc(sizeof(int), maxy); + green = (int*)opj_calloc(sizeof(int), maxy); + blue = (int*)opj_calloc(sizeof(int), maxy); + + yuv420rgb(y, cb, cr, red, green, blue, maxw, maxh); + + opj_free(img->comps[0].data); img->comps[0].data = red; + opj_free(img->comps[1].data); img->comps[1].data = green; + opj_free(img->comps[2].data); img->comps[2].data = blue; + + img->comps[1].w = maxw; img->comps[2].h = maxh; + img->comps[1].dx = img->comps[0].dx; + img->comps[2].dx = img->comps[0].dx; + img->comps[1].dy = img->comps[0].dy; + img->comps[2].dy = img->comps[0].dy; + + img->comps[0].prec = 8; img->comps[1].prec = 8; img->comps[2].prec = 8; +} + +void opj_convert_sycc_to_rgb(opj_image_t *img) +{ + if(img->numcomps < 3) + { + img->color_space = CLRSPC_GRAY; + return; + } + if((img->comps[0].dx == 1) + && (img->comps[1].dx == 2) + && (img->comps[2].dx == 2) + && (img->comps[0].dy == 1) + && (img->comps[1].dy == 2) + && (img->comps[2].dy == 2))// horizontal and vertical + { + opj_convert_yuv420(img); + } + else + if((img->comps[0].dx == 1) + && (img->comps[1].dx == 2) + && (img->comps[2].dx == 2) + && (img->comps[0].dy == 1) + && (img->comps[1].dy == 1) + && (img->comps[2].dy == 1))// horizontal only + { + opj_convert_yuv422(img); + } + else + if((img->comps[0].dx == 1) + && (img->comps[1].dx == 1) + && (img->comps[2].dx == 1) + && (img->comps[0].dy == 1) + && (img->comps[1].dy == 1) + && (img->comps[2].dy == 1)) + { + opj_convert_yuv444(img); + } + else + { +fprintf(stderr,"%s:%d:opj_convert_sycc_to_rgb\n\tCAN NOT CONVERT\n", +__FILE__,__LINE__); + return; + } + img->color_space = CLRSPC_SRGB; +}/* opj_convert_sycc_to_rgb() */ |
