diff --git a/config/autoconf.mk.in b/config/autoconf.mk.in index bb34bed3028..77712c8a039 100644 --- a/config/autoconf.mk.in +++ b/config/autoconf.mk.in @@ -99,6 +99,7 @@ MOZ_DEBUG_DISABLE_DEFS = @MOZ_DEBUG_DISABLE_DEFS@ MOZ_DEBUG_FLAGS = @MOZ_DEBUG_FLAGS@ MOZ_DEBUG_LDFLAGS=@MOZ_DEBUG_LDFLAGS@ MOZ_EXTENSIONS = @MOZ_EXTENSIONS@ +MOZ_IMG_DECODERS= @MOZ_IMG_DECODERS@ MOZ_IMG_ENCODERS= @MOZ_IMG_ENCODERS@ MOZ_JSDEBUGGER = @MOZ_JSDEBUGGER@ MOZ_IPC = @MOZ_IPC@ diff --git a/configure.in b/configure.in index 551f7ad9f37..cbc851e35dd 100644 --- a/configure.in +++ b/configure.in @@ -4876,6 +4876,7 @@ MOZ_ACTIVEX_SCRIPTING_SUPPORT= MOZ_BRANDING_DIRECTORY= MOZ_OFFICIAL_BRANDING= MOZ_FEEDS=1 +MOZ_IMG_DECODERS_DEFAULT="png gif jpeg bmp icon" MOZ_IMG_ENCODERS_DEFAULT="png jpeg" MOZ_INSTALLER=1 MOZ_IPC=1 @@ -6308,6 +6309,41 @@ for extension in $MOZ_EXTENSIONS; do fi done + +dnl ======================================================== +dnl Image decoders +dnl ======================================================== +case "$MOZ_WIDGET_TOOLKIT" in +beos|windows|os2|mac|cocoa) + ;; +*) + if test -z "$MOZ_ENABLE_GTK2" -a -z "$MOZ_ENABLE_QT"; then + MOZ_IMG_DECODERS_DEFAULT=`echo $MOZ_IMG_DECODERS_DEFAULT | sed -e 's|icon||'` + fi + ;; +esac + +MOZ_ARG_ENABLE_STRING(image-decoders, +[ --enable-image-decoders[={mod1,mod2,default,all,none}] + Enable specific image decoders], +[ for option in `echo $enableval | sed 's/,/ /g'`; do + if test "$option" = "yes" -o "$option" = "all"; then + MOZ_IMG_DECODERS="$MOZ_IMG_DECODERS $MOZ_IMG_DECODERS_DEFAULT" + elif test "$option" = "no" -o "$option" = "none"; then + MOZ_IMG_DECODERS="" + elif test "$option" = "default"; then + MOZ_IMG_DECODERS="$MOZ_IMG_DECODERS $MOZ_IMG_DECODERS_DEFAULT" + elif test `echo "$option" | grep -c \^-` != 0; then + option=`echo $option | sed 's/^-//'` + MOZ_IMG_DECODERS=`echo "$MOZ_IMG_DECODERS" | sed "s/ ${option}//"` + else + MOZ_IMG_DECODERS="$MOZ_IMG_DECODERS $option" + fi +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 ======================================================== @@ -6333,6 +6369,7 @@ 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 ======================================================== @@ -8689,6 +8726,7 @@ AC_SUBST(MOZ_DEBUG_FLAGS) AC_SUBST(MOZ_DEBUG_LDFLAGS) AC_SUBST(WARNINGS_AS_ERRORS) AC_SUBST(MOZ_EXTENSIONS) +AC_SUBST(MOZ_IMG_DECODERS) AC_SUBST(MOZ_IMG_ENCODERS) AC_SUBST(MOZ_JSDEBUGGER) AC_SUBST(MOZ_PLUGINS) diff --git a/js/src/config/autoconf.mk.in b/js/src/config/autoconf.mk.in index cadff17fa94..dcc4abb2619 100644 --- a/js/src/config/autoconf.mk.in +++ b/js/src/config/autoconf.mk.in @@ -83,6 +83,7 @@ MOZ_DEBUG_DISABLE_DEFS = @MOZ_DEBUG_DISABLE_DEFS@ MOZ_DEBUG_FLAGS = @MOZ_DEBUG_FLAGS@ MOZ_DEBUG_LDFLAGS=@MOZ_DEBUG_LDFLAGS@ MOZ_EXTENSIONS = @MOZ_EXTENSIONS@ +MOZ_IMG_DECODERS= @MOZ_IMG_DECODERS@ MOZ_IMG_ENCODERS= @MOZ_IMG_ENCODERS@ MOZ_JSDEBUGGER = @MOZ_JSDEBUGGER@ MOZ_LEAKY = @MOZ_LEAKY@ diff --git a/modules/libimg/png/Makefile.in b/modules/libimg/png/Makefile.in index bda884827f0..83e42c92523 100644 --- a/modules/libimg/png/Makefile.in +++ b/modules/libimg/png/Makefile.in @@ -67,6 +67,7 @@ CSRCS = \ $(NULL) # These files enable support for reading PNGs +ifneq (,$(filter png,$(MOZ_IMG_DECODERS))) CSRCS += \ pngpread.c \ pngread.c \ @@ -76,6 +77,7 @@ CSRCS += \ $(NULL) DEFINES += -DMOZ_PNG_READ +endif # These files enable support for writing PNGs ifneq (,$(filter png,$(MOZ_IMG_ENCODERS))) diff --git a/modules/libpr0n/Makefile.in b/modules/libpr0n/Makefile.in index 768c0fa8a14..0f1c593e9e5 100644 --- a/modules/libpr0n/Makefile.in +++ b/modules/libpr0n/Makefile.in @@ -44,7 +44,11 @@ include $(DEPTH)/config/autoconf.mk MODULE = imglib2 -DIRS = public src decoders +DIRS = public src + +ifdef MOZ_IMG_DECODERS +DIRS += decoders +endif ifdef MOZ_IMG_ENCODERS DIRS += encoders diff --git a/modules/libpr0n/build/Makefile.in b/modules/libpr0n/build/Makefile.in index af7ef97c090..66d0017df99 100644 --- a/modules/libpr0n/build/Makefile.in +++ b/modules/libpr0n/build/Makefile.in @@ -50,6 +50,7 @@ MODULE_NAME = nsImageLib2Module GRE_MODULE = 1 LIBXUL_LIBRARY = 1 + CPPSRCS = \ nsImageModule.cpp \ $(NULL) @@ -57,13 +58,16 @@ CPPSRCS = \ LOCAL_INCLUDES = \ -I. \ -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) \ - ../decoders/$(LIB_PREFIX)imgdecoders_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) @@ -88,6 +92,8 @@ GARBAGE += _img_list nsImgBuildDefines.h export:: { \ + $(foreach d,$(filter-out icon,$(MOZ_IMG_DECODERS)), \ + echo "#define IMG_BUILD_DECODER_${d}" ; ) \ $(foreach d,$(MOZ_IMG_ENCODERS), \ echo "#define IMG_BUILD_ENCODER_${d}" ; ) \ } > nsImgBuildDefines.tmp diff --git a/modules/libpr0n/build/nsImageModule.cpp b/modules/libpr0n/build/nsImageModule.cpp index ee1396333a9..302a359466b 100644 --- a/modules/libpr0n/build/nsImageModule.cpp +++ b/modules/libpr0n/build/nsImageModule.cpp @@ -39,6 +39,13 @@ #include "nsImgBuildDefines.h" +#ifdef XP_MAC +#define IMG_BUILD_gif 1 +#define IMG_BUILD_bmp 1 +#define IMG_BUILD_png 1 +#define IMG_BUILD_jpeg 1 +#endif + #include "nsIDeviceContext.h" #include "mozilla/ModuleUtils.h" #include "nsXPCOMCID.h" @@ -60,6 +67,28 @@ #include "imgTools.h" #include "DiscardTracker.h" +#ifdef IMG_BUILD_DECODER_gif +// gif +#include "nsGIFDecoder2.h" +#endif + +#ifdef IMG_BUILD_DECODER_bmp +// bmp/ico +#include "nsBMPDecoder.h" +#include "nsICODecoder.h" +#include "nsIconDecoder.h" +#endif + +#ifdef IMG_BUILD_DECODER_png +// png +#include "nsPNGDecoder.h" +#endif + +#ifdef IMG_BUILD_DECODER_jpeg +// jpeg +#include "nsJPEGDecoder.h" +#endif + #ifdef IMG_BUILD_ENCODER_png // png #include "nsPNGEncoder.h" @@ -81,11 +110,31 @@ NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(imgLoader, Init) NS_GENERIC_FACTORY_CONSTRUCTOR(imgRequestProxy) NS_GENERIC_FACTORY_CONSTRUCTOR(imgTools) +#ifdef IMG_BUILD_DECODER_gif +// gif +NS_GENERIC_FACTORY_CONSTRUCTOR(nsGIFDecoder2) +#endif + +#ifdef IMG_BUILD_DECODER_jpeg +// jpeg +NS_GENERIC_FACTORY_CONSTRUCTOR(nsJPEGDecoder) +#endif #ifdef IMG_BUILD_ENCODER_jpeg // jpeg NS_GENERIC_FACTORY_CONSTRUCTOR(nsJPEGEncoder) #endif +#ifdef IMG_BUILD_DECODER_bmp +// bmp +NS_GENERIC_FACTORY_CONSTRUCTOR(nsICODecoder) +NS_GENERIC_FACTORY_CONSTRUCTOR(nsBMPDecoder) +NS_GENERIC_FACTORY_CONSTRUCTOR(nsIconDecoder) +#endif + +#ifdef IMG_BUILD_DECODER_png +// png +NS_GENERIC_FACTORY_CONSTRUCTOR(nsPNGDecoder) +#endif #ifdef IMG_BUILD_ENCODER_png // png NS_GENERIC_FACTORY_CONSTRUCTOR(nsPNGEncoder) @@ -95,9 +144,23 @@ NS_DEFINE_NAMED_CID(NS_IMGLOADER_CID); NS_DEFINE_NAMED_CID(NS_IMGREQUESTPROXY_CID); NS_DEFINE_NAMED_CID(NS_IMGTOOLS_CID); NS_DEFINE_NAMED_CID(NS_RASTERIMAGE_CID); +#ifdef IMG_BUILD_DECODER_gif +NS_DEFINE_NAMED_CID(NS_GIFDECODER2_CID); +#endif +#ifdef IMG_BUILD_DECODER_jpeg +NS_DEFINE_NAMED_CID(NS_JPEGDECODER_CID); +#endif #ifdef IMG_BUILD_ENCODER_jpeg NS_DEFINE_NAMED_CID(NS_JPEGENCODER_CID); #endif +#ifdef IMG_BUILD_DECODER_bmp +NS_DEFINE_NAMED_CID(NS_ICODECODER_CID); +NS_DEFINE_NAMED_CID(NS_BMPDECODER_CID); +NS_DEFINE_NAMED_CID(NS_ICONDECODER_CID); +#endif +#ifdef IMG_BUILD_DECODER_png +NS_DEFINE_NAMED_CID(NS_PNGDECODER_CID); +#endif #ifdef IMG_BUILD_ENCODER_png NS_DEFINE_NAMED_CID(NS_PNGENCODER_CID); #endif @@ -108,9 +171,23 @@ static const mozilla::Module::CIDEntry kImageCIDs[] = { { &kNS_IMGREQUESTPROXY_CID, false, NULL, imgRequestProxyConstructor, }, { &kNS_IMGTOOLS_CID, false, NULL, imgToolsConstructor, }, { &kNS_RASTERIMAGE_CID, false, NULL, RasterImageConstructor, }, +#ifdef IMG_BUILD_DECODER_gif + { &kNS_GIFDECODER2_CID, false, NULL, nsGIFDecoder2Constructor, }, +#endif +#ifdef IMG_BUILD_DECODER_jpeg + { &kNS_JPEGDECODER_CID, false, NULL, nsJPEGDecoderConstructor, }, +#endif #ifdef IMG_BUILD_ENCODER_jpeg { &kNS_JPEGENCODER_CID, false, NULL, nsJPEGEncoderConstructor, }, #endif +#ifdef IMG_BUILD_DECODER_bmp + { &kNS_ICODECODER_CID, false, NULL, nsICODecoderConstructor, }, + { &kNS_BMPDECODER_CID, false, NULL, nsBMPDecoderConstructor, }, + { &kNS_ICONDECODER_CID, false, NULL, nsIconDecoderConstructor, }, +#endif +#ifdef IMG_BUILD_DECODER_png + { &kNS_PNGDECODER_CID, false, NULL, nsPNGDecoderConstructor, }, +#endif #ifdef IMG_BUILD_ENCODER_png { &kNS_PNGENCODER_CID, false, NULL, nsPNGEncoderConstructor, }, #endif @@ -123,9 +200,28 @@ static const mozilla::Module::ContractIDEntry kImageContracts[] = { { "@mozilla.org/image/request;1", &kNS_IMGREQUESTPROXY_CID }, { "@mozilla.org/image/tools;1", &kNS_IMGTOOLS_CID }, { "@mozilla.org/image/rasterimage;1", &kNS_RASTERIMAGE_CID }, +#ifdef IMG_BUILD_DECODER_gif + { "@mozilla.org/image/decoder;3?type=image/gif", &kNS_GIFDECODER2_CID }, +#endif +#ifdef IMG_BUILD_DECODER_jpeg + { "@mozilla.org/image/decoder;3?type=image/jpeg", &kNS_JPEGDECODER_CID }, + { "@mozilla.org/image/decoder;3?type=image/pjpeg", &kNS_JPEGDECODER_CID }, + { "@mozilla.org/image/decoder;3?type=image/jpg", &kNS_JPEGDECODER_CID }, +#endif #ifdef IMG_BUILD_ENCODER_jpeg { "@mozilla.org/image/encoder;2?type=image/jpeg", &kNS_JPEGENCODER_CID }, #endif +#ifdef IMG_BUILD_DECODER_bmp + { "@mozilla.org/image/decoder;3?type=image/x-icon", &kNS_ICODECODER_CID }, + { "@mozilla.org/image/decoder;3?type=image/vnd.microsoft.icon", &kNS_ICODECODER_CID }, + { "@mozilla.org/image/decoder;3?type=image/bmp", &kNS_BMPDECODER_CID }, + { "@mozilla.org/image/decoder;3?type=image/x-ms-bmp", &kNS_BMPDECODER_CID }, + { "@mozilla.org/image/decoder;3?type=image/icon", &kNS_ICONDECODER_CID }, +#endif +#ifdef IMG_BUILD_DECODER_png + { "@mozilla.org/image/decoder;3?type=image/png", &kNS_PNGDECODER_CID }, + { "@mozilla.org/image/decoder;3?type=image/x-png", &kNS_PNGDECODER_CID }, +#endif #ifdef IMG_BUILD_ENCODER_png { "@mozilla.org/image/encoder;2?type=image/png", &kNS_PNGENCODER_CID }, #endif @@ -133,17 +229,25 @@ static const mozilla::Module::ContractIDEntry kImageContracts[] = { }; static const mozilla::Module::CategoryEntry kImageCategories[] = { +#ifdef IMG_BUILD_DECODER_gif { "Gecko-Content-Viewers", "image/gif", "@mozilla.org/content/document-loader-factory;1" }, +#endif +#ifdef IMG_BUILD_DECODER_jpeg { "Gecko-Content-Viewers", "image/jpeg", "@mozilla.org/content/document-loader-factory;1" }, { "Gecko-Content-Viewers", "image/pjpeg", "@mozilla.org/content/document-loader-factory;1" }, { "Gecko-Content-Viewers", "image/jpg", "@mozilla.org/content/document-loader-factory;1" }, +#endif +#ifdef IMG_BUILD_DECODER_bmp { "Gecko-Content-Viewers", "image/x-icon", "@mozilla.org/content/document-loader-factory;1" }, { "Gecko-Content-Viewers", "image/vnd.microsoft.icon", "@mozilla.org/content/document-loader-factory;1" }, { "Gecko-Content-Viewers", "image/bmp", "@mozilla.org/content/document-loader-factory;1" }, { "Gecko-Content-Viewers", "image/x-ms-bmp", "@mozilla.org/content/document-loader-factory;1" }, { "Gecko-Content-Viewers", "image/icon", "@mozilla.org/content/document-loader-factory;1" }, +#endif +#ifdef IMG_BUILD_DECODER_png { "Gecko-Content-Viewers", "image/png", "@mozilla.org/content/document-loader-factory;1" }, { "Gecko-Content-Viewers", "image/x-png", "@mozilla.org/content/document-loader-factory;1" }, +#endif { "content-sniffing-services", "@mozilla.org/image/loader;1", "@mozilla.org/image/loader;1" }, { NULL } }; diff --git a/modules/libpr0n/decoders/Makefile.in b/modules/libpr0n/decoders/Makefile.in index 893a87b2ebf..55081f9bef9 100644 --- a/modules/libpr0n/decoders/Makefile.in +++ b/modules/libpr0n/decoders/Makefile.in @@ -42,32 +42,7 @@ VPATH = @srcdir@ include $(DEPTH)/config/autoconf.mk -MODULE = imgdecoders -LIBRARY_NAME = imgdecoders_s -FORCE_STATIC_LIB = 1 -MODULE_NAME = nsDecodersModule -LIBXUL_LIBRARY = 1 - - -CPPSRCS = nsPNGDecoder.cpp nsJPEGDecoder.cpp nsGIFDecoder2.cpp \ - nsBMPDecoder.cpp nsICODecoder.cpp nsIconDecoder.cpp \ - $(NULL) - -CSRCS = iccjpeg.c \ - $(NULL) - -# Decoders need RasterImage.h -LOCAL_INCLUDES += -I$(topsrcdir)/modules/libpr0n/src/ - -# PNG read/write stuff -ifneq (,$(filter png,$(MOZ_IMG_ENCODERS))) -DEFINES += -DMOZ_PNG_WRITE -endif -DEFINES += -DMOZ_PNG_READ - - -# The Icon Channel stuff really shouldn't live in decoders/icon, but we'll -# fix that another time. +ifneq (,$(filter icon,$(MOZ_IMG_DECODERS))) ifneq (,$(filter gtk2,$(MOZ_WIDGET_TOOLKIT))) DIRS = icon/gtk icon endif @@ -86,6 +61,9 @@ endif ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT)) DIRS = icon/mac icon endif +endif # icon + +DIRS += $(filter-out icon,$(MOZ_IMG_DECODERS)) include $(topsrcdir)/config/rules.mk diff --git a/modules/libpr0n/decoders/bmp/Makefile.in b/modules/libpr0n/decoders/bmp/Makefile.in new file mode 100644 index 00000000000..d3d4c9ed8a3 --- /dev/null +++ b/modules/libpr0n/decoders/bmp/Makefile.in @@ -0,0 +1,58 @@ +# +# ***** 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 +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 2001 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Christian Biesinger +# +# 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 = imgbmp +LIBRARY_NAME = imgbmp_s +FORCE_STATIC_LIB = 1 +MODULE_NAME = nsBMPModule +LIBXUL_LIBRARY = 1 + + +CPPSRCS = nsBMPDecoder.cpp nsICODecoder.cpp nsIconDecoder.cpp + +# ns[BMP,ICO,Icon]Decoder.cpp all include RasterImage.h +LOCAL_INCLUDES += -I$(topsrcdir)/modules/libpr0n/src/ + +include $(topsrcdir)/config/rules.mk diff --git a/modules/libpr0n/decoders/nsBMPDecoder.cpp b/modules/libpr0n/decoders/bmp/nsBMPDecoder.cpp similarity index 93% rename from modules/libpr0n/decoders/nsBMPDecoder.cpp rename to modules/libpr0n/decoders/bmp/nsBMPDecoder.cpp index 9ec2339af6a..fb4f74ce78f 100644 --- a/modules/libpr0n/decoders/nsBMPDecoder.cpp +++ b/modules/libpr0n/decoders/bmp/nsBMPDecoder.cpp @@ -46,13 +46,15 @@ #include "nsBMPDecoder.h" #include "nsIInputStream.h" +#include "nsIComponentManager.h" #include "RasterImage.h" #include "imgIContainerObserver.h" +#include "nsIInterfaceRequestor.h" +#include "nsIInterfaceRequestorUtils.h" #include "prlog.h" -namespace mozilla { -namespace imagelib { +using namespace mozilla::imagelib; #ifdef PR_LOGGING PRLogModuleInfo *gBMPLog = PR_NewLogModule("BMPDecoder"); @@ -62,6 +64,8 @@ PRLogModuleInfo *gBMPLog = PR_NewLogModule("BMPDecoder"); #define LINE(row) ((mBIH.height < 0) ? (-mBIH.height - (row)) : ((row) - 1)) #define PIXEL_OFFSET(row, col) (LINE(row) * mBIH.width + col) +NS_IMPL_ISUPPORTS1(nsBMPDecoder, imgIDecoder) + nsBMPDecoder::nsBMPDecoder() { mColors = nsnull; @@ -81,27 +85,35 @@ nsBMPDecoder::~nsBMPDecoder() free(mRow); } -nsresult -nsBMPDecoder::InitInternal() +NS_IMETHODIMP nsBMPDecoder::Init(imgIContainer *aImage, + imgIDecoderObserver *aObserver, + PRUint32 aFlags) { - PR_LOG(gBMPLog, PR_LOG_DEBUG, ("nsBMPDecoder::Init(%p)\n", mImage.get())); + NS_ABORT_IF_FALSE(aImage->GetType() == imgIContainer::TYPE_RASTER, + "wrong type of imgIContainer for decoding into"); + + PR_LOG(gBMPLog, PR_LOG_DEBUG, ("nsBMPDecoder::Init(%p)\n", aImage)); + + mImage = static_cast(aImage); + mObserver = aObserver; + mFlags = aFlags; // Fire OnStartDecode at init time to support bug 512435 - if (!IsSizeDecode() && mObserver) + if (!(mFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) && mObserver) mObserver->OnStartDecode(nsnull); return NS_OK; } -nsresult -nsBMPDecoder::FinishInternal() +NS_IMETHODIMP nsBMPDecoder::Close(PRUint32 aFlags) { - // We should never make multiple frames - NS_ABORT_IF_FALSE(GetFrameCount() <= 1, "Multiple BMP frames?"); + PR_LOG(gBMPLog, PR_LOG_DEBUG, ("nsBMPDecoder::Close()\n")); // Send notifications if appropriate - if (!IsSizeDecode() && !mError && (GetFrameCount() == 1)) { - PostFrameStop(); + if (!(mFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) && + !mError && !(aFlags & CLOSE_FLAG_DONTNOTIFY)) { + if (mObserver) + mObserver->OnStopFrame(nsnull, 0); mImage->DecodingComplete(); if (mObserver) { mObserver->OnStopContainer(nsnull, mImage); @@ -111,6 +123,11 @@ nsBMPDecoder::FinishInternal() return NS_OK; } +NS_IMETHODIMP nsBMPDecoder::Flush() +{ + return NS_OK; +} + // ---------------------------------------- // Actual Data Processing // ---------------------------------------- @@ -151,8 +168,8 @@ NS_METHOD nsBMPDecoder::CalcBitShift() return NS_OK; } -nsresult -nsBMPDecoder::WriteInternal(const char* aBuffer, PRUint32 aCount) +NS_IMETHODIMP +nsBMPDecoder::Write(const char* aBuffer, PRUint32 aCount) { // No forgiveness if (mError) @@ -211,12 +228,17 @@ nsBMPDecoder::WriteInternal(const char* aBuffer, PRUint32 aCount) PRUint32 real_height = (mBIH.height > 0) ? mBIH.height : -mBIH.height; - // Post our size to the superclass - PostSize(mBIH.width, real_height); + // Set the size and notify + rv = mImage->SetSize(mBIH.width, real_height); + NS_ENSURE_SUCCESS(rv, rv); + if (mObserver) { + rv = mObserver->OnStartContainer(nsnull, mImage); + NS_ENSURE_SUCCESS(rv, rv); + } - // We have the size. If we're doing a size decode, we got what + // We have the size. If we're doing a header-only decode, we got what // we came for. - if (IsSizeDecode()) + if (mFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) return NS_OK; // We're doing a real decode. @@ -279,8 +301,10 @@ nsBMPDecoder::WriteInternal(const char* aBuffer, PRUint32 aCount) memset(mImageData, 0, imageLength); } - // Tell the superclass we're starting a frame - PostFrameStart(); + if (mObserver) { + mObserver->OnStartFrame(nsnull, 0); + NS_ENSURE_SUCCESS(rv, rv); + } } PRUint8 bpc; // bytes per color bpc = (mBFH.bihsize == OS2_BIH_LENGTH) ? 3 : 4; // OS/2 Bitmaps have no padding byte @@ -649,6 +673,3 @@ void nsBMPDecoder::ProcessInfoHeader() mBIH.colors = LITTLE_TO_NATIVE32(mBIH.colors); mBIH.important_colors = LITTLE_TO_NATIVE32(mBIH.important_colors); } - -} // namespace imagelib -} // namespace mozilla diff --git a/modules/libpr0n/decoders/nsBMPDecoder.h b/modules/libpr0n/decoders/bmp/nsBMPDecoder.h similarity index 94% rename from modules/libpr0n/decoders/nsBMPDecoder.h rename to modules/libpr0n/decoders/bmp/nsBMPDecoder.h index c2394b873ad..6821e5cc1fe 100644 --- a/modules/libpr0n/decoders/nsBMPDecoder.h +++ b/modules/libpr0n/decoders/bmp/nsBMPDecoder.h @@ -41,12 +41,17 @@ #define _nsBMPDecoder_h #include "nsAutoPtr.h" +#include "imgIDecoder.h" #include "imgIDecoderObserver.h" #include "gfxColor.h" -#include "Decoder.h" -namespace mozilla { -namespace imagelib { +#define NS_BMPDECODER_CID \ +{ /* {78c61626-4d1f-4843-9364-4652d98ff6e1} */ \ + 0x78c61626, \ + 0x4d1f, \ + 0x4843, \ + { 0x93, 0x64, 0x46, 0x52, 0xd9, 0x8f, 0xf6, 0xe1 } \ +} struct BMPFILEHEADER { char signature[2]; // String "BM" @@ -134,28 +139,35 @@ enum ERLEState { eRLEStateAbsoluteModePadded ///< As above, but another byte of data has to be read as padding }; +namespace mozilla { +namespace imagelib { class RasterImage; +} // namespace imagelib +} // namespace mozilla /** * Decoder for BMP-Files, as used by Windows and OS/2 */ -class nsBMPDecoder : public Decoder +class nsBMPDecoder : public imgIDecoder { public: - + NS_DECL_ISUPPORTS + NS_DECL_IMGIDECODER + nsBMPDecoder(); ~nsBMPDecoder(); - virtual nsresult InitInternal(); - virtual nsresult WriteInternal(const char* aBuffer, PRUint32 aCount); - virtual nsresult FinishInternal(); - private: /** Calculates the red-, green- and blueshift in mBitFields using * the bitmasks from mBitFields */ NS_METHOD CalcBitShift(); + nsCOMPtr mObserver; + + nsRefPtr mImage; + PRUint32 mFlags; + PRUint32 mPos; BMPFILEHEADER mBFH; @@ -219,9 +231,5 @@ inline void Set4BitPixel(PRUint32*& aDecoded, PRUint8 aData, } } -} // namespace imagelib -} // namespace mozilla - - #endif diff --git a/modules/libpr0n/decoders/nsICODecoder.cpp b/modules/libpr0n/decoders/bmp/nsICODecoder.cpp similarity index 92% rename from modules/libpr0n/decoders/nsICODecoder.cpp rename to modules/libpr0n/decoders/bmp/nsICODecoder.cpp index 338a58e483b..a03fcec784f 100644 --- a/modules/libpr0n/decoders/nsICODecoder.cpp +++ b/modules/libpr0n/decoders/bmp/nsICODecoder.cpp @@ -50,11 +50,15 @@ #include "RasterImage.h" #include "imgIContainerObserver.h" +#include "nsIInterfaceRequestor.h" +#include "nsIInterfaceRequestorUtils.h" + #include "nsIProperties.h" #include "nsISupportsPrimitives.h" -namespace mozilla { -namespace imagelib { +using namespace mozilla::imagelib; + +NS_IMPL_ISUPPORTS1(nsICODecoder, imgIDecoder) #define ICONCOUNTOFFSET 4 #define DIRENTRYOFFSET 6 @@ -84,6 +88,50 @@ nsICODecoder::nsICODecoder() nsICODecoder::~nsICODecoder() { +} + +NS_IMETHODIMP nsICODecoder::Init(imgIContainer *aImage, + imgIDecoderObserver *aObserver, + PRUint32 aFlags) +{ + NS_ABORT_IF_FALSE(aImage->GetType() == imgIContainer::TYPE_RASTER, + "wrong type of imgIContainer for decoding into"); + + // Grab parameters + mImage = static_cast(aImage); + mObserver = aObserver; + mFlags = aFlags; + + // Fire OnStartDecode at init time to support bug 512435 + if (!(mFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) && mObserver) + mObserver->OnStartDecode(nsnull); + + return NS_OK; +} + +NS_IMETHODIMP nsICODecoder::Close(PRUint32 aFlags) +{ + nsresult rv = NS_OK; + + // Send notifications if appropriate + if (!(mFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) && + !mError && !(aFlags & CLOSE_FLAG_DONTNOTIFY)) { + // Tell the image that it's data has been updated + nsIntRect r(0, 0, mDirEntry.mWidth, mDirEntry.mHeight); + rv = mImage->FrameUpdated(0, r); + + + if (mObserver) { + mObserver->OnDataAvailable(nsnull, PR_TRUE, &r); + mObserver->OnStopFrame(nsnull, 0); + } + mImage->DecodingComplete(); + if (mObserver) { + mObserver->OnStopContainer(nsnull, 0); + mObserver->OnStopDecode(nsnull, NS_OK, nsnull); + } + } + mPos = 0; delete[] mColors; @@ -99,49 +147,17 @@ nsICODecoder::~nsICODecoder() mRow = nsnull; } mDecodingAndMask = PR_FALSE; -} - -nsresult -nsICODecoder::InitInternal() -{ - // Fire OnStartDecode at init time to support bug 512435 - if (!IsSizeDecode() && mObserver) - mObserver->OnStartDecode(nsnull); - - return NS_OK; -} - -nsresult -nsICODecoder::FinishInternal() -{ - nsresult rv = NS_OK; - - // We should never make multiple frames - NS_ABORT_IF_FALSE(GetFrameCount() <= 1, "Multiple ICO frames?"); - - // Send notifications if appropriate - if (!IsSizeDecode() && !mError && (GetFrameCount() == 1)) { - // Tell the image that it's data has been updated - nsIntRect r(0, 0, mDirEntry.mWidth, mDirEntry.mHeight); - rv = mImage->FrameUpdated(0, r); - - - if (mObserver) { - mObserver->OnDataAvailable(nsnull, PR_TRUE, &r); - } - PostFrameStop(); - mImage->DecodingComplete(); - if (mObserver) { - mObserver->OnStopContainer(nsnull, 0); - mObserver->OnStopDecode(nsnull, NS_OK, nsnull); - } - } return rv; } -nsresult -nsICODecoder::WriteInternal(const char* aBuffer, PRUint32 aCount) +NS_IMETHODIMP nsICODecoder::Flush() +{ + return NS_OK; +} + +NS_IMETHODIMP +nsICODecoder::Write(const char* aBuffer, PRUint32 aCount) { // No forgiveness if (mError) @@ -235,8 +251,13 @@ nsICODecoder::WriteInternal(const char* aBuffer, PRUint32 aCount) if (mPos == mImageOffset + BITMAPINFOSIZE) { ProcessInfoHeader(); - PostSize(mDirEntry.mWidth, mDirEntry.mHeight); - if (IsSizeDecode()) + rv = mImage->SetSize(mDirEntry.mWidth, mDirEntry.mHeight); + NS_ENSURE_SUCCESS(rv, rv); + if (mObserver) { + rv = mObserver->OnStartContainer(nsnull, mImage); + NS_ENSURE_SUCCESS(rv, rv); + } + if (mFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) return NS_OK; if (mBIH.bpp <= 8) { @@ -290,8 +311,10 @@ nsICODecoder::WriteInternal(const char* aBuffer, PRUint32 aCount) gfxASurface::ImageFormatARGB32, (PRUint8**)&mImageData, &imageLength); NS_ENSURE_SUCCESS(rv, rv); - // Tell the superclass we're starting a frame - PostFrameStart(); + if (mObserver) { + mObserver->OnStartFrame(nsnull, 0); + NS_ENSURE_SUCCESS(rv, rv); + } } if (mColors && (mPos >= mImageOffset + BITMAPINFOSIZE) && @@ -532,6 +555,3 @@ void nsICODecoder::ProcessInfoHeader() { mBIH.colors = LITTLE_TO_NATIVE32(mBIH.colors); mBIH.important_colors = LITTLE_TO_NATIVE32(mBIH.important_colors); } - -} // namespace imagelib -} // namespace mozilla diff --git a/modules/libpr0n/decoders/nsICODecoder.h b/modules/libpr0n/decoders/bmp/nsICODecoder.h similarity index 88% rename from modules/libpr0n/decoders/nsICODecoder.h rename to modules/libpr0n/decoders/bmp/nsICODecoder.h index 702037d1752..0f313e337aa 100644 --- a/modules/libpr0n/decoders/nsICODecoder.h +++ b/modules/libpr0n/decoders/bmp/nsICODecoder.h @@ -42,14 +42,20 @@ #define _nsICODecoder_h #include "nsAutoPtr.h" -#include "Decoder.h" +#include "imgIDecoder.h" +#include "imgIContainer.h" #include "imgIDecoderObserver.h" #include "nsBMPDecoder.h" +// {CB3EDE1A-0FA5-4e27-AAFE-0F7801E5A1F1} +#define NS_ICODECODER_CID \ +{ 0xcb3ede1a, 0xfa5, 0x4e27, { 0xaa, 0xfe, 0xf, 0x78, 0x1, 0xe5, 0xa1, 0xf1 } } + namespace mozilla { namespace imagelib { - class RasterImage; +} // namespace imagelib +} // namespace mozilla struct IconDirEntry { @@ -69,17 +75,15 @@ struct IconDirEntry PRUint32 mImageOffset; }; -class nsICODecoder : public Decoder +class nsICODecoder : public imgIDecoder { public: + NS_DECL_ISUPPORTS + NS_DECL_IMGIDECODER nsICODecoder(); virtual ~nsICODecoder(); - virtual nsresult InitInternal(); - virtual nsresult WriteInternal(const char* aBuffer, PRUint32 aCount); - virtual nsresult FinishInternal(); - private: // Private helper methods void ProcessDirEntry(IconDirEntry& aTarget); @@ -89,6 +93,11 @@ private: PRUint32 CalcAlphaRowSize(); +private: + nsRefPtr mImage; + nsCOMPtr mObserver; + PRUint32 mFlags; + PRUint32 mPos; PRUint16 mNumIcons; PRUint16 mCurrIcon; @@ -115,7 +124,5 @@ private: PRPackedBool mError; }; -} // namespace imagelib -} // namespace mozilla #endif diff --git a/modules/libpr0n/decoders/nsIconDecoder.cpp b/modules/libpr0n/decoders/bmp/nsIconDecoder.cpp similarity index 75% rename from modules/libpr0n/decoders/nsIconDecoder.cpp rename to modules/libpr0n/decoders/bmp/nsIconDecoder.cpp index f76e973a440..3cccf085e60 100644 --- a/modules/libpr0n/decoders/nsIconDecoder.cpp +++ b/modules/libpr0n/decoders/bmp/nsIconDecoder.cpp @@ -43,14 +43,27 @@ #include "RasterImage.h" #include "imgIContainerObserver.h" #include "nspr.h" +#include "nsIComponentManager.h" #include "nsRect.h" +#include "nsComponentManagerUtils.h" +#include "nsIInterfaceRequestorUtils.h" #include "ImageErrors.h" -namespace mozilla { -namespace imagelib { +using namespace mozilla::imagelib; + +NS_IMPL_THREADSAFE_ADDREF(nsIconDecoder) +NS_IMPL_THREADSAFE_RELEASE(nsIconDecoder) + +NS_INTERFACE_MAP_BEGIN(nsIconDecoder) + NS_INTERFACE_MAP_ENTRY(imgIDecoder) +NS_INTERFACE_MAP_END_THREADSAFE + nsIconDecoder::nsIconDecoder() : + mImage(nsnull), + mObserver(nsnull), + mFlags(imgIDecoder::DECODER_FLAG_NONE), mWidth(-1), mHeight(-1), mPixBytesRead(0), @@ -66,29 +79,48 @@ nsIconDecoder::~nsIconDecoder() { } -nsresult -nsIconDecoder::InitInternal() +/** imgIDecoder methods **/ + +NS_IMETHODIMP nsIconDecoder::Init(imgIContainer *aImage, + imgIDecoderObserver *aObserver, + PRUint32 aFlags) { + + // Grab parameters + NS_ABORT_IF_FALSE(aImage->GetType() == imgIContainer::TYPE_RASTER, + "wrong type of imgIContainer for decoding into"); + + mImage = static_cast(aImage); + mObserver = aObserver; + mFlags = aFlags; + // Fire OnStartDecode at init time to support bug 512435 - if (!IsSizeDecode() && mObserver) + if (!(mFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) && mObserver) mObserver->OnStartDecode(nsnull); return NS_OK; } -nsresult -nsIconDecoder::FinishInternal() +NS_IMETHODIMP nsIconDecoder::Close(PRUint32 aFlags) { // If we haven't notified of completion yet for a full/success decode, we // didn't finish. Notify in error mode - if (!IsSizeDecode() && !mNotifiedDone) + if (!(aFlags & CLOSE_FLAG_DONTNOTIFY) && + !(mFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) && + !mNotifiedDone) NotifyDone(/* aSuccess = */ PR_FALSE); + mImage = nsnull; return NS_OK; } -nsresult -nsIconDecoder::WriteInternal(const char *aBuffer, PRUint32 aCount) +NS_IMETHODIMP nsIconDecoder::Flush() +{ + return NS_OK; +} + +NS_IMETHODIMP +nsIconDecoder::Write(const char *aBuffer, PRUint32 aCount) { nsresult rv; @@ -119,11 +151,13 @@ nsIconDecoder::WriteInternal(const char *aBuffer, PRUint32 aCount) // Grab the Height mHeight = (PRUint8)*aBuffer; - // Post our size to the superclass - PostSize(mWidth, mHeight); + // Set up the container and signal + mImage->SetSize(mWidth, mHeight); + if (mObserver) + mObserver->OnStartContainer(nsnull, mImage); - // If We're doing a size decode, we're done - if (IsSizeDecode()) { + // If We're doing a header-only decode, we're done + if (mFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) { mState = iconStateFinished; break; } @@ -136,9 +170,8 @@ nsIconDecoder::WriteInternal(const char *aBuffer, PRUint32 aCount) mState = iconStateError; return rv; } - - // Tell the superclass we're starting a frame - PostFrameStart(); + if (mObserver) + mObserver->OnStartFrame(nsnull, 0); // Book Keeping aBuffer++; @@ -198,7 +231,8 @@ nsIconDecoder::NotifyDone(PRBool aSuccess) NS_ABORT_IF_FALSE(!mNotifiedDone, "Calling NotifyDone twice"); // Notify - PostFrameStop(); + if (mObserver) + mObserver->OnStopFrame(nsnull, 0); if (aSuccess) mImage->DecodingComplete(); if (mObserver) { @@ -211,5 +245,3 @@ nsIconDecoder::NotifyDone(PRBool aSuccess) mNotifiedDone = PR_TRUE; } -} // namespace imagelib -} // namespace mozilla diff --git a/modules/libpr0n/decoders/nsIconDecoder.h b/modules/libpr0n/decoders/bmp/nsIconDecoder.h similarity index 85% rename from modules/libpr0n/decoders/nsIconDecoder.h rename to modules/libpr0n/decoders/bmp/nsIconDecoder.h index b5e050dc824..e1dc1a23897 100644 --- a/modules/libpr0n/decoders/nsIconDecoder.h +++ b/modules/libpr0n/decoders/bmp/nsIconDecoder.h @@ -41,15 +41,26 @@ #ifndef nsIconDecoder_h__ #define nsIconDecoder_h__ -#include "Decoder.h" +#include "imgIDecoder.h" #include "nsCOMPtr.h" +#include "imgIContainer.h" #include "imgIDecoderObserver.h" +#define NS_ICONDECODER_CID \ +{ /* FFC08380-256C-11d5-9905-001083010E9B */ \ + 0xffc08380, \ + 0x256c, \ + 0x11d5, \ + { 0x99, 0x5, 0x0, 0x10, 0x83, 0x1, 0xe, 0x9b } \ +} + namespace mozilla { namespace imagelib { class RasterImage; +} // namespace imagelib +} // namespace mozilla ////////////////////////////////////////////////////////////////////////////////////////////// // The icon decoder is a decoder specifically tailored for loading icons @@ -70,17 +81,18 @@ class RasterImage; // ////////////////////////////////////////////////////////////////////////////////////////////// -class nsIconDecoder : public Decoder +class nsIconDecoder : public imgIDecoder { public: + NS_DECL_ISUPPORTS + NS_DECL_IMGIDECODER nsIconDecoder(); virtual ~nsIconDecoder(); - virtual nsresult InitInternal(); - virtual nsresult WriteInternal(const char* aBuffer, PRUint32 aCount); - virtual nsresult FinishInternal(); - + nsRefPtr mImage; + nsCOMPtr mObserver; + PRUint32 mFlags; PRUint8 mWidth; PRUint8 mHeight; PRUint32 mPixBytesRead; @@ -100,7 +112,5 @@ enum { iconStateError = 4 }; -} // namespace imagelib -} // namespace mozilla #endif // nsIconDecoder_h__ diff --git a/modules/libpr0n/decoders/GIF2.h b/modules/libpr0n/decoders/gif/GIF2.h similarity index 100% rename from modules/libpr0n/decoders/GIF2.h rename to modules/libpr0n/decoders/gif/GIF2.h diff --git a/modules/libpr0n/decoders/gif/Makefile.in b/modules/libpr0n/decoders/gif/Makefile.in new file mode 100644 index 00000000000..3888fde12c1 --- /dev/null +++ b/modules/libpr0n/decoders/gif/Makefile.in @@ -0,0 +1,59 @@ +# +# ***** 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 +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 2001 +# 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 = imggif +LIBRARY_NAME = imggif_s +FORCE_STATIC_LIB = 1 +MODULE_NAME = nsGIFModule2 +LIBXUL_LIBRARY = 1 + + +CPPSRCS = nsGIFDecoder2.cpp + +# nsGIFDecoder2.cpp includes RasterImage.h +LOCAL_INCLUDES += -I$(topsrcdir)/modules/libpr0n/src + +include $(topsrcdir)/config/rules.mk + +CXXFLAGS += $(MOZ_CAIRO_CFLAGS) diff --git a/modules/libpr0n/decoders/nsGIFDecoder2.cpp b/modules/libpr0n/decoders/gif/nsGIFDecoder2.cpp similarity index 89% rename from modules/libpr0n/decoders/nsGIFDecoder2.cpp rename to modules/libpr0n/decoders/gif/nsGIFDecoder2.cpp index 015a8efa88f..f6977beac14 100644 --- a/modules/libpr0n/decoders/nsGIFDecoder2.cpp +++ b/modules/libpr0n/decoders/gif/nsGIFDecoder2.cpp @@ -75,8 +75,11 @@ mailing address. #include #include "prmem.h" +#include "nsIInterfaceRequestorUtils.h" + #include "nsGIFDecoder2.h" #include "nsIInputStream.h" +#include "nsIComponentManager.h" #include "imgIContainerObserver.h" #include "RasterImage.h" @@ -84,9 +87,6 @@ mailing address. #include "gfxPlatform.h" #include "qcms.h" -namespace mozilla { -namespace imagelib { - /* * GETN(n, s) requests at least 'n' bytes available from 'q', at start of state 's' * @@ -104,8 +104,13 @@ namespace imagelib { /* Get a 16-bit value stored in little-endian format */ #define GETINT16(p) ((p)[1]<<8|(p)[0]) + + ////////////////////////////////////////////////////////////////////// // GIF Decoder Implementation +// This is an adaptor between GIF2 and imgIDecoder + +NS_IMPL_ISUPPORTS1(nsGIFDecoder2, imgIDecoder) nsGIFDecoder2::nsGIFDecoder2() : mCurrentRow(-1) @@ -126,14 +131,30 @@ nsGIFDecoder2::nsGIFDecoder2() nsGIFDecoder2::~nsGIFDecoder2() { - PR_FREEIF(mGIFStruct.local_colormap); } -nsresult -nsGIFDecoder2::InitInternal() +//****************************************************************************** +/** imgIDecoder methods **/ +//****************************************************************************** + +//****************************************************************************** +/* void init (in imgIContainer aImage, + in imgIDecoderObserver aObsever, + in unsigned long aFlags); */ +NS_IMETHODIMP nsGIFDecoder2::Init(imgIContainer *aImage, + imgIDecoderObserver *aObserver, + PRUint32 aFlags) { + NS_ABORT_IF_FALSE(aImage->GetType() == imgIContainer::TYPE_RASTER, + "wrong type of imgIContainer for decoding into"); + + // Store parameters + mImageContainer = static_cast(aImage); + mObserver = aObserver; + mFlags = aFlags; + // Fire OnStartDecode at init time to support bug 512435 - if (!IsSizeDecode() && mObserver) + if (!(mFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) && mObserver) mObserver->OnStartDecode(nsnull); // Start with the version (GIF89a|GIF87a) @@ -143,19 +164,37 @@ nsGIFDecoder2::InitInternal() return NS_OK; } -nsresult -nsGIFDecoder2::FinishInternal() + +//****************************************************************************** +/** nsIOutputStream methods **/ +//****************************************************************************** + +//****************************************************************************** +/* void close (); */ +NS_IMETHODIMP nsGIFDecoder2::Close(PRUint32 aFlags) { // Send notifications if appropriate - if (!IsSizeDecode() && !mError) { + if (!(mFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) && + !mError && !(aFlags & CLOSE_FLAG_DONTNOTIFY)) { if (mCurrentFrame == mGIFStruct.images_decoded) EndImageFrame(); EndGIF(/* aSuccess = */ PR_TRUE); } + PR_FREEIF(mGIFStruct.local_colormap); + + mImageContainer = nsnull; + return NS_OK; } +//****************************************************************************** +/* void flush (); */ +NS_IMETHODIMP nsGIFDecoder2::Flush() +{ + return NS_OK; +} + // Push any new rows according to mCurrentPass/mLastFlushedPass and // mCurrentRow/mLastFlushedRow. Note: caller is responsible for // updating mlastFlushed{Row,Pass}. @@ -165,7 +204,7 @@ nsGIFDecoder2::FlushImageData(PRUint32 fromRow, PRUint32 rows) nsIntRect r(mGIFStruct.x_offset, mGIFStruct.y_offset + fromRow, mGIFStruct.width, rows); // Update image - nsresult rv = mImage->FrameUpdated(mGIFStruct.images_decoded, r); + nsresult rv = mImageContainer->FrameUpdated(mGIFStruct.images_decoded, r); if (NS_FAILED(rv)) { return rv; } @@ -173,7 +212,8 @@ nsGIFDecoder2::FlushImageData(PRUint32 fromRow, PRUint32 rows) // Offset to the frame position // Only notify observer(s) for first frame if (!mGIFStruct.images_decoded && mObserver) { - PRUint32 imgCurFrame = mImage->GetCurrentFrameIndex(); + PRUint32 imgCurFrame; + mImageContainer->GetCurrentFrameIndex(&imgCurFrame); mObserver->OnDataAvailable(nsnull, imgCurFrame == PRUint32(mGIFStruct.images_decoded), &r); } return NS_OK; @@ -201,8 +241,10 @@ nsGIFDecoder2::FlushImageData() return rv; } -nsresult -nsGIFDecoder2::WriteInternal(const char *aBuffer, PRUint32 aCount) +//****************************************************************************** +/* void write (in string aBuffer, in PRUint32 aCount); */ +NS_IMETHODIMP +nsGIFDecoder2::Write(const char *aBuffer, PRUint32 aCount) { // Don't forgive previously flagged errors if (mError) @@ -226,11 +268,15 @@ nsGIFDecoder2::WriteInternal(const char *aBuffer, PRUint32 aCount) // pretend that we're decoded. Otherwise, we set mError. if (NS_FAILED(rv)) { - // Determine if we want to salvage the situation. - // If we're salvaging, send off notifications. + // Determine if we want to salvage the situation + PRUint32 numFrames = 0; + if (mImageContainer) + mImageContainer->GetNumFrames(&numFrames); + + // If we're salvaging, send off notifications // Note that we need to make sure that we have 2 frames, since that tells us // that the first frame is complete (the second could be in any state). - if (mImage && mImage->GetNumFrames() > 1) { + if (numFrames > 1) { EndGIF(/* aSuccess = */ PR_TRUE); } @@ -254,10 +300,12 @@ void nsGIFDecoder2::BeginGIF() mGIFOpen = PR_TRUE; - PostSize(mGIFStruct.screen_width, mGIFStruct.screen_height); + mImageContainer->SetSize(mGIFStruct.screen_width, mGIFStruct.screen_height); + if (mObserver) + mObserver->OnStartContainer(nsnull, mImageContainer); - // If we're doing a size decode, we have what we came for - if (IsSizeDecode()) + // If we're doing a header-only decode, we have what we came for + if (mFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) return; } @@ -268,15 +316,15 @@ void nsGIFDecoder2::EndGIF(PRBool aSuccess) return; if (aSuccess) - mImage->DecodingComplete(); + mImageContainer->DecodingComplete(); if (mObserver) { - mObserver->OnStopContainer(nsnull, mImage); + mObserver->OnStopContainer(nsnull, mImageContainer); mObserver->OnStopDecode(nsnull, aSuccess ? NS_OK : NS_ERROR_FAILURE, nsnull); } - mImage->SetLoopCount(mGIFStruct.loop_count); + mImageContainer->SetLoopCount(mGIFStruct.loop_count); mGIFOpen = PR_FALSE; mEnded = PR_TRUE; @@ -291,8 +339,9 @@ nsresult nsGIFDecoder2::BeginImageFrame(gfx_depth aDepth) // and the placeholder will remain on the screen. (Bug 37589) if (mGIFStruct.y_offset > 0) { PRInt32 imgWidth; - mImage->GetWidth(&imgWidth); - PRUint32 imgCurFrame = mImage->GetCurrentFrameIndex(); + mImageContainer->GetWidth(&imgWidth); + PRUint32 imgCurFrame; + mImageContainer->GetCurrentFrameIndex(&imgCurFrame); nsIntRect r(0, 0, imgWidth, mGIFStruct.y_offset); if (mObserver) mObserver->OnDataAvailable(nsnull, @@ -313,25 +362,25 @@ nsresult nsGIFDecoder2::BeginImageFrame(gfx_depth aDepth) // and include transparency to allow for optimization of opaque images if (mGIFStruct.images_decoded) { // Image data is stored with original depth and palette - rv = mImage->AppendPalettedFrame(mGIFStruct.x_offset, mGIFStruct.y_offset, - mGIFStruct.width, mGIFStruct.height, - format, aDepth, &mImageData, &imageDataLength, - &mColormap, &mColormapSize); + rv = mImageContainer->AppendPalettedFrame(mGIFStruct.x_offset, mGIFStruct.y_offset, + mGIFStruct.width, mGIFStruct.height, + format, aDepth, &mImageData, &imageDataLength, + &mColormap, &mColormapSize); } else { // Regardless of depth of input, image is decoded into 24bit RGB - rv = mImage->AppendFrame(mGIFStruct.x_offset, mGIFStruct.y_offset, - mGIFStruct.width, mGIFStruct.height, - format, &mImageData, &imageDataLength); + rv = mImageContainer->AppendFrame(mGIFStruct.x_offset, mGIFStruct.y_offset, + mGIFStruct.width, mGIFStruct.height, + format, &mImageData, &imageDataLength); } if (NS_FAILED(rv)) return rv; - mImage->SetFrameDisposalMethod(mGIFStruct.images_decoded, - mGIFStruct.disposal_method); + mImageContainer->SetFrameDisposalMethod(mGIFStruct.images_decoded, + mGIFStruct.disposal_method); - // Tell the superclass we're starting a frame - PostFrameStart(); + if (mObserver) + mObserver->OnStartFrame(nsnull, mGIFStruct.images_decoded); mCurrentFrame = mGIFStruct.images_decoded; return NS_OK; @@ -351,7 +400,8 @@ void nsGIFDecoder2::EndImageFrame() // This will clear the remaining bits of the placeholder. (Bug 37589) const PRUint32 realFrameHeight = mGIFStruct.height + mGIFStruct.y_offset; if (realFrameHeight < mGIFStruct.screen_height) { - PRUint32 imgCurFrame = mImage->GetCurrentFrameIndex(); + PRUint32 imgCurFrame; + mImageContainer->GetCurrentFrameIndex(&imgCurFrame); nsIntRect r(0, realFrameHeight, mGIFStruct.screen_width, mGIFStruct.screen_height - realFrameHeight); @@ -362,12 +412,14 @@ void nsGIFDecoder2::EndImageFrame() } // This transparency check is only valid for first frame if (mGIFStruct.is_transparent && !mSawTransparency) { - mImage->SetFrameHasNoAlpha(mGIFStruct.images_decoded); + mImageContainer->SetFrameHasNoAlpha(mGIFStruct.images_decoded); } } mCurrentRow = mLastFlushedRow = -1; mCurrentPass = mLastFlushedPass = 0; + PRUint32 curframe = mGIFStruct.images_decoded; + // Only add frame if we have any rows at all if (mGIFStruct.rows_remaining != mGIFStruct.height) { if (mGIFStruct.rows_remaining && mGIFStruct.images_decoded) { @@ -380,18 +432,18 @@ void nsGIFDecoder2::EndImageFrame() // image data, at least according to the spec, but we delay in setting the // timeout for the image until here to help ensure that we have the whole // image frame decoded before we go off and try to display another frame. - mImage->SetFrameTimeout(mGIFStruct.images_decoded, mGIFStruct.delay_time); - mImage->EndFrameDecode(mGIFStruct.images_decoded); + mImageContainer->SetFrameTimeout(mGIFStruct.images_decoded, mGIFStruct.delay_time); + mImageContainer->EndFrameDecode(mGIFStruct.images_decoded); } // Unconditionally increment images_decoded, because we unconditionally // append frames in BeginImageFrame(). This ensures that images_decoded - // always refers to the frame in mImage we're currently decoding, + // always refers to the frame in mImageContainer we're currently decoding, // even if some of them weren't decoded properly and thus are blank. mGIFStruct.images_decoded++; - // Tell the superclass we finished a frame - PostFrameStop(); + if (mObserver) + mObserver->OnStopFrame(nsnull, curframe); // Reset the transparent pixel if (mOldColor) { @@ -1014,8 +1066,8 @@ nsresult nsGIFDecoder2::GifWrite(const PRUint8 *buf, PRUint32 len) // Create the image container with the right size. BeginGIF(); - // If we were doing a size decode, we're done - if (IsSizeDecode()) + // If we were doing header-only, we're done + if (mFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) return NS_OK; } @@ -1185,6 +1237,3 @@ nsresult nsGIFDecoder2::GifWrite(const PRUint8 *buf, PRUint32 len) return NS_OK; } - -} // namespace imagelib -} // namespace mozilla diff --git a/modules/libpr0n/decoders/nsGIFDecoder2.h b/modules/libpr0n/decoders/gif/nsGIFDecoder2.h similarity index 83% rename from modules/libpr0n/decoders/nsGIFDecoder2.h rename to modules/libpr0n/decoders/gif/nsGIFDecoder2.h index 647a8613576..d31abbd2b28 100644 --- a/modules/libpr0n/decoders/nsGIFDecoder2.h +++ b/modules/libpr0n/decoders/gif/nsGIFDecoder2.h @@ -42,29 +42,38 @@ #define _nsGIFDecoder2_h #include "nsCOMPtr.h" -#include "Decoder.h" +#include "imgIDecoder.h" +#include "imgIContainer.h" #include "imgIDecoderObserver.h" #include "GIF2.h" +#define NS_GIFDECODER2_CID \ +{ /* 797bec5a-1dd2-11b2-a7f8-ca397e0179c4 */ \ + 0x797bec5a, \ + 0x1dd2, \ + 0x11b2, \ + {0xa7, 0xf8, 0xca, 0x39, 0x7e, 0x01, 0x79, 0xc4} \ +} + namespace mozilla { namespace imagelib { class RasterImage; +} // namespace imagelib +} // namespace mozilla ////////////////////////////////////////////////////////////////////// // nsGIFDecoder2 Definition -class nsGIFDecoder2 : public Decoder +class nsGIFDecoder2 : public imgIDecoder { public: + NS_DECL_ISUPPORTS + NS_DECL_IMGIDECODER nsGIFDecoder2(); ~nsGIFDecoder2(); - virtual nsresult InitInternal(); - virtual nsresult WriteInternal(const char* aBuffer, PRUint32 aCount); - virtual nsresult FinishInternal(); - private: /* These functions will be called when the decoder has a decoded row, * frame size information, etc. */ @@ -82,6 +91,11 @@ private: inline int ClearCode() const { return 1 << mGIFStruct.datasize; } + // XXXdholbert This member variable should probably be renamed to "mImage" + // for consistency with nsPNGDecoder + nsRefPtr mImageContainer; + nsCOMPtr mObserver; + PRUint32 mFlags; PRInt32 mCurrentRow; PRInt32 mLastFlushedRow; @@ -105,7 +119,4 @@ private: gif_struct mGIFStruct; }; -} // namespace imagelib -} // namespace mozilla - #endif diff --git a/modules/libpr0n/decoders/jpeg/Makefile.in b/modules/libpr0n/decoders/jpeg/Makefile.in new file mode 100644 index 00000000000..4986cd98165 --- /dev/null +++ b/modules/libpr0n/decoders/jpeg/Makefile.in @@ -0,0 +1,60 @@ +# +# ***** 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 +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 2001 +# 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 = imgjpeg +LIBRARY_NAME = imgjpeg_s +FORCE_STATIC_LIB = 1 +MODULE_NAME = nsJPEGDecoderModule +LIBXUL_LIBRARY = 1 + + +CPPSRCS = nsJPEGDecoder.cpp + +CSRCS = iccjpeg.c + +# nsJPEGDecoder.cpp includes RasterImage.h +LOCAL_INCLUDES += -I$(topsrcdir)/modules/libpr0n/src/ + +include $(topsrcdir)/config/rules.mk + diff --git a/modules/libpr0n/decoders/iccjpeg.c b/modules/libpr0n/decoders/jpeg/iccjpeg.c similarity index 100% rename from modules/libpr0n/decoders/iccjpeg.c rename to modules/libpr0n/decoders/jpeg/iccjpeg.c diff --git a/modules/libpr0n/decoders/iccjpeg.h b/modules/libpr0n/decoders/jpeg/iccjpeg.h similarity index 100% rename from modules/libpr0n/decoders/iccjpeg.h rename to modules/libpr0n/decoders/jpeg/iccjpeg.h diff --git a/modules/libpr0n/decoders/nsJPEGDecoder.cpp b/modules/libpr0n/decoders/jpeg/nsJPEGDecoder.cpp similarity index 96% rename from modules/libpr0n/decoders/nsJPEGDecoder.cpp rename to modules/libpr0n/decoders/jpeg/nsJPEGDecoder.cpp index 6649dd99443..0923b9d1d34 100644 --- a/modules/libpr0n/decoders/nsJPEGDecoder.cpp +++ b/modules/libpr0n/decoders/jpeg/nsJPEGDecoder.cpp @@ -43,17 +43,21 @@ #include "imgIContainerObserver.h" +#include "nsIComponentManager.h" #include "nsIInputStream.h" #include "nspr.h" #include "nsCRT.h" #include "ImageLogging.h" +#include "nsIInterfaceRequestorUtils.h" #include "gfxColor.h" #include "jerror.h" #include "gfxPlatform.h" +using namespace mozilla::imagelib; + extern "C" { #include "iccjpeg.h" @@ -71,10 +75,7 @@ ycc_rgb_convert_argb (j_decompress_ptr cinfo, JSAMPARRAY output_buf, int num_rows); } -static void cmyk_convert_rgb(JSAMPROW row, JDIMENSION width); - -namespace mozilla { -namespace imagelib { +NS_IMPL_ISUPPORTS1(nsJPEGDecoder, imgIDecoder) #if defined(PR_LOGGING) PRLogModuleInfo *gJPEGlog = PR_NewLogModule("JPEGDecoder"); @@ -91,6 +92,8 @@ METHODDEF(void) skip_input_data (j_decompress_ptr jd, long num_bytes); METHODDEF(void) term_source (j_decompress_ptr jd); METHODDEF(void) my_error_exit (j_common_ptr cinfo); +static void cmyk_convert_rgb(JSAMPROW row, JDIMENSION width); + /* Normal JFIF markers can't have more bytes than this. */ #define MAX_JPEG_MARKER_LENGTH (((PRUint32)1 << 16) - 1) @@ -123,10 +126,6 @@ nsJPEGDecoder::nsJPEGDecoder() nsJPEGDecoder::~nsJPEGDecoder() { - // Step 8: Release JPEG decompression object - mInfo.src = nsnull; - jpeg_destroy_decompress(&mInfo); - PR_FREEIF(mBackBuffer); if (mTransform) qcms_transform_release(mTransform); @@ -139,11 +138,25 @@ nsJPEGDecoder::~nsJPEGDecoder() } -nsresult -nsJPEGDecoder::InitInternal() +/** imgIDecoder methods **/ + +/* void init (in imgIContainer aImage, + in imgIDecoderObserver aObserver, + in unsigned long aFlags); */ +NS_IMETHODIMP nsJPEGDecoder::Init(imgIContainer *aImage, + imgIDecoderObserver *aObserver, + PRUint32 aFlags) { + NS_ABORT_IF_FALSE(aImage->GetType() == imgIContainer::TYPE_RASTER, + "wrong type of imgIContainer for decoding into"); + + /* Grab the parameters. */ + mImage = static_cast(aImage); + mObserver = aObserver; + mFlags = aFlags; + /* Fire OnStartDecode at init time to support bug 512435 */ - if (!IsSizeDecode() && mObserver) + if (!(mFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) && mObserver) mObserver->OnStartDecode(nsnull); /* We set up the normal JPEG error routines, then override error_exit. */ @@ -179,19 +192,17 @@ nsJPEGDecoder::InitInternal() return NS_OK; } -nsresult -nsJPEGDecoder::FinishInternal() + +/* void close (); */ +NS_IMETHODIMP nsJPEGDecoder::Close(PRUint32 aFlags) { - /* If we're not in any sort of error case, flush the decoder. - * - * XXXbholley - It seems wrong that this should be necessary, but at the - * moment I'm just folding the contents of Flush() into Close() so that - * we can get rid of it. - */ - if ((mState != JPEG_DONE && mState != JPEG_SINK_NON_JPEG_TRAILER) && - (mState != JPEG_ERROR) && - !IsSizeDecode()) - this->Write(nsnull, 0); + PR_LOG(gJPEGlog, PR_LOG_DEBUG, + ("[this=%p] nsJPEGDecoder::Close\n", this)); + + /* Step 8: Release JPEG decompression object */ + mInfo.src = nsnull; + + jpeg_destroy_decompress(&mInfo); /* If we already know we're in an error state, don't bother flagging another one here. */ @@ -200,15 +211,28 @@ nsJPEGDecoder::FinishInternal() /* If we're doing a full decode and haven't notified of completion yet, * we must not have got everything we wanted. Send error notifications. */ - if (!IsSizeDecode() && !mNotifiedDone) + if (!(aFlags & CLOSE_FLAG_DONTNOTIFY) && + !(mFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) && + !mNotifiedDone) NotifyDone(/* aSuccess = */ PR_FALSE); /* Otherwise, no problems. */ return NS_OK; } -nsresult -nsJPEGDecoder::WriteInternal(const char *aBuffer, PRUint32 aCount) +/* void flush (); */ +NS_IMETHODIMP nsJPEGDecoder::Flush() +{ + LOG_SCOPE(gJPEGlog, "nsJPEGDecoder::Flush"); + + if (mState != JPEG_DONE && mState != JPEG_SINK_NON_JPEG_TRAILER && mState != JPEG_ERROR) + return this->Write(nsnull, 0); + + return NS_OK; +} + +//****************************************************************************** +nsresult nsJPEGDecoder::Write(const char *aBuffer, PRUint32 aCount) { mSegment = (const JOCTET *)aBuffer; mSegmentLen = aCount; @@ -249,11 +273,13 @@ nsJPEGDecoder::WriteInternal(const char *aBuffer, PRUint32 aCount) return NS_OK; /* I/O suspension */ } - // Post our size to the superclass - PostSize(mInfo.image_width, mInfo.image_height); + /* Set Width and height, and notify that the container is ready to go. */ + mImage->SetSize(mInfo.image_width, mInfo.image_height); + if (mObserver) + mObserver->OnStartContainer(nsnull, mImage); - /* If we're doing a size decode, we're done. */ - if (IsSizeDecode()) + /* If we're doing a header-only decode, we're done. */ + if (mFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) return NS_OK; /* We're doing a full decode. */ @@ -395,9 +421,8 @@ nsJPEGDecoder::WriteInternal(const char *aBuffer, PRUint32 aCount) (" JPEGDecoderAccounting: nsJPEGDecoder::Write -- created image frame with %ux%u pixels", mInfo.image_width, mInfo.image_height)); - // Tell the superclass we're starting a frame - PostFrameStart(); - + if (mObserver) + mObserver->OnStartFrame(nsnull, 0); mState = JPEG_START_DECOMPRESS; } @@ -568,7 +593,8 @@ nsJPEGDecoder::NotifyDone(PRBool aSuccess) NS_ABORT_IF_FALSE(!mNotifiedDone, "calling NotifyDone twice!"); // Notify - PostFrameStop(); + if (mObserver) + mObserver->OnStopFrame(nsnull, 0); if (aSuccess) mImage->DecodingComplete(); if (mObserver) { @@ -902,9 +928,6 @@ term_source (j_decompress_ptr jd) decoder->NotifyDone(/* aSuccess = */ PR_TRUE); } -} // namespace imagelib -} // namespace mozilla - /**************** YCbCr -> Cairo's RGB24/ARGB32 conversion: most common case **************/ diff --git a/modules/libpr0n/decoders/nsJPEGDecoder.h b/modules/libpr0n/decoders/jpeg/nsJPEGDecoder.h similarity index 88% rename from modules/libpr0n/decoders/nsJPEGDecoder.h rename to modules/libpr0n/decoders/jpeg/nsJPEGDecoder.h index 9dbf4282dc1..3c6f685b4f2 100644 --- a/modules/libpr0n/decoders/nsJPEGDecoder.h +++ b/modules/libpr0n/decoders/jpeg/nsJPEGDecoder.h @@ -47,7 +47,7 @@ * we need to undefine the version from 'windows.h'. */ #undef INT32 -#include "Decoder.h" +#include "imgIDecoder.h" #include "nsAutoPtr.h" @@ -62,8 +62,13 @@ extern "C" { #include -namespace mozilla { -namespace imagelib { +#define NS_JPEGDECODER_CID \ +{ /* 5871a422-1dd2-11b2-ab3f-e2e56be5da9c */ \ + 0x5871a422, \ + 0x1dd2, \ + 0x11b2, \ + {0xab, 0x3f, 0xe2, 0xe5, 0x6b, 0xe5, 0xda, 0x9c} \ +} typedef struct { struct jpeg_error_mgr pub; /* "public" fields for IJG library*/ @@ -81,24 +86,31 @@ typedef enum { JPEG_ERROR } jstate; +namespace mozilla { +namespace imagelib { class RasterImage; +} // namespace imagelib +} // namespace mozilla -class nsJPEGDecoder : public Decoder +class nsJPEGDecoder : public imgIDecoder { public: + NS_DECL_ISUPPORTS + NS_DECL_IMGIDECODER + nsJPEGDecoder(); virtual ~nsJPEGDecoder(); - virtual nsresult InitInternal(); - virtual nsresult WriteInternal(const char* aBuffer, PRUint32 aCount); - virtual nsresult FinishInternal(); - void NotifyDone(PRBool aSuccess); protected: nsresult OutputScanlines(PRBool* suspend); public: + nsRefPtr mImage; + nsCOMPtr mObserver; + + PRUint32 mFlags; PRUint8 *mImageData; struct jpeg_decompress_struct mInfo; @@ -126,7 +138,4 @@ public: PRPackedBool mNotifiedDone; }; -} // namespace imagelib -} // namespace mozilla - #endif // nsJPEGDecoder_h__ diff --git a/modules/libpr0n/decoders/png/Makefile.in b/modules/libpr0n/decoders/png/Makefile.in new file mode 100644 index 00000000000..1f6344067bf --- /dev/null +++ b/modules/libpr0n/decoders/png/Makefile.in @@ -0,0 +1,66 @@ +# +# ***** 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 +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 2001 +# 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 = imgpng +LIBRARY_NAME = imgpng_s +FORCE_STATIC_LIB = 1 +MODULE_NAME = nsPNGDecoderModule +LIBXUL_LIBRARY = 1 + +EXTRA_DSO_LIBS = gkgfx + +CPPSRCS = nsPNGDecoder.cpp + +ifneq (,$(filter png,$(MOZ_IMG_ENCODERS))) +DEFINES += -DMOZ_PNG_WRITE +endif + +ifneq (,$(filter png,$(MOZ_IMG_DECODERS))) +DEFINES += -DMOZ_PNG_READ +endif + +# nsPNGDecoder.cpp includes RasterImage.h +LOCAL_INCLUDES += -I$(topsrcdir)/modules/libpr0n/src/ + +include $(topsrcdir)/config/rules.mk diff --git a/modules/libpr0n/decoders/nsPNGDecoder.cpp b/modules/libpr0n/decoders/png/nsPNGDecoder.cpp similarity index 87% rename from modules/libpr0n/decoders/nsPNGDecoder.cpp rename to modules/libpr0n/decoders/png/nsPNGDecoder.cpp index 5550d92843d..19422e5d32a 100644 --- a/modules/libpr0n/decoders/nsPNGDecoder.cpp +++ b/modules/libpr0n/decoders/png/nsPNGDecoder.cpp @@ -46,10 +46,12 @@ #include "nsMemory.h" #include "nsRect.h" +#include "nsIComponentManager.h" #include "nsIInputStream.h" #include "RasterImage.h" #include "imgIContainerObserver.h" +#include "nsIInterfaceRequestorUtils.h" #include "gfxColor.h" #include "nsColor.h" @@ -59,9 +61,20 @@ #include "gfxPlatform.h" -namespace mozilla { -namespace imagelib { +using namespace mozilla::imagelib; +static void PNGAPI info_callback(png_structp png_ptr, png_infop info_ptr); +static void PNGAPI row_callback(png_structp png_ptr, png_bytep new_row, + png_uint_32 row_num, int pass); +#ifdef PNG_APNG_SUPPORTED +static void PNGAPI frame_info_callback(png_structp png_ptr, + png_uint_32 frame_num); +#endif +static void PNGAPI end_callback(png_structp png_ptr, png_infop info_ptr); +static void PNGAPI error_callback(png_structp png_ptr, + png_const_charp error_msg); +static void PNGAPI warning_callback(png_structp png_ptr, + png_const_charp warning_msg); #ifdef PR_LOGGING static PRLogModuleInfo *gPNGLog = PR_NewLogModule("PNGDecoder"); static PRLogModuleInfo *gPNGDecoderAccountingLog = @@ -71,7 +84,7 @@ static PRLogModuleInfo *gPNGDecoderAccountingLog = /* limit image dimensions (bug #251381) */ #define MOZ_PNG_MAX_DIMENSION 1000000L -// For size decodes +// For header-only decodes #define WIDTH_OFFSET 16 #define HEIGHT_OFFSET (WIDTH_OFFSET + 4) #define BYTES_NEEDED_FOR_DIMENSIONS (HEIGHT_OFFSET + 4) @@ -81,6 +94,9 @@ static PRLogModuleInfo *gPNGDecoderAccountingLog = static const PRUint8 pngSignatureBytes[] = { 137, 80, 78, 71, 13, 10, 26, 10 }; + +NS_IMPL_ISUPPORTS1(nsPNGDecoder, imgIDecoder) + nsPNGDecoder::nsPNGDecoder() : mPNG(nsnull), mInfo(nsnull), mCMSLine(nsnull), interlacebuf(nsnull), @@ -93,8 +109,6 @@ nsPNGDecoder::nsPNGDecoder() : nsPNGDecoder::~nsPNGDecoder() { - if (mPNG) - png_destroy_read_struct(&mPNG, mInfo ? &mInfo : NULL, NULL); if (mCMSLine) nsMemory::Free(mCMSLine); if (interlacebuf) @@ -131,8 +145,11 @@ void nsPNGDecoder::CreateFrame(png_uint_32 x_offset, png_uint_32 y_offset, SetAnimFrameInfo(); #endif - // Tell the superclass we're starting a frame - PostFrameStart(); + PRUint32 numFrames = 0; + mImage->GetNumFrames(&numFrames); + + if (mObserver) + mObserver->OnStartFrame(nsnull, numFrames - 1); PR_LOG(gPNGDecoderAccountingLog, PR_LOG_DEBUG, ("PNGDecoderAccounting: nsPNGDecoder::CreateFrame -- created " @@ -170,7 +187,8 @@ void nsPNGDecoder::SetAnimFrameInfo() (static_cast(delay_num) * 1000 / delay_den); } - PRUint32 numFrames = mImage->GetNumFrames(); + PRUint32 numFrames = 0; + mImage->GetNumFrames(&numFrames); mImage->SetFrameTimeout(numFrames - 1, timeout); @@ -196,7 +214,7 @@ void nsPNGDecoder::EndImageFrame() { PRUint32 numFrames = 1; #ifdef PNG_APNG_SUPPORTED - numFrames = mImage->GetNumFrames(); + mImage->GetNumFrames(&numFrames); // We can't use mPNG->num_frames_read as it may be one ahead. if (numFrames > 1) { @@ -208,7 +226,8 @@ void nsPNGDecoder::EndImageFrame() mError = PR_TRUE; // allow the call out to the observers. } - PRUint32 curFrame = mImage->GetCurrentFrameIndex(); + PRUint32 curFrame; + mImage->GetCurrentFrameIndex(&curFrame); if (mObserver) mObserver->OnDataAvailable(nsnull, curFrame == numFrames - 1, &mFrameRect); @@ -216,13 +235,20 @@ void nsPNGDecoder::EndImageFrame() #endif mImage->EndFrameDecode(numFrames - 1); - PostFrameStop(); + if (mObserver) + mObserver->OnStopFrame(nsnull, numFrames - 1); } -nsresult -nsPNGDecoder::InitInternal() -{ +/** imgIDecoder methods **/ + +/* void init (in imgIContainer aImage, + imgIDecoderObserver aObserver, + unsigned long aFlags); */ +NS_IMETHODIMP nsPNGDecoder::Init(imgIContainer *aImage, + imgIDecoderObserver *aObserver, + PRUint32 aFlags) +{ #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED static png_byte color_chunks[]= { 99, 72, 82, 77, '\0', /* cHRM */ @@ -241,13 +267,19 @@ nsPNGDecoder::InitInternal() 116, 73, 77, 69, '\0', /* tIME */ 122, 84, 88, 116, '\0'}; /* zTXt */ #endif + NS_ABORT_IF_FALSE(aImage->GetType() == imgIContainer::TYPE_RASTER, + "wrong type of imgIContainer for decoding into"); + + mImage = static_cast(aImage); + mObserver = aObserver; + mFlags = aFlags; // Fire OnStartDecode at init time to support bug 512435 - if (!IsSizeDecode() && mObserver) + if (!(mFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) && mObserver) mObserver->OnStartDecode(nsnull); - // For size decodes, we only need a small buffer - if (IsSizeDecode()) { + // For header-only decodes, we only need a small buffer + if (mFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) { mHeaderBuf = (PRUint8 *)nsMemory::Alloc(BYTES_NEEDED_FOR_DIMENSIONS); if (!mHeaderBuf) return NS_ERROR_OUT_OF_MEMORY; @@ -260,8 +292,8 @@ nsPNGDecoder::InitInternal() /* Always decode to 24 bit pixdepth */ mPNG = png_create_read_struct(PNG_LIBPNG_VER_STRING, - NULL, nsPNGDecoder::error_callback, - nsPNGDecoder::warning_callback); + NULL, error_callback, + warning_callback); if (!mPNG) return NS_ERROR_OUT_OF_MEMORY; @@ -287,30 +319,40 @@ nsPNGDecoder::InitInternal() /* use this as libpng "progressive pointer" (retrieve in callbacks) */ png_set_progressive_read_fn(mPNG, static_cast(this), - nsPNGDecoder::info_callback, - nsPNGDecoder::row_callback, - nsPNGDecoder::end_callback); + info_callback, row_callback, end_callback); return NS_OK; } -nsresult -nsPNGDecoder::FinishInternal() +/* void close (); */ +NS_IMETHODIMP nsPNGDecoder::Close(PRUint32 aFlags) { + if (mPNG) + png_destroy_read_struct(&mPNG, mInfo ? &mInfo : NULL, NULL); // If we're a full/success decode but haven't sent stop notifications yet, // we didn't get all the data we needed. Send error notifications. - if (!IsSizeDecode() && !mNotifiedDone) + if (!(aFlags & CLOSE_FLAG_DONTNOTIFY) && + !(mFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) && + !mNotifiedDone) NotifyDone(/* aSuccess = */ PR_FALSE); + mImage = nsnull; return NS_OK; } -nsresult -nsPNGDecoder::WriteInternal(const char *aBuffer, PRUint32 aCount) +/* void flush (); */ +NS_IMETHODIMP nsPNGDecoder::Flush() +{ + return NS_OK; +} + +NS_IMETHODIMP +nsPNGDecoder::Write(const char *aBuffer, PRUint32 aCount) { // We use gotos, so we need to declare variables here + nsresult rv; PRUint32 width = 0; PRUint32 height = 0; @@ -319,7 +361,7 @@ nsPNGDecoder::WriteInternal(const char *aBuffer, PRUint32 aCount) goto error; // If we only want width/height, we don't need to go through libpng - if (IsSizeDecode()) { + if (mFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) { // Are we done? if (mHeaderBytesRead == BYTES_NEEDED_FOR_DIMENSIONS) @@ -346,8 +388,14 @@ nsPNGDecoder::WriteInternal(const char *aBuffer, PRUint32 aCount) if ((width > MOZ_PNG_MAX_DIMENSION) || (height > MOZ_PNG_MAX_DIMENSION)) goto error; - // Post our size to the superclass - PostSize(width, height); + // Set the size + rv = mImage->SetSize(width, height); + if (NS_FAILED(rv)) + goto error; + + // Notify the observer that the container is up + if (mObserver) + mObserver->OnStartContainer(nsnull, mImage); } } @@ -516,7 +564,7 @@ PNGGetColorProfile(png_structp png_ptr, png_infop info_ptr, } void -nsPNGDecoder::info_callback(png_structp png_ptr, png_infop info_ptr) +info_callback(png_structp png_ptr, png_infop info_ptr) { /* int number_passes; NOT USED */ png_uint_32 width, height; @@ -528,6 +576,7 @@ nsPNGDecoder::info_callback(png_structp png_ptr, png_infop info_ptr) nsPNGDecoder *decoder = static_cast(png_get_progressive_ptr(png_ptr)); + nsresult rv; /* always decode to 24-bit RGB or 32-bit RGBA */ png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, @@ -537,8 +586,14 @@ nsPNGDecoder::info_callback(png_structp png_ptr, png_infop info_ptr) if (width > MOZ_PNG_MAX_DIMENSION || height > MOZ_PNG_MAX_DIMENSION) longjmp(png_jmpbuf(decoder->mPNG), 1); - // Post our size to the superclass - decoder->PostSize(width, height); + // Set the size and notify that the container is set up + rv = decoder->mImage->SetSize(width, height); + + if (NS_FAILED(rv)) + longjmp(png_jmpbuf(decoder->mPNG), 5); // NS_ERROR_UNEXPECTED + + if (decoder->mObserver) + decoder->mObserver->OnStartContainer(nsnull, decoder->mImage); if (color_type == PNG_COLOR_TYPE_PALETTE) png_set_expand(png_ptr); @@ -648,7 +703,7 @@ nsPNGDecoder::info_callback(png_structp png_ptr, png_infop info_ptr) #ifdef PNG_APNG_SUPPORTED if (png_get_valid(png_ptr, info_ptr, PNG_INFO_acTL)) - png_set_progressive_frame_fn(png_ptr, nsPNGDecoder::frame_info_callback, NULL); + png_set_progressive_frame_fn(png_ptr, frame_info_callback, NULL); if (png_get_first_frame_is_hidden(png_ptr, info_ptr)) { decoder->mFrameIsHidden = PR_TRUE; @@ -689,8 +744,8 @@ nsPNGDecoder::info_callback(png_structp png_ptr, png_infop info_ptr) } void -nsPNGDecoder::row_callback(png_structp png_ptr, png_bytep new_row, - png_uint_32 row_num, int pass) +row_callback(png_structp png_ptr, png_bytep new_row, + png_uint_32 row_num, int pass) { /* libpng comments: * @@ -726,7 +781,7 @@ nsPNGDecoder::row_callback(png_structp png_ptr, png_bytep new_row, if (decoder->mFrameIsHidden) return; - if (row_num >= (png_uint_32) decoder->mFrameRect.height) + if (row_num >= decoder->mFrameRect.height) return; if (new_row) { @@ -806,7 +861,8 @@ nsPNGDecoder::row_callback(png_structp png_ptr, png_bytep new_row, if (!rowHasNoAlpha) decoder->mFrameHasNoAlpha = PR_FALSE; - PRUint32 numFrames = decoder->mImage->GetNumFrames(); + PRUint32 numFrames = 0; + decoder->mImage->GetNumFrames(&numFrames); if (numFrames <= 1) { // Only do incremental image display for the first frame nsIntRect r(0, row_num, width, 1); @@ -814,7 +870,8 @@ nsPNGDecoder::row_callback(png_structp png_ptr, png_bytep new_row, decoder->mError = PR_TRUE; /* bail */ return; } - PRUint32 curFrame = decoder->mImage->GetCurrentFrameIndex(); + PRUint32 curFrame; + decoder->mImage->GetCurrentFrameIndex(&curFrame); if (decoder->mObserver) decoder->mObserver->OnDataAvailable(nsnull, curFrame == numFrames - 1, &r); @@ -824,7 +881,7 @@ nsPNGDecoder::row_callback(png_structp png_ptr, png_bytep new_row, // got the header of a new frame that's coming void -nsPNGDecoder::frame_info_callback(png_structp png_ptr, png_uint_32 frame_num) +frame_info_callback(png_structp png_ptr, png_uint_32 frame_num) { #ifdef PNG_APNG_SUPPORTED png_uint_32 x_offset, y_offset; @@ -849,7 +906,7 @@ nsPNGDecoder::frame_info_callback(png_structp png_ptr, png_uint_32 frame_num) } void -nsPNGDecoder::end_callback(png_structp png_ptr, png_infop info_ptr) +end_callback(png_structp png_ptr, png_infop info_ptr) { /* libpng comments: * @@ -882,7 +939,7 @@ nsPNGDecoder::end_callback(png_structp png_ptr, png_infop info_ptr) void -nsPNGDecoder::error_callback(png_structp png_ptr, png_const_charp error_msg) +error_callback(png_structp png_ptr, png_const_charp error_msg) { PR_LOG(gPNGLog, PR_LOG_ERROR, ("libpng error: %s\n", error_msg)); longjmp(png_jmpbuf(png_ptr), 1); @@ -890,10 +947,8 @@ nsPNGDecoder::error_callback(png_structp png_ptr, png_const_charp error_msg) void -nsPNGDecoder::warning_callback(png_structp png_ptr, png_const_charp warning_msg) +warning_callback(png_structp png_ptr, png_const_charp warning_msg) { PR_LOG(gPNGLog, PR_LOG_WARNING, ("libpng warning: %s\n", warning_msg)); } -} // namespace imagelib -} // namespace mozilla diff --git a/modules/libpr0n/decoders/nsPNGDecoder.h b/modules/libpr0n/decoders/png/nsPNGDecoder.h similarity index 73% rename from modules/libpr0n/decoders/nsPNGDecoder.h rename to modules/libpr0n/decoders/png/nsPNGDecoder.h index edc10592fb5..f429807fcc9 100644 --- a/modules/libpr0n/decoders/nsPNGDecoder.h +++ b/modules/libpr0n/decoders/png/nsPNGDecoder.h @@ -41,8 +41,9 @@ #ifndef nsPNGDecoder_h__ #define nsPNGDecoder_h__ -#include "Decoder.h" +#include "imgIDecoder.h" +#include "imgIContainer.h" #include "imgIDecoderObserver.h" #include "gfxASurface.h" @@ -52,20 +53,29 @@ #include "qcms.h" +#define NS_PNGDECODER_CID \ +{ /* 36fa00c2-1dd2-11b2-be07-d16eeb4c50ed */ \ + 0x36fa00c2, \ + 0x1dd2, \ + 0x11b2, \ + {0xbe, 0x07, 0xd1, 0x6e, 0xeb, 0x4c, 0x50, 0xed} \ +} + namespace mozilla { namespace imagelib { class RasterImage; +} // namespace imagelib +} // namespace mozilla -class nsPNGDecoder : public Decoder +class nsPNGDecoder : public imgIDecoder { public: + NS_DECL_ISUPPORTS + NS_DECL_IMGIDECODER + nsPNGDecoder(); virtual ~nsPNGDecoder(); - virtual nsresult InitInternal(); - virtual nsresult WriteInternal(const char* aBuffer, PRUint32 aCount); - virtual nsresult FinishInternal(); - void CreateFrame(png_uint_32 x_offset, png_uint_32 y_offset, PRInt32 width, PRInt32 height, gfxASurface::gfxImageFormat format); @@ -75,6 +85,10 @@ public: void NotifyDone(PRBool aSuccess); public: + nsRefPtr mImage; + nsCOMPtr mObserver; + PRUint32 mFlags; + png_structp mPNG; png_infop mInfo; nsIntRect mFrameRect; @@ -86,7 +100,7 @@ public: gfxASurface::gfxImageFormat format; - // For size decodes + // For header-only decodes PRUint8 *mHeaderBuf; PRUint32 mHeaderBytesRead; @@ -95,27 +109,6 @@ public: PRPackedBool mFrameHasNoAlpha; PRPackedBool mFrameIsHidden; PRPackedBool mNotifiedDone; - - /* - * libpng callbacks - * - * We put these in the class so that they can access protected members. - */ - static void PNGAPI info_callback(png_structp png_ptr, png_infop info_ptr); - static void PNGAPI row_callback(png_structp png_ptr, png_bytep new_row, - png_uint_32 row_num, int pass); -#ifdef PNG_APNG_SUPPORTED - static void PNGAPI frame_info_callback(png_structp png_ptr, - png_uint_32 frame_num); -#endif - static void PNGAPI end_callback(png_structp png_ptr, png_infop info_ptr); - static void PNGAPI error_callback(png_structp png_ptr, - png_const_charp error_msg); - static void PNGAPI warning_callback(png_structp png_ptr, - png_const_charp warning_msg); }; -} // namespace imagelib -} // namespace mozilla - #endif // nsPNGDecoder_h__ diff --git a/modules/libpr0n/encoders/png/Makefile.in b/modules/libpr0n/encoders/png/Makefile.in index a212d3e07c7..ed2d2490919 100644 --- a/modules/libpr0n/encoders/png/Makefile.in +++ b/modules/libpr0n/encoders/png/Makefile.in @@ -53,7 +53,9 @@ ifneq (,$(filter png,$(MOZ_IMG_ENCODERS))) DEFINES += -DMOZ_PNG_WRITE endif +ifneq (,$(filter png,$(MOZ_IMG_DECODERS))) DEFINES += -DMOZ_PNG_READ +endif CPPSRCS = nsPNGEncoder.cpp diff --git a/modules/libpr0n/public/Makefile.in b/modules/libpr0n/public/Makefile.in index 2ad51c8c864..b3505b5c89c 100644 --- a/modules/libpr0n/public/Makefile.in +++ b/modules/libpr0n/public/Makefile.in @@ -51,6 +51,7 @@ XPIDLSRCS = \ imgICache.idl \ imgIContainer.idl \ imgIContainerObserver.idl \ + imgIDecoder.idl \ imgIDecoderObserver.idl \ imgIEncoder.idl \ imgILoader.idl \ diff --git a/modules/libpr0n/public/imgIDecoder.idl b/modules/libpr0n/public/imgIDecoder.idl new file mode 100644 index 00000000000..2caad7a70ab --- /dev/null +++ b/modules/libpr0n/public/imgIDecoder.idl @@ -0,0 +1,119 @@ +/* -*- 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 mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Stuart Parmenter + * Bobby Holley + * + * 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" + +interface nsIInputStream; +interface imgIContainer; +interface imgIDecoderObserver; + +/** + * imgIDecoder interface + * + * @author Stuart Parmenter + * @version 0.2 + * @see imagelib2 + */ +[scriptable, uuid(6fc61088-5443-4539-9e24-629a266a800a)] +interface imgIDecoder : nsISupports +{ + /** + * Bits that can be passed to the decoder to affect decoding. + * @name decodeflags + * + * Meanings: + * + * DECODER_FLAG_NONE: No flags + * + * DECODER_FLAG_HEADERONLY: Read basic data from the image in order to + * set up the image container, but don't read any actual image data. + */ + const long DECODER_FLAG_NONE = 0x0; + const long DECODER_FLAG_HEADERONLY = 0x1; + + /** + * Initialize an image decoder. + * @param aContainer The image container to decode to. + * @param aObserver The observer for decode notification events. + * @param aFlags Flags for the decoder + * + * @note The decoder should always pass NULL as the + * first two parameters to all of the imgIDecoderObserver APIs. + */ + void init(in imgIContainer aImage, in imgIDecoderObserver aObserver, + in unsigned long aFlags); + + /** + * Closes the stream. + * @param aFlags Close flags of the CLOSE_FLAG_* Variety + * + * Resources are always freed with this call. If notifications are sent, + * OnStopDecode is guaranteed to be called if it hasn't been called already. + * + * CLOSE_FLAG_DONTNOTIFY - Don't send any observer notifications, and don't + * call imgIContainer::decodingComplete(). + */ + const long CLOSE_FLAG_DONTNOTIFY = 0x01; + void close(in PRUint32 aFlags); + + /** + * Flushes the stream. + */ + void flush(); + + /** + * Writes data to the decoder. + * + * For Header-Only decodes, OnStartContainer is the only notification + * fired. It is an error to write any more data to the decoder for header-only + * decodes after SetSize() has been called. + * + * If a decoding error occurs, an internal flag is set and an error is + * returned. Each subsequent call to write will fail immediately + * for the lifetime of the decoder. Shutdown notifications of the OnStopX + * variety, as well as DecodingComplete(), are guaranteed not to be called + * if a decoding error occurs. + * + * @param aBuffer buffer containing the data to be written + * @param aCount the number of bytes to write + */ + void write(in string aBuffer, in unsigned long count); + +}; diff --git a/modules/libpr0n/src/Decoder.cpp b/modules/libpr0n/src/Decoder.cpp deleted file mode 100644 index 73587a46501..00000000000 --- a/modules/libpr0n/src/Decoder.cpp +++ /dev/null @@ -1,158 +0,0 @@ - -/* -*- 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 mozilla.org code. - * - * The Initial Developer of the Original Code is - * the Mozilla Foundation. - * Portions created by the Initial Developer are Copyright (C) 2010. - * 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 ***** */ - -#include "Decoder.h" - -namespace mozilla { -namespace imagelib { - -Decoder::Decoder() - : mFrameCount(0) - , mInitialized(false) - , mSizeDecode(false) - , mInFrame(false) -{ -} - -Decoder::~Decoder() -{ - NS_WARN_IF_FALSE(!mInFrame, "Shutting down decoder mid-frame!"); - mInitialized = false; -} - -/* - * Common implementation of the decoder interface. - */ - -nsresult -Decoder::Init(RasterImage* aImage, imgIDecoderObserver* aObserver) -{ - // We should always have an image - NS_ABORT_IF_FALSE(aImage, "Can't initialize decoder without an image!"); - - // No re-initializing - NS_ABORT_IF_FALSE(mImage == nsnull, "Can't re-initialize a decoder!"); - - // Save our paremeters - mImage = aImage; - mObserver = aObserver; - - // Implementation-specific initialization - nsresult rv = InitInternal(); - mInitialized = true; - return rv; -} - -nsresult -Decoder::Write(const char* aBuffer, PRUint32 aCount) -{ - // Pass the data along to the implementation - return WriteInternal(aBuffer, aCount); -} - -nsresult -Decoder::Finish() -{ - // Implementation-specific finalization - return FinishInternal(); -} - -/* - * Hook stubs. Override these as necessary in decoder implementations. - */ - -nsresult Decoder::InitInternal() {return NS_OK; } -nsresult Decoder::WriteInternal(const char* aBuffer, PRUint32 aCount) {return NS_OK; } -nsresult Decoder::FinishInternal() {return NS_OK; } - -/* - * Progress Notifications - */ - -void -Decoder::PostSize(PRInt32 aWidth, PRInt32 aHeight) -{ - // Validate - NS_ABORT_IF_FALSE(aWidth >= 0, "Width can't be negative!"); - NS_ABORT_IF_FALSE(aHeight >= 0, "Height can't be negative!"); - - // Tell the image - mImage->SetSize(aWidth, aHeight); - - // Notify the observer - if (mObserver) - mObserver->OnStartContainer(nsnull, mImage); -} - -void -Decoder::PostFrameStart() -{ - // We shouldn't already be mid-frame - NS_ABORT_IF_FALSE(!mInFrame, "Starting new frame but not done with old one!"); - - // Update our state to reflect the new frame - mFrameCount++; - mInFrame = true; - - // Decoder implementations should only call this method if they successfully - // appended the frame to the image. So mFrameCount should always match that - // reported by the Image. - NS_ABORT_IF_FALSE(mFrameCount == mImage->GetNumFrames(), - "Decoder frame count doesn't match image's!"); - - // Fire notification - if (mObserver) - mObserver->OnStartFrame(nsnull, mFrameCount - 1); // frame # is zero-indexed -} - -void -Decoder::PostFrameStop() -{ - // We should be mid-frame - NS_ABORT_IF_FALSE(mInFrame, "Stopping frame when we didn't start one!"); - - // Update our state - mInFrame = false; - - // Fire notification - if (mObserver) - mObserver->OnStopFrame(nsnull, mFrameCount - 1); // frame # is zero-indexed -} - -} // namespace imagelib -} // namespace mozilla diff --git a/modules/libpr0n/src/Decoder.h b/modules/libpr0n/src/Decoder.h deleted file mode 100644 index ccd99a2035b..00000000000 --- a/modules/libpr0n/src/Decoder.h +++ /dev/null @@ -1,152 +0,0 @@ -/* -*- 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 mozilla.org code. - * - * The Initial Developer of the Original Code is - * the Mozilla Foundation. - * Portions created by the Initial Developer are Copyright (C) 2010. - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Bobby Holley - * - * 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 ***** */ - -#ifndef MOZILLA_IMAGELIB_DECODER_H_ -#define MOZILLA_IMAGELIB_DECODER_H_ - -#include "RasterImage.h" - -#include "imgIDecoderObserver.h" - -namespace mozilla { -namespace imagelib { - -class Decoder -{ -public: - - Decoder(); - ~Decoder(); - - /** - * XXX - These methods will stop returning nsresults in a later patch. - */ - - /** - * Initialize an image decoder. Decoders may not be re-initialized. - * - * @param aContainer The image container to decode to. - * @param aObserver The observer for decode notification events. - * - * Notifications Sent: TODO - */ - nsresult Init(RasterImage* aImage, imgIDecoderObserver* aObserver); - - /** - * Writes data to the decoder. - * - * @param aBuffer buffer containing the data to be written - * @param aCount the number of bytes to write - * - * Any errors are reported by setting the appropriate state on the decoder. - * - * Notifications Sent: TODO - */ - nsresult Write(const char* aBuffer, PRUint32 aCount); - - /** - * Informs the decoder that all the data has been written. - * - * Notifications Sent: TODO - */ - nsresult Finish(); - - // We're not COM-y, so we don't get refcounts by default - NS_INLINE_DECL_REFCOUNTING(Decoder) - - /* - * State. - */ - - // If we're doing a "size decode", we more or less pass through the image - // data, stopping only to scoop out the image dimensions. A size decode - // must be enabled by SetSizeDecode() _before_calling Init(). - bool IsSizeDecode() { return mSizeDecode; }; - void SetSizeDecode(bool aSizeDecode) - { - NS_ABORT_IF_FALSE(!mInitialized, "Can't set size decode after Init()!"); - mSizeDecode = aSizeDecode; - } - - // The number of frames we have, including anything in-progress. Thus, this - // is only 0 if we haven't begun any frames. - PRUint32 GetFrameCount() { return mFrameCount; } - -protected: - - /* - * Internal hooks. Decoder implementations may override these and - * only these methods. - */ - virtual nsresult InitInternal(); - virtual nsresult WriteInternal(const char* aBuffer, PRUint32 aCount); - virtual nsresult FinishInternal(); - - /* - * Progress notifications. - */ - - // Called by decoders when they determine the size of the image. Informs - // the image of its size and sends notifications. - void PostSize(PRInt32 aWidth, PRInt32 aHeight); - - // Called by decoders when they begin/end a frame. Informs the image, sends - // notifications, and does internal book-keeping. - void PostFrameStart(); - void PostFrameStop(); - - - /* - * Member variables. - * - * XXX - Some of these become private later in the patch stack. - */ - nsRefPtr mImage; - nsCOMPtr mObserver; - - PRUint32 mFrameCount; // Number of frames, including anything in-progress - - bool mInitialized; - bool mSizeDecode; - bool mInFrame; -}; - -} // namespace imagelib -} // namespace mozilla - -#endif // MOZILLA_IMAGELIB_DECODER_H_ diff --git a/modules/libpr0n/src/Image.cpp b/modules/libpr0n/src/Image.cpp index 886097d3e2b..53dd3973e84 100644 --- a/modules/libpr0n/src/Image.cpp +++ b/modules/libpr0n/src/Image.cpp @@ -47,52 +47,5 @@ Image::Image() : { } -// Translates a mimetype into a concrete decoder -Image::eDecoderType -Image::GetDecoderType(const char *aMimeType) -{ - // By default we don't know - eDecoderType rv = eDecoderType_unknown; - - // PNG - if (!strcmp(aMimeType, "image/png")) - rv = eDecoderType_png; - else if (!strcmp(aMimeType, "image/x-png")) - rv = eDecoderType_png; - - // GIF - else if (!strcmp(aMimeType, "image/gif")) - rv = eDecoderType_gif; - - - // JPEG - else if (!strcmp(aMimeType, "image/jpeg")) - rv = eDecoderType_jpeg; - else if (!strcmp(aMimeType, "image/pjpeg")) - rv = eDecoderType_jpeg; - else if (!strcmp(aMimeType, "image/jpg")) - rv = eDecoderType_jpeg; - - // BMP - else if (!strcmp(aMimeType, "image/bmp")) - rv = eDecoderType_bmp; - else if (!strcmp(aMimeType, "image/x-ms-bmp")) - rv = eDecoderType_bmp; - - - // ICO - else if (!strcmp(aMimeType, "image/x-icon")) - rv = eDecoderType_ico; - else if (!strcmp(aMimeType, "image/vnd.microsoft.icon")) - rv = eDecoderType_ico; - - // Icon - else if (!strcmp(aMimeType, "image/icon")) - rv = eDecoderType_icon; - - return rv; -} - - } // namespace imagelib } // namespace mozilla diff --git a/modules/libpr0n/src/Image.h b/modules/libpr0n/src/Image.h index fae90d49373..d4b86dc289e 100644 --- a/modules/libpr0n/src/Image.h +++ b/modules/libpr0n/src/Image.h @@ -94,30 +94,18 @@ public: * The index of the current frame that would be drawn if the image was to be * drawn now. */ - virtual PRUint32 GetCurrentFrameIndex() = 0; + virtual nsresult GetCurrentFrameIndex(PRUint32* aCurrentFrameIdx) = 0; /** * The total number of frames in this image. */ - virtual PRUint32 GetNumFrames() = 0; + virtual nsresult GetNumFrames(PRUint32* aNumFrames) = 0; /** * The size, in bytes, occupied by the significant data portions of the image. * This includes both compressed source data and decoded frames. */ - virtual PRUint32 GetDataSize() = 0; - - // Mimetype translation - enum eDecoderType { - eDecoderType_png = 0, - eDecoderType_gif = 1, - eDecoderType_jpeg = 2, - eDecoderType_bmp = 3, - eDecoderType_ico = 4, - eDecoderType_icon = 5, - eDecoderType_unknown = 6 - }; - static eDecoderType GetDecoderType(const char *aMimeType); + virtual nsresult GetDataSize(PRUint32* aDataSize) = 0; protected: Image(); diff --git a/modules/libpr0n/src/Makefile.in b/modules/libpr0n/src/Makefile.in index d16e57e3254..b5db3c25b8e 100644 --- a/modules/libpr0n/src/Makefile.in +++ b/modules/libpr0n/src/Makefile.in @@ -52,7 +52,6 @@ LIBXUL_LIBRARY = 1 CPPSRCS = \ Image.cpp \ - Decoder.cpp \ DiscardTracker.cpp \ RasterImage.cpp \ imgFrame.cpp \ @@ -63,9 +62,6 @@ CPPSRCS = \ imgStatusTracker.cpp \ $(NULL) -# We need to instantiate the decoders -LOCAL_INCLUDES += -I$(topsrcdir)/modules/libpr0n/decoders - include $(topsrcdir)/config/rules.mk # Because imgFrame.cpp includes "cairo.h" diff --git a/modules/libpr0n/src/RasterImage.cpp b/modules/libpr0n/src/RasterImage.cpp index 07d605e8b34..a7c6992c755 100644 --- a/modules/libpr0n/src/RasterImage.cpp +++ b/modules/libpr0n/src/RasterImage.cpp @@ -45,7 +45,7 @@ #include "nsComponentManagerUtils.h" #include "imgIContainerObserver.h" #include "ImageErrors.h" -#include "Decoder.h" +#include "imgIDecoder.h" #include "imgIDecoderObserver.h" #include "RasterImage.h" #include "nsIInterfaceRequestor.h" @@ -58,13 +58,6 @@ #include "nsTime.h" #include "ImageLogging.h" -#include "nsPNGDecoder.h" -#include "nsGIFDecoder2.h" -#include "nsJPEGDecoder.h" -#include "nsBMPDecoder.h" -#include "nsICODecoder.h" -#include "nsIconDecoder.h" - #include "gfxContext.h" using namespace mozilla::imagelib; @@ -159,6 +152,7 @@ RasterImage::RasterImage() : mDecoder(nsnull), mWorker(nsnull), mBytesDecoded(0), + mDecoderFlags(imgIDecoder::DECODER_FLAG_NONE), mHasSize(PR_FALSE), mDecodeOnDraw(PR_FALSE), mMultipart(PR_FALSE), @@ -260,12 +254,16 @@ RasterImage::Init(imgIDecoderObserver *aObserver, return NS_OK; } + // Determine our decoder flags. If we're doing decode-on-draw, + // we want to do a quick first pass to get the size but nothing + // else. We instantiate another decoder later to do the full + // decoding. + PRUint32 dFlags = imgIDecoder::DECODER_FLAG_NONE; + if (mDecodeOnDraw) + dFlags |= imgIDecoder::DECODER_FLAG_HEADERONLY; + // Instantiate the decoder - // - // If we're doing decode-on-draw, we want to do a quick first pass to get - // the size but nothing else. We instantiate another decoder later to do - // the full decoding. - nsresult rv = InitDecoder(/* aDoSizeDecode = */ mDecodeOnDraw); + nsresult rv = InitDecoder(dFlags); CONTAINER_ENSURE_SUCCESS(rv); // Mark us as initialized @@ -493,16 +491,30 @@ RasterImage::GetCurrentFrameRect(nsIntRect &aRect) return NS_OK; } -PRUint32 -RasterImage::GetCurrentFrameIndex() +nsresult +RasterImage::GetCurrentFrameIndex(PRUint32 *aCurrentFrameIdx) { - return GetCurrentImgFrameIndex(); + if (mError) + return NS_ERROR_FAILURE; + + NS_ENSURE_ARG_POINTER(aCurrentFrameIdx); + + *aCurrentFrameIdx = GetCurrentImgFrameIndex(); + + return NS_OK; } -PRUint32 -RasterImage::GetNumFrames() +nsresult +RasterImage::GetNumFrames(PRUint32 *aNumFrames) { - return mFrames.Length(); + if (mError) + return NS_ERROR_FAILURE; + + NS_ENSURE_ARG_POINTER(aNumFrames); + + *aNumFrames = mFrames.Length(); + + return NS_OK; } //****************************************************************************** @@ -651,24 +663,25 @@ RasterImage::GetFrame(PRUint32 aWhichFrame, return rv; } -PRUint32 -RasterImage::GetDataSize() +nsresult +RasterImage::GetDataSize(PRUint32 *_retval) { if (mError) - return 0; + return NS_ERROR_FAILURE; + + NS_ENSURE_ARG_POINTER(_retval); // Start with 0 - PRUint32 size = 0; + *_retval = 0; // Account for any compressed source data - size += GetSourceDataSize(); - NS_ABORT_IF_FALSE(StoringSourceData() || (size == 0), + *_retval += GetSourceDataSize(); + NS_ABORT_IF_FALSE(StoringSourceData() || (*_retval == 0), "Non-zero source data size when we aren't storing it?"); // Account for any uncompressed frames - size += GetDecodedDataSize(); - - return size; + *_retval += GetDecodedDataSize(); + return NS_OK; } PRUint32 @@ -1391,7 +1404,7 @@ RasterImage::NewSourceData() // We're decode-on-load here. Open up a new decoder just like what happens when // we call Init() for decode-on-load images. - rv = InitDecoder(/* aDoSizeDecode = */ false); + rv = InitDecoder(imgIDecoder::DECODER_FLAG_NONE); CONTAINER_ENSURE_SUCCESS(rv); return NS_OK; @@ -2098,7 +2111,7 @@ RasterImage::StoringSourceData() { // Sets up a decoder for this image. It is an error to call this function // when decoding is already in process (ie - when mDecoder is non-null). nsresult -RasterImage::InitDecoder(bool aDoSizeDecode) +RasterImage::InitDecoder(PRUint32 dFlags) { // Ensure that the decoder is not already initialized NS_ABORT_IF_FALSE(!mDecoder, "Calling InitDecoder() while already decoding!"); @@ -2109,38 +2122,18 @@ RasterImage::InitDecoder(bool aDoSizeDecode) // Since we're not decoded, we should not have a discard timer active NS_ABORT_IF_FALSE(!DiscardingActive(), "Discard Timer active in InitDecoder()!"); - // Figure out which decoder we want - eDecoderType type = GetDecoderType(mSourceDataMimeType.get()); - CONTAINER_ENSURE_TRUE(type != eDecoderType_unknown, NS_IMAGELIB_ERROR_NO_DECODER); + // Find and instantiate the decoder + nsCAutoString decoderCID(NS_LITERAL_CSTRING("@mozilla.org/image/decoder;3?type=") + + mSourceDataMimeType); + mDecoder = do_CreateInstance(decoderCID.get()); + CONTAINER_ENSURE_TRUE(mDecoder, NS_IMAGELIB_ERROR_NO_DECODER); - // Instantiate the appropriate decoder - switch (type) { - case eDecoderType_png: - mDecoder = new nsPNGDecoder(); - break; - case eDecoderType_gif: - mDecoder = new nsGIFDecoder2(); - break; - case eDecoderType_jpeg: - mDecoder = new nsJPEGDecoder(); - break; - case eDecoderType_bmp: - mDecoder = new nsBMPDecoder(); - break; - case eDecoderType_ico: - mDecoder = new nsICODecoder(); - break; - case eDecoderType_icon: - mDecoder = new nsIconDecoder(); - break; - default: - NS_ABORT_IF_FALSE(0, "Shouldn't get here!"); - } + // Store the flags for this decoder + mDecoderFlags = dFlags; // Initialize the decoder nsCOMPtr observer(do_QueryReferent(mObserver)); - mDecoder->SetSizeDecode(aDoSizeDecode); - nsresult result = mDecoder->Init(this, observer); + nsresult result = mDecoder->Init(this, observer, dFlags); CONTAINER_ENSURE_SUCCESS(result); // Create a decode worker @@ -2168,17 +2161,31 @@ RasterImage::ShutdownDecoder(eShutdownIntent aIntent) // Ensure that the decoder is initialized NS_ABORT_IF_FALSE(mDecoder, "Calling ShutdownDecoder() with no active decoder!"); - // Figure out what kind of decode we were doing before we get rid of our decoder - bool wasSizeDecode = mDecoder->IsSizeDecode(); + nsresult rv; - // If we're not in error mode, finalize the decoder - nsresult rv = NS_OK; - if (aIntent != eShutdownIntent_Error) { + // If we're "done" _and_ it's a full decode, flush + if ((aIntent == eShutdownIntent_Done) && + !(mDecoderFlags && imgIDecoder::DECODER_FLAG_HEADERONLY)) { mInDecoder = PR_TRUE; - rv = mDecoder->Finish(); + rv = mDecoder->Flush(); mInDecoder = PR_FALSE; + + // The error case here is a bit tricky. We flag an error, which takes us + // back into this function, and then we return. + if (NS_FAILED(rv)) { + DoError(); + return rv; + } } + // Close the decoder with the appropriate flags + mInDecoder = PR_TRUE; + PRUint32 closeFlags = (aIntent == eShutdownIntent_Error) + ? (PRUint32) imgIDecoder::CLOSE_FLAG_DONTNOTIFY + : 0; + rv = mDecoder->Close(closeFlags); + mInDecoder = PR_FALSE; + // null out the decoder, _then_ check for errors on the close (otherwise the // error routine might re-invoke ShutdownDecoder) mDecoder = nsnull; @@ -2193,15 +2200,18 @@ RasterImage::ShutdownDecoder(eShutdownIntent aIntent) // We just shut down the decoder. If we didn't get what we want, but expected // to, flag an error PRBool failed = PR_FALSE; - if (wasSizeDecode && !mHasSize) + if ((mDecoderFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) && !mHasSize) failed = PR_TRUE; - if (!wasSizeDecode && !mDecoded) + if (!(mDecoderFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) && !mDecoded) failed = PR_TRUE; if ((aIntent == eShutdownIntent_Done) && failed) { DoError(); return NS_ERROR_FAILURE; } + // Clear the flags + mDecoderFlags = imgIDecoder::DECODER_FLAG_NONE; + // Reset number of decoded bytes mBytesDecoded = 0; @@ -2288,11 +2298,11 @@ RasterImage::RequestDecode() return NS_OK; // If we've already got a full decoder running, we have nothing to do - if (mDecoder && !mDecoder->IsSizeDecode()) + if (mDecoder && !(mDecoderFlags & imgIDecoder::DECODER_FLAG_HEADERONLY)) return NS_OK; - // If our callstack goes through a size decoder, we have a problem. - // We need to shutdown the size decode and replace it with a full + // If our callstack goes through a header-only decoder, we have a problem. + // We need to shutdown the header-only decoder and replace it with a full // decoder, but can't do that from within the decoder itself. Thus, we post // an asynchronous event to the event loop to do it later. Since // RequestDecode() is an asynchronous function this works fine (though it's @@ -2305,8 +2315,8 @@ RasterImage::RequestDecode() } - // If we have a size decode open, interrupt it and shut it down - if (mDecoder && mDecoder->IsSizeDecode()) { + // If we have a header-only decoder open, interrupt it and shut it down + if (mDecoder && (mDecoderFlags & imgIDecoder::DECODER_FLAG_HEADERONLY)) { rv = ShutdownDecoder(eShutdownIntent_Interrupted); CONTAINER_ENSURE_SUCCESS(rv); } @@ -2314,7 +2324,7 @@ RasterImage::RequestDecode() // If we don't have a decoder, create one if (!mDecoder) { NS_ABORT_IF_FALSE(mFrames.IsEmpty(), "Trying to decode to non-empty frame-array"); - rv = InitDecoder(/* aDoSizeDecode = */ false); + rv = InitDecoder(imgIDecoder::DECODER_FLAG_NONE); CONTAINER_ENSURE_SUCCESS(rv); } @@ -2352,8 +2362,8 @@ RasterImage::SyncDecode() // disallow this type of call in the API, and check for it in API methods. NS_ABORT_IF_FALSE(!mInDecoder, "Yikes, forcing sync in reentrant call!"); - // If we have a size decode open, shut it down - if (mDecoder && mDecoder->IsSizeDecode()) { + // If we have a header-only decoder open, shut it down + if (mDecoder && (mDecoderFlags & imgIDecoder::DECODER_FLAG_HEADERONLY)) { rv = ShutdownDecoder(eShutdownIntent_Interrupted); CONTAINER_ENSURE_SUCCESS(rv); } @@ -2361,7 +2371,7 @@ RasterImage::SyncDecode() // If we don't have a decoder, create one if (!mDecoder) { NS_ABORT_IF_FALSE(mFrames.IsEmpty(), "Trying to decode to non-empty frame-array"); - rv = InitDecoder(/* aDoSizeDecode = */ false); + rv = InitDecoder(imgIDecoder::DECODER_FLAG_NONE); CONTAINER_ENSURE_SUCCESS(rv); } @@ -2494,14 +2504,9 @@ RasterImage::DecodeSomeData(PRUint32 aMaxBytes) // There are various indicators that tell us we're finished with the decode // task at hand and can shut down the decoder. -// -// This method may not be called if there is no decoder. PRBool RasterImage::IsDecodeFinished() { - // Precondition - NS_ABORT_IF_FALSE(mDecoder, "Can't call IsDecodeFinished() without decoder!"); - // Assume it's not finished PRBool decodeFinished = PR_FALSE; @@ -2511,7 +2516,7 @@ RasterImage::IsDecodeFinished() "just shut down on SourceDataComplete!"); // The decode is complete if we got what we wanted... - if (mDecoder->IsSizeDecode()) { + if (mDecoderFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) { if (mHasSize) decodeFinished = PR_TRUE; } @@ -2599,10 +2604,11 @@ imgDecodeWorker::Run() if (!image->mDecoder) return NS_OK; - // Size decodes are cheap and we more or less want them to be + // Header-only decodes are cheap and we more or less want them to be // synchronous. Write all the data in that case, otherwise write a // chunk - PRUint32 maxBytes = image->mDecoder->IsSizeDecode() + PRUint32 maxBytes = + (image->mDecoderFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) ? image->mSourceData.Length() : DECODE_BYTES_AT_A_TIME; // Loop control @@ -2640,7 +2646,7 @@ imgDecodeWorker::Run() // If Conditions 1 & 2 are still true, then the only reason we bailed was // because we hit the deadline. Repost ourselves to the end of the event // queue. - if (image->mDecoder && !image->IsDecodeFinished() && haveMoreData) + if (!image->IsDecodeFinished() && haveMoreData) return this->Dispatch(); // Otherwise, return success diff --git a/modules/libpr0n/src/RasterImage.h b/modules/libpr0n/src/RasterImage.h index 609835ba76f..63814723ede 100644 --- a/modules/libpr0n/src/RasterImage.h +++ b/modules/libpr0n/src/RasterImage.h @@ -143,7 +143,6 @@ namespace mozilla { namespace imagelib { class imgDecodeWorker; -class Decoder; class RasterImage : public mozilla::imagelib::Image, public nsITimerCallback, @@ -167,9 +166,9 @@ public: const char* aMimeType, PRUint32 aFlags); nsresult GetCurrentFrameRect(nsIntRect& aRect); - PRUint32 GetCurrentFrameIndex(); - PRUint32 GetNumFrames(); - PRUint32 GetDataSize(); + nsresult GetCurrentFrameIndex(PRUint32* aCurrentFrameIdx); + nsresult GetNumFrames(PRUint32* aNumFrames); + nsresult GetDataSize(PRUint32* aDataSize); // Raster-specific methods static NS_METHOD WriteToRasterImage(nsIInputStream* aIn, void* aClosure, @@ -459,9 +458,10 @@ private: // data friend class DiscardTracker; // Decoder and friends - nsRefPtr mDecoder; + nsCOMPtr mDecoder; nsRefPtr mWorker; PRUint32 mBytesDecoded; + PRUint32 mDecoderFlags; // Boolean flags (clustered together to conserve space): PRPackedBool mHasSize:1; // Has SetSize() been called? @@ -483,7 +483,7 @@ private: // data // Decoding nsresult WantDecodedFrames(); nsresult SyncDecode(); - nsresult InitDecoder(bool aDoSizeDecode); + nsresult InitDecoder(PRUint32 dFlags); nsresult WriteToDecoder(const char *aBuffer, PRUint32 aCount); nsresult DecodeSomeData(PRUint32 aMaxBytes); PRBool IsDecodeFinished(); diff --git a/modules/libpr0n/src/imgLoader.cpp b/modules/libpr0n/src/imgLoader.cpp index dfd063da586..7e00310dbdb 100644 --- a/modules/libpr0n/src/imgLoader.cpp +++ b/modules/libpr0n/src/imgLoader.cpp @@ -1853,11 +1853,14 @@ NS_IMETHODIMP imgLoader::LoadImageWithChannel(nsIChannel *channel, imgIDecoderOb NS_IMETHODIMP imgLoader::SupportImageWithMimeType(const char* aMimeType, PRBool *_retval) { *_retval = PR_FALSE; + nsCOMPtr reg; + nsresult rv = NS_GetComponentRegistrar(getter_AddRefs(reg)); + if (NS_FAILED(rv)) + return rv; nsCAutoString mimeType(aMimeType); ToLowerCase(mimeType); - *_retval = (Image::GetDecoderType(mimeType.get()) == Image::eDecoderType_unknown) - ? PR_FALSE : PR_TRUE; - return NS_OK; + nsCAutoString decoderId(NS_LITERAL_CSTRING("@mozilla.org/image/decoder;3?type=") + mimeType); + return reg->IsContractIDRegistered(decoderId.get(), _retval); } NS_IMETHODIMP imgLoader::GetMIMETypeFromContent(nsIRequest* aRequest, diff --git a/modules/libpr0n/src/imgRequest.cpp b/modules/libpr0n/src/imgRequest.cpp index 731b0027718..dc4191ecea5 100644 --- a/modules/libpr0n/src/imgRequest.cpp +++ b/modules/libpr0n/src/imgRequest.cpp @@ -482,7 +482,9 @@ void imgRequest::SetIsInCache(PRBool incache) void imgRequest::UpdateCacheEntrySize() { if (mCacheEntry) { - mCacheEntry->SetDataSize(mImage->GetDataSize()); + PRUint32 imageSize = 0; + mImage->GetDataSize(&imageSize); + mCacheEntry->SetDataSize(imageSize); #ifdef DEBUG_joe nsCAutoString url; @@ -960,7 +962,7 @@ NS_IMETHODIMP imgRequest::OnDataAvailable(nsIRequest *aRequest, nsISupports *ctx /* now we have mimetype, so we can infer the image type that we want */ imageType = mContentType.EqualsLiteral(SVG_MIMETYPE) ? - (PRUint16) imgIContainer::TYPE_VECTOR : (PRUint16) imgIContainer::TYPE_RASTER; + imgIContainer::TYPE_VECTOR : imgIContainer::TYPE_RASTER; /* set our mimetype as a property */ nsCOMPtr contentType(do_CreateInstance("@mozilla.org/supports-cstring;1")); diff --git a/modules/libpr0n/src/imgRequest.h b/modules/libpr0n/src/imgRequest.h index bf89781370f..0a517d47521 100644 --- a/modules/libpr0n/src/imgRequest.h +++ b/modules/libpr0n/src/imgRequest.h @@ -41,6 +41,7 @@ #ifndef imgRequest_h__ #define imgRequest_h__ +#include "imgIDecoder.h" #include "imgIDecoderObserver.h" #include "nsIChannelEventSink.h" diff --git a/modules/libpr0n/src/imgRequestProxy.h b/modules/libpr0n/src/imgRequestProxy.h index e7ca8a61879..f4616c39b4b 100644 --- a/modules/libpr0n/src/imgRequestProxy.h +++ b/modules/libpr0n/src/imgRequestProxy.h @@ -44,6 +44,7 @@ #include "imgIDecoderObserver.h" #include "nsISecurityInfoProvider.h" +#include "imgIDecoder.h" #include "nsIRequestObserver.h" #include "nsIChannel.h" #include "nsILoadGroup.h" diff --git a/modules/libpr0n/src/imgStatusTracker.cpp b/modules/libpr0n/src/imgStatusTracker.cpp index 75978798e46..c48ad0fa21f 100644 --- a/modules/libpr0n/src/imgStatusTracker.cpp +++ b/modules/libpr0n/src/imgStatusTracker.cpp @@ -223,8 +223,12 @@ imgStatusTracker::SyncNotify(imgRequestProxy* proxy) proxy->OnStartDecode(); // Send frame messages (OnStartFrame, OnDataAvailable, OnStopFrame) - if (mImage->GetNumFrames() > 0) { - PRUint32 frame = mImage->GetCurrentFrameIndex(); + PRUint32 nframes = 0; + mImage->GetNumFrames(&nframes); + + if (nframes > 0) { + PRUint32 frame; + mImage->GetCurrentFrameIndex(&frame); proxy->OnStartFrame(frame); // OnDataAvailable diff --git a/modules/libpr0n/src/imgTools.cpp b/modules/libpr0n/src/imgTools.cpp index 89becb09365..38b18301350 100644 --- a/modules/libpr0n/src/imgTools.cpp +++ b/modules/libpr0n/src/imgTools.cpp @@ -41,6 +41,7 @@ #include "nsString.h" #include "ImageErrors.h" #include "imgIContainer.h" +#include "imgIDecoder.h" #include "imgIEncoder.h" #include "imgIDecoderObserver.h" #include "imgIContainerObserver.h" diff --git a/toolkit/library/Makefile.in b/toolkit/library/Makefile.in index 426d8de26d6..a6a749ce8ab 100644 --- a/toolkit/library/Makefile.in +++ b/toolkit/library/Makefile.in @@ -240,12 +240,6 @@ ifeq ($(OS_ARCH),SunOS) EXTRA_DSO_LDOPTS += -lelf -ldemangle endif -ifeq ($(OS_ARCH),AIX) -ifdef HAVE_64BIT_OS -EXTRA_DSO_LDOPTS += -bbigtoc -endif -endif - ifeq ($(OS_ARCH),WINNT) OS_LIBS += $(call EXPAND_LIBNAME,shell32 ole32 uuid version winspool comdlg32 imm32 winmm wsock32 msimg32 shlwapi psapi) ifneq (,$(MOZ_DEBUG)$(NS_TRACE_MALLOC)) diff --git a/toolkit/library/libxul-config.mk b/toolkit/library/libxul-config.mk index 96cac2b73d7..4ee3d8de31e 100644 --- a/toolkit/library/libxul-config.mk +++ b/toolkit/library/libxul-config.mk @@ -293,8 +293,7 @@ STATIC_LIBS += gtkxtbin endif endif -# Platform-specific icon channel stuff - supported mostly-everywhere -ifneq (,$(filter beos windows os2 mac cocoa gtk2 qt,$(MOZ_WIDGET_TOOLKIT))) +ifneq (,$(filter icon,$(MOZ_IMG_DECODERS))) DEFINES += -DICON_DECODER COMPONENT_LIBS += imgicon endif