[mapserver-commits] r12133 - in trunk/mapserver/mapcache: . include
src
svn at osgeo.org
svn at osgeo.org
Fri Aug 26 07:00:37 EDT 2011
Author: tbonfort
Date: 2011-08-26 04:00:36 -0700 (Fri, 26 Aug 2011)
New Revision: 12133
Modified:
trunk/mapserver/mapcache/Makefile.in
trunk/mapserver/mapcache/Makefile.inc.in
trunk/mapserver/mapcache/configure
trunk/mapserver/mapcache/configure.in
trunk/mapserver/mapcache/geocache.xml
trunk/mapserver/mapcache/include/geocache.h
trunk/mapserver/mapcache/src/Makefile
trunk/mapserver/mapcache/src/buffer.c
trunk/mapserver/mapcache/src/configuration.c
trunk/mapserver/mapcache/src/image.c
trunk/mapserver/mapcache/src/imageio.c
trunk/mapserver/mapcache/src/mod_geocache.c
trunk/mapserver/mapcache/src/tileset.c
Log:
add support for Last-Modified and If-Modified-Since http headers
update issue 12
- returns 304 code if suitable if the client has added an If-Modified-Since header
- adds a Last-Modified header with a 200 OK response
thomas.bonfort | 2010-10-19 17:43:18 +0200 (Tue, 19 Oct 2010)
Modified: trunk/mapserver/mapcache/Makefile.in
===================================================================
--- trunk/mapserver/mapcache/Makefile.in 2011-08-26 11:00:27 UTC (rev 12132)
+++ trunk/mapserver/mapcache/Makefile.in 2011-08-26 11:00:36 UTC (rev 12133)
@@ -16,7 +16,7 @@
true
src/.libs/mod_geocache.so: src/mod_geocache.c $(SRCS) include/geocache.h
- $(APXS) -Wc,"$(CFLAGS)" -Iinclude $(PNG_INC) $(CURL_CFLAGS) $(XML2_CFLAGS) $(XML2_LIBS) $(CURL_LIBS) $(PNG_LIB) -c src/mod_geocache.c $(SRCS)
+ $(APXS) -Wc,"$(CFLAGS)" -Iinclude $(JPEG_INC) $(PNG_INC) $(CURL_CFLAGS) $(XML2_CFLAGS) $(XML2_LIBS) $(CURL_LIBS) $(JPEG_LIB) $(PNG_LIB) -c src/mod_geocache.c $(SRCS)
#install: src/.libs/mod_geocache.so
#$(APACHECTL) stop
Modified: trunk/mapserver/mapcache/Makefile.inc.in
===================================================================
--- trunk/mapserver/mapcache/Makefile.inc.in 2011-08-26 11:00:27 UTC (rev 12132)
+++ trunk/mapserver/mapcache/Makefile.inc.in 2011-08-26 11:00:36 UTC (rev 12133)
@@ -13,7 +13,10 @@
PNG_INC=@PNG_INC@
PNG_LIB=@PNG_LIB@
+JPEG_INC=@JPEG_INC@
+JPEG_LIB=@JPEG_LIB@
+
OBJS=$(shell find . -regex '^.*\.c$$' -print | grep -v mod_geocache.c | sed "s/^\(.*\)\.c$$/\1.o/")
LOBJS=$(shell find . -regex '^.*\.c$$' -print | grep -v mod_geocache.c | sed "s/^\(.*\)\.c$$/\1.lo/")
Modified: trunk/mapserver/mapcache/configure
===================================================================
--- trunk/mapserver/mapcache/configure 2011-08-26 11:00:27 UTC (rev 12132)
+++ trunk/mapserver/mapcache/configure 2011-08-26 11:00:36 UTC (rev 12133)
@@ -601,6 +601,8 @@
XML2_LIBS
XML2_CFLAGS
XML2CONFIG
+JPEG_LIB
+JPEG_INC
PNG_LIB
PNG_INC
EGREP
@@ -664,6 +666,7 @@
enable_debug
with_apxs
with_png
+with_jpeg
with_xml2_config
with_curl_config
'
@@ -1293,6 +1296,7 @@
--without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
--with-apxs=/path/to/apxs Apache 2 apxs tool location
--with-png=DIR Specify where PNG is installed
+ --with-jpeg=DIR Specify where JPEG is installed
--with-xml2-config=/path/to/xml2-config xml2-config tool location
--with-curl-config path to curl-config program
@@ -2843,6 +2847,8 @@
+
+
# Check whether --enable-debug was given.
if test "${enable_debug+set}" = set; then :
enableval=$enable_debug;
@@ -3594,8 +3600,8 @@
if test -n "$PNG_LIB" ; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: using libpng from system libs." >&5
-$as_echo " using libpng from system libs." >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: using libpng from system libs." >&5
+$as_echo "using libpng from system libs." >&6; }
else
as_fn_error "PNG (libpng) library cannot be found. install or reconfigure with --with-png=DIR" "$LINENO" 5
fi
@@ -3616,6 +3622,125 @@
+
+
+# Check whether --with-jpeg was given.
+if test "${with_jpeg+set}" = set; then :
+ withval=$with_jpeg; JPEG_DIR=$withval
+else
+ JPEG_DIR=''
+fi
+
+
+
+ if test -z "$JPEG_DIR" || echo "$JPEG_DIR" | grep '^/' >/dev/null ; then
+ JPEG_DIR="$JPEG_DIR"
+ else
+ JPEG_DIR="`pwd`/$JPEG_DIR"
+ fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking where JPEG is installed..." >&5
+$as_echo "$as_me: checking where JPEG is installed..." >&6;}
+ JPEG_LIB=''
+ JPEG_INC=''
+ JPEG_FOUND='no'
+
+ if test -n "$JPEG_DIR" ; then
+ test -f $JPEG_DIR/lib/libjpeg.a -o -f $JPEG_DIR/lib/libjpeg.so -o -f $JPEG_DIR/lib/libjpeg.sl -o -f $JPEG_DIR/lib/libjpeg.dylib && JPEG_LIBDIR="$JPEG_DIR/lib"
+ test -f $JPEG_DIR/lib64/libjpeg.a -o -f $JPEG_DIR/lib64/libjpeg.so -o -f $JPEG_DIR/lib64/libjpeg.sl -o -f $JPEG_DIR/libjpeg.dylib && JPEG_LIBDIR="$JPEG_DIR/lib64"
+ test -f $JPEG_DIR/libjpeg.a -o -f $JPEG_DIR/libjpeg.so -o -f $JPEG_DIR/libjpeg.sl -o -f $JPEG_DIR/libjpeg.dylib && JPEG_LIBDIR="$JPEG_DIR"
+ test -f $JPEG_DIR/include/jpeglib.h && JPEG_INCLUDE="$JPEG_DIR/include"
+ test -f $JPEG_DIR/include/jpeg/jpeglib.h && JPEG_INCLUDE="$JPEG_DIR/include/jpeg"
+ test -f $JPEG_DIR/lib/jpeglib.h && JPEG_INCLUDE="$JPEG_DIR/lib"
+ test -f $JPEG_DIR/jpeglib.h && JPEG_INCLUDE="$JPEG_DIR"
+
+ if test -n "$JPEG_LIBDIR" ; then
+ JPEG_LIB="-L$JPEG_LIBDIR -ljpeg"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: using libjpeg from $JPEG_LIB" >&5
+$as_echo "using libjpeg from $JPEG_LIB" >&6; }
+ else
+ as_fn_error "cannot find jpeg lib in $JPEG_DIR" "$LINENO" 5
+ fi
+
+ if test -n "$JPEG_INCLUDE" ; then
+ as_ac_Header=`$as_echo "ac_cv_header_$JPEG_INCLUDE/jpeglib.h" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$JPEG_INCLUDE/jpeglib.h" "$as_ac_Header" "$ac_includes_default"
+eval as_val=\$$as_ac_Header
+ if test "x$as_val" = x""yes; then :
+ JPEG_INC=-I$JPEG_INCLUDE
+else
+ as_fn_error "cannot find jpeg headers" "$LINENO" 5
+fi
+
+
+ else
+ as_fn_error "cannot find jpeg headers in $JPEG_DIR" "$LINENO" 5
+ fi
+ else
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for jpeg_read_header in -ljpeg" >&5
+$as_echo_n "checking for jpeg_read_header in -ljpeg... " >&6; }
+if test "${ac_cv_lib_jpeg_jpeg_read_header+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ljpeg $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char jpeg_read_header ();
+int
+main ()
+{
+return jpeg_read_header ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_jpeg_jpeg_read_header=yes
+else
+ ac_cv_lib_jpeg_jpeg_read_header=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_jpeg_jpeg_read_header" >&5
+$as_echo "$ac_cv_lib_jpeg_jpeg_read_header" >&6; }
+if test "x$ac_cv_lib_jpeg_jpeg_read_header" = x""yes; then :
+ JPEG_LIB="-ljpeg"
+fi
+
+ ac_fn_c_check_header_mongrel "$LINENO" "jpeglib.h" "ac_cv_header_jpeglib_h" "$ac_includes_default"
+if test "x$ac_cv_header_jpeglib_h" = x""yes; then :
+
+else
+ as_fn_error "cannot find jpeg headers in system path" "$LINENO" 5
+fi
+
+
+ if test -n "$JPEG_LIB" ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: using libjpeg from system libs." >&5
+$as_echo "using libjpeg from system libs." >&6; }
+ else
+ as_fn_error "JPEG (libjpeg) library cannot be found. install or reconfigure with --with-jpeg=DIR" "$LINENO" 5
+ fi
+ fi
+
+ JPEG_INC=$JPEG_INC
+
+ JPEG_LIB=$JPEG_LIB
+
+
+
#PKGCONFIG_CHECK
#CAIRO_CHECK
Modified: trunk/mapserver/mapcache/configure.in
===================================================================
--- trunk/mapserver/mapcache/configure.in 2011-08-26 11:00:27 UTC (rev 12132)
+++ trunk/mapserver/mapcache/configure.in 2011-08-26 11:00:36 UTC (rev 12133)
@@ -278,7 +278,7 @@
AC_CHECK_HEADER([png.h],,
[AC_MSG_ERROR([cannot find png headers in system path])])
if test -n "$PNG_LIB" ; then
- AC_MSG_RESULT([ using libpng from system libs.])
+ AC_MSG_RESULT([using libpng from system libs.])
else
AC_MSG_ERROR([PNG (libpng) library cannot be found. install or reconfigure with --with-png=DIR])
fi
@@ -290,12 +290,65 @@
AC_SUBST(PNG_LIB,$PNG_LIB)
])
+AC_DEFUN(JPEG_CHECK,[
+ AC_ARG_WITH(jpeg,
+ AC_HELP_STRING([--with-jpeg=DIR],[Specify where JPEG is installed]),
+ JPEG_DIR=$withval,JPEG_DIR='')
+
+ AC_EXPAND_PATH($JPEG_DIR, JPEG_DIR)
+ AC_CHECKING(where JPEG is installed)
+ JPEG_LIB=''
+ JPEG_INC=''
+ JPEG_FOUND='no'
+
+ if test -n "$JPEG_DIR" ; then
+ test -f $JPEG_DIR/lib/libjpeg.a -o -f $JPEG_DIR/lib/libjpeg.so -o -f $JPEG_DIR/lib/libjpeg.sl -o -f $JPEG_DIR/lib/libjpeg.dylib && JPEG_LIBDIR="$JPEG_DIR/lib"
+ test -f $JPEG_DIR/lib64/libjpeg.a -o -f $JPEG_DIR/lib64/libjpeg.so -o -f $JPEG_DIR/lib64/libjpeg.sl -o -f $JPEG_DIR/libjpeg.dylib && JPEG_LIBDIR="$JPEG_DIR/lib64"
+ test -f $JPEG_DIR/libjpeg.a -o -f $JPEG_DIR/libjpeg.so -o -f $JPEG_DIR/libjpeg.sl -o -f $JPEG_DIR/libjpeg.dylib && JPEG_LIBDIR="$JPEG_DIR"
+ test -f $JPEG_DIR/include/jpeglib.h && JPEG_INCLUDE="$JPEG_DIR/include"
+ test -f $JPEG_DIR/include/jpeg/jpeglib.h && JPEG_INCLUDE="$JPEG_DIR/include/jpeg"
+ test -f $JPEG_DIR/lib/jpeglib.h && JPEG_INCLUDE="$JPEG_DIR/lib"
+ test -f $JPEG_DIR/jpeglib.h && JPEG_INCLUDE="$JPEG_DIR"
+
+ if test -n "$JPEG_LIBDIR" ; then
+ JPEG_LIB="-L$JPEG_LIBDIR -ljpeg"
+ AC_MSG_RESULT([using libjpeg from $JPEG_LIB])
+ else
+ AC_MSG_ERROR([cannot find jpeg lib in $JPEG_DIR])
+ fi
+
+ if test -n "$JPEG_INCLUDE" ; then
+ AC_CHECK_HEADER([$JPEG_INCLUDE/jpeglib.h],JPEG_INC=-I$JPEG_INCLUDE,
+ [AC_MSG_ERROR([cannot find jpeg headers])])
+ else
+ AC_MSG_ERROR([cannot find jpeg headers in $JPEG_DIR])
+ fi
+ else
+
+ dnl check for jpeg in system locations
+
+ AC_CHECK_LIB(jpeg, jpeg_read_header, JPEG_LIB="-ljpeg",,)
+ AC_CHECK_HEADER([jpeglib.h],,
+ [AC_MSG_ERROR([cannot find jpeg headers in system path])])
+ if test -n "$JPEG_LIB" ; then
+ AC_MSG_RESULT([using libjpeg from system libs.])
+ else
+ AC_MSG_ERROR([JPEG (libjpeg) library cannot be found. install or reconfigure with --with-jpeg=DIR])
+ fi
+ fi
+
+ AC_SUBST(JPEG_INC,$JPEG_INC)
+ AC_SUBST(JPEG_LIB,$JPEG_LIB)
+])
+
DEBUG_CHECK
APXS_CHECK
PNG_CHECK
+JPEG_CHECK
+
#PKGCONFIG_CHECK
#CAIRO_CHECK
Modified: trunk/mapserver/mapcache/geocache.xml
===================================================================
--- trunk/mapserver/mapcache/geocache.xml 2011-08-26 11:00:27 UTC (rev 12132)
+++ trunk/mapserver/mapcache/geocache.xml 2011-08-26 11:00:36 UTC (rev 12133)
@@ -36,7 +36,9 @@
<size>256 256</size>
<resolutions>1.40625 0.703125 0.3515625 0.17578125 0.087890625 0.0439453125 0.02197265625 0.010986328125 0.0054931640625 0.00274658203125 0.001373291015625 0.0006866455078125 0.00034332275390625 0.000171661376953125 0.0000858306884765625 0.00004291534423828125</resolutions>
<extent>-180 -90 180 90</extent>
-
+ <metatile>5 5</metatile>
+ <metabuffer>30</metabuffer>
+ <format>JPG</format>
</tileset>
<tileset name="test2">
<source>nexrad</source>
Modified: trunk/mapserver/mapcache/include/geocache.h
===================================================================
--- trunk/mapserver/mapcache/include/geocache.h 2011-08-26 11:00:27 UTC (rev 12132)
+++ trunk/mapserver/mapcache/include/geocache.h 2011-08-26 11:00:36 UTC (rev 12133)
@@ -51,7 +51,7 @@
extern module AP_MODULE_DECLARE_DATA geocache_module;
typedef struct {
- char* buf ; /* buffer */
+ unsigned char* buf ; /* buffer */
size_t size ; /* bytes used */
size_t avail ; /* bytes allocated */
apr_pool_t* pool; /*apache pool to allocate from */
@@ -144,6 +144,7 @@
double *resolutions;
int metasize_x, metasize_y;
int metabuffer;
+ geocache_image_format_type format;
geocache_cache *cache;
geocache_source *source;
apr_table_t *forwarded_params;
@@ -223,7 +224,7 @@
typedef struct {
geocache_buffer *buffer;
- char *ptr;
+ unsigned char *ptr;
} _geocache_buffer_closure;
/* in image.c */
@@ -231,8 +232,8 @@
int geocache_image_metatile_split(geocache_metatile *mt, request_rec *r);
/* in imageio.c */
-geocache_buffer* geocache_imageio_png_encode(request_rec *r, geocache_image *img);
-geocache_image* geocache_imageio_png_decode(request_rec *r, geocache_buffer *buffer);
+geocache_buffer* geocache_imageio_encode(request_rec *r, geocache_image *img, geocache_image_format_type format);
geocache_image_format_type geocache_imageio_header_sniff(request_rec *r, geocache_buffer *buffer);
geocache_image* geocache_imageio_decode(request_rec *r, geocache_buffer *buffer);
+
#endif /* GEOCACHE_H_ */
Modified: trunk/mapserver/mapcache/src/Makefile
===================================================================
--- trunk/mapserver/mapcache/src/Makefile 2011-08-26 11:00:27 UTC (rev 12132)
+++ trunk/mapserver/mapcache/src/Makefile 2011-08-26 11:00:36 UTC (rev 12133)
@@ -9,7 +9,7 @@
$(APXS) -Wc,"$(CFLAGS)" -I../include $(PNG_INC) $(CURL_CFLAGS) $(XML2_CFLAGS) -c $<
mod_geocache.o: mod_geocache.c $(OBJS)
- $(APXS) -Wc,"$(CFLAGS)" -I../include $(PNG_INC) $(CURL_CFLAGS) $(XML2_CFLAGS) $(XML2_LIBS) $(CURL_LIBS) $(PNG_LIB) -c mod_geocache.c $(LOBJS)
+ $(APXS) -Wc,"$(CFLAGS)" -I../include $(JPEG_INC) $(PNG_INC) $(CURL_CFLAGS) $(XML2_CFLAGS) $(XML2_LIBS) $(CURL_LIBS) $(JPEG_LIB) $(PNG_LIB) -c mod_geocache.c $(LOBJS)
.libs/mod_geocache.so: mod_geocache.o $(OBJS)
Modified: trunk/mapserver/mapcache/src/buffer.c
===================================================================
--- trunk/mapserver/mapcache/src/buffer.c 2011-08-26 11:00:27 UTC (rev 12132)
+++ trunk/mapserver/mapcache/src/buffer.c 2011-08-26 11:00:36 UTC (rev 12133)
@@ -19,7 +19,7 @@
#define INITIAL_BUFFER_SIZE 100
static void _geocache_buffer_realloc(geocache_buffer *buffer, size_t len) {
- char* newbuf ;
+ unsigned char* newbuf ;
while ( len > buffer->avail ) {
buffer->avail += buffer->avail;
}
Modified: trunk/mapserver/mapcache/src/configuration.c
===================================================================
--- trunk/mapserver/mapcache/src/configuration.c 2011-08-26 11:00:27 UTC (rev 12132)
+++ trunk/mapserver/mapcache/src/configuration.c 2011-08-26 11:00:36 UTC (rev 12133)
@@ -264,6 +264,19 @@
xmlFree(value);
+ } else if(!xmlStrcmp(cur_node->name, BAD_CAST "format")) {
+ value = (char*)xmlNodeGetContent(cur_node);
+ if(!strcasecmp("PNG", value)) {
+ tileset->format = GEOCACHE_IMAGE_FORMAT_PNG;
+ } else if(!strcasecmp("JPEG", value) || !strcasecmp("JPG", value)) {
+ tileset->format = GEOCACHE_IMAGE_FORMAT_JPEG;
+ } else {
+ return apr_psprintf(pool,"failed to parse format %s."
+ "(expecting PNG or JPEG, "
+ "eg <format>PNG</format>",
+ value);
+ }
+ xmlFree(value);
}
}
/* check we have all we want */
Modified: trunk/mapserver/mapcache/src/image.c
===================================================================
--- trunk/mapserver/mapcache/src/image.c 2011-08-26 11:00:27 UTC (rev 12132)
+++ trunk/mapserver/mapcache/src/image.c 2011-08-26 11:00:36 UTC (rev 12133)
@@ -73,7 +73,7 @@
_geocache_image_merge(r, base, overlay);
}
tile = apr_pcalloc(r->pool,sizeof(geocache_tile));
- tile->data = geocache_imageio_png_encode(r,base);
+ tile->data = geocache_imageio_encode(r,base, GEOCACHE_IMAGE_FORMAT_PNG);
tile->sx = base->w;
tile->sy = base->h;
tile->tileset = tiles[0]->tileset;
@@ -82,23 +82,21 @@
int geocache_image_metatile_split(geocache_metatile *mt, request_rec *r) {
geocache_image *metatile;
- geocache_image tile;
+ geocache_image tileimg;
int i,j;
int sx,sy;
- tile.w = mt->tile.tileset->tile_sx;
- tile.h = mt->tile.tileset->tile_sy;
+ tileimg.w = mt->tile.tileset->tile_sx;
+ tileimg.h = mt->tile.tileset->tile_sy;
metatile = geocache_imageio_decode(r, mt->tile.data);
- tile.stride = metatile->stride;
+ tileimg.stride = metatile->stride;
if(!metatile) return GEOCACHE_FAILURE;
for(i=0;i<mt->tile.tileset->metasize_x;i++) {
for(j=0;j<mt->tile.tileset->metasize_y;j++) {
-
-
- sx = mt->tile.tileset->metabuffer + i * tile.w;
- sy = mt->tile.sy - (mt->tile.tileset->metabuffer + (j+1) * tile.w);
- tile.data = &(metatile->data[sy*metatile->stride + 4 * sx]);
- mt->tiles[i*mt->tile.tileset->metasize_x+j].data = geocache_imageio_png_encode(r,&tile);
+ sx = mt->tile.tileset->metabuffer + i * tileimg.w;
+ sy = mt->tile.sy - (mt->tile.tileset->metabuffer + (j+1) * tileimg.w);
+ tileimg.data = &(metatile->data[sy*metatile->stride + 4 * sx]);
+ mt->tiles[i*mt->tile.tileset->metasize_x+j].data = geocache_imageio_encode(r,&tileimg, mt->tile.tileset->format);
}
}
return GEOCACHE_SUCCESS;
Modified: trunk/mapserver/mapcache/src/imageio.c
===================================================================
--- trunk/mapserver/mapcache/src/imageio.c 2011-08-26 11:00:27 UTC (rev 12132)
+++ trunk/mapserver/mapcache/src/imageio.c 2011-08-26 11:00:36 UTC (rev 12133)
@@ -17,6 +17,7 @@
#include "geocache.h"
#include <http_log.h>
#include <png.h>
+#include <jpeglib.h>
int _geocache_imageio_image_has_alpha(geocache_image *img) {
int i,j;
@@ -46,20 +47,254 @@
// do nothing
}
+typedef struct {
+ struct jpeg_destination_mgr pub;
+ unsigned char *data;
+ geocache_buffer *buffer;
+} geocache_jpeg_destination_mgr;
+
+
+#define OUTPUT_BUF_SIZE 4096
+
+static void _geocache_imageio_jpeg_init_source(j_decompress_ptr cinfo)
+{
+ /* nothing to do */
+}
+
+static int _geocache_imageio_jpeg_fill_input_buffer(j_decompress_ptr cinfo)
+{
+ static JOCTET mybuffer[4];
+
+ /* The whole JPEG data is expected to reside in the supplied memory
+ * buffer, so any request for more data beyond the given buffer size
+ * is treated as an error.
+ */
+ /* Insert a fake EOI marker */
+ mybuffer[0] = (JOCTET) 0xFF;
+ mybuffer[1] = (JOCTET) JPEG_EOI;
+
+ cinfo->src->next_input_byte = mybuffer;
+ cinfo->src->bytes_in_buffer = 2;
+
+ return TRUE;
+}
+
+static void _geocache_imageio_jpeg_skip_input_data(j_decompress_ptr cinfo, long num_bytes)
+{
+ struct jpeg_source_mgr * src = cinfo->src;
+
+ /* Just a dumb implementation for now. Could use fseek() except
+ * it doesn't work on pipes. Not clear that being smart is worth
+ * any trouble anyway --- large skips are infrequent.
+ */
+ if (num_bytes > 0) {
+ while (num_bytes > (long) src->bytes_in_buffer) {
+ num_bytes -= (long) src->bytes_in_buffer;
+ (void) (*src->fill_input_buffer) (cinfo);
+ /* note we assume that fill_input_buffer will never return FALSE,
+ * so suspension need not be handled.
+ */
+ }
+ src->next_input_byte += (size_t) num_bytes;
+ src->bytes_in_buffer -= (size_t) num_bytes;
+ }
+}
+
+static void _geocache_imageio_jpeg_term_source(j_decompress_ptr cinfo)
+{
+}
+
+
+
+int _geocache_imageio_jpeg_mem_src (j_decompress_ptr cinfo, unsigned char * inbuffer, unsigned long insize)
+{
+ struct jpeg_source_mgr * src;
+
+ if (inbuffer == NULL || insize == 0) /* Treat empty input as fatal error */
+ return GEOCACHE_FAILURE;
+
+ /* The source object is made permanent so that a series of JPEG images
+ * can be read from the same buffer by calling jpeg_mem_src only before
+ * the first one.
+ */
+ if (cinfo->src == NULL) { /* first time for this JPEG object? */
+ cinfo->src = (struct jpeg_source_mgr *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
+ sizeof(struct jpeg_source_mgr));
+ }
+
+ src = cinfo->src;
+ src->init_source = _geocache_imageio_jpeg_init_source;
+ src->fill_input_buffer = _geocache_imageio_jpeg_fill_input_buffer;
+ src->skip_input_data = _geocache_imageio_jpeg_skip_input_data;
+ src->resync_to_restart = jpeg_resync_to_restart; /* use default method */
+ src->term_source = _geocache_imageio_jpeg_term_source;
+ src->bytes_in_buffer = (size_t) insize;
+ src->next_input_byte = (JOCTET *) inbuffer;
+ return GEOCACHE_SUCCESS;
+}
+
+
+
+void _geocache_imageio_jpeg_init_destination (j_compress_ptr cinfo) {
+ geocache_jpeg_destination_mgr *dest = (geocache_jpeg_destination_mgr*) cinfo->dest;
+
+ /* Allocate the output buffer --- it will be released when done with image */
+ dest->data = (unsigned char *)(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo,
+ JPOOL_IMAGE,OUTPUT_BUF_SIZE * sizeof (unsigned char));
+
+ dest->pub.next_output_byte = dest->data;
+ dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
+}
+
+void _geocache_imageio_jpeg_buffer_term_destination (j_compress_ptr cinfo) {
+ geocache_jpeg_destination_mgr *dest = (geocache_jpeg_destination_mgr*) cinfo->dest;
+ geocache_buffer_append(dest->buffer,OUTPUT_BUF_SIZE-dest->pub.free_in_buffer, dest->data);
+ dest->pub.next_output_byte = dest->data;
+ dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
+}
+
+
+int _geocache_imageio_jpeg_buffer_empty_output_buffer (j_compress_ptr cinfo) {
+ geocache_jpeg_destination_mgr *dest = (geocache_jpeg_destination_mgr*) cinfo->dest;
+ geocache_buffer_append(dest->buffer,OUTPUT_BUF_SIZE, dest->data);
+ dest->pub.next_output_byte = dest->data;
+ dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
+ return TRUE;
+}
+
+geocache_buffer* _geocache_imageio_jpeg_encode(request_rec *r, geocache_image *img) {
+ struct jpeg_compress_struct cinfo;
+ struct jpeg_error_mgr jerr;
+ int quality = 85;
+ geocache_jpeg_destination_mgr *dest;
+ JSAMPLE *rowdata;
+ unsigned int row;
+ geocache_buffer *buffer = geocache_buffer_create(5000,r->pool);
+ cinfo.err = jpeg_std_error(&jerr);
+ jpeg_create_compress(&cinfo);
+
+ cinfo.dest = (struct jpeg_destination_mgr *)
+ (*cinfo.mem->alloc_small) ((j_common_ptr) &cinfo, JPOOL_PERMANENT,
+ sizeof (geocache_jpeg_destination_mgr));
+ ((geocache_jpeg_destination_mgr*)cinfo.dest)->pub.empty_output_buffer = _geocache_imageio_jpeg_buffer_empty_output_buffer;
+ ((geocache_jpeg_destination_mgr*)cinfo.dest)->pub.term_destination = _geocache_imageio_jpeg_buffer_term_destination;
+ ((geocache_jpeg_destination_mgr*)cinfo.dest)->buffer = buffer;
+
+ dest = (geocache_jpeg_destination_mgr*) cinfo.dest;
+ dest->pub.init_destination = _geocache_imageio_jpeg_init_destination;
+
+ cinfo.image_width = img->w;
+ cinfo.image_height = img->h;
+ cinfo.input_components = 3;
+ cinfo.in_color_space = JCS_RGB;
+ jpeg_set_defaults(&cinfo);
+ jpeg_set_quality(&cinfo, quality, TRUE);
+ jpeg_start_compress(&cinfo, TRUE);
+
+ rowdata = (JSAMPLE*)malloc(img->w*cinfo.input_components*sizeof(JSAMPLE));
+ for(row=0;row<img->h;row++) {
+ JSAMPLE *pixptr = rowdata;
+ int col;
+ unsigned char *r,*g,*b;
+ r=&(img->data[0])+row*img->stride;
+ g=&(img->data[1])+row*img->stride;
+ b=&(img->data[2])+row*img->stride;
+ for(col=0;col<img->w;col++) {
+ *(pixptr++) = *r;
+ *(pixptr++) = *g;
+ *(pixptr++) = *b;
+ r+=4;
+ g+=4;
+ b+=4;
+ }
+ (void) jpeg_write_scanlines(&cinfo, &rowdata, 1);
+ }
+
+ /* Step 6: Finish compression */
+
+ jpeg_finish_compress(&cinfo);
+ jpeg_destroy_compress(&cinfo);
+ free(rowdata);
+ return buffer;
+}
+
+
geocache_image_format_type geocache_imageio_header_sniff(request_rec *r, geocache_buffer *buffer) {
- if(!buffer || buffer->size < 8) {
+ if(!buffer) {
return GEOCACHE_IMAGE_FORMAT_UNKNOWN;
}
- if(png_sig_cmp((png_bytep)buffer->buf, 0, 8) == 0) {
+ if(buffer->size >= 8 && png_sig_cmp((png_bytep)buffer->buf, 0, 8) == 0) {
return GEOCACHE_IMAGE_FORMAT_PNG;
- /* } else if(png_sig_cmp(buffer->buf, 0, 8) == 0) {
- return GEOCACHE_IMAGE_FORMAT_JPEG;*/
+ } else if(buffer->size >= 2 && buffer->buf[0] == 0xFF && buffer->buf[1] == 0xD8) {
+ return GEOCACHE_IMAGE_FORMAT_JPEG;
} else {
return GEOCACHE_IMAGE_FORMAT_UNKNOWN;
}
}
-geocache_image* geocache_imageio_png_decode(request_rec *r, geocache_buffer *buffer) {
+
+
+geocache_image* _geocache_imageio_jpeg_decode(request_rec *r, geocache_buffer *buffer) {
+ struct jpeg_decompress_struct cinfo = {NULL};
+ struct jpeg_error_mgr jerr;
+ jpeg_create_decompress(&cinfo);
+ cinfo.err = jpeg_std_error(&jerr);
+ geocache_image *img = apr_pcalloc(r->pool,sizeof(geocache_image));
+ if (_geocache_imageio_jpeg_mem_src(&cinfo,buffer->buf, buffer->size) != GEOCACHE_SUCCESS){
+ return NULL;
+ }
+
+ jpeg_read_header(&cinfo, TRUE);
+ jpeg_start_decompress(&cinfo);
+ img->w = cinfo.output_width;
+ img->h = cinfo.output_height;
+ int s = cinfo.output_components;
+ img->data = apr_pcalloc(r->pool,img->w*img->h*4*sizeof(unsigned char));
+ img->stride = img->w * 4;
+
+ unsigned char *temp = apr_pcalloc(r->pool,img->w*s);
+ while ((int)cinfo.output_scanline < img->h)
+ {
+ int i;
+ unsigned char *rowptr = &img->data[cinfo.output_scanline * img->stride];
+ unsigned char *tempptr = temp;
+ jpeg_read_scanlines(&cinfo, &tempptr, 1);
+ if (s == 1)
+ {
+ for (i = 0; i < img->w; i++)
+ {
+ *rowptr++ = *tempptr;
+ *rowptr++ = *tempptr;
+ *rowptr++ = *tempptr;
+ *rowptr++ = 255;
+ tempptr++;
+ }
+ }
+ else if (s == 3)
+ {
+ for (i = 0; i < img->w; i++)
+ {
+ *rowptr++ = *tempptr++;
+ *rowptr++ = *tempptr++;
+ *rowptr++ = *tempptr++;
+ *rowptr++ = 255;
+ }
+ }
+ else
+ {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "unsupported jpeg format");
+ jpeg_destroy_decompress(&cinfo);
+ return NULL;
+ }
+ }
+ jpeg_finish_decompress(&cinfo);
+ jpeg_destroy_decompress(&cinfo);
+ return img;
+
+}
+
+geocache_image* _geocache_imageio_png_decode(request_rec *r, geocache_buffer *buffer) {
geocache_image *img;
png_uint_32 row_bytes;
int bit_depth,color_type,i;
@@ -70,7 +305,7 @@
b.buffer = buffer;
b.ptr = buffer->buf;
-
+
/* could pass pointers to user-defined error handlers instead of NULLs: */
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!png_ptr) {
@@ -93,14 +328,14 @@
return NULL;
}
png_set_read_fn(png_ptr,&b,_geocache_imageio_png_read_func);
-
+
png_read_info(png_ptr,info_ptr);
img = apr_pcalloc(r->pool,sizeof(geocache_image));
if(!png_get_IHDR(png_ptr, info_ptr, &img->w, &img->h,&bit_depth, &color_type,NULL,NULL,NULL)) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "failed to read png header");
return NULL;
}
-
+
img->data = apr_pcalloc(r->pool,img->w*img->h*4*sizeof(unsigned char));
img->stride = img->w * 4;
row_pointers = apr_pcalloc(r->pool,img->h * sizeof(unsigned char*));
@@ -143,8 +378,7 @@
return img;
}
-
-geocache_buffer* geocache_imageio_png_encode(request_rec *r, geocache_image *img) {
+geocache_buffer* _geocache_imageio_png_encode(request_rec *r, geocache_image *img) {
png_infop info_ptr;
int color_type;
size_t row;
@@ -198,9 +432,24 @@
return buffer;
}
+geocache_buffer* geocache_imageio_encode(request_rec *r, geocache_image *image, geocache_image_format_type format) {
+ if(format == GEOCACHE_IMAGE_FORMAT_PNG) {
+ return _geocache_imageio_png_encode(r,image);
+ } else if(format == GEOCACHE_IMAGE_FORMAT_JPEG) {
+ return _geocache_imageio_jpeg_encode(r,image);
+ } else {
+ return NULL;
+ }
+}
+
geocache_image* geocache_imageio_decode(request_rec *r, geocache_buffer *buffer) {
- if(geocache_imageio_header_sniff(r,buffer) != GEOCACHE_IMAGE_FORMAT_PNG) {
+ geocache_image_format_type type = geocache_imageio_header_sniff(r,buffer);
+ if(type == GEOCACHE_IMAGE_FORMAT_PNG) {
+ return _geocache_imageio_png_decode(r,buffer);
+ } else if(type == GEOCACHE_IMAGE_FORMAT_JPEG) {
+ return _geocache_imageio_jpeg_decode(r,buffer);
+ } else {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "geocache_imageio_decode: unrecognized image format");
return NULL;
}
- return geocache_imageio_png_decode(r,buffer);
}
Modified: trunk/mapserver/mapcache/src/mod_geocache.c
===================================================================
--- trunk/mapserver/mapcache/src/mod_geocache.c 2011-08-26 11:00:27 UTC (rev 12132)
+++ trunk/mapserver/mapcache/src/mod_geocache.c 2011-08-26 11:00:36 UTC (rev 12133)
@@ -97,6 +97,10 @@
/* TODO: individual check on tiles if merging is allowed */
tile = (geocache_tile*)geocache_image_merge_tiles(r,request->tiles,request->ntiles);
+ if(!tile) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "tile merging failed to return data");
+ return HTTP_INTERNAL_SERVER_ERROR;
+ }
tile->tileset = request->tiles[0]->tileset;
}
return geocache_write_tile(r,tile);
Modified: trunk/mapserver/mapcache/src/tileset.c
===================================================================
--- trunk/mapserver/mapcache/src/tileset.c 2011-08-26 11:00:27 UTC (rev 12132)
+++ trunk/mapserver/mapcache/src/tileset.c 2011-08-26 11:00:36 UTC (rev 12133)
@@ -164,6 +164,7 @@
tileset->tile_sx = tileset->tile_sy = 256;
tileset->extent[0]=tileset->extent[1]=tileset->extent[2]=tileset->extent[3]=0;
tileset->forwarded_params = apr_table_make(pool,1);
+ tileset->format = GEOCACHE_IMAGE_FORMAT_PNG;
return tileset;
}
More information about the mapserver-commits
mailing list