📄 jpeg_rgb_decoder.c
字号:
#include <stdio.h>#include <string.h>#include <stdlib.h>#include "jpeg.h"#include <liboil/liboil.h>#include <liboil/liboildebug.h>#define CLAMP(x,a,b) ((x)<(a) ? (a) : ((x)>(b) ? (b) : (x)))#define oil_argb(a,r,g,b) \ ((oil_clamp_255(a)<<24) | \ (oil_clamp_255(r)<<16) | \ (oil_clamp_255(g)<<8) | \ (oil_clamp_255(b)<<0))#define oil_max(x,y) ((x)>(y)?(x):(y))#define oil_min(x,y) ((x)<(y)?(x):(y))#define oil_clamp_255(x) oil_max(0,oil_min((x),255))static int16_t jfif_matrix[24] = { 0, 0, -8192, -8192, 16384, 0, 0, 0, 0, 16384, 16384, 16384, 0, 0, -5638, 29032, 0, 22970, -11700, 0, 0, 0, 0, 0};unsigned char * get_argb_444 (JpegDecoder *dec);unsigned char * get_argb_422 (JpegDecoder *dec);unsigned char * get_argb_422v (JpegDecoder *dec);unsigned char * get_argb_420 (JpegDecoder *dec);#if 0static void imagescale2h_u8 (unsigned char *dest, int d_rowstride, unsigned char *src, int src_rowstride, int width, int height);static void imagescale2v_u8 (unsigned char *dest, int d_rowstride, unsigned char *src, int src_rowstride, int width, int height);static void imagescale2h2v_u8 (unsigned char *dest, int d_rowstride, unsigned char *src, int src_rowstride, int width, int height);static void scanlinescale2_u8 (unsigned char *dest, unsigned char *src, int len);#endifint jpeg_decode_argb (uint8_t *data, int length, uint32_t **image, int *width, int *height){ JpegDecoder *dec; int ret; dec = jpeg_decoder_new(); jpeg_decoder_addbits (dec, data, length); ret = jpeg_decoder_decode(dec); if (!ret) return FALSE; jpeg_decoder_get_image_size (dec, width, height); *image = (uint32_t *)jpeg_decoder_get_argb_image (dec); jpeg_decoder_free (dec); return TRUE;}unsigned char *jpeg_decoder_get_argb_image (JpegDecoder *dec){ if (dec->n_components == 3) { if (dec->components[0].h_subsample == 1 && dec->components[0].v_subsample == 1 && dec->components[1].h_subsample == dec->components[2].h_subsample && dec->components[1].v_subsample == dec->components[2].v_subsample) { if (dec->components[1].h_subsample == 1 && dec->components[1].v_subsample == 1) { return get_argb_444 (dec); } else if (dec->components[1].h_subsample == 2 && dec->components[1].v_subsample == 1) { return get_argb_422 (dec); } else if (dec->components[1].h_subsample == 1 && dec->components[1].v_subsample == 2) { return get_argb_422v (dec); } else if (dec->components[1].h_subsample == 2 && dec->components[1].v_subsample == 2) { return get_argb_420 (dec); } } } return NULL;}static voidyuv_mux (uint32_t *dest, uint8_t *src_y, uint8_t *src_u, uint8_t *src_v, int n){ int i; for (i = 0; i < n; i++) { dest[i] = oil_argb(255, src_y[i], src_u[i], src_v[i]); }}static voidupsample (uint8_t *d, uint8_t *s, int n){ int i; d[0] = s[0]; for (i = 0; i < n-3; i+=2) { d[i + 1] = (3*s[i/2] + s[i/2+1] + 2)>>2; d[i + 2] = (s[i/2] + 3*s[i/2+1] + 2)>>2; } if (n&1) { i = n-3; d[n-2] = s[n/2]; d[n-1] = s[n/2]; } else { d[n-1] = s[n/2-1]; }}unsigned char *get_argb_444 (JpegDecoder *dec){ uint32_t *tmp; uint32_t *argb_image; uint8_t *yp, *up, *vp; uint32_t *argbp; int j; tmp = malloc (4 * dec->width * dec->height); argb_image = malloc (4 * dec->width * dec->height); yp = dec->components[0].image; up = dec->components[1].image; vp = dec->components[2].image; argbp = argb_image; for(j=0;j<dec->height;j++){ yuv_mux (tmp, yp, up, vp, dec->width); oil_colorspace_argb(argbp, tmp, jfif_matrix, dec->width); yp += dec->components[0].rowstride; up += dec->components[1].rowstride; vp += dec->components[2].rowstride; argbp += dec->width; } free(tmp); return (unsigned char *)argb_image;}unsigned char *get_argb_422 (JpegDecoder *dec){ uint32_t *tmp; uint8_t *tmp_u; uint8_t *tmp_v; uint32_t *argb_image; uint8_t *yp, *up, *vp; uint32_t *argbp; int j; tmp = malloc (4 * dec->width * dec->height); tmp_u = malloc (dec->width); tmp_v = malloc (dec->width); argb_image = malloc (4 * dec->width * dec->height); yp = dec->components[0].image; up = dec->components[1].image; vp = dec->components[2].image; argbp = argb_image; for(j=0;j<dec->height;j++){ upsample (tmp_u, up, dec->width); upsample (tmp_v, vp, dec->width); yuv_mux (tmp, yp, tmp_u, tmp_v, dec->width); oil_colorspace_argb(argbp, tmp, jfif_matrix, dec->width); yp += dec->components[0].rowstride; up += dec->components[1].rowstride; vp += dec->components[2].rowstride; argbp += dec->width; } free(tmp); free(tmp_u); free(tmp_v); return (unsigned char *)argb_image;}unsigned char *get_argb_422v (JpegDecoder *dec){ uint32_t *tmp; uint8_t *tmp_u; uint8_t *tmp_v; uint32_t *argb_image; uint8_t *yp, *up, *vp; uint32_t *argbp; int halfheight; int j; tmp = malloc (4 * dec->width * dec->height); tmp_u = malloc (dec->width); tmp_v = malloc (dec->width); argb_image = malloc (4 * dec->width * dec->height); yp = dec->components[0].image; up = dec->components[1].image; vp = dec->components[2].image; argbp = argb_image; halfheight = (dec->height+1)>>1; for(j=0;j<dec->height;j++){ uint32_t weight = 192 - 128*(j&1); oil_merge_linear_u8(tmp_u, up + dec->components[1].rowstride * CLAMP((j-1)/2,0,halfheight-1), up + dec->components[1].rowstride * CLAMP((j+1)/2,0,halfheight-1), &weight, dec->width); oil_merge_linear_u8(tmp_v, vp + dec->components[2].rowstride * CLAMP((j-1)/2,0,halfheight-1), vp + dec->components[2].rowstride * CLAMP((j+1)/2,0,halfheight-1), &weight, dec->width); yuv_mux (tmp, yp, tmp_u, tmp_v, dec->width); oil_colorspace_argb(argbp, tmp, jfif_matrix, dec->width); yp += dec->components[0].rowstride; argbp += dec->width; } free(tmp); free(tmp_u); free(tmp_v); return (unsigned char *)argb_image;}unsigned char *get_argb_420 (JpegDecoder *dec){ uint32_t *tmp; uint8_t *tmp_u; uint8_t *tmp_v; uint8_t *tmp1; uint32_t *argb_image; uint8_t *yp, *up, *vp; uint32_t *argbp; int j; int halfwidth; int halfheight; halfwidth = (dec->width + 1)>>1; tmp = malloc (4 * dec->width * dec->height); tmp_u = malloc (dec->width); tmp_v = malloc (dec->width); tmp1 = malloc (halfwidth); argb_image = malloc (4 * dec->width * dec->height); yp = dec->components[0].image; up = dec->components[1].image; vp = dec->components[2].image; argbp = argb_image; halfheight = (dec->height+1)>>1; for(j=0;j<dec->height;j++){ uint32_t weight = 192 - 128*(j&1); oil_merge_linear_u8(tmp1, up + dec->components[1].rowstride * CLAMP((j-1)/2,0,halfheight-1), up + dec->components[1].rowstride * CLAMP((j+1)/2,0,halfheight-1), &weight, halfwidth); upsample (tmp_u, tmp1, dec->width); oil_merge_linear_u8(tmp1, vp + dec->components[2].rowstride * CLAMP((j-1)/2,0,halfheight-1), vp + dec->components[2].rowstride * CLAMP((j+1)/2,0,halfheight-1), &weight, halfwidth); upsample (tmp_v, tmp1, dec->width); yuv_mux (tmp, yp, tmp_u, tmp_v, dec->width); oil_colorspace_argb(argbp, tmp, jfif_matrix, dec->width); yp += dec->components[0].rowstride; argbp += dec->width; } free(tmp); free(tmp_u); free(tmp_v); free(tmp1); return (unsigned char *)argb_image;}#if 0intjpeg_rgb_decoder_get_image (JpegRGBDecoder * rgbdec, unsigned char **image, int *rowstride, int *width, int *height){ int i; jpeg_decoder_get_image_size (rgbdec->dec, &rgbdec->width, &rgbdec->height); for (i = 0; i < 3; i++) { jpeg_decoder_get_component_ptr (rgbdec->dec, i + 1, &rgbdec->component[i].image, &rgbdec->component[i].rowstride); jpeg_decoder_get_component_subsampling (rgbdec->dec, i + 1, &rgbdec->component[i].h_subsample, &rgbdec->component[i].v_subsample); rgbdec->component[i].alloc = 0; if (rgbdec->component[i].h_subsample > 1 || rgbdec->component[i].v_subsample > 1) { unsigned char *dest; dest = malloc (rgbdec->width * rgbdec->height); if (rgbdec->component[i].v_subsample > 1) { if (rgbdec->component[i].h_subsample > 1) { imagescale2h2v_u8 (dest, rgbdec->width, rgbdec->component[i].image, rgbdec->component[i].rowstride, rgbdec->width, rgbdec->height); } else { imagescale2v_u8 (dest, rgbdec->width, rgbdec->component[i].image, rgbdec->component[i].rowstride, rgbdec->width, rgbdec->height); } } else { imagescale2h_u8 (dest, rgbdec->width, rgbdec->component[i].image, rgbdec->component[i].rowstride, rgbdec->width, rgbdec->height); } rgbdec->component[i].alloc = 1; rgbdec->component[i].image = dest; rgbdec->component[i].rowstride = rgbdec->width; rgbdec->component[i].h_subsample = 1; rgbdec->component[i].v_subsample = 1; } } rgbdec->image = malloc (rgbdec->width * rgbdec->height * 4); convert (rgbdec); if (image) *image = rgbdec->image; if (rowstride) *rowstride = rgbdec->width * 4; if (width) *width = rgbdec->width; if (height) *height = rgbdec->height; return 0;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -