diff --git a/mozilla/allmakefiles.sh b/mozilla/allmakefiles.sh index ad5f1b6ea59..cdf26a52c38 100755 --- a/mozilla/allmakefiles.sh +++ b/mozilla/allmakefiles.sh @@ -1174,6 +1174,8 @@ embedding/components/profilesharingsetup/src/Makefile modules/libpr0n/decoders/icon/win/Makefile modules/libpr0n/decoders/icon/gtk/Makefile modules/libpr0n/decoders/xbm/Makefile + modules/libpr0n/encoders/Makefile + modules/libpr0n/encoders/png/Makefile " MAKEFILES_accessible=" diff --git a/mozilla/config/autoconf.mk.in b/mozilla/config/autoconf.mk.in index 72426085069..b6590d93932 100644 --- a/mozilla/config/autoconf.mk.in +++ b/mozilla/config/autoconf.mk.in @@ -87,6 +87,7 @@ MOZ_DEBUG_LDFLAGS=@MOZ_DEBUG_LDFLAGS@ MOZ_DBGRINFO_MODULES = @MOZ_DBGRINFO_MODULES@ MOZ_EXTENSIONS = @MOZ_EXTENSIONS@ MOZ_IMG_DECODERS= @MOZ_IMG_DECODERS@ +MOZ_IMG_ENCODERS= @MOZ_IMG_ENCODERS@ MOZ_JSDEBUGGER = @MOZ_JSDEBUGGER@ MOZ_PERF_METRICS = @MOZ_PERF_METRICS@ MOZ_LEAKY = @MOZ_LEAKY@ diff --git a/mozilla/configure.in b/mozilla/configure.in index 7488bbd38fb..fc1e560387d 100644 --- a/mozilla/configure.in +++ b/mozilla/configure.in @@ -3955,6 +3955,7 @@ MOZ_DBGRINFO_MODULES= MOZ_ENABLE_LIBXUL= MOZ_EXTENSIONS_ALL=" cookie wallet content-packs xml-rpc xmlextras help p3p pref transformiix venkman inspector irc universalchardet typeaheadfind webservices spellcheck gnomevfs auth sroaming xmlterm datetime finger cview layout-debug tasks sql xforms permissions schema-validation reporter" MOZ_IMG_DECODERS_DEFAULT="png gif jpeg bmp xbm" +MOZ_IMG_ENCODERS_DEFAULT="png" MOZ_IPCD= MOZ_JSDEBUGGER=1 MOZ_JSLOADER=1 @@ -4058,6 +4059,7 @@ minimo) MOZ_ENABLE_POSTSCRIPT= MOZ_EXTENSIONS_DEFAULT="xml-rpc xmlextras transformiix webservices spatialnavigation" MOZ_IMG_DECODERS="png,gif,jpeg" + MOZ_IMG_ENCODERS= MOZ_INSTALLER= MOZ_JSDEBUGGER= MOZ_LDAP_XPCOM= @@ -4884,8 +4886,35 @@ MOZ_ARG_ENABLE_STRING(image-decoders, done], MOZ_IMG_DECODERS="$MOZ_IMG_DECODERS_DEFAULT") +dnl Dupes are removed in the encoder section because it will also add decoders + +dnl ======================================================== +dnl Image encoders +dnl ======================================================== +MOZ_ARG_ENABLE_STRING(image-encoders, +[ --enable-image-encoders[={mod1,mod2,default,all,none}] + Enable specific image encoders], +[ for option in `echo $enableval | sed 's/,/ /g'`; do + if test "$option" = "yes" || test "$option" = "all"; then + addencoder="$MOZ_IMG_ENCODERS_DEFAULT" + elif test "$option" = "no" || test "$option" = "none"; then + MOZ_IMG_ENCODERS="" + addencoder="" + elif test "$option" = "default"; then + addencoder="$MOZ_IMG_ENCODERS_DEFAULT" + elif test `echo "$option" | grep -c \^-` != 0; then + option=`echo $option | sed 's/^-//'` + addencoder=`echo "$MOZ_IMG_ENCODERS" | sed "s/ ${option}//"` + else + addencoder="$option" + fi + MOZ_IMG_ENCODERS="$MOZ_IMG_ENCODERS $addencoder" +done], + MOZ_IMG_ENCODERS="$MOZ_IMG_ENCODERS_DEFAULT") + dnl Remove dupes MOZ_IMG_DECODERS=`${PERL} ${srcdir}/build/unix/uniq.pl ${MOZ_IMG_DECODERS}` +MOZ_IMG_ENCODERS=`${PERL} ${srcdir}/build/unix/uniq.pl ${MOZ_IMG_ENCODERS}` dnl ======================================================== dnl experimental ldap features @@ -6609,6 +6638,7 @@ AC_SUBST(MOZ_DEBUG_LDFLAGS) AC_SUBST(MOZ_DBGRINFO_MODULES) AC_SUBST(MOZ_EXTENSIONS) AC_SUBST(MOZ_IMG_DECODERS) +AC_SUBST(MOZ_IMG_ENCODERS) AC_SUBST(MOZ_JSDEBUGGER) AC_SUBST(MOZ_OJI) AC_SUBST(MOZ_NO_XPCOM_OBSOLETE) diff --git a/mozilla/modules/libimg/png/Makefile.in b/mozilla/modules/libimg/png/Makefile.in index f55981b78fa..eff1653e13c 100644 --- a/mozilla/modules/libimg/png/Makefile.in +++ b/mozilla/modules/libimg/png/Makefile.in @@ -64,6 +64,11 @@ FORCE_USE_PIC = 1 include $(topsrcdir)/config/rules.mk +#ifeq (png,$(filter png,$(MOZ_IMG_ENCODERS))) +ifdef MOZ_IMG_ENCODERS +DEFINES += -DMOZ_PNG_WRITE +endif + ifeq ($(OS_ARCH),WINNT) DEFINES += -DZLIB_DLL ifdef BUILD_DEBUG_GC diff --git a/mozilla/modules/libimg/png/mozpngconf.h b/mozilla/modules/libimg/png/mozpngconf.h index a53c6f549f5..8204a21d8eb 100644 --- a/mozilla/modules/libimg/png/mozpngconf.h +++ b/mozilla/modules/libimg/png/mozpngconf.h @@ -70,7 +70,36 @@ #define PNG_NO_READ_OPT_PLTE #define PNG_NO_MNG_FEATURES +#ifdef MOZ_PNG_WRITE +#define PNG_NO_WRITE_BACKGROUND +#define PNG_NO_WRITE_DITHER +#define PNG_NO_WRITE_INVERT +#define PNG_NO_WRITE_SHIFT +#define PNG_NO_WRITE_PACK +#define PNG_NO_WRITE_PACKSWAP +#define PNG_NO_WRITE_FILLER +#define PNG_NO_WRITE_SWAP_ALPHA +#define PNG_NO_WRITE_INVERT_ALPHA +#define PNG_NO_WRITE_RGB_TO_GRAY +#define PNG_NO_WRITE_USER_TRANSFORM +#define PNG_NO_WRITE_bKGD +#define PNG_NO_WRITE_cHRM +#define PNG_NO_WRITE_hIST +#define PNG_NO_WRITE_iCCP +#define PNG_NO_WRITE_pCAL +#define PNG_NO_WRITE_pHYs +#define PNG_NO_WRITE_sBIT +#define PNG_NO_WRITE_sCAL +#define PNG_NO_WRITE_sPLT +#define PNG_NO_WRITE_TEXT +#define PNG_NO_WRITE_tIME +#define PNG_NO_WRITE_UNKNOWN_CHUNKS +#define PNG_NO_WRITE_USER_CHUNKS +#define PNG_NO_WRITE_EMPTY_PLTE +#define PNG_NO_WRITE_OPT_PLTE +#else #define PNG_NO_WRITE_SUPPORTED +#endif #define PNG_NO_READ_STRIP_ALPHA #define PNG_NO_USER_TRANSFORM_PTR diff --git a/mozilla/modules/libpr0n/Makefile.in b/mozilla/modules/libpr0n/Makefile.in index 3c17dcfbb81..8a1216dae18 100644 --- a/mozilla/modules/libpr0n/Makefile.in +++ b/mozilla/modules/libpr0n/Makefile.in @@ -50,6 +50,10 @@ ifdef MOZ_IMG_DECODERS DIRS += decoders endif +ifdef MOZ_IMG_ENCODERS +DIRS += encoders +endif + DIRS += build include $(topsrcdir)/config/rules.mk diff --git a/mozilla/modules/libpr0n/build/Makefile.in b/mozilla/modules/libpr0n/build/Makefile.in index c275883f40b..31c98c7edf9 100644 --- a/mozilla/modules/libpr0n/build/Makefile.in +++ b/mozilla/modules/libpr0n/build/Makefile.in @@ -66,19 +66,25 @@ CPPSRCS = \ nsImageModule.cpp \ $(NULL) -DEFINES += $(foreach d,$(filter-out icon,$(MOZ_IMG_DECODERS)),\ - -DIMG_BUILD_${d}) +DEFINES += $(foreach d,$(filter-out icon,$(MOZ_IMG_DECODERS)), \ + -DIMG_BUILD_DECODER_${d}) \ + $(foreach d,$(MOZ_IMG_ENCODERS), \ + -DIMG_BUILD_ENCODER_${d}) LOCAL_INCLUDES = \ -I$(srcdir)/../src \ $(foreach d,$(filter-out icon,$(MOZ_IMG_DECODERS)), \ -I$(srcdir)/../decoders/${d}) \ + $(foreach d,$(MOZ_IMG_ENCODERS), \ + -I$(srcdir)/../encoders/${d}) \ $(NULL) SHARED_LIBRARY_LIBS = \ ../src/$(LIB_PREFIX)imglib2_s.$(LIB_SUFFIX) \ $(foreach d,$(filter-out icon,$(MOZ_IMG_DECODERS)), \ ../decoders/${d}/$(LIB_PREFIX)img${d}_s.$(LIB_SUFFIX))\ + $(foreach d,$(MOZ_IMG_ENCODERS), \ + ../encoders/${d}/$(LIB_PREFIX)img${d}e_s.$(LIB_SUFFIX))\ $(NULL) EXTRA_DSO_LIBS = \ diff --git a/mozilla/modules/libpr0n/build/nsImageModule.cpp b/mozilla/modules/libpr0n/build/nsImageModule.cpp index 122cf4c6c1d..48547dbfcfb 100644 --- a/mozilla/modules/libpr0n/build/nsImageModule.cpp +++ b/mozilla/modules/libpr0n/build/nsImageModule.cpp @@ -57,33 +57,40 @@ #include "imgRequest.h" #include "imgRequestProxy.h" -#ifdef IMG_BUILD_gif +#ifdef IMG_BUILD_DECODER_gif // gif #include "imgContainerGIF.h" #include "nsGIFDecoder2.h" #endif -#ifdef IMG_BUILD_bmp +#ifdef IMG_BUILD_DECODER_bmp // bmp/ico #include "nsBMPDecoder.h" #include "nsICODecoder.h" #endif -#ifdef IMG_BUILD_png +#ifdef IMG_BUILD_DECODER_png // png #include "nsPNGDecoder.h" #endif -#ifdef IMG_BUILD_jpeg +#ifdef IMG_BUILD_DECODER_jpeg // jpeg #include "nsJPEGDecoder.h" #endif -#ifdef IMG_BUILD_xbm +#ifdef IMG_BUILD_DECODER_xbm // xbm #include "nsXBMDecoder.h" #endif + +#ifdef IMG_BUILD_ENCODER_png +// png +#include "nsPNGEncoder.h" +#endif + + // objects that just require generic constructors NS_GENERIC_FACTORY_CONSTRUCTOR(imgCache) @@ -91,52 +98,56 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(imgContainer) NS_GENERIC_FACTORY_CONSTRUCTOR(imgLoader) NS_GENERIC_FACTORY_CONSTRUCTOR(imgRequestProxy) -#ifdef IMG_BUILD_gif +#ifdef IMG_BUILD_DECODER_gif // gif NS_GENERIC_FACTORY_CONSTRUCTOR(imgContainerGIF) NS_GENERIC_FACTORY_CONSTRUCTOR(nsGIFDecoder2) #endif -#ifdef IMG_BUILD_jpeg +#ifdef IMG_BUILD_DECODER_jpeg // jpeg NS_GENERIC_FACTORY_CONSTRUCTOR(nsJPEGDecoder) #endif -#ifdef IMG_BUILD_bmp +#ifdef IMG_BUILD_DECODER_bmp // bmp NS_GENERIC_FACTORY_CONSTRUCTOR(nsICODecoder) NS_GENERIC_FACTORY_CONSTRUCTOR(nsBMPDecoder) #endif -#ifdef IMG_BUILD_png +#ifdef IMG_BUILD_DECODER_png // png NS_GENERIC_FACTORY_CONSTRUCTOR(nsPNGDecoder) #endif +#ifdef IMG_BUILD_ENCODER_png +// png +NS_GENERIC_FACTORY_CONSTRUCTOR(nsPNGEncoder) +#endif -#ifdef IMG_BUILD_xbm +#ifdef IMG_BUILD_DECODER_xbm // xbm NS_GENERIC_FACTORY_CONSTRUCTOR(nsXBMDecoder) #endif static const char* gImageMimeTypes[] = { -#ifdef IMG_BUILD_gif +#ifdef IMG_BUILD_DECODER_gif "image/gif", #endif -#ifdef IMG_BUILD_jpeg +#ifdef IMG_BUILD_DECODER_jpeg "image/jpeg", "image/pjpeg", "image/jpg", #endif -#ifdef IMG_BUILD_bmp +#ifdef IMG_BUILD_DECODER_bmp "image/x-icon", "image/vnd.microsoft.icon", "image/bmp", #endif -#ifdef IMG_BUILD_png +#ifdef IMG_BUILD_DECODER_png "image/png", "image/x-png", #endif -#ifdef IMG_BUILD_xbm +#ifdef IMG_BUILD_DECODER_xbm "image/x-xbitmap", "image/x-xbm", "image/xbm" @@ -199,7 +210,7 @@ static const nsModuleComponentInfo components[] = "@mozilla.org/image/request;1", imgRequestProxyConstructor, }, -#ifdef IMG_BUILD_gif +#ifdef IMG_BUILD_DECODER_gif // gif { "GIF image container", NS_GIFCONTAINER_CID, @@ -211,7 +222,7 @@ static const nsModuleComponentInfo components[] = nsGIFDecoder2Constructor, }, #endif -#ifdef IMG_BUILD_jpeg +#ifdef IMG_BUILD_DECODER_jpeg // jpeg { "JPEG decoder", NS_JPEGDECODER_CID, @@ -227,7 +238,7 @@ static const nsModuleComponentInfo components[] = nsJPEGDecoderConstructor, }, #endif -#ifdef IMG_BUILD_bmp +#ifdef IMG_BUILD_DECODER_bmp // bmp { "ICO Decoder", NS_ICODECODER_CID, @@ -243,7 +254,7 @@ static const nsModuleComponentInfo components[] = nsBMPDecoderConstructor, }, #endif -#ifdef IMG_BUILD_png +#ifdef IMG_BUILD_DECODER_png // png { "PNG Decoder", NS_PNGDECODER_CID, @@ -254,8 +265,15 @@ static const nsModuleComponentInfo components[] = "@mozilla.org/image/decoder;2?type=image/x-png", nsPNGDecoderConstructor, }, #endif +#ifdef IMG_BUILD_ENCODER_png + // png + { "PNG Decoder", + NS_PNGENCODER_CID, + "@mozilla.org/image/encoder;2?type=image/png", + nsPNGEncoderConstructor, }, +#endif -#ifdef IMG_BUILD_xbm +#ifdef IMG_BUILD_DECODER_xbm // xbm { "XBM Decoder", NS_XBMDECODER_CID, @@ -283,7 +301,7 @@ PR_STATIC_CALLBACK(void) imglib_Shutdown(nsIModule* aSelf) { imgCache::Shutdown(); -#ifdef IMG_BUILD_gif +#ifdef IMG_BUILD_DECODER_gif nsGifShutdown(); #endif } diff --git a/mozilla/modules/libpr0n/encoders/Makefile.in b/mozilla/modules/libpr0n/encoders/Makefile.in new file mode 100644 index 00000000000..9ef431eb037 --- /dev/null +++ b/mozilla/modules/libpr0n/encoders/Makefile.in @@ -0,0 +1,46 @@ +# ***** BEGIN LICENSE BLOCK ***** +# Version: MPL 1.1/GPL 2.0/LGPL 2.1 +# +# The contents of this file are subject to the Mozilla Public License Version +# 1.1 (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +# for the specific language governing rights and limitations under the +# License. +# +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is Mozilla Foundation. +# Portions created by the Initial Developer are Copyright (C) 2005 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# +# Alternatively, the contents of this file may be used under the terms of +# either the GNU General Public License Version 2 or later (the "GPL"), or +# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +# in which case the provisions of the GPL or the LGPL are applicable instead +# of those above. If you wish to allow use of your version of this file only +# under the terms of either the GPL or the LGPL, and not to allow others to +# use your version of this file under the terms of the MPL, indicate your +# decision by deleting the provisions above and replace them with the notice +# and other provisions required by the GPL or the LGPL. If you do not delete +# the provisions above, a recipient may use your version of this file under +# the terms of any one of the MPL, the GPL or the LGPL. +# +# ***** END LICENSE BLOCK ***** + +DEPTH = ../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(DEPTH)/config/autoconf.mk + +DIRS += $(MOZ_IMG_ENCODERS) + +include $(topsrcdir)/config/rules.mk + diff --git a/mozilla/modules/libpr0n/encoders/png/Makefile.in b/mozilla/modules/libpr0n/encoders/png/Makefile.in new file mode 100644 index 00000000000..3b455272cb3 --- /dev/null +++ b/mozilla/modules/libpr0n/encoders/png/Makefile.in @@ -0,0 +1,63 @@ +# ***** BEGIN LICENSE BLOCK ***** +# Version: MPL 1.1/GPL 2.0/LGPL 2.1 +# +# The contents of this file are subject to the Mozilla Public License Version +# 1.1 (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +# for the specific language governing rights and limitations under the +# License. +# +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is Mozilla Foundation +# Portions created by the Initial Developer are Copyright (C) 2005 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# +# Alternatively, the contents of this file may be used under the terms of +# either the GNU General Public License Version 2 or later (the "GPL"), or +# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +# in which case the provisions of the GPL or the LGPL are applicable instead +# of those above. If you wish to allow use of your version of this file only +# under the terms of either the GPL or the LGPL, and not to allow others to +# use your version of this file under the terms of the MPL, indicate your +# decision by deleting the provisions above and replace them with the notice +# and other provisions required by the GPL or the LGPL. If you do not delete +# the provisions above, a recipient may use your version of this file under +# the terms of any one of the MPL, the GPL or the LGPL. +# +# ***** END LICENSE BLOCK ***** + +DEPTH = ../../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(DEPTH)/config/autoconf.mk + +MODULE = imgpnge +LIBRARY_NAME = imgpnge_s +FORCE_STATIC_LIB = 1 +MODULE_NAME = imgEncoderPNGModule +LIBXUL_LIBRARY = 1 + +EXTRA_DSO_LIBS = gkgfx + +REQUIRES = xpcom \ + gfx \ + string \ + imglib2 \ + $(PNG_REQUIRES) \ + $(ZLIB_REQUIRES) \ + $(NULL) + +CPPSRCS = nsPNGEncoder.cpp + +include $(topsrcdir)/config/rules.mk + + diff --git a/mozilla/modules/libpr0n/encoders/png/nsPNGEncoder.cpp b/mozilla/modules/libpr0n/encoders/png/nsPNGEncoder.cpp new file mode 100644 index 00000000000..ac00f110241 --- /dev/null +++ b/mozilla/modules/libpr0n/encoders/png/nsPNGEncoder.cpp @@ -0,0 +1,326 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is PNG Encoding code + * + * The Initial Developer of the Original Code is + * Google Inc. + * Portions created by the Initial Developer are Copyright (C) 2005 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Brett Wilson + * Stuart Parmenter + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsPNGEncoder.h" +#include "prmem.h" +#include "nsString.h" +#include "nsDependentSubstring.h" + +NS_IMPL_ISUPPORTS2(nsPNGEncoder, imgIEncoder, nsIInputStream) + +nsPNGEncoder::nsPNGEncoder() : mImageBuffer(nsnull), mImageBufferSize(0), + mImageBufferUsed(0), mImageBufferReadPoint(0) +{ +} + +nsPNGEncoder::~nsPNGEncoder() +{ + if (mImageBuffer) { + PR_Free(mImageBuffer); + mImageBuffer = nsnull; + } +} + +// nsPNGEncoder::InitFromData +// +// One output option is supported: "transparency=none" means that the +// output PNG will not have an alpha channel, even if the input does. +// +// Based partially on gfx/cairo/cairo/src/cairo-png.c +// See also modules/libimg/png/libpng.txt + +NS_IMETHODIMP nsPNGEncoder::InitFromData(const PRUint8* aData, + PRUint32 aLength, // (unused, req'd by JS) + PRUint32 aWidth, + PRUint32 aHeight, + PRUint32 aStride, + PRUint32 aInputFormat, + const nsAString& aOutputOptions) +{ + // validate input format + if (aInputFormat != INPUT_FORMAT_RGB && + aInputFormat != INPUT_FORMAT_RGBA && + aInputFormat != INPUT_FORMAT_HOSTARGB) + return NS_ERROR_INVALID_ARG; + + // Stride is the padded width of each row, so it better be longer (I'm afraid + // people will not understand what stride means, so check it well) + if ((aInputFormat == INPUT_FORMAT_RGB && + aStride < aWidth * 3) || + ((aInputFormat == INPUT_FORMAT_RGBA || aInputFormat == INPUT_FORMAT_HOSTARGB) && + aStride < aWidth * 4)) { + NS_WARNING("Invalid stride for InitFromData"); + return NS_ERROR_INVALID_ARG; + } + + // can't initialize more than once + if (mImageBuffer != nsnull) + return NS_ERROR_ALREADY_INITIALIZED; + + // options: we only have one option so this is easy + PRBool useTransparency = PR_TRUE; + if (aOutputOptions.Length() >= 17) { + if (StringBeginsWith(aOutputOptions, NS_LITERAL_STRING("transparency=none"))) + useTransparency = PR_FALSE; + } + + // initialize + png_struct* png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, + png_voidp_NULL, + png_error_ptr_NULL, + png_error_ptr_NULL); + if (! png_ptr) + return NS_ERROR_OUT_OF_MEMORY; + png_info* info_ptr = png_create_info_struct(png_ptr); + if (! info_ptr) + { + png_destroy_write_struct(&png_ptr, nsnull); + return NS_ERROR_FAILURE; + } + if (setjmp(png_jmpbuf(png_ptr))) { + png_destroy_write_struct(&png_ptr, &info_ptr); + return NS_ERROR_OUT_OF_MEMORY; + } + + // Set up to read the data into our image buffer, start out with an 8K + // estimated size. Note: we don't have to worry about freeing this data + // in this function. It will be freed on object destruction. + mImageBufferSize = 8192; + mImageBuffer = (PRUint8*)PR_Malloc(mImageBufferSize); + if (!mImageBuffer) { + png_destroy_write_struct(&png_ptr, &info_ptr); + return NS_ERROR_OUT_OF_MEMORY; + } + mImageBufferUsed = 0; + + // set our callback for libpng to give us the data + png_set_write_fn(png_ptr, this, WriteCallback, NULL); + + // include alpha? + int colorType; + if ((aInputFormat == INPUT_FORMAT_HOSTARGB || + aInputFormat == INPUT_FORMAT_RGBA) && useTransparency) + colorType = PNG_COLOR_TYPE_RGB_ALPHA; + else + colorType = PNG_COLOR_TYPE_RGB; + + png_set_IHDR(png_ptr, info_ptr, aWidth, aHeight, 8, colorType, + PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, + PNG_FILTER_TYPE_DEFAULT); + + png_write_info(png_ptr, info_ptr); + + // write each row: if we add more input formats, we may want to + // generalize the conversions + if (aInputFormat == INPUT_FORMAT_HOSTARGB) { + // PNG requires RGBA with post-multiplied alpha, so we need to convert + PRUint8* row = new PRUint8[aWidth * 4]; + for (PRUint32 y = 0; y < aHeight; y ++) { + ConvertHostARGBRow(&aData[y * aStride], row, aWidth, useTransparency); + png_write_row(png_ptr, row); + } + delete[] row; + + } else if (aInputFormat == INPUT_FORMAT_RGBA && ! useTransparency) { + // RBGA, but we need to strip the alpha + PRUint8* row = new PRUint8[aWidth * 4]; + for (PRUint32 y = 0; y < aHeight; y ++) { + StripAlpha(&aData[y * aStride], row, aWidth); + png_write_row(png_ptr, row); + } + delete[] row; + + } else if (aInputFormat == INPUT_FORMAT_RGB || + aInputFormat == INPUT_FORMAT_RGBA) { + // simple RBG(A), no conversion needed + for (PRUint32 y = 0; y < aHeight; y ++) { + png_write_row(png_ptr, (PRUint8*)&aData[y * aStride]); + } + + } else { + NS_NOTREACHED("Bad format type"); + } + + png_write_end(png_ptr, info_ptr); + png_destroy_write_struct(&png_ptr, &info_ptr); + + // if output callback can't get enough memory, it will free our buffer + if (mImageBuffer) + return NS_OK; + else + return NS_ERROR_OUT_OF_MEMORY; +} + + +/* void close (); */ +NS_IMETHODIMP nsPNGEncoder::Close() +{ + if (mImageBuffer != nsnull) { + PR_Free(mImageBuffer); + mImageBuffer = nsnull; + mImageBufferSize = 0; + mImageBufferUsed = 0; + } + return NS_OK; +} + +/* unsigned long available (); */ +NS_IMETHODIMP nsPNGEncoder::Available(PRUint32 *_retval) +{ + *_retval = mImageBufferUsed - mImageBufferReadPoint; + return NS_OK; +} + +/* [noscript] unsigned long read (in charPtr aBuf, in unsigned long aCount); */ +NS_IMETHODIMP nsPNGEncoder::Read(char * aBuf, PRUint32 aCount, PRUint32 *_retval) +{ + if (mImageBufferReadPoint >= mImageBufferUsed) { + // done reading + *_retval = 0; + return NS_OK; + } + + PRUint32 toRead = mImageBufferUsed - mImageBufferReadPoint; + if (aCount < toRead) + toRead = aCount; + + memcpy(aBuf, &mImageBuffer[mImageBufferReadPoint], toRead); + + mImageBufferReadPoint += toRead; + *_retval = toRead; + return NS_OK; +} + +/* [noscript] unsigned long readSegments (in nsWriteSegmentFun aWriter, in voidPtr aClosure, in unsigned long aCount); */ +NS_IMETHODIMP nsPNGEncoder::ReadSegments(nsWriteSegmentFun aWriter, void *aClosure, PRUint32 aCount, PRUint32 *_retval) +{ + if (mImageBufferUsed == 0) + return NS_ERROR_FAILURE; + + PRUint32 writeCount = 0; + aWriter(this, aClosure, (const char*)mImageBuffer, 0, mImageBufferUsed, &writeCount); + + if (writeCount > 0) + return NS_OK; + else + return NS_ERROR_FAILURE; // some problem with callback +} + +/* boolean isNonBlocking (); */ +NS_IMETHODIMP nsPNGEncoder::IsNonBlocking(PRBool *_retval) +{ + *_retval = PR_TRUE; + return NS_OK; +} + + +// nsPNGEncoder::ConvertHostARGBRow +// +// Our colors are stored with premultiplied alphas, but PNGs use +// post-multiplied alpha. This swaps to PNG-style alpha. +// +// Copied from gfx/cairo/cairo/src/cairo-png.c + +void +nsPNGEncoder::ConvertHostARGBRow(const PRUint8* aSrc, PRUint8* aDest, + PRUint32 aPixelWidth, PRBool aUseTransparency) +{ + PRUint32 pixelStride = aUseTransparency ? 4 : 3; + for (PRUint32 x = 0; x < aPixelWidth; x ++) { + const PRUint32& pixelIn = ((const PRUint32*)(aSrc))[x]; + PRUint8 *pixelOut = &aDest[x * pixelStride]; + + PRUint8 alpha = (pixelIn & 0xff000000) >> 24; + if (alpha == 0) { + pixelOut[0] = pixelOut[1] = pixelOut[2] = pixelOut[3] = 0; + } else { + pixelOut[0] = (((pixelIn & 0xff0000) >> 16) * 255 + alpha / 2) / alpha; + pixelOut[1] = (((pixelIn & 0x00ff00) >> 8) * 255 + alpha / 2) / alpha; + pixelOut[2] = (((pixelIn & 0x0000ff) >> 0) * 255 + alpha / 2) / alpha; + if (aUseTransparency) + pixelOut[3] = alpha; + } + } +} + + +// nsPNGEncoder::StripAlpha +// +// Input is RGBA, output is RGB + +void +nsPNGEncoder::StripAlpha(const PRUint8* aSrc, PRUint8* aDest, + PRUint32 aPixelWidth) +{ + for (PRUint32 x = 0; x < aPixelWidth; x ++) { + const PRUint8* pixelIn = &aSrc[x * 4]; + PRUint8* pixelOut = &aDest[x * 3]; + pixelOut[0] = pixelIn[0]; + pixelOut[1] = pixelIn[1]; + pixelOut[2] = pixelIn[2]; + } +} + + +// nsPNGEncoder::WriteCallback + +void // static +nsPNGEncoder::WriteCallback(png_structp png, png_bytep data, png_size_t size) +{ + nsPNGEncoder* that = NS_STATIC_CAST(nsPNGEncoder*, png_get_io_ptr(png)); + if (! that->mImageBuffer) + return; + + if (that->mImageBufferUsed + size > that->mImageBufferSize) { + // expand buffer, just double each time + that->mImageBufferSize *= 2; + PRUint8* newBuf = (PRUint8*)PR_Realloc(that->mImageBuffer, + that->mImageBufferSize); + if (! newBuf) { + // can't resize, just zero (this will keep us from writing more) + PR_Free(that->mImageBuffer); + that->mImageBufferSize = 0; + that->mImageBufferUsed = 0; + return; + } + that->mImageBuffer = newBuf; + } + memcpy(&that->mImageBuffer[that->mImageBufferUsed], data, size); + that->mImageBufferUsed += size; +} diff --git a/mozilla/modules/libpr0n/encoders/png/nsPNGEncoder.h b/mozilla/modules/libpr0n/encoders/png/nsPNGEncoder.h new file mode 100644 index 00000000000..2fe3c6bae72 --- /dev/null +++ b/mozilla/modules/libpr0n/encoders/png/nsPNGEncoder.h @@ -0,0 +1,78 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Oracle Corporation code. + * + * The Initial Developer of the Original Code is Oracle Corporation. + * Portions created by the Initial Developer are Copyright (C) 2005 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Stuart Parmenter + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "imgIEncoder.h" + +#include + +#define NS_PNGENCODER_CID \ +{ /* 38d1592e-b81e-432b-86f8-471878bbfe07 */ \ + 0x38d1592e, \ + 0xb81e, \ + 0x432b, \ + {0x86, 0xf8, 0x47, 0x18, 0x78, 0xbb, 0xfe, 0x07} \ +} + +// Provides PNG encoding functionality. Use InitFromData() to do the +// encoding. See that function definition for encoding options. + +class nsPNGEncoder : public imgIEncoder +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_IMGIENCODER + NS_DECL_NSIINPUTSTREAM + + nsPNGEncoder(); + +private: + ~nsPNGEncoder(); + +protected: + void ConvertHostARGBRow(const PRUint8* aSrc, PRUint8* aDest, + PRUint32 aPixelWidth, PRBool aUseTransparency); + void StripAlpha(const PRUint8* aSrc, PRUint8* aDest, + PRUint32 aPixelWidth); + static void WriteCallback(png_structp png, png_bytep data, png_size_t size); + + // image buffer + PRUint8* mImageBuffer; + PRUint32 mImageBufferSize; + PRUint32 mImageBufferUsed; + + PRUint32 mImageBufferReadPoint; +}; diff --git a/mozilla/modules/libpr0n/public/Makefile.in b/mozilla/modules/libpr0n/public/Makefile.in index 9af5774fa1a..ef1af92dec5 100644 --- a/mozilla/modules/libpr0n/public/Makefile.in +++ b/mozilla/modules/libpr0n/public/Makefile.in @@ -53,6 +53,7 @@ XPIDLSRCS = \ imgIContainerObserver.idl \ imgIDecoder.idl \ imgIDecoderObserver.idl \ + imgIEncoder.idl \ imgILoad.idl \ imgILoader.idl \ imgIRequest.idl \ diff --git a/mozilla/modules/libpr0n/public/imgIEncoder.idl b/mozilla/modules/libpr0n/public/imgIEncoder.idl new file mode 100755 index 00000000000..cd7ac6d9a5e --- /dev/null +++ b/mozilla/modules/libpr0n/public/imgIEncoder.idl @@ -0,0 +1,90 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Oracle Corporation code. + * + * The Initial Developer of the Original Code is Oracle Corporation. + * Portions created by the Initial Developer are Copyright (C) 2005 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Stuart Parmenter + * Brett Wilson + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsISupports.idl" +#include "nsIInputStream.idl" + +/** + * imgIEncoder interface + */ + +[scriptable, uuid(CCC5B3AD-3E67-4e3d-97E1-B06B2E96FEF8)] +interface imgIEncoder : nsIInputStream +{ + // Possible values for input format (note that not all image formats + // support saving alpha channels): + + // Input is RGB each pixel is represented by three bytes: + // R, G, and B (in that order, regardless of host endianness) + const PRUint32 INPUT_FORMAT_RGB = 0; + + // Input is RGB each pixel is represented by four bytes: + // R, G, and B (in that order, regardless of host endianness). + // POST-MULTIPLIED alpha us used (50% transparent red is 0xff000080) + const PRUint32 INPUT_FORMAT_RGBA = 1; + + // Input is host-endian ARGB: On big-endian machines each pixel is therefore + // ARGB, and for little-endian machiens (Intel) each pixel is BGRA + // (This is used by canvas to match it's internal representation) + // + // PRE-MULTIPLIED alpha is used (That is, 50% transparent red is 0x80800000, + // not 0x80ff0000 + const PRUint32 INPUT_FORMAT_HOSTARGB = 2; + + /* data - list of bytes in the format specified by inputFormat + * width - width in pixels + * height - height in pixels + * stride - number of bytes per row in the image + * Normally (width*3) or (width*4), depending on your input format, + * but some data uses padding at the end of each row, which would + * be extra. + * inputFormat - one of INPUT_FORMAT_* specifying the format of data + * outputOptions - semicolon-delimited list of name=value pairs that can + * give options to the output encoder. Options are encoder- + * specific. Just give empty string for default behavior. + */ + void initFromData([array, size_is(length), const] in PRUint8 data, + in unsigned long length, + in PRUint32 width, + in PRUint32 height, + in PRUint32 stride, + in PRUint32 inputFormat, + in AString outputOptions); +}; + +