Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -354,3 +354,7 @@ SIMD extensions be disabled, either by passing an argument of `-DWITH_SIMD=0`
to `cmake` when configuring the build or by setting the environment variable
`JSIMD_FORCENONE` to `1` at run time, when testing libjpeg-turbo with Valgrind,
MSan, or other memory debuggers.

Decoding in memory instead of file:
==================================
I have embedded the jpeg image in esp-idf and have modified the code in djpeg.c to be fit to decode the image(grayscale) in memory buffer. This is a trial code and has not been tested yet!
255 changes: 255 additions & 0 deletions cjpeg.c
Original file line number Diff line number Diff line change
Expand Up @@ -496,10 +496,258 @@ parse_switches(j_compress_ptr cinfo, int argc, char **argv,
}


int
encode_greyscale(unsigned char *in_buf, unsigned char *out_buf,
unsigned long *out_buf_sz,
int image_width, int image_height)
{
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
#ifdef PROGRESS_REPORT
struct cdjpeg_progress_mgr progress;
#endif

/* Initialize the JPEG compression object with default error handling. */
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo);
/* Add some application-specific error messages (from cderror.h) */
jerr.addon_message_table = cdjpeg_message_table;
jerr.first_addon_message = JMSG_FIRSTADDONCODE;
jerr.last_addon_message = JMSG_LASTADDONCODE;

/* Initialize JPEG parameters.
* Much of this may be overridden later.
* In particular, we don't yet know the input file's color space,
* but we need to provide some value for jpeg_set_defaults() to work.
*/

cinfo.image_width = image_width;
cinfo.image_height = image_height;
cinfo.input_components = 1;
cinfo.in_color_space = JCS_GRAYSCALE; /* arbitrary guess */
jpeg_set_defaults(&cinfo);

#ifdef PROGRESS_REPORT
start_progress_monitor((j_common_ptr)&cinfo, &progress);
#endif

/* Specify data destination for compression */
jpeg_mem_dest(&cinfo, &out_buf, out_buf_sz);

/* Start compressor */
jpeg_start_compress(&cinfo, TRUE);

unsigned char *buf[3]; //96
while (cinfo.next_scanline < cinfo.image_height) {
buf[0] = in_buf + cinfo.image_width * cinfo.next_scanline;
jpeg_write_scanlines(&cinfo, (JSAMPARRAY) buf, 1);
}
/* Finish compression and release memory */
jpeg_finish_compress(&cinfo);
jpeg_destroy_compress(&cinfo);

#ifdef PROGRESS_REPORT
end_progress_monitor((j_common_ptr)&cinfo);
#endif

/* All done. */
printf("Compressed size: %lu bytes\n", *out_buf_sz);
return 0; /* suppress no-return-value warnings */
}

/*
* The main program.
*/

#if 0 /* GREY_SCALE input */
int
main(int argc, char **argv)
{
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
#ifdef PROGRESS_REPORT
struct cdjpeg_progress_mgr progress;
#endif
int file_index;
cjpeg_source_ptr src_mgr;
FILE *input_file;
FILE *icc_file;
JOCTET *icc_profile = NULL;
long icc_len = 0;
FILE *output_file = NULL;
unsigned char *outbuffer = NULL;
unsigned long outsize = 0;
JDIMENSION num_scanlines;

/* On Mac, fetch a command line. */
#ifdef USE_CCOMMAND
argc = ccommand(&argv);
#endif

progname = argv[0];
if (progname == NULL || progname[0] == 0)
progname = "cjpeg"; /* in case C library doesn't provide it */

/* Initialize the JPEG compression object with default error handling. */
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo);
/* Add some application-specific error messages (from cderror.h) */
jerr.addon_message_table = cdjpeg_message_table;
jerr.first_addon_message = JMSG_FIRSTADDONCODE;
jerr.last_addon_message = JMSG_LASTADDONCODE;

/* Initialize JPEG parameters.
* Much of this may be overridden later.
* In particular, we don't yet know the input file's color space,
* but we need to provide some value for jpeg_set_defaults() to work.
*/


cinfo.image_width = 96;
cinfo.image_height = 96;
cinfo.input_components = 1;
cinfo.in_color_space = JCS_GRAYSCALE; /* arbitrary guess */
jpeg_set_defaults(&cinfo);

/* Scan command line to find file names.
* It is convenient to use just one switch-parsing routine, but the switch
* values read here are ignored; we will rescan the switches after opening
* the input file.
*/

file_index = parse_switches(&cinfo, argc, argv, 0, FALSE);

#ifdef TWO_FILE_COMMANDLINE
if (!memdst) {
/* Must have either -outfile switch or explicit output file name */
if (outfilename == NULL) {
if (file_index != argc - 2) {
fprintf(stderr, "%s: must name one input and one output file\n",
progname);
usage();
}
outfilename = argv[file_index + 1];
} else {
if (file_index != argc - 1) {
fprintf(stderr, "%s: must name one input and one output file\n",
progname);
usage();
}
}
}
#else
/* Unix style: expect zero or one file name */
if (file_index < argc - 1) {
fprintf(stderr, "%s: only one input file\n", progname);
usage();
}
#endif /* TWO_FILE_COMMANDLINE */
/* Open the input file. */
if (file_index < argc) {
if ((input_file = fopen(argv[file_index], READ_BINARY)) == NULL) {
fprintf(stderr, "%s: can't open %s\n", progname, argv[file_index]);
exit(EXIT_FAILURE);
}
} else {
/* default input file is stdin */
input_file = read_stdin();
}

/* Open the output file. */
if (outfilename != NULL) {
if ((output_file = fopen(outfilename, WRITE_BINARY)) == NULL) {
fprintf(stderr, "%s: can't open %s\n", progname, outfilename);
exit(EXIT_FAILURE);
}
} else if (!memdst) {
/* default output file is stdout */
output_file = write_stdout();
}

if (icc_filename != NULL) {
if ((icc_file = fopen(icc_filename, READ_BINARY)) == NULL) {
fprintf(stderr, "%s: can't open %s\n", progname, icc_filename);
exit(EXIT_FAILURE);
}
if (fseek(icc_file, 0, SEEK_END) < 0 ||
(icc_len = ftell(icc_file)) < 1 ||
fseek(icc_file, 0, SEEK_SET) < 0) {
fprintf(stderr, "%s: can't determine size of %s\n", progname,
icc_filename);
exit(EXIT_FAILURE);
}
if ((icc_profile = (JOCTET *)malloc(icc_len)) == NULL) {
fprintf(stderr, "%s: can't allocate memory for ICC profile\n", progname);
fclose(icc_file);
exit(EXIT_FAILURE);
}
if (fread(icc_profile, icc_len, 1, icc_file) < 1) {
fprintf(stderr, "%s: can't read ICC profile from %s\n", progname,
icc_filename);
free(icc_profile);
fclose(icc_file);
exit(EXIT_FAILURE);
}
fclose(icc_file);
}

#ifdef PROGRESS_REPORT
start_progress_monitor((j_common_ptr)&cinfo, &progress);
#endif

/* Adjust default compression parameters by re-parsing the options */
file_index = parse_switches(&cinfo, argc, argv, 0, TRUE);

/* Specify data destination for compression */
#if JPEG_LIB_VERSION >= 80 || defined(MEM_SRCDST_SUPPORTED)
if (memdst)
jpeg_mem_dest(&cinfo, &outbuffer, &outsize);
else
#endif
jpeg_stdio_dest(&cinfo, output_file);

/* Start compressor */
jpeg_start_compress(&cinfo, TRUE);

if (icc_profile != NULL)
jpeg_write_icc_profile(&cinfo, icc_profile, (unsigned int)icc_len);


unsigned char *buf[3]; //96
buf[0] = malloc(cinfo.image_width);

while (cinfo.next_scanline < cinfo.image_height) {
fread(buf[0], 1, cinfo.image_width, input_file);
jpeg_write_scanlines(&cinfo, (JSAMPARRAY) buf, 1);
}
free(buf[0]);

/* Finish compression and release memory */
jpeg_finish_compress(&cinfo);
jpeg_destroy_compress(&cinfo);

/* Close files, if we opened them */
if (input_file != stdin)
fclose(input_file);
if (output_file != stdout && output_file != NULL)
fclose(output_file);

#ifdef PROGRESS_REPORT
end_progress_monitor((j_common_ptr)&cinfo);
#endif

if (memdst) {
fprintf(stderr, "Compressed size: %lu bytes\n", outsize);
free(outbuffer);
}

free(icc_profile);

/* All done. */
exit(jerr.num_warnings ? EXIT_WARNING : EXIT_SUCCESS);
return 0; /* suppress no-return-value warnings */
}
#else
int
main(int argc, char **argv)
{
Expand Down Expand Up @@ -664,6 +912,12 @@ main(int argc, char **argv)
num_scanlines = (*src_mgr->get_pixel_rows) (&cinfo, src_mgr);
(void)jpeg_write_scanlines(&cinfo, src_mgr->buffer, num_scanlines);
}
/* vikram's dattu's code:for comparison::
while (cinfo.next_scanline < cinfo.image_height) {
buf[0] = in_buf + cinfo.image_width * cinfo.next_scanline;
jpeg_write_scanlines(&cinfo, (JSAMPARRAY) buf, 1);
}
*/

/* Finish compression and release memory */
(*src_mgr->finish_input) (&cinfo, src_mgr);
Expand Down Expand Up @@ -691,3 +945,4 @@ main(int argc, char **argv)
exit(jerr.num_warnings ? EXIT_WARNING : EXIT_SUCCESS);
return 0; /* suppress no-return-value warnings */
}
#endif
84 changes: 80 additions & 4 deletions djpeg.c
Original file line number Diff line number Diff line change
Expand Up @@ -676,10 +676,6 @@ main(int argc, char **argv)
break;
}
dest_mgr->output_file = output_file;

/* Start decompressor */
(void)jpeg_start_decompress(&cinfo);

/* Skip rows */
if (skip) {
JDIMENSION tmp;
Expand Down Expand Up @@ -836,3 +832,83 @@ main(int argc, char **argv)
exit(jerr.num_warnings ? EXIT_WARNING : EXIT_SUCCESS);
return 0; /* suppress no-return-value warnings */
}

/* self demo code <--not part of official libjpeg */
unsigned long decode_jpeg(unsigned char *in_buf,unsigned long in_buf_sz,unsigned char *out_buf)
{
unsigned long out_buf_sz;
struct jpeg_decompress_struct cinfo;
cinfo.out_color_space=JCS_GRAYSCALE;/*out=grey*/
struct jpeg_error_mgr jerr;
#ifdef PROGRESS_REPORT
struct cdjpeg_progress_mgr progress;
#endif
/* Initialize the JPEG decompression object with default error handling. */
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_decompress(&cinfo);
/* Add some application-specific error messages (from cderror.h) */
jerr.addon_message_table = cdjpeg_message_table;
jerr.first_addon_message = JMSG_FIRSTADDONCODE;
jerr.last_addon_message = JMSG_LASTADDONCODE;

/* Read file header, set default decompression parameters */
(void)jpeg_read_header(&cinfo, TRUE);

/*specify data source for decompression*/
jpeg_mem_src(&cinfo, in_buf, in_buf_sz);

/* Start decompressor */
(void)jpeg_start_decompress(&cinfo);

/*unsigned char *buf[3];*/
/*unsigned int num_scanlines;*/
/* Process data */
while(cinfo.output_scanline < cinfo.output_height) {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay. This seems problematic! Do we have output height at this point?

jpeg_read_scanlines(&cinfo,(JSAMPARRAY)out_buf,
1);
/*(*dest_mgr->put_pixel_rows) (&cinfo, dest_mgr, num_scanlines);study this*/

}
out_buf_sz=cinfo.output_height*cinfo.output_width;
/*if ((tmp = jpeg_skip_scanlines(&cinfo, skip_end - skip_start + 1)) !=
skip_end - skip_start + 1) {
fprintf(stderr, "%s: jpeg_skip_scanlines() returned %d rather than %d\n",
progname, tmp, skip_end - skip_start + 1);
exit(EXIT_FAILURE);
}
while (cinfo.output_scanline < cinfo.output_height) {
num_scanlines = jpeg_read_scanlines(&cinfo,out_buf,
dest_mgr->buffer_height);
(*dest_mgr->put_pixel_rows) (&cinfo, dest_mgr, num_scanlines);
}*/


/*Finish decompression and release memory.*/
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
#ifdef PROGRESS_REPORT
end_progress_monitor((j_common_ptr)&cinfo);
#endif

return out_buf_sz;
}
/*
put_pixel_rows(j_decompress_ptr cinfo, djpeg_dest_ptr dinfo,
JDIMENSION rows_supplied)
used for unquantized full-color output
{
tga_dest_ptr dest = (tga_dest_ptr)dinfo;
register JSAMPROW inptr;
register char *outptr;
register JDIMENSION col;

inptr = dest->pub.buffer[0];
outptr = dest->iobuffer;
for (col = cinfo->output_width; col > 0; col--) {
outptr[0] = (char)GETJSAMPLE(inptr[2]); // RGB to BGR order
outptr[1] = (char)GETJSAMPLE(inptr[1]);
outptr[2] = (char)GETJSAMPLE(inptr[0]);
inptr += 3, outptr += 3;
}
(void)JFWRITE(dest->pub.output_file, dest->iobuffer, dest->buffer_width);
}*/
Binary file added esp32_jpeg_dec/.djpeg.c.swp
Binary file not shown.
9 changes: 9 additions & 0 deletions esp32_jpeg_dec/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# The following lines of boilerplate have to be in your project's
# CMakeLists in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.5)

set(EXTRA_COMPONENT_DIRS ../ $ENV{IDF_PATH}/examples/common_components/protocol_examples_common)
#set(EXTRA_COMPONENT_DIRS )

include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(jpeg-enc)
8 changes: 8 additions & 0 deletions esp32_jpeg_dec/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#
# This is a project Makefile. It is assumed the directory this Makefile resides in is a
# project subdirectory.
#

PROJECT_NAME := jpeg-enc

include $(IDF_PATH)/make/project.mk
Loading