Skip to content

Commit

Permalink
Added support for directly reading standard JPEG input images.
Browse files Browse the repository at this point in the history
Implementation uses libjpeg's partial decoding and DCT-scaling functions to optimize decoding as much as is possible and supports ICC, XMP and EXIF metadata.
Note that JPEG does not support multi-resolution encoding, so decoding will be slower than reading TIFF or JPEG2000, especially for large images.
  • Loading branch information
ruven committed Sep 25, 2024
1 parent 91b553a commit ea8c7c5
Show file tree
Hide file tree
Showing 9 changed files with 668 additions and 9 deletions.
7 changes: 7 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
25/09/2024:
- Added support for directly reading standard JPEG input images. Implementation uses libjpeg's partial decoding
and DCT-scaling functions to optimize decoding as much as is possible and supports ICC, XMP and EXIF metadata.
Note that JPEG does not support multi-resolution encoding, so decoding will be slower than reading TIFF
or JPEG2000, especially for large images.


24/09/2024:
- Added TIFF codec version reporting in logfile and updated return signature for getCodecVersion() function.
Also code cleanups for OpenJPEGImage and KakaduImage classes.
Expand Down
6 changes: 3 additions & 3 deletions README
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ FEATURES
* Fast lightweight FastCGI server
* High performance with inbuilt configurable cache
* Support for extremely large images: tera-pixel and multi gigapixel support
* TIFF and JPEG2000 input support
* TIFF, JPEG2000 and JPEG input support
* JPEG, PNG, WebP and AVIF output support: export of whole or regions of images at any size
* Supports IIP, Zoomify, DeepZoom and IIIF API's
* 1, 8, 16 and 32 bit image support including 32 bit floating point support
Expand Down Expand Up @@ -469,13 +469,13 @@ IMAGES
------

### Image Input Formats
Input images must be in either tiled multi-resolution (pyramid) TIFF format or in JPEG2000 format. See https://iipimage.sourceforge.io/documentation/images for details on how to create appropriate images.
Input images must be in either tiled multi-resolution (pyramid) TIFF format, in JPEG2000 or in JPEG format. See https://iipimage.sourceforge.io/documentation/images for details on how to create appropriate images.

### Image Input Paths
The images paths given to the server via the FIF command for the IIP API or in the IIIF, Deepzoom or Zoomify requests must be absolute paths on the server machine (eg. FIF=/images/test.tif) and not paths relative to the web server document root location. Images do not, therefore, need to be directly accessible through the web server. The FILESYSTEM_PREFIX configuration parameter can be used to avoid overly long image paths. Make sure the iipsrv process owner is able to access and read the images!

### Output Images
iipsrv can transcode input images in TIFF or JPEG2000 to JPEG, PNG or WebP format. See the API documentation for details on how to use iipsrv: https://iipimage.sourceforge.io/documentation/protocol
iipsrv can transcode input images in TIFF, JPEG2000 or JPEG to JPEG, PNG, WebP or AVIF format. See the API documentation for details on how to use iipsrv: https://iipimage.sourceforge.io/documentation/protocol



Expand Down
11 changes: 6 additions & 5 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,12 @@ AC_LANG_POP([C++])
# Enable debugging
AC_ARG_ENABLE([debug-mode],
[ --enable-debug-mode enable debugging mode (no FCGI)],
[AC_DEFINE(DEBUG)
AC_DEFINE(KAKADU_DEBUG)
AC_DEFINE(OPENJPEG_DEBUG)
DEBUG=true
AC_MSG_RESULT([configure: enabling debug mode])]
AC_DEFINE(DEBUG)
AC_DEFINE(KAKADU_DEBUG)
AC_DEFINE(OPENJPEG_DEBUG)
AC_DEFINE(JPEG_DEBUG)
DEBUG=true
AC_MSG_RESULT([configure: enabling debug mode])]
)


Expand Down
5 changes: 5 additions & 0 deletions src/FIF.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "URL.h"
#include "Environment.h"
#include "TPTImage.h"
#include "JPEGImage.h"

#ifdef HAVE_KAKADU
#include "KakaduImage.h"
Expand Down Expand Up @@ -134,6 +135,10 @@ void FIF::run( Session* session, const string& src ){
if( session->loglevel >= 2 ) *(session->logfile) << "FIF :: TIFF image detected" << endl;
*session->image = new TPTImage( test );
}
else if( format == ImageEncoding::JPEG ){
if( session->loglevel >= 2 ) *(session->logfile) << "FIF :: JPEG image detected" << endl;
*session->image = new JPEGImage( test );
}
#if defined(HAVE_KAKADU) || defined(HAVE_OPENJPEG)
else if( format == ImageEncoding::JPEG2000 ){
if( session->loglevel >= 2 )
Expand Down
6 changes: 5 additions & 1 deletion src/IIPImage.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

/* IIP fcgi server module
Copyright (C) 2000-2023 Ruven Pillay.
Copyright (C) 2000-2024 Ruven Pillay.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -137,8 +137,12 @@ void IIPImage::testImageType()
static const unsigned char lbigtiff[4] = {0x4D,0x4D,0x00,0x2B}; // Little Endian BigTIFF
static const unsigned char bbigtiff[4] = {0x49,0x49,0x2B,0x00}; // Big Endian BigTIFF

// Magic file signature for JPEG
static const unsigned char jpeg[3] = {0xFF,0xDA,0xFF};

// Compare our header sequence to our magic byte signatures
if( memcmp( header, j2k, 10 ) == 0 ) format = ImageEncoding::JPEG2000;
else if( memcmp( header, jpeg, 3 ) ) format = ImageEncoding::JPEG;
else if( memcmp( header, stdtiff, 3 ) == 0
|| memcmp( header, lsbtiff, 4 ) == 0 || memcmp( header, msbtiff, 4 ) == 0
|| memcmp( header, lbigtiff, 4 ) == 0 || memcmp( header, bbigtiff, 4 ) == 0 ){
Expand Down
Loading

0 comments on commit ea8c7c5

Please sign in to comment.