From 917fe711935ca683764743068647ba75dde5170f Mon Sep 17 00:00:00 2001 From: Ruven Date: Sat, 29 Jun 2024 22:47:14 +0200 Subject: [PATCH] Re-factoring of metadata handling in output compressor classes and addition of more complete metadata embedding for PNG. --- ChangeLog | 2 + src/CVT.cc | 12 ++- src/Compressor.h | 73 ++++++++++++------ src/IIPImage.h | 2 +- src/JPEGCompressor.cc | 34 +++++---- src/JPEGCompressor.h | 11 +-- src/JTL.cc | 9 ++- src/OBJ.cc | 5 +- src/PNGCompressor.cc | 171 +++++++++++++++++++++++++++--------------- src/PNGCompressor.h | 14 ++-- src/WebPCompressor.cc | 14 ++-- src/WebPCompressor.h | 6 -- 12 files changed, 221 insertions(+), 132 deletions(-) diff --git a/ChangeLog b/ChangeLog index 71252c09..cb527c05 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,8 @@ 29/06/2024: - Updated autoconf tiff m4 to search for tiffio.h rather than just tiff.h when using TIFFOpen(). - Switched metadata assignment within input image classes to use more efficient map insert() syntax. + - Re-factoring of metadata handling in output compressor classes and addition of more complete metadata + embedding for PNG. 29/05/2024: diff --git a/src/CVT.cc b/src/CVT.cc index 071e29d7..4e7dab4c 100644 --- a/src/CVT.cc +++ b/src/CVT.cc @@ -502,6 +502,10 @@ void CVT::send( Session* session ){ } + // Add metadata + compressor->setMetadata( (*session->image)->metadata ); + + // Set the physical output resolution for this particular view and zoom level if( (*session->image)->dpi_x > 0 && (*session->image)->dpi_y > 0 ){ float dpi_x = (*session->image)->dpi_x * (float) im_width / (float) (*session->image)->getImageWidth(); @@ -513,14 +517,14 @@ void CVT::send( Session* session ){ } } - // Set ICC profile if of a reasonable size + // Embed ICC profile if of a reasonable size if( session->view->embedICC() && ((*session->image)->getMetadata("icc").size()>0) ){ if( (*session->image)->getMetadata("icc").size() < 65536 ){ if( session->loglevel >= 3 ){ *(session->logfile) << "CVT :: Embedding ICC profile with size " << (*session->image)->getMetadata("icc").size() << " bytes" << endl; } - compressor->setICCProfile( (*session->image)->getMetadata("icc") ); + compressor->embedICCProfile( true ); } else{ if( session->loglevel >= 3 ){ @@ -530,13 +534,13 @@ void CVT::send( Session* session ){ } } - // Add XMP metadata if this exists + // Always embed XMP metadata in CVT function if( (*session->image)->getMetadata("xmp").size() > 0 ){ if( session->loglevel >= 3 ){ *(session->logfile) << "CVT :: Embedding XMP metadata with size " << (*session->image)->getMetadata("xmp").size() << " bytes" << endl; } - compressor->setXMPMetadata( (*session->image)->getMetadata("xmp") ); + compressor->embedXMPMetadata( true ); } diff --git a/src/Compressor.h b/src/Compressor.h index e9c2af19..cc65b5d9 100644 --- a/src/Compressor.h +++ b/src/Compressor.h @@ -1,6 +1,6 @@ /* Generic compressor class - extended by JPEG and PNG Compressor classes - Copyright (C) 2017-2023 Ruven Pillay + Copyright (C) 2017-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 @@ -23,9 +23,8 @@ -#include #include "RawTile.h" - +#include /// Base class for IIP output images @@ -52,12 +51,23 @@ class Compressor { /** Units can be 0 for unknown, 1 for dots/inch or 2 for dots/cm */ int dpi_units; + /// Metadata + std::map metadata; + /// ICC Profile + bool embedICC; std::string icc; /// XMP metadata + bool embedXMP; std::string xmp; + /// Write metadata + virtual void writeMetadata() {}; + + /// Write DPI + virtual void writeResolution() {}; + /// Write ICC profile virtual void writeICCProfile() {}; @@ -76,12 +86,24 @@ class Compressor { header_size( 0 ), dpi_x( 0 ), dpi_y( 0 ), - dpi_units( 0 ) {}; + dpi_units( 0 ), + embedICC( false ), + embedXMP( false ) {}; virtual ~Compressor() {}; + /// Return the image header size + /** @return header size in bytes */ + unsigned int getHeaderSize() const { return header_size; }; + + + /// Return a pointer to the image header itself + /** @return binary header blob */ + unsigned char* getHeader() { return header; }; + + /// Get the current quality level inline int getQuality() const { return Q; } @@ -94,24 +116,38 @@ class Compressor { inline void setResolution( float x, float y, int units ){ dpi_x = x; dpi_y = y; dpi_units = units; }; - /// Set the ICC profile - /** @param profile ICC profile string */ - inline void setICCProfile( const std::string& profile ){ icc = profile; } + /// Embed ICC profile + /** @param embed Whether ICC profile should be embedded */ + inline void embedICCProfile( const bool embed ){ this->embedICC = embed; } - /// Set XMP metadata - /** @param x XMP metadata string */ - inline void setXMPMetadata( const std::string& x ){ xmp = x; } + /// Embed XMP metadata + /** @param embed Whether XMP metadata should be embedded */ + inline void embedXMPMetadata( const bool embed ){ this->embedXMP = embed; } - /// Return the image header size - /** @return header size in bytes */ - virtual unsigned int getHeaderSize() const { return 0; }; + /// Set general metadata + /** @param metadata Metadata list */ + inline void setMetadata( const std::map & metadata ) + { + this->metadata = std::map ( metadata ); + // Extract ICC profile if it exists and remove from list + std::map :: const_iterator it; + it = this->metadata.find("icc"); + if( it != this->metadata.end() ){ + icc = it->second; + this->metadata.erase( it ); + } + + // Extract XMP chunk if it exists and remove from list + it = this->metadata.find("xmp"); + if( it != this->metadata.end() ){ + xmp = it->second; + this->metadata.erase( it ); + } + }; - /// Return a pointer to the image header itself - /** @return binary header blob */ - virtual unsigned char* getHeader() { return NULL; }; /// Initialise strip based compression @@ -147,11 +183,6 @@ class Compressor { virtual unsigned int Compress( RawTile& t ) { return 0; }; - /// Add metadata to the image header - /** @param m metadata */ - virtual void addXMPMetadata( const std::string& m ) {}; - - /// Get mime type /** @return IANA mime type as const char* */ virtual const char* getMimeType() const { return "image/example"; }; diff --git a/src/IIPImage.h b/src/IIPImage.h index ac0cdec8..e3f09e8a 100644 --- a/src/IIPImage.h +++ b/src/IIPImage.h @@ -174,7 +174,7 @@ class IIPImage { std::vector histogram; /// STL map to hold string metadata - std::map metadata; + std::map metadata; /// Image modification timestamp time_t timestamp; diff --git a/src/JPEGCompressor.cc b/src/JPEGCompressor.cc index f6303d1e..cd1c718a 100644 --- a/src/JPEGCompressor.cc +++ b/src/JPEGCompressor.cc @@ -1,6 +1,6 @@ /* JPEG class wrapper to ijg jpeg library - 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 @@ -228,10 +228,8 @@ void JPEGCompressor::InitCompression( const RawTile& rawtile, unsigned int strip cinfo.in_color_space = ( channels == 3 ? JCS_RGB : JCS_GRAYSCALE ); jpeg_set_defaults( &cinfo ); - // Set our physical output resolution (JPEG only supports integers) - cinfo.X_density = round( dpi_x ); - cinfo.Y_density = round( dpi_y ); - cinfo.density_unit = dpi_units; + // Add DPI + writeResolution(); // Set compression point quality (highest, but possibly slower depending // on hardware) - must do this after we've set the defaults! @@ -402,10 +400,8 @@ unsigned int JPEGCompressor::Compress( RawTile& rawtile ) cinfo.in_color_space = ( channels == 3 ? JCS_RGB : JCS_GRAYSCALE ); jpeg_set_defaults( &cinfo ); - // Set our physical output resolution (JPEG only supports integers) - if( dpi_x ) cinfo.X_density = round( dpi_x ); - if( dpi_y ) cinfo.Y_density = round( dpi_y ); - if( dpi_x || dpi_y ) cinfo.density_unit = dpi_units; + // Add DPI + writeResolution(); // Set compression quality (fastest, but possibly slower depending // on hardware) - must do this after we've set the defaults! @@ -468,6 +464,17 @@ unsigned int JPEGCompressor::Compress( RawTile& rawtile ) +// Write DPI information +void JPEGCompressor::writeResolution() +{ + // Set our physical output resolution (JPEG only supports integers) + if( dpi_x ) cinfo.X_density = round( dpi_x ); + if( dpi_y ) cinfo.Y_density = round( dpi_y ); + if( dpi_x || dpi_y ) cinfo.density_unit = dpi_units; +} + + + // Write ICC profile into JPEG header if profile has been set // Function *must* be called AFTER calling jpeg_start_compress() and BEFORE // the first call to jpeg_write_scanlines(). @@ -478,14 +485,13 @@ unsigned int JPEGCompressor::Compress( RawTile& rawtile ) // See the copyright notice in COPYING.ijg for details void JPEGCompressor::writeICCProfile() { + // Skip if profile embedding disabled + if( !embedICC || icc.empty() ) return; + unsigned int num_markers; // total number of markers we'll write int cur_marker = 1; // per spec, counting starts at 1 unsigned int length; // number of bytes to write in this marker - // Skip if our profile has zero size or is too big - // if( icc.size() == 0 || icc.size() > MAX_DATA_BYTES_IN_MARKER ) return; - if( icc.empty() ) return; - unsigned int icc_data_len = icc.size(); const char* icc_data_ptr = icc.c_str(); @@ -542,7 +548,7 @@ void JPEGCompressor::writeICCProfile() void JPEGCompressor::writeXMPMetadata() { // Make sure our XMP data has a valid size (namespace prefix is 29 bytes) - if( xmp.empty() || xmp.size()>(65536-XMP_PREFIX_SIZE) ) return; + if( !embedXMP || xmp.empty() || xmp.size()>(65536-XMP_PREFIX_SIZE) ) return; // The XMP data in a JPEG stream needs to be prefixed with a zero-terminated ID string // ref http://www.adobe.com/content/dam/Adobe/en/devnet/xmp/pdfs/cs6/XMPSpecificationPart3.pdf (pp13-14) diff --git a/src/JPEGCompressor.h b/src/JPEGCompressor.h index 9de42ea5..9db7d1e1 100644 --- a/src/JPEGCompressor.h +++ b/src/JPEGCompressor.h @@ -1,6 +1,6 @@ /* JPEG class wrapper to ijg libjpeg library - 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 @@ -73,6 +73,9 @@ class JPEGCompressor: public Compressor{ iip_destination_mgr dest_mgr; iip_dest_ptr dest; + /// Write DPI + void writeResolution(); + /// Write ICC profile void writeICCProfile(); @@ -128,12 +131,6 @@ class JPEGCompressor: public Compressor{ /** @param t tile of image data */ unsigned int Compress( RawTile& t ); - /// Return the JPEG header size - inline unsigned int getHeaderSize() const { return header_size; } - - /// Return a pointer to the header itself - inline unsigned char* getHeader() { return header; } - /// Return the JPEG mime type inline const char* getMimeType() const { return "image/jpeg"; } diff --git a/src/JTL.cc b/src/JTL.cc index ef8fff98..4461323c 100644 --- a/src/JTL.cc +++ b/src/JTL.cc @@ -141,16 +141,21 @@ void JTL::send( Session* session, int resolution, int tile ){ } + // Add metadata + compressor->setMetadata( (*session->image)->metadata ); + + // Embed ICC profile - if( session->view->embedICC() && ((*session->image)->getMetadata("icc").size()>0) ){ + if( session->view->embedICC() && (*session->image)->metadata["icc"].size() > 0 ){ if( session->loglevel >= 3 ){ *(session->logfile) << "JTL :: Embedding ICC profile with size " << (*session->image)->getMetadata("icc").size() << " bytes" << endl; } - compressor->setICCProfile( (*session->image)->getMetadata("icc") ); + compressor->embedICCProfile( true ); } + RawTile rawtile = tilemanager.getTile( resolution, tile, session->view->xangle, session->view->yangle, session->view->getLayers(), ct ); diff --git a/src/OBJ.cc b/src/OBJ.cc index 42ebaf3f..62d59eee 100644 --- a/src/OBJ.cc +++ b/src/OBJ.cc @@ -112,9 +112,8 @@ void OBJ::run( Session* s, const std::string& a ) stringstream json; json << "{ "; - map metadata = (*session->image)->metadata; - map :: const_iterator i; - for( i = metadata.begin(); i != metadata.end(); i++ ){ + map :: const_iterator i; + for( i = (*session->image)->metadata.begin(); i != (*session->image)->metadata.end(); i++ ){ if( i->first == "icc" || i->first == "xmp" ) continue; if( (i->second).length() ) json << endl << "\t\"" << i->first << "\": \"" << i->second << "\","; } diff --git a/src/PNGCompressor.cc b/src/PNGCompressor.cc index e150342f..fb8f517e 100644 --- a/src/PNGCompressor.cc +++ b/src/PNGCompressor.cc @@ -1,6 +1,6 @@ /* PNG class wrapper to libpng library - Copyright (C) 2012-2021 Ruven Pillay + Copyright (C) 2012-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 @@ -27,6 +27,14 @@ using namespace std; #define MX 65536 +// Handle libpng versions that don't have itxt support +#ifdef PNG_WRITE_iTXt_SUPPORTED +#define iTXt_COMPRESSION PNG_ITXT_COMPRESSION_NONE +#else +#define iTXt_COMPRESSION PNG_TEXT_COMPRESSION_NONE +#endif + + // ICC profile definitions #define ICC_PROFILE_NAME "ICC" // PNG requires a name for the ICC profile name #define ICC_OVERHEAD_SIZE 5 // ICC overhead for PNG = profile name + 2 bytes: 1 for null byte + 1 for compression type @@ -149,32 +157,10 @@ void PNGCompressor::InitCompression( const RawTile& rawtile, unsigned int strip_ png_set_filter( dest.png_ptr, 0, filterType ); - // Set physical resolution - convert from inches or cm to meters - if( dpi_x || dpi_y ){ - png_uint_32 res_x = (dpi_units==2) ? dpi_x*10 : ( (dpi_units==1) ? dpi_x*25.4 : dpi_x ); - png_uint_32 res_y = (dpi_units==2) ? dpi_y*10 : ( (dpi_units==1) ? dpi_y*25.4 : dpi_y ); - png_set_pHYs( dest.png_ptr, dest.info_ptr, res_x, res_y, ((dpi_units==0) ? PNG_RESOLUTION_UNKNOWN : PNG_RESOLUTION_METER) ); - } - - - // Set some text metadata - png_text text; - text.compression = PNG_TEXT_COMPRESSION_NONE; - text.key = (png_charp) "Software"; - text.text = (png_charp) "iipsrv/" VERSION; - text.text_length = 7 + strlen(VERSION); - png_textp text_ptr[1]; - text_ptr[0] = &text; - png_set_text( dest.png_ptr, dest.info_ptr, *text_ptr, 1 ); - - - // Add any ICC profile - writeICCProfile(); + // Add metadata + writeMetadata(); - // Add XMP metadata - writeXMPMetadata(); - // Write out the encoded header png_write_info( dest.png_ptr, dest.info_ptr ); @@ -302,30 +288,11 @@ unsigned int PNGCompressor::Compress( RawTile& rawtile ) png_set_compression_level( dest.png_ptr, Q ); png_set_filter( dest.png_ptr, 0, filterType ); - // Set physical resolution - convert from inches or cm to meters - if( dpi_x || dpi_y ){ - png_uint_32 res_x = (dpi_units==2) ? dpi_x*10 : ( (dpi_units==1) ? dpi_x*25.4 : dpi_x ); - png_uint_32 res_y = (dpi_units==2) ? dpi_y*10 : ( (dpi_units==1) ? dpi_y*25.4 : dpi_y ); - png_set_pHYs( dest.png_ptr, dest.info_ptr, res_x, res_y, ((dpi_units==0) ? PNG_RESOLUTION_UNKNOWN : PNG_RESOLUTION_METER) ); - } - - // Set some text metadata - png_text text; - text.compression = PNG_TEXT_COMPRESSION_NONE; - text.key = (png_charp) "Software"; - text.text = (png_charp) "iipsrv/" VERSION; - text.text_length = 7 + strlen(VERSION); - png_textp text_ptr[1]; - text_ptr[0] = &text; - png_set_text( dest.png_ptr, dest.info_ptr, *text_ptr, 1 ); + // Write metadata + writeMetadata(); - // Write our ICC profile - writeICCProfile(); - - writeXMPMetadata(); - // Write out the encoded header png_write_info( dest.png_ptr, dest.info_ptr ); @@ -377,28 +344,94 @@ unsigned int PNGCompressor::Compress( RawTile& rawtile ) -void PNGCompressor::writeXMPMetadata(){ +void PNGCompressor::writeMetadata() +{ + // Set some basic text metadata + std::map :: const_iterator it; + png_text text[6]; + int n = 0; + + text[n].compression = PNG_TEXT_COMPRESSION_NONE; + text[n].key = (png_charp) "Software"; + text[n].text = (png_charp) "iipsrv/" VERSION; + text[n].text_length = 7 + strlen(VERSION); + n++; + + it = metadata.find("title"); + if( it != metadata.end() ){ + text[n].compression = iTXt_COMPRESSION; + text[n].key = (png_charp) "Title"; + text[n].text = (png_charp) it->second.c_str(); + text[n].text_length = it->second.size(); + n++; + } - unsigned int len = xmp.size(); - if( len == 0 ) return; + it = metadata.find("creator"); + if( it != metadata.end() ){ + text[n].compression = iTXt_COMPRESSION; + text[n].key = (png_charp) "Author"; + text[n].text = (png_charp) it->second.c_str(); + text[n].text_length = it->second.size(); + n++; + } - png_text text; - text.key = (png_charp) XMP_PREFIX; - text.text = (png_charp) xmp.c_str(); - text.compression = PNG_TEXT_COMPRESSION_NONE; - text.text_length = len; + it = metadata.find("description"); + if( it != metadata.end() ){ + text[n].compression = iTXt_COMPRESSION; + text[n].key = (png_charp) "Description"; + text[n].text = (png_charp) it->second.c_str(); + text[n].text_length = it->second.size(); + n++; + } - // Write out our XMP chunk - png_set_text( dest.png_ptr, dest.info_ptr, &text, 1 ); + it = metadata.find("rights"); + if( it != metadata.end() ){ + text[n].compression = iTXt_COMPRESSION; + text[n].key = (png_charp) "Copyright"; + text[n].text = (png_charp) it->second.c_str(); + text[n].text_length = it->second.size(); + n++; + } + it = metadata.find("date"); + if( it != metadata.end() ){ + text[n].compression = PNG_TEXT_COMPRESSION_NONE; + text[n].key = (png_charp) "Creation Time"; + text[n].text = (png_charp) it->second.c_str(); + text[n].text_length = it->second.size(); + n++; + } + + png_set_text( dest.png_ptr, dest.info_ptr, text, n ); + + // Write DPI + writeResolution(); + + // Write our ICC profile + writeICCProfile(); + + // Write XMP chunk + writeXMPMetadata(); } -void PNGCompressor::writeICCProfile(){ +void PNGCompressor::writeResolution() +{ + // Set physical resolution - convert from inches or cm to meters + if( dpi_x || dpi_y ){ + png_uint_32 res_x = (dpi_units==2) ? dpi_x*10 : ( (dpi_units==1) ? dpi_x*25.4 : dpi_x ); + png_uint_32 res_y = (dpi_units==2) ? dpi_y*10 : ( (dpi_units==1) ? dpi_y*25.4 : dpi_y ); + png_set_pHYs( dest.png_ptr, dest.info_ptr, res_x, res_y, ((dpi_units==0) ? PNG_RESOLUTION_UNKNOWN : PNG_RESOLUTION_METER) ); + } +} + + - unsigned int len = icc.size(); - if( len == 0 ) return; +void PNGCompressor::writeICCProfile() +{ + // Skip if profile embedding disabled or no profile exists + if( !embedICC || icc.empty() ) return; const char* icc_data_ptr = icc.c_str(); @@ -420,6 +453,24 @@ void PNGCompressor::writeICCProfile(){ #endif // Write out ICC profile - png_set_iCCP( dest.png_ptr, dest.info_ptr, ICC_PROFILE_NAME, PNG_COMPRESSION_TYPE_BASE, icc_profile_buf_png, len ); + png_set_iCCP( dest.png_ptr, dest.info_ptr, ICC_PROFILE_NAME, PNG_COMPRESSION_TYPE_BASE, icc_profile_buf_png, icc.size() ); + +} + + + +void PNGCompressor::writeXMPMetadata() +{ + // Skip if XMP embedding disabled or no XMP chunk exists + if( !embedXMP || xmp.empty() ) return; + + png_text text; + text.key = (png_charp) XMP_PREFIX; + text.text = (png_charp) xmp.c_str(); + text.compression = PNG_TEXT_COMPRESSION_NONE; + text.text_length = xmp.size(); + + // Write out our XMP chunk + png_set_text( dest.png_ptr, dest.info_ptr, &text, 1 ); } diff --git a/src/PNGCompressor.h b/src/PNGCompressor.h index 7ca3572c..1e9e169e 100644 --- a/src/PNGCompressor.h +++ b/src/PNGCompressor.h @@ -1,7 +1,7 @@ /* IIP PNG Compressor Class: Handles alpha channels, 8 or 16 bit data, ICC profiles and XMP metadata - Copyright (C) 2012-2023 Ruven Pillay + Copyright (C) 2012-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 @@ -68,6 +68,12 @@ class PNGCompressor : public Compressor { // The Compressor class Q parameter stores the zlib compression level (0-9) int filterType; ///< PNG compression filter type - see png.h + /// Write metadata + void writeMetadata(); + + /// Write DPI + void writeResolution(); + /// Write ICC profile void writeICCProfile(); @@ -131,12 +137,6 @@ class PNGCompressor : public Compressor { unsigned int Compress( RawTile& t ); - /// Return the PNG header size - inline unsigned int getHeaderSize() const { return header_size; } - - /// Return a pointer to the header itself - inline unsigned char* getHeader() { return header; } - /// Return the PNG mime type inline const char* getMimeType() const { return "image/png"; } diff --git a/src/WebPCompressor.cc b/src/WebPCompressor.cc index 0b6ff5d0..08588ab6 100644 --- a/src/WebPCompressor.cc +++ b/src/WebPCompressor.cc @@ -1,7 +1,7 @@ /* IIP WebP Compressor Class: Handles alpha channels, ICC profiles and XMP metadata - Copyright (C) 2022 Ruven Pillay + Copyright (C) 2022-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 @@ -195,12 +195,12 @@ unsigned int WebPCompressor::Compress( RawTile& rawtile ){ /// Write ICC profile void WebPCompressor::writeICCProfile() { - unsigned int len = icc.size(); - if( len == 0 ) return; + // Skip if profile embedding disabled or no profile exists + if( !embedICC || icc.empty() ) return; WebPData chunk; chunk.bytes = (const uint8_t*) icc.c_str(); - chunk.size = len; + chunk.size = icc.size(); if( WebPMuxSetChunk( mux, "ICCP", &chunk, 0 ) != WEBP_MUX_OK ){ throw string( "WebPCompressor :: Error setting ICC profile chunk" ); @@ -212,12 +212,12 @@ void WebPCompressor::writeICCProfile() /// Write XMP metadata void WebPCompressor::writeXMPMetadata() { - unsigned int len = xmp.size(); - if( len == 0 ) return; + // Skip if XMP embedding disabled or no XMP chunk exists + if( !embedXMP || xmp.empty() ) return; WebPData chunk; chunk.bytes = (const uint8_t*) xmp.c_str(); - chunk.size = len; + chunk.size = xmp.size(); if( WebPMuxSetChunk( mux, "XMP ", &chunk, 0 ) != WEBP_MUX_OK ){ throw string( "WebPCompressor :: Error setting XMP chunk" ); diff --git a/src/WebPCompressor.h b/src/WebPCompressor.h index 7e870773..183dcb29 100644 --- a/src/WebPCompressor.h +++ b/src/WebPCompressor.h @@ -119,12 +119,6 @@ class WebPCompressor : public Compressor { unsigned int Compress( RawTile& t ); - /// Return the WebP header size - inline unsigned int getHeaderSize() const { return header_size; } - - /// Return a pointer to the header itself - inline unsigned char* getHeader() { return header; } - /// Return the WebP mime type inline const char* getMimeType() const { return "image/webp"; }