return iErrorCode;
}
-static int __mm_image_decode_from_jpeg_file_with_libjpeg(mm_util_jpeg_yuv_data *decoded_data, const char *pFileName, mm_util_color_format_e input_fmt, mm_util_jpeg_decode_downscale downscale)
-{
- int iErrorCode = MM_UTIL_ERROR_NONE;
- FILE *infile = NULL;
- struct jpeg_decompress_struct dinfo;
- struct my_error_mgr_s jerr;
- JSAMPARRAY buffer; /* Output row buffer */
- int row_stride = 0; /* physical row width in output buffer */
- JSAMPROW image, u_image, v_image;
- JSAMPROW row; /* point to buffer[0] */
-
- mm_util_fenter();
-
- mm_util_retvm_if(decoded_data == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid decoded_data");
- mm_util_retvm_if(!MMUTIL_STRING_VALID(pFileName), MM_UTIL_ERROR_NO_SUCH_FILE, "invalid path");
-
- if (decoded_data)
- decoded_data->data = NULL;
-
- iErrorCode = mm_util_safe_fopen(pFileName, "rb", &infile);
- if (iErrorCode != MM_UTIL_ERROR_NONE) {
- mm_util_error("mm_util_safe_fopen failed (%d)", iErrorCode);
- return iErrorCode;
- }
-
- mm_util_debug("infile");
- /* allocate and initialize JPEG decompression object We set up the normal JPEG error routines, then override error_exit. */
- dinfo.err = jpeg_std_error(&jerr.pub);
- mm_util_debug("jpeg_std_error");
- jerr.pub.error_exit = __my_error_exit;
- mm_util_debug("jerr.pub.error_exit ");
-
- /* Establish the setjmp return context for __my_error_exit to use. */
- if (setjmp(jerr.setjmp_buffer)) {
- /* If we get here, the JPEG code has signaled an error. We need to clean up the JPEG object, close the input file, and return.*/
- mm_util_debug("setjmp");
- jpeg_destroy_decompress(&dinfo);
- MMUTIL_SAFE_FREE(decoded_data->data);
- mm_util_safe_fclose(infile);
- mm_util_fleave();
- return MM_UTIL_ERROR_INVALID_PARAMETER;
- }
-
- mm_util_debug("if (setjmp)");
- /* Now we can initialize the JPEG decompression object. */
- jpeg_create_decompress(&dinfo);
- mm_util_debug("jpeg_create_decompress");
-
- /*specify data source (eg, a file) */
- jpeg_stdio_src(&dinfo, infile);
- mm_util_debug("jpeg_stdio_src");
-
- /*read file parameters with jpeg_read_header() */
- jpeg_read_header(&dinfo, TRUE);
-
- mm_util_debug("image width: %d height: %d", dinfo.image_width, dinfo.image_height);
- if (dinfo.image_width > ENC_MAX_LEN || dinfo.image_height > ENC_MAX_LEN) {
- dinfo.scale_num = 1;
- dinfo.scale_denom = 8;
- dinfo.do_fancy_upsampling = FALSE;
- dinfo.do_block_smoothing = FALSE;
- dinfo.dither_mode = JDITHER_ORDERED;
- } else if (downscale != MM_UTIL_JPEG_DECODE_DOWNSCALE_1_1) {
- dinfo.scale_num = 1;
- dinfo.scale_denom = (unsigned int)downscale;
- dinfo.do_fancy_upsampling = FALSE;
- dinfo.do_block_smoothing = FALSE;
- dinfo.dither_mode = JDITHER_ORDERED;
- }
-
- dinfo.dct_method = JDCT_FASTEST;
+typedef enum {
+ MM_UTIL_JPEG_FILE,
+ MM_UTIL_JPEG_MEM,
+} mm_util_jpeg_input_format_e;
- /* set parameters for decompression */
- if (input_fmt == MM_UTIL_COLOR_RGB24) {
- dinfo.out_color_space = JCS_RGB;
- mm_util_debug("cinfo.out_color_space = JCS_RGB");
- } else if (input_fmt == MM_UTIL_COLOR_YUV420 || input_fmt == MM_UTIL_COLOR_YUV422 || input_fmt == MM_UTIL_COLOR_UYVY) {
- dinfo.out_color_space = JCS_YCbCr;
- mm_util_debug("cinfo.out_color_space = JCS_YCbCr");
- } else if (input_fmt == MM_UTIL_COLOR_GRAYSCALE) {
- dinfo.out_color_space = JCS_GRAYSCALE;
- mm_util_debug("cinfo.out_color_space = JCS_GRAYSCALE");
- } else if (input_fmt == MM_UTIL_COLOR_RGBA) {
- dinfo.out_color_space = JCS_EXT_RGBA;
- mm_util_debug("cinfo.out_color_space = JCS_EXT_RGBA");
- } else if (input_fmt == MM_UTIL_COLOR_BGRA) {
- dinfo.out_color_space = JCS_EXT_BGRA;
- mm_util_debug("cinfo.out_color_space = JCS_EXT_BGRA");
- } else if (input_fmt == MM_UTIL_COLOR_ARGB) {
- dinfo.out_color_space = JCS_EXT_ARGB;
- mm_util_debug("cinfo.out_color_space = JCS_EXT_ARGB");
- }
- decoded_data->format = input_fmt;
-
- /* Start decompressor*/
- jpeg_start_decompress(&dinfo);
-
- /* byte-align for YUV format */
- if (input_fmt == MM_UTIL_COLOR_YUV420 || input_fmt == MM_UTIL_COLOR_YUV422) {
- if (dinfo.output_width % 2 != 0)
- dinfo.output_width = MM_UTIL_ROUND_DOWN_2(dinfo.output_width);
- if (dinfo.output_height % 2 != 0)
- dinfo.output_height = MM_UTIL_ROUND_DOWN_2(dinfo.output_height);
- }
-
- /* JSAMPLEs per row in output buffer */
- row_stride = dinfo.output_width * dinfo.output_components;
-
- /* Make a one-row-high sample array that will go away when done with image */
- buffer = (*dinfo.mem->alloc_sarray) ((j_common_ptr) &dinfo, JPOOL_IMAGE, row_stride, 1);
- mm_util_debug("JPOOL_IMAGE BUFFER (input_fmt: %d)", input_fmt);
- decoded_data->width = dinfo.output_width;
- decoded_data->height = dinfo.output_height;
- if (input_fmt == MM_UTIL_COLOR_RGB24 || input_fmt == MM_UTIL_COLOR_RGBA || input_fmt == MM_UTIL_COLOR_BGRA || input_fmt == MM_UTIL_COLOR_ARGB) {
- decoded_data->size = dinfo.output_height * row_stride;
- } else if (input_fmt == MM_UTIL_COLOR_YUV420) {
- decoded_data->size = dinfo.output_height * row_stride / 2;
- } else if (input_fmt == MM_UTIL_COLOR_YUV422 || input_fmt == MM_UTIL_COLOR_UYVY) {
- decoded_data->size = dinfo.output_height * dinfo.output_width * 2;
- } else if (input_fmt == MM_UTIL_COLOR_GRAYSCALE) {
- decoded_data->size = dinfo.output_height * dinfo.output_width;
- } else{
- jpeg_finish_decompress(&dinfo);
- jpeg_destroy_decompress(&dinfo);
- mm_util_error("[%d] We can't decode the IMAGE format", input_fmt);
- mm_util_safe_fclose(infile);
- return MM_UTIL_ERROR_NOT_SUPPORTED_FORMAT;
- }
-
- decoded_data->data = (void *) calloc(1, decoded_data->size);
- decoded_data->format = input_fmt;
-
- if (decoded_data->data == NULL) {
- jpeg_finish_decompress(&dinfo);
- jpeg_destroy_decompress(&dinfo);
- mm_util_error("decoded_data->data is NULL");
- mm_util_safe_fclose(infile);
- return MM_UTIL_ERROR_OUT_OF_MEMORY;
- }
- mm_util_debug("decoded_data->data");
-
- if (input_fmt == MM_UTIL_COLOR_YUV420 || input_fmt == MM_UTIL_COLOR_YUV422 || input_fmt == MM_UTIL_COLOR_UYVY) {
- image = decoded_data->data;
- u_image = image + (dinfo.output_width * dinfo.output_height);
- v_image = u_image + (dinfo.output_width*dinfo.output_height) / 4;
- row = buffer[0];
- int i = 0;
- int y = 0;
- while (dinfo.output_scanline < dinfo.output_height) {
- jpeg_read_scanlines(&dinfo, buffer, 1);
- for (i = 0; i < row_stride; i += 3) {
- image[i/3] = row[i];
- if (i & 1) {
- u_image[(i/3)/2] = row[i+1];
- v_image[(i/3)/2] = row[i+2];
- }
- }
- image += row_stride/3;
- if (y++ & 1) {
- u_image += dinfo.output_width / 2;
- v_image += dinfo.output_width / 2;
- }
- }
- } else if (input_fmt == MM_UTIL_COLOR_RGB24 || input_fmt == MM_UTIL_COLOR_GRAYSCALE || input_fmt == MM_UTIL_COLOR_RGBA || input_fmt == MM_UTIL_COLOR_BGRA || input_fmt == MM_UTIL_COLOR_ARGB) {
- int state = 0;
- /* while (scan lines remain to be read) jpeg_read_scanlines(...); */
- while (dinfo.output_scanline < dinfo.output_height) {
- /* jpeg_read_scanlines expects an array of pointers to scanlines. Here the array is only one element long, but you could ask formore than one scanline at a time if that's more convenient. */
- jpeg_read_scanlines(&dinfo, buffer, 1);
- memcpy(decoded_data->data + state, buffer[0], row_stride);
- state += row_stride;
- }
- mm_util_debug("jpeg_read_scanlines");
- }
-
- /* Finish decompression */
- jpeg_finish_decompress(&dinfo);
-
- /* Release JPEG decompression object */
- jpeg_destroy_decompress(&dinfo);
-
- mm_util_safe_fclose(infile);
-
- mm_util_fleave();
-
- return iErrorCode;
-}
-
-static int __mm_image_decode_from_jpeg_memory_with_libjpeg(mm_util_jpeg_yuv_data *decoded_data, void *src, unsigned int size, mm_util_color_format_e input_fmt, mm_util_jpeg_decode_downscale downscale)
+static int __mm_image_decode_with_libjpeg(mm_util_jpeg_input_format_e input_format, mm_util_jpeg_yuv_data *decoded_data, FILE *fp, void *src, unsigned int size, mm_util_color_format_e color_format, mm_util_jpeg_decode_downscale downscale)
{
int iErrorCode = MM_UTIL_ERROR_NONE;
struct jpeg_decompress_struct dinfo;
mm_util_fenter();
mm_util_retvm_if(decoded_data == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid decoded_data");
- mm_util_retvm_if(src == NULL, MM_UTIL_ERROR_INVALID_PARAMETER, "invalid src");
-
- mm_util_debug("infile");
-
- if (decoded_data)
- decoded_data->data = NULL;
+ mm_util_retvm_if((input_format != MM_UTIL_JPEG_FILE) && (input_format != MM_UTIL_JPEG_MEM), MM_UTIL_ERROR_INVALID_PARAMETER, "invalid input_format [%u]", input_format);
+ mm_util_retvm_if((input_format == MM_UTIL_JPEG_FILE) && (fp == NULL), MM_UTIL_ERROR_INVALID_PARAMETER, "invalid fp");
+ mm_util_retvm_if((input_format == MM_UTIL_JPEG_MEM) && ((src == NULL) || (size == 0)), MM_UTIL_ERROR_INVALID_PARAMETER, "invalid src or size");
/* allocate and initialize JPEG decompression object We set up the normal JPEG error routines, then override error_exit. */
dinfo.err = jpeg_std_error(&jerr.pub);
/* Establish the setjmp return context for __my_error_exit to use. */
if (setjmp(jerr.setjmp_buffer)) {
/* If we get here, the JPEG code has signaled an error. We need to clean up the JPEG object, close the input file, and return.*/
- mm_util_debug("setjmp");
- MMUTIL_SAFE_FREE(decoded_data->data);
+ mm_util_error("ERROR setjmp");
jpeg_destroy_decompress(&dinfo);
return MM_UTIL_ERROR_NO_SUCH_FILE;
}
mm_util_debug("jpeg_create_decompress");
/*specify data source (eg, a file) */
- jpeg_mem_src(&dinfo, src, size);
- mm_util_debug("jpeg_stdio_src");
+ if (input_format == MM_UTIL_JPEG_FILE) {
+ jpeg_stdio_src(&dinfo, fp);
+ mm_util_debug("jpeg_stdio_src");
+ } else {
+ jpeg_mem_src(&dinfo, src, size);
+ mm_util_debug("jpeg_mem_src");
+ }
/*read file parameters with jpeg_read_header() */
jpeg_read_header(&dinfo, TRUE);
dinfo.dct_method = JDCT_FASTEST;
/* set parameters for decompression */
- if (input_fmt == MM_UTIL_COLOR_RGB24) {
+ if (color_format == MM_UTIL_COLOR_RGB24) {
dinfo.out_color_space = JCS_RGB;
mm_util_debug("cinfo.out_color_space = JCS_RGB");
- } else if (input_fmt == MM_UTIL_COLOR_YUV420 || input_fmt == MM_UTIL_COLOR_YUV422 || input_fmt == MM_UTIL_COLOR_UYVY) {
+ } else if (color_format == MM_UTIL_COLOR_YUV420 || color_format == MM_UTIL_COLOR_YUV422 || color_format == MM_UTIL_COLOR_UYVY) {
dinfo.out_color_space = JCS_YCbCr;
mm_util_debug("cinfo.out_color_space = JCS_YCbCr");
- } else if (input_fmt == MM_UTIL_COLOR_GRAYSCALE) {
+ } else if (color_format == MM_UTIL_COLOR_GRAYSCALE) {
dinfo.out_color_space = JCS_GRAYSCALE;
mm_util_debug("cinfo.out_color_space = JCS_GRAYSCALE");
- } else if (input_fmt == MM_UTIL_COLOR_RGBA) {
+ } else if (color_format == MM_UTIL_COLOR_RGBA) {
dinfo.out_color_space = JCS_EXT_RGBA;
mm_util_debug("cinfo.out_color_space = JCS_EXT_RGBA");
- } else if (input_fmt == MM_UTIL_COLOR_BGRA) {
+ } else if (color_format == MM_UTIL_COLOR_BGRA) {
dinfo.out_color_space = JCS_EXT_BGRA;
mm_util_debug("cinfo.out_color_space = JCS_EXT_BGRA");
- } else if (input_fmt == MM_UTIL_COLOR_ARGB) {
+ } else if (color_format == MM_UTIL_COLOR_ARGB) {
dinfo.out_color_space = JCS_EXT_ARGB;
mm_util_debug("cinfo.out_color_space = JCS_EXT_ARGB");
}
- decoded_data->format = input_fmt;
+ decoded_data->format = color_format;
/* Start decompressor*/
jpeg_start_decompress(&dinfo);
mm_util_debug("jpeg_start_decompress");
/* byte-align for YUV format */
- if (input_fmt == MM_UTIL_COLOR_YUV420 || input_fmt == MM_UTIL_COLOR_YUV422) {
+ if (color_format == MM_UTIL_COLOR_YUV420 || color_format == MM_UTIL_COLOR_YUV422) {
if (dinfo.output_width % 2 != 0)
dinfo.output_width = MM_UTIL_ROUND_DOWN_2(dinfo.output_width);
if (dinfo.output_height % 2 != 0)
/* Make a one-row-high sample array that will go away when done with image */
buffer = (*dinfo.mem->alloc_sarray) ((j_common_ptr) &dinfo, JPOOL_IMAGE, row_stride, 1);
- mm_util_debug("JPOOL_IMAGE BUFFER (input_fmt: %d)", input_fmt);
+ mm_util_debug("JPOOL_IMAGE BUFFER (color_format: %d)", color_format);
decoded_data->width = dinfo.output_width;
decoded_data->height = dinfo.output_height;
- if (input_fmt == MM_UTIL_COLOR_RGB24 || input_fmt == MM_UTIL_COLOR_RGBA || input_fmt == MM_UTIL_COLOR_BGRA || input_fmt == MM_UTIL_COLOR_ARGB) {
+ if (color_format == MM_UTIL_COLOR_RGB24 || color_format == MM_UTIL_COLOR_RGBA || color_format == MM_UTIL_COLOR_BGRA || color_format == MM_UTIL_COLOR_ARGB) {
decoded_data->size = dinfo.output_height * row_stride;
- } else if (input_fmt == MM_UTIL_COLOR_YUV420) {
+ } else if (color_format == MM_UTIL_COLOR_YUV420) {
decoded_data->size = dinfo.output_height * row_stride / 2;
- } else if (input_fmt == MM_UTIL_COLOR_YUV422 || input_fmt == MM_UTIL_COLOR_UYVY) {
+ } else if (color_format == MM_UTIL_COLOR_YUV422 || color_format == MM_UTIL_COLOR_UYVY) {
decoded_data->size = dinfo.output_height * dinfo.output_width * 2;
- } else if (input_fmt == MM_UTIL_COLOR_GRAYSCALE) {
+ } else if (color_format == MM_UTIL_COLOR_GRAYSCALE) {
decoded_data->size = dinfo.output_height * dinfo.output_width;
} else{
jpeg_finish_decompress(&dinfo);
jpeg_destroy_decompress(&dinfo);
- mm_util_error("[%d] We can't decode the IMAGE format", input_fmt);
+ mm_util_error("[%d] We can't decode the IMAGE format", color_format);
return MM_UTIL_ERROR_NOT_SUPPORTED_FORMAT;
}
decoded_data->data = (void *) calloc(1, decoded_data->size);
- decoded_data->format = input_fmt;
+ decoded_data->format = color_format;
if (decoded_data->data == NULL) {
jpeg_finish_decompress(&dinfo);
mm_util_debug("decoded_data->data");
/* while (scan lines remain to be read) jpeg_read_scanlines(...); */
- if (input_fmt == MM_UTIL_COLOR_YUV420 || input_fmt == MM_UTIL_COLOR_YUV422 || input_fmt == MM_UTIL_COLOR_UYVY) {
+ if (color_format == MM_UTIL_COLOR_YUV420 || color_format == MM_UTIL_COLOR_YUV422 || color_format == MM_UTIL_COLOR_UYVY) {
image = decoded_data->data;
u_image = image + (dinfo.output_width * dinfo.output_height);
v_image = u_image + (dinfo.output_width*dinfo.output_height)/4;
v_image += dinfo.output_width / 2;
}
}
- } else if (input_fmt == MM_UTIL_COLOR_RGB24 || input_fmt == MM_UTIL_COLOR_GRAYSCALE || input_fmt == MM_UTIL_COLOR_RGBA || input_fmt == MM_UTIL_COLOR_BGRA || input_fmt == MM_UTIL_COLOR_ARGB) {
+ } else if (color_format == MM_UTIL_COLOR_RGB24 || color_format == MM_UTIL_COLOR_GRAYSCALE || color_format == MM_UTIL_COLOR_RGBA || color_format == MM_UTIL_COLOR_BGRA || color_format == MM_UTIL_COLOR_ARGB) {
int state = 0;
while (dinfo.output_scanline < dinfo.output_height) {
/* jpeg_read_scanlines expects an array of pointers to scanlines. Here the array is only one element long, but you could ask formore than one scanline at a time if that's more convenient. */
return iErrorCode;
}
+
#endif
int mm_util_jpeg_encode_to_file(const char *filename, void* src, int width, int height, mm_util_color_format_e fmt, int quality)
mm_util_debug("Success fread");
mm_util_debug("%x %x", magic[0], magic[1]);
- mm_util_safe_fclose(fp);
} else {
mm_util_error("[infile] file open [%s]", filename);
mm_util_stderror("file open failed");
return MM_UTIL_ERROR_NO_SUCH_FILE;
}
+
+ fseek(fp, 0, SEEK_SET);
+
if (magic[0] == 0xff && magic[1] == 0xd8) {
#ifdef LIBJPEG_TURBO
mm_util_debug("#START# LIBJPEG_TURBO");
#else
mm_util_debug("#START# libjpeg fmt [%d]", fmt);
if (fmt == MM_UTIL_COLOR_NV12) {
- ret = __mm_image_decode_from_jpeg_file_with_libjpeg(decoded, filename, MM_UTIL_COLOR_YUV420, downscale);
+ ret = __mm_image_decode_with_libjpeg(MM_UTIL_JPEG_FILE, decoded, fp, NULL, 0, MM_UTIL_COLOR_YUV420, downscale);
if (ret == MM_UTIL_ERROR_NONE) {
unsigned int res_w = 0;
unsigned int res_h = 0;
MMUTIL_SAFE_FREE(decoded->data);
- decoded->data = calloc(1, res_buffer_size);
- if (decoded->data == NULL) {
- mm_util_debug("memory allocation failed");
- MMUTIL_SAFE_FREE(dst);
- return MM_UTIL_ERROR_OUT_OF_MEMORY;
- }
-
- memcpy(decoded->data, dst, res_buffer_size);
+ decoded->data = dst;
decoded->size = (unsigned int)res_buffer_size;
MMUTIL_SAFE_FREE(dst);
}
} else {
- ret = __mm_image_decode_from_jpeg_file_with_libjpeg(decoded, filename, fmt, downscale);
+ ret = __mm_image_decode_with_libjpeg(MM_UTIL_JPEG_FILE, decoded, fp, NULL, 0, fmt, downscale);
}
-
#endif
mm_util_debug("decoded->data: %p\t width: %d\t height: %d\t size: %u", decoded->data, decoded->width, decoded->height, decoded->size);
mm_util_debug("#End# libjpeg, Success!! ret: %d", ret);
ret = MM_UTIL_ERROR_NOT_SUPPORTED_FORMAT;
}
+ mm_util_safe_fclose(fp);
+
mm_util_fleave();
+
return ret;
}
#else
mm_util_debug("#START# libjpeg");
if (fmt == MM_UTIL_COLOR_NV12) {
- ret = __mm_image_decode_from_jpeg_memory_with_libjpeg(decoded, src, size, MM_UTIL_COLOR_YUV420, downscale);
+ ret = __mm_image_decode_with_libjpeg(MM_UTIL_JPEG_MEM, decoded, NULL, src, size, MM_UTIL_COLOR_YUV420, downscale);
if (ret == MM_UTIL_ERROR_NONE) {
unsigned int res_w = 0;
unsigned int res_h = 0;
MMUTIL_SAFE_FREE(decoded->data);
- decoded->data = calloc(1, res_buffer_size);
- if (decoded->data == NULL) {
- mm_util_debug("memory allocation failed");
- MMUTIL_SAFE_FREE(dst);
- return MM_UTIL_ERROR_OUT_OF_MEMORY;
- }
-
- memcpy(decoded->data, dst, res_buffer_size);
+ decoded->data = dst;
decoded->size = (unsigned int)res_buffer_size;
MMUTIL_SAFE_FREE(dst);
}
} else {
- ret = __mm_image_decode_from_jpeg_memory_with_libjpeg(decoded, src, size, fmt, downscale);
+ ret = __mm_image_decode_with_libjpeg(MM_UTIL_JPEG_MEM, decoded, NULL, src, size, fmt, downscale);
}
#endif
mm_util_debug("decoded->data: %p\t width: %d\t height: %d\t size: %u", decoded->data, decoded->width, decoded->height, decoded->size);