Skip to content
Merged
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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,12 @@ cjpeg_LDADD = libjpeg.la
cjpeg_CFLAGS = -DBMP_SUPPORTED -DGIF_SUPPORTED -DPPM_SUPPORTED \
-DTARGA_SUPPORTED

if HAVE_LIBPNG
cjpeg_CFLAGS += -DPNG_SUPPORTED $(libpng_CFLAGS)
cjpeg_LDADD += $(libpng_LIBS)
cjpeg_SOURCES += rdpng.c
endif

djpeg_SOURCES = cdjpeg.h cderror.h cdjpeg.c djpeg.c rdcolmap.c rdswitch.c \
wrbmp.c wrgif.c wrppm.c wrtarga.c

Expand Down
4 changes: 4 additions & 0 deletions cderror.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,10 @@ JMESSAGE(JERR_UNKNOWN_FORMAT, "Unrecognized input file format")
#endif
JMESSAGE(JERR_UNSUPPORTED_FORMAT, "Unsupported output file format")

#ifdef PNG_SUPPORTED
JMESSAGE(JERR_PNG_ERROR, "Unable to read PNG file: %s")
#endif

#ifdef JMAKE_ENUM_LIST

JMSG_LASTADDONCODE
Expand Down
1 change: 1 addition & 0 deletions cdjpeg.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ EXTERN(cjpeg_source_ptr) jinit_read_gif JPP((j_compress_ptr cinfo));
EXTERN(djpeg_dest_ptr) jinit_write_gif JPP((j_decompress_ptr cinfo));
EXTERN(cjpeg_source_ptr) jinit_read_jpeg JPP((j_compress_ptr cinfo));
EXTERN(cjpeg_source_ptr) jinit_read_ppm JPP((j_compress_ptr cinfo));
EXTERN(cjpeg_source_ptr) jinit_read_png JPP((j_compress_ptr cinfo));
EXTERN(djpeg_dest_ptr) jinit_write_ppm JPP((j_decompress_ptr cinfo));
EXTERN(cjpeg_source_ptr) jinit_read_rle JPP((j_compress_ptr cinfo));
EXTERN(djpeg_dest_ptr) jinit_write_rle JPP((j_decompress_ptr cinfo));
Expand Down
4 changes: 4 additions & 0 deletions cjpeg.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,10 @@ select_file_type (j_compress_ptr cinfo, FILE * infile)
case 'P':
return jinit_read_ppm(cinfo);
#endif
#ifdef PNG_SUPPORTED
case 0x89:
return jinit_read_png(cinfo);
#endif
#ifdef RLE_SUPPORTED
case 'R':
return jinit_read_rle(cinfo);
Expand Down
5 changes: 5 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,11 @@ fi
# Checks for libraries.
AC_CHECK_LIB([m],[pow])

PKG_CHECK_MODULES([libpng], [libpng], [HAVE_LIBPNG=1], [
PKG_CHECK_MODULES([libpng], [libpng12], [HAVE_LIBPNG=1], [HAVE_LIBPNG=0])
])
AM_CONDITIONAL([HAVE_LIBPNG], [test "$HAVE_LIBPNG" -eq 1])

# Checks for header files.
AC_HEADER_STDC
AC_CHECK_HEADERS([stddef.h stdlib.h string.h])
Expand Down
11 changes: 6 additions & 5 deletions jconfig.txt
Original file line number Diff line number Diff line change
Expand Up @@ -130,11 +130,12 @@ typedef unsigned char boolean;

/* These defines indicate which image (non-JPEG) file formats are allowed. */

#define BMP_SUPPORTED /* BMP image file format */
#define GIF_SUPPORTED /* GIF image file format */
#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */
#undef RLE_SUPPORTED /* Utah RLE image file format */
#define TARGA_SUPPORTED /* Targa image file format */
#define PNG_SUPPORTED /* PNG image file format */
#define BMP_SUPPORTED /* BMP image file format */
#define GIF_SUPPORTED /* GIF image file format */
#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */
#undef RLE_SUPPORTED /* Utah RLE image file format */
#define TARGA_SUPPORTED /* Targa image file format */

/* Define this if you want to name both input and output files on the command
* line, rather than using stdout and optionally stdin. You MUST do this if
Expand Down
116 changes: 116 additions & 0 deletions rdpng.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@

#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */

#ifdef PNG_SUPPORTED

#include <png.h> /* if this fails, you need to install libpng-devel */


typedef struct png_source_struct {
struct cjpeg_source_struct pub;
png_structp png_ptr;
png_infop info_ptr;
JDIMENSION current_row;
} png_source_struct;


METHODDEF(void)
finish_input_png (j_compress_ptr cinfo, cjpeg_source_ptr sinfo);

METHODDEF(JDIMENSION)
get_pixel_rows_png (j_compress_ptr cinfo, cjpeg_source_ptr sinfo);

METHODDEF(void)
start_input_png (j_compress_ptr cinfo, cjpeg_source_ptr sinfo);


GLOBAL(cjpeg_source_ptr)
jinit_read_png(j_compress_ptr cinfo)
{
png_source_struct *source = (*cinfo->mem->alloc_small)((j_common_ptr) cinfo, JPOOL_IMAGE, sizeof(png_source_struct));

memset(source, 0, sizeof(*source));

/* Fill in method ptrs, except get_pixel_rows which start_input sets */
source->pub.start_input = start_input_png;
source->pub.finish_input = finish_input_png;

return &source->pub;
}

METHODDEF(void) error_input_png(png_structp png_ptr, png_const_charp msg) {
j_compress_ptr cinfo = png_get_error_ptr(png_ptr);
ERREXITS(cinfo, JERR_PNG_ERROR, msg);
}

METHODDEF(void)
start_input_png (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
{
png_source_struct *source = (png_source_struct *)sinfo;

source->png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, cinfo, error_input_png, NULL);
source->info_ptr = png_create_info_struct(source->png_ptr);

if (!source->png_ptr || !source->info_ptr) {
ERREXITS(cinfo, JERR_PNG_ERROR, "Can't create read/info_struct");
return;
}

png_set_palette_to_rgb(source->png_ptr);
png_set_expand_gray_1_2_4_to_8(source->png_ptr);
png_set_strip_alpha(source->png_ptr);
png_set_interlace_handling(source->png_ptr);

png_init_io(source->png_ptr, source->pub.input_file);
png_read_info(source->png_ptr, source->info_ptr);

png_uint_32 width, height;
int bit_depth, color_type;
png_get_IHDR(source->png_ptr, source->info_ptr, &width, &height,
&bit_depth, &color_type, NULL, NULL, NULL);

if (color_type == PNG_COLOR_TYPE_GRAY) {
cinfo->in_color_space = JCS_GRAYSCALE;
cinfo->input_components = 1;
} else {
cinfo->in_color_space = JCS_RGB;
cinfo->input_components = 3;
}
cinfo->data_precision = 8;
cinfo->image_width = width;
cinfo->image_height = height;

double gamma = 0.45455;
if (!png_get_valid(source->png_ptr, source->info_ptr, PNG_INFO_sRGB)) {
png_get_gAMA(source->png_ptr, source->info_ptr, &gamma);
}
cinfo->input_gamma = gamma;
sinfo->get_pixel_rows = get_pixel_rows_png;

png_read_update_info(source->png_ptr, source->info_ptr);

png_size_t rowbytes = png_get_rowbytes(source->png_ptr, source->info_ptr);

source->pub.buffer = (*cinfo->mem->alloc_sarray)((j_common_ptr)cinfo, JPOOL_IMAGE, (JDIMENSION)rowbytes, 1);
source->pub.buffer_height = 1;
}

METHODDEF(JDIMENSION)
get_pixel_rows_png (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
{
png_source_struct *source = (png_source_struct *)sinfo;

png_read_row(source->png_ptr, source->pub.buffer[0], NULL);
return 1;
}

METHODDEF(void)
finish_input_png (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
{
png_source_struct *source = (png_source_struct *)sinfo;

png_read_end(source->png_ptr, source->info_ptr);
png_destroy_read_struct(&source->png_ptr, &source->info_ptr, NULL);
}

#endif