Backing out Bug 513681 and Bug 587371 for timeouts.

This commit is contained in:
Kyle Huey 2010-08-22 10:13:09 -04:00
parent b9bf8841c5
commit c5800700be
45 changed files with 1183 additions and 808 deletions

View File

@ -99,6 +99,7 @@ MOZ_DEBUG_DISABLE_DEFS = @MOZ_DEBUG_DISABLE_DEFS@
MOZ_DEBUG_FLAGS = @MOZ_DEBUG_FLAGS@ MOZ_DEBUG_FLAGS = @MOZ_DEBUG_FLAGS@
MOZ_DEBUG_LDFLAGS=@MOZ_DEBUG_LDFLAGS@ MOZ_DEBUG_LDFLAGS=@MOZ_DEBUG_LDFLAGS@
MOZ_EXTENSIONS = @MOZ_EXTENSIONS@ MOZ_EXTENSIONS = @MOZ_EXTENSIONS@
MOZ_IMG_DECODERS= @MOZ_IMG_DECODERS@
MOZ_IMG_ENCODERS= @MOZ_IMG_ENCODERS@ MOZ_IMG_ENCODERS= @MOZ_IMG_ENCODERS@
MOZ_JSDEBUGGER = @MOZ_JSDEBUGGER@ MOZ_JSDEBUGGER = @MOZ_JSDEBUGGER@
MOZ_IPC = @MOZ_IPC@ MOZ_IPC = @MOZ_IPC@

View File

@ -4876,6 +4876,7 @@ MOZ_ACTIVEX_SCRIPTING_SUPPORT=
MOZ_BRANDING_DIRECTORY= MOZ_BRANDING_DIRECTORY=
MOZ_OFFICIAL_BRANDING= MOZ_OFFICIAL_BRANDING=
MOZ_FEEDS=1 MOZ_FEEDS=1
MOZ_IMG_DECODERS_DEFAULT="png gif jpeg bmp icon"
MOZ_IMG_ENCODERS_DEFAULT="png jpeg" MOZ_IMG_ENCODERS_DEFAULT="png jpeg"
MOZ_INSTALLER=1 MOZ_INSTALLER=1
MOZ_IPC=1 MOZ_IPC=1
@ -6308,6 +6309,41 @@ for extension in $MOZ_EXTENSIONS; do
fi fi
done 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 ========================================================
dnl Image encoders dnl Image encoders
dnl ======================================================== dnl ========================================================
@ -6333,6 +6369,7 @@ done],
MOZ_IMG_ENCODERS="$MOZ_IMG_ENCODERS_DEFAULT") MOZ_IMG_ENCODERS="$MOZ_IMG_ENCODERS_DEFAULT")
dnl Remove dupes 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}` MOZ_IMG_ENCODERS=`${PERL} ${srcdir}/build/unix/uniq.pl ${MOZ_IMG_ENCODERS}`
dnl ======================================================== dnl ========================================================
@ -8689,6 +8726,7 @@ AC_SUBST(MOZ_DEBUG_FLAGS)
AC_SUBST(MOZ_DEBUG_LDFLAGS) AC_SUBST(MOZ_DEBUG_LDFLAGS)
AC_SUBST(WARNINGS_AS_ERRORS) AC_SUBST(WARNINGS_AS_ERRORS)
AC_SUBST(MOZ_EXTENSIONS) AC_SUBST(MOZ_EXTENSIONS)
AC_SUBST(MOZ_IMG_DECODERS)
AC_SUBST(MOZ_IMG_ENCODERS) AC_SUBST(MOZ_IMG_ENCODERS)
AC_SUBST(MOZ_JSDEBUGGER) AC_SUBST(MOZ_JSDEBUGGER)
AC_SUBST(MOZ_PLUGINS) AC_SUBST(MOZ_PLUGINS)

View File

@ -83,6 +83,7 @@ MOZ_DEBUG_DISABLE_DEFS = @MOZ_DEBUG_DISABLE_DEFS@
MOZ_DEBUG_FLAGS = @MOZ_DEBUG_FLAGS@ MOZ_DEBUG_FLAGS = @MOZ_DEBUG_FLAGS@
MOZ_DEBUG_LDFLAGS=@MOZ_DEBUG_LDFLAGS@ MOZ_DEBUG_LDFLAGS=@MOZ_DEBUG_LDFLAGS@
MOZ_EXTENSIONS = @MOZ_EXTENSIONS@ MOZ_EXTENSIONS = @MOZ_EXTENSIONS@
MOZ_IMG_DECODERS= @MOZ_IMG_DECODERS@
MOZ_IMG_ENCODERS= @MOZ_IMG_ENCODERS@ MOZ_IMG_ENCODERS= @MOZ_IMG_ENCODERS@
MOZ_JSDEBUGGER = @MOZ_JSDEBUGGER@ MOZ_JSDEBUGGER = @MOZ_JSDEBUGGER@
MOZ_LEAKY = @MOZ_LEAKY@ MOZ_LEAKY = @MOZ_LEAKY@

View File

@ -67,6 +67,7 @@ CSRCS = \
$(NULL) $(NULL)
# These files enable support for reading PNGs # These files enable support for reading PNGs
ifneq (,$(filter png,$(MOZ_IMG_DECODERS)))
CSRCS += \ CSRCS += \
pngpread.c \ pngpread.c \
pngread.c \ pngread.c \
@ -76,6 +77,7 @@ CSRCS += \
$(NULL) $(NULL)
DEFINES += -DMOZ_PNG_READ DEFINES += -DMOZ_PNG_READ
endif
# These files enable support for writing PNGs # These files enable support for writing PNGs
ifneq (,$(filter png,$(MOZ_IMG_ENCODERS))) ifneq (,$(filter png,$(MOZ_IMG_ENCODERS)))

View File

@ -44,7 +44,11 @@ include $(DEPTH)/config/autoconf.mk
MODULE = imglib2 MODULE = imglib2
DIRS = public src decoders DIRS = public src
ifdef MOZ_IMG_DECODERS
DIRS += decoders
endif
ifdef MOZ_IMG_ENCODERS ifdef MOZ_IMG_ENCODERS
DIRS += encoders DIRS += encoders

View File

@ -50,6 +50,7 @@ MODULE_NAME = nsImageLib2Module
GRE_MODULE = 1 GRE_MODULE = 1
LIBXUL_LIBRARY = 1 LIBXUL_LIBRARY = 1
CPPSRCS = \ CPPSRCS = \
nsImageModule.cpp \ nsImageModule.cpp \
$(NULL) $(NULL)
@ -57,13 +58,16 @@ CPPSRCS = \
LOCAL_INCLUDES = \ LOCAL_INCLUDES = \
-I. \ -I. \
-I$(srcdir)/../src \ -I$(srcdir)/../src \
$(foreach d,$(filter-out icon,$(MOZ_IMG_DECODERS)), \
-I$(srcdir)/../decoders/${d}) \
$(foreach d,$(MOZ_IMG_ENCODERS), \ $(foreach d,$(MOZ_IMG_ENCODERS), \
-I$(srcdir)/../encoders/${d}) \ -I$(srcdir)/../encoders/${d}) \
$(NULL) $(NULL)
SHARED_LIBRARY_LIBS = \ SHARED_LIBRARY_LIBS = \
../src/$(LIB_PREFIX)imglib2_s.$(LIB_SUFFIX) \ ../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), \ $(foreach d,$(MOZ_IMG_ENCODERS), \
../encoders/${d}/$(LIB_PREFIX)img${d}e_s.$(LIB_SUFFIX))\ ../encoders/${d}/$(LIB_PREFIX)img${d}e_s.$(LIB_SUFFIX))\
$(NULL) $(NULL)
@ -88,6 +92,8 @@ GARBAGE += _img_list nsImgBuildDefines.h
export:: export::
{ \ { \
$(foreach d,$(filter-out icon,$(MOZ_IMG_DECODERS)), \
echo "#define IMG_BUILD_DECODER_${d}" ; ) \
$(foreach d,$(MOZ_IMG_ENCODERS), \ $(foreach d,$(MOZ_IMG_ENCODERS), \
echo "#define IMG_BUILD_ENCODER_${d}" ; ) \ echo "#define IMG_BUILD_ENCODER_${d}" ; ) \
} > nsImgBuildDefines.tmp } > nsImgBuildDefines.tmp

View File

@ -39,6 +39,13 @@
#include "nsImgBuildDefines.h" #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 "nsIDeviceContext.h"
#include "mozilla/ModuleUtils.h" #include "mozilla/ModuleUtils.h"
#include "nsXPCOMCID.h" #include "nsXPCOMCID.h"
@ -60,6 +67,28 @@
#include "imgTools.h" #include "imgTools.h"
#include "DiscardTracker.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 #ifdef IMG_BUILD_ENCODER_png
// png // png
#include "nsPNGEncoder.h" #include "nsPNGEncoder.h"
@ -81,11 +110,31 @@ NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(imgLoader, Init)
NS_GENERIC_FACTORY_CONSTRUCTOR(imgRequestProxy) NS_GENERIC_FACTORY_CONSTRUCTOR(imgRequestProxy)
NS_GENERIC_FACTORY_CONSTRUCTOR(imgTools) 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 #ifdef IMG_BUILD_ENCODER_jpeg
// jpeg // jpeg
NS_GENERIC_FACTORY_CONSTRUCTOR(nsJPEGEncoder) NS_GENERIC_FACTORY_CONSTRUCTOR(nsJPEGEncoder)
#endif #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 #ifdef IMG_BUILD_ENCODER_png
// png // png
NS_GENERIC_FACTORY_CONSTRUCTOR(nsPNGEncoder) 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_IMGREQUESTPROXY_CID);
NS_DEFINE_NAMED_CID(NS_IMGTOOLS_CID); NS_DEFINE_NAMED_CID(NS_IMGTOOLS_CID);
NS_DEFINE_NAMED_CID(NS_RASTERIMAGE_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 #ifdef IMG_BUILD_ENCODER_jpeg
NS_DEFINE_NAMED_CID(NS_JPEGENCODER_CID); NS_DEFINE_NAMED_CID(NS_JPEGENCODER_CID);
#endif #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 #ifdef IMG_BUILD_ENCODER_png
NS_DEFINE_NAMED_CID(NS_PNGENCODER_CID); NS_DEFINE_NAMED_CID(NS_PNGENCODER_CID);
#endif #endif
@ -108,9 +171,23 @@ static const mozilla::Module::CIDEntry kImageCIDs[] = {
{ &kNS_IMGREQUESTPROXY_CID, false, NULL, imgRequestProxyConstructor, }, { &kNS_IMGREQUESTPROXY_CID, false, NULL, imgRequestProxyConstructor, },
{ &kNS_IMGTOOLS_CID, false, NULL, imgToolsConstructor, }, { &kNS_IMGTOOLS_CID, false, NULL, imgToolsConstructor, },
{ &kNS_RASTERIMAGE_CID, false, NULL, RasterImageConstructor, }, { &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 #ifdef IMG_BUILD_ENCODER_jpeg
{ &kNS_JPEGENCODER_CID, false, NULL, nsJPEGEncoderConstructor, }, { &kNS_JPEGENCODER_CID, false, NULL, nsJPEGEncoderConstructor, },
#endif #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 #ifdef IMG_BUILD_ENCODER_png
{ &kNS_PNGENCODER_CID, false, NULL, nsPNGEncoderConstructor, }, { &kNS_PNGENCODER_CID, false, NULL, nsPNGEncoderConstructor, },
#endif #endif
@ -123,9 +200,28 @@ static const mozilla::Module::ContractIDEntry kImageContracts[] = {
{ "@mozilla.org/image/request;1", &kNS_IMGREQUESTPROXY_CID }, { "@mozilla.org/image/request;1", &kNS_IMGREQUESTPROXY_CID },
{ "@mozilla.org/image/tools;1", &kNS_IMGTOOLS_CID }, { "@mozilla.org/image/tools;1", &kNS_IMGTOOLS_CID },
{ "@mozilla.org/image/rasterimage;1", &kNS_RASTERIMAGE_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 #ifdef IMG_BUILD_ENCODER_jpeg
{ "@mozilla.org/image/encoder;2?type=image/jpeg", &kNS_JPEGENCODER_CID }, { "@mozilla.org/image/encoder;2?type=image/jpeg", &kNS_JPEGENCODER_CID },
#endif #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 #ifdef IMG_BUILD_ENCODER_png
{ "@mozilla.org/image/encoder;2?type=image/png", &kNS_PNGENCODER_CID }, { "@mozilla.org/image/encoder;2?type=image/png", &kNS_PNGENCODER_CID },
#endif #endif
@ -133,17 +229,25 @@ static const mozilla::Module::ContractIDEntry kImageContracts[] = {
}; };
static const mozilla::Module::CategoryEntry kImageCategories[] = { static const mozilla::Module::CategoryEntry kImageCategories[] = {
#ifdef IMG_BUILD_DECODER_gif
{ "Gecko-Content-Viewers", "image/gif", "@mozilla.org/content/document-loader-factory;1" }, { "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/jpeg", "@mozilla.org/content/document-loader-factory;1" },
{ "Gecko-Content-Viewers", "image/pjpeg", "@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" }, { "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/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/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/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/x-ms-bmp", "@mozilla.org/content/document-loader-factory;1" },
{ "Gecko-Content-Viewers", "image/icon", "@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/png", "@mozilla.org/content/document-loader-factory;1" },
{ "Gecko-Content-Viewers", "image/x-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" }, { "content-sniffing-services", "@mozilla.org/image/loader;1", "@mozilla.org/image/loader;1" },
{ NULL } { NULL }
}; };

View File

@ -42,32 +42,7 @@ VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk include $(DEPTH)/config/autoconf.mk
MODULE = imgdecoders ifneq (,$(filter icon,$(MOZ_IMG_DECODERS)))
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 gtk2,$(MOZ_WIDGET_TOOLKIT))) ifneq (,$(filter gtk2,$(MOZ_WIDGET_TOOLKIT)))
DIRS = icon/gtk icon DIRS = icon/gtk icon
endif endif
@ -86,6 +61,9 @@ endif
ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT)) ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
DIRS = icon/mac icon DIRS = icon/mac icon
endif endif
endif # icon
DIRS += $(filter-out icon,$(MOZ_IMG_DECODERS))
include $(topsrcdir)/config/rules.mk include $(topsrcdir)/config/rules.mk

View File

@ -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 <cbiesinger@web.de>
#
# 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

View File

@ -46,13 +46,15 @@
#include "nsBMPDecoder.h" #include "nsBMPDecoder.h"
#include "nsIInputStream.h" #include "nsIInputStream.h"
#include "nsIComponentManager.h"
#include "RasterImage.h" #include "RasterImage.h"
#include "imgIContainerObserver.h" #include "imgIContainerObserver.h"
#include "nsIInterfaceRequestor.h"
#include "nsIInterfaceRequestorUtils.h"
#include "prlog.h" #include "prlog.h"
namespace mozilla { using namespace mozilla::imagelib;
namespace imagelib {
#ifdef PR_LOGGING #ifdef PR_LOGGING
PRLogModuleInfo *gBMPLog = PR_NewLogModule("BMPDecoder"); 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 LINE(row) ((mBIH.height < 0) ? (-mBIH.height - (row)) : ((row) - 1))
#define PIXEL_OFFSET(row, col) (LINE(row) * mBIH.width + col) #define PIXEL_OFFSET(row, col) (LINE(row) * mBIH.width + col)
NS_IMPL_ISUPPORTS1(nsBMPDecoder, imgIDecoder)
nsBMPDecoder::nsBMPDecoder() nsBMPDecoder::nsBMPDecoder()
{ {
mColors = nsnull; mColors = nsnull;
@ -81,27 +85,35 @@ nsBMPDecoder::~nsBMPDecoder()
free(mRow); free(mRow);
} }
nsresult NS_IMETHODIMP nsBMPDecoder::Init(imgIContainer *aImage,
nsBMPDecoder::InitInternal() 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<RasterImage*>(aImage);
mObserver = aObserver;
mFlags = aFlags;
// Fire OnStartDecode at init time to support bug 512435 // Fire OnStartDecode at init time to support bug 512435
if (!IsSizeDecode() && mObserver) if (!(mFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) && mObserver)
mObserver->OnStartDecode(nsnull); mObserver->OnStartDecode(nsnull);
return NS_OK; return NS_OK;
} }
nsresult NS_IMETHODIMP nsBMPDecoder::Close(PRUint32 aFlags)
nsBMPDecoder::FinishInternal()
{ {
// We should never make multiple frames PR_LOG(gBMPLog, PR_LOG_DEBUG, ("nsBMPDecoder::Close()\n"));
NS_ABORT_IF_FALSE(GetFrameCount() <= 1, "Multiple BMP frames?");
// Send notifications if appropriate // Send notifications if appropriate
if (!IsSizeDecode() && !mError && (GetFrameCount() == 1)) { if (!(mFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) &&
PostFrameStop(); !mError && !(aFlags & CLOSE_FLAG_DONTNOTIFY)) {
if (mObserver)
mObserver->OnStopFrame(nsnull, 0);
mImage->DecodingComplete(); mImage->DecodingComplete();
if (mObserver) { if (mObserver) {
mObserver->OnStopContainer(nsnull, mImage); mObserver->OnStopContainer(nsnull, mImage);
@ -111,6 +123,11 @@ nsBMPDecoder::FinishInternal()
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP nsBMPDecoder::Flush()
{
return NS_OK;
}
// ---------------------------------------- // ----------------------------------------
// Actual Data Processing // Actual Data Processing
// ---------------------------------------- // ----------------------------------------
@ -151,8 +168,8 @@ NS_METHOD nsBMPDecoder::CalcBitShift()
return NS_OK; return NS_OK;
} }
nsresult NS_IMETHODIMP
nsBMPDecoder::WriteInternal(const char* aBuffer, PRUint32 aCount) nsBMPDecoder::Write(const char* aBuffer, PRUint32 aCount)
{ {
// No forgiveness // No forgiveness
if (mError) if (mError)
@ -211,12 +228,17 @@ nsBMPDecoder::WriteInternal(const char* aBuffer, PRUint32 aCount)
PRUint32 real_height = (mBIH.height > 0) ? mBIH.height : -mBIH.height; PRUint32 real_height = (mBIH.height > 0) ? mBIH.height : -mBIH.height;
// Post our size to the superclass // Set the size and notify
PostSize(mBIH.width, real_height); 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. // we came for.
if (IsSizeDecode()) if (mFlags & imgIDecoder::DECODER_FLAG_HEADERONLY)
return NS_OK; return NS_OK;
// We're doing a real decode. // We're doing a real decode.
@ -279,8 +301,10 @@ nsBMPDecoder::WriteInternal(const char* aBuffer, PRUint32 aCount)
memset(mImageData, 0, imageLength); memset(mImageData, 0, imageLength);
} }
// Tell the superclass we're starting a frame if (mObserver) {
PostFrameStart(); mObserver->OnStartFrame(nsnull, 0);
NS_ENSURE_SUCCESS(rv, rv);
}
} }
PRUint8 bpc; // bytes per color PRUint8 bpc; // bytes per color
bpc = (mBFH.bihsize == OS2_BIH_LENGTH) ? 3 : 4; // OS/2 Bitmaps have no padding byte 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.colors = LITTLE_TO_NATIVE32(mBIH.colors);
mBIH.important_colors = LITTLE_TO_NATIVE32(mBIH.important_colors); mBIH.important_colors = LITTLE_TO_NATIVE32(mBIH.important_colors);
} }
} // namespace imagelib
} // namespace mozilla

View File

@ -41,12 +41,17 @@
#define _nsBMPDecoder_h #define _nsBMPDecoder_h
#include "nsAutoPtr.h" #include "nsAutoPtr.h"
#include "imgIDecoder.h"
#include "imgIDecoderObserver.h" #include "imgIDecoderObserver.h"
#include "gfxColor.h" #include "gfxColor.h"
#include "Decoder.h"
namespace mozilla { #define NS_BMPDECODER_CID \
namespace imagelib { { /* {78c61626-4d1f-4843-9364-4652d98ff6e1} */ \
0x78c61626, \
0x4d1f, \
0x4843, \
{ 0x93, 0x64, 0x46, 0x52, 0xd9, 0x8f, 0xf6, 0xe1 } \
}
struct BMPFILEHEADER { struct BMPFILEHEADER {
char signature[2]; // String "BM" 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 eRLEStateAbsoluteModePadded ///< As above, but another byte of data has to be read as padding
}; };
namespace mozilla {
namespace imagelib {
class RasterImage; class RasterImage;
} // namespace imagelib
} // namespace mozilla
/** /**
* Decoder for BMP-Files, as used by Windows and OS/2 * Decoder for BMP-Files, as used by Windows and OS/2
*/ */
class nsBMPDecoder : public Decoder class nsBMPDecoder : public imgIDecoder
{ {
public: public:
NS_DECL_ISUPPORTS
NS_DECL_IMGIDECODER
nsBMPDecoder(); nsBMPDecoder();
~nsBMPDecoder(); ~nsBMPDecoder();
virtual nsresult InitInternal();
virtual nsresult WriteInternal(const char* aBuffer, PRUint32 aCount);
virtual nsresult FinishInternal();
private: private:
/** Calculates the red-, green- and blueshift in mBitFields using /** Calculates the red-, green- and blueshift in mBitFields using
* the bitmasks from mBitFields */ * the bitmasks from mBitFields */
NS_METHOD CalcBitShift(); NS_METHOD CalcBitShift();
nsCOMPtr<imgIDecoderObserver> mObserver;
nsRefPtr<mozilla::imagelib::RasterImage> mImage;
PRUint32 mFlags;
PRUint32 mPos; PRUint32 mPos;
BMPFILEHEADER mBFH; BMPFILEHEADER mBFH;
@ -219,9 +231,5 @@ inline void Set4BitPixel(PRUint32*& aDecoded, PRUint8 aData,
} }
} }
} // namespace imagelib
} // namespace mozilla
#endif #endif

View File

@ -50,11 +50,15 @@
#include "RasterImage.h" #include "RasterImage.h"
#include "imgIContainerObserver.h" #include "imgIContainerObserver.h"
#include "nsIInterfaceRequestor.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsIProperties.h" #include "nsIProperties.h"
#include "nsISupportsPrimitives.h" #include "nsISupportsPrimitives.h"
namespace mozilla { using namespace mozilla::imagelib;
namespace imagelib {
NS_IMPL_ISUPPORTS1(nsICODecoder, imgIDecoder)
#define ICONCOUNTOFFSET 4 #define ICONCOUNTOFFSET 4
#define DIRENTRYOFFSET 6 #define DIRENTRYOFFSET 6
@ -84,6 +88,50 @@ nsICODecoder::nsICODecoder()
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<RasterImage*>(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; mPos = 0;
delete[] mColors; delete[] mColors;
@ -99,49 +147,17 @@ nsICODecoder::~nsICODecoder()
mRow = nsnull; mRow = nsnull;
} }
mDecodingAndMask = PR_FALSE; 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; return rv;
} }
nsresult NS_IMETHODIMP nsICODecoder::Flush()
nsICODecoder::WriteInternal(const char* aBuffer, PRUint32 aCount) {
return NS_OK;
}
NS_IMETHODIMP
nsICODecoder::Write(const char* aBuffer, PRUint32 aCount)
{ {
// No forgiveness // No forgiveness
if (mError) if (mError)
@ -235,8 +251,13 @@ nsICODecoder::WriteInternal(const char* aBuffer, PRUint32 aCount)
if (mPos == mImageOffset + BITMAPINFOSIZE) { if (mPos == mImageOffset + BITMAPINFOSIZE) {
ProcessInfoHeader(); ProcessInfoHeader();
PostSize(mDirEntry.mWidth, mDirEntry.mHeight); rv = mImage->SetSize(mDirEntry.mWidth, mDirEntry.mHeight);
if (IsSizeDecode()) 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; return NS_OK;
if (mBIH.bpp <= 8) { if (mBIH.bpp <= 8) {
@ -290,8 +311,10 @@ nsICODecoder::WriteInternal(const char* aBuffer, PRUint32 aCount)
gfxASurface::ImageFormatARGB32, (PRUint8**)&mImageData, &imageLength); gfxASurface::ImageFormatARGB32, (PRUint8**)&mImageData, &imageLength);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
// Tell the superclass we're starting a frame if (mObserver) {
PostFrameStart(); mObserver->OnStartFrame(nsnull, 0);
NS_ENSURE_SUCCESS(rv, rv);
}
} }
if (mColors && (mPos >= mImageOffset + BITMAPINFOSIZE) && if (mColors && (mPos >= mImageOffset + BITMAPINFOSIZE) &&
@ -532,6 +555,3 @@ void nsICODecoder::ProcessInfoHeader() {
mBIH.colors = LITTLE_TO_NATIVE32(mBIH.colors); mBIH.colors = LITTLE_TO_NATIVE32(mBIH.colors);
mBIH.important_colors = LITTLE_TO_NATIVE32(mBIH.important_colors); mBIH.important_colors = LITTLE_TO_NATIVE32(mBIH.important_colors);
} }
} // namespace imagelib
} // namespace mozilla

View File

@ -42,14 +42,20 @@
#define _nsICODecoder_h #define _nsICODecoder_h
#include "nsAutoPtr.h" #include "nsAutoPtr.h"
#include "Decoder.h" #include "imgIDecoder.h"
#include "imgIContainer.h"
#include "imgIDecoderObserver.h" #include "imgIDecoderObserver.h"
#include "nsBMPDecoder.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 mozilla {
namespace imagelib { namespace imagelib {
class RasterImage; class RasterImage;
} // namespace imagelib
} // namespace mozilla
struct IconDirEntry struct IconDirEntry
{ {
@ -69,17 +75,15 @@ struct IconDirEntry
PRUint32 mImageOffset; PRUint32 mImageOffset;
}; };
class nsICODecoder : public Decoder class nsICODecoder : public imgIDecoder
{ {
public: public:
NS_DECL_ISUPPORTS
NS_DECL_IMGIDECODER
nsICODecoder(); nsICODecoder();
virtual ~nsICODecoder(); virtual ~nsICODecoder();
virtual nsresult InitInternal();
virtual nsresult WriteInternal(const char* aBuffer, PRUint32 aCount);
virtual nsresult FinishInternal();
private: private:
// Private helper methods // Private helper methods
void ProcessDirEntry(IconDirEntry& aTarget); void ProcessDirEntry(IconDirEntry& aTarget);
@ -89,6 +93,11 @@ private:
PRUint32 CalcAlphaRowSize(); PRUint32 CalcAlphaRowSize();
private:
nsRefPtr<mozilla::imagelib::RasterImage> mImage;
nsCOMPtr<imgIDecoderObserver> mObserver;
PRUint32 mFlags;
PRUint32 mPos; PRUint32 mPos;
PRUint16 mNumIcons; PRUint16 mNumIcons;
PRUint16 mCurrIcon; PRUint16 mCurrIcon;
@ -115,7 +124,5 @@ private:
PRPackedBool mError; PRPackedBool mError;
}; };
} // namespace imagelib
} // namespace mozilla
#endif #endif

View File

@ -43,14 +43,27 @@
#include "RasterImage.h" #include "RasterImage.h"
#include "imgIContainerObserver.h" #include "imgIContainerObserver.h"
#include "nspr.h" #include "nspr.h"
#include "nsIComponentManager.h"
#include "nsRect.h" #include "nsRect.h"
#include "nsComponentManagerUtils.h"
#include "nsIInterfaceRequestorUtils.h"
#include "ImageErrors.h" #include "ImageErrors.h"
namespace mozilla { using namespace mozilla::imagelib;
namespace 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() : nsIconDecoder::nsIconDecoder() :
mImage(nsnull),
mObserver(nsnull),
mFlags(imgIDecoder::DECODER_FLAG_NONE),
mWidth(-1), mWidth(-1),
mHeight(-1), mHeight(-1),
mPixBytesRead(0), mPixBytesRead(0),
@ -66,29 +79,48 @@ nsIconDecoder::~nsIconDecoder()
{ } { }
nsresult /** imgIDecoder methods **/
nsIconDecoder::InitInternal()
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<RasterImage*>(aImage);
mObserver = aObserver;
mFlags = aFlags;
// Fire OnStartDecode at init time to support bug 512435 // Fire OnStartDecode at init time to support bug 512435
if (!IsSizeDecode() && mObserver) if (!(mFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) && mObserver)
mObserver->OnStartDecode(nsnull); mObserver->OnStartDecode(nsnull);
return NS_OK; return NS_OK;
} }
nsresult NS_IMETHODIMP nsIconDecoder::Close(PRUint32 aFlags)
nsIconDecoder::FinishInternal()
{ {
// If we haven't notified of completion yet for a full/success decode, we // If we haven't notified of completion yet for a full/success decode, we
// didn't finish. Notify in error mode // 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); NotifyDone(/* aSuccess = */ PR_FALSE);
mImage = nsnull;
return NS_OK; return NS_OK;
} }
nsresult NS_IMETHODIMP nsIconDecoder::Flush()
nsIconDecoder::WriteInternal(const char *aBuffer, PRUint32 aCount) {
return NS_OK;
}
NS_IMETHODIMP
nsIconDecoder::Write(const char *aBuffer, PRUint32 aCount)
{ {
nsresult rv; nsresult rv;
@ -119,11 +151,13 @@ nsIconDecoder::WriteInternal(const char *aBuffer, PRUint32 aCount)
// Grab the Height // Grab the Height
mHeight = (PRUint8)*aBuffer; mHeight = (PRUint8)*aBuffer;
// Post our size to the superclass // Set up the container and signal
PostSize(mWidth, mHeight); mImage->SetSize(mWidth, mHeight);
if (mObserver)
mObserver->OnStartContainer(nsnull, mImage);
// If We're doing a size decode, we're done // If We're doing a header-only decode, we're done
if (IsSizeDecode()) { if (mFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) {
mState = iconStateFinished; mState = iconStateFinished;
break; break;
} }
@ -136,9 +170,8 @@ nsIconDecoder::WriteInternal(const char *aBuffer, PRUint32 aCount)
mState = iconStateError; mState = iconStateError;
return rv; return rv;
} }
if (mObserver)
// Tell the superclass we're starting a frame mObserver->OnStartFrame(nsnull, 0);
PostFrameStart();
// Book Keeping // Book Keeping
aBuffer++; aBuffer++;
@ -198,7 +231,8 @@ nsIconDecoder::NotifyDone(PRBool aSuccess)
NS_ABORT_IF_FALSE(!mNotifiedDone, "Calling NotifyDone twice"); NS_ABORT_IF_FALSE(!mNotifiedDone, "Calling NotifyDone twice");
// Notify // Notify
PostFrameStop(); if (mObserver)
mObserver->OnStopFrame(nsnull, 0);
if (aSuccess) if (aSuccess)
mImage->DecodingComplete(); mImage->DecodingComplete();
if (mObserver) { if (mObserver) {
@ -211,5 +245,3 @@ nsIconDecoder::NotifyDone(PRBool aSuccess)
mNotifiedDone = PR_TRUE; mNotifiedDone = PR_TRUE;
} }
} // namespace imagelib
} // namespace mozilla

View File

@ -41,15 +41,26 @@
#ifndef nsIconDecoder_h__ #ifndef nsIconDecoder_h__
#define nsIconDecoder_h__ #define nsIconDecoder_h__
#include "Decoder.h" #include "imgIDecoder.h"
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
#include "imgIContainer.h"
#include "imgIDecoderObserver.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 mozilla {
namespace imagelib { namespace imagelib {
class RasterImage; class RasterImage;
} // namespace imagelib
} // namespace mozilla
////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////
// The icon decoder is a decoder specifically tailored for loading icons // 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: public:
NS_DECL_ISUPPORTS
NS_DECL_IMGIDECODER
nsIconDecoder(); nsIconDecoder();
virtual ~nsIconDecoder(); virtual ~nsIconDecoder();
virtual nsresult InitInternal(); nsRefPtr<mozilla::imagelib::RasterImage> mImage;
virtual nsresult WriteInternal(const char* aBuffer, PRUint32 aCount); nsCOMPtr<imgIDecoderObserver> mObserver;
virtual nsresult FinishInternal(); PRUint32 mFlags;
PRUint8 mWidth; PRUint8 mWidth;
PRUint8 mHeight; PRUint8 mHeight;
PRUint32 mPixBytesRead; PRUint32 mPixBytesRead;
@ -100,7 +112,5 @@ enum {
iconStateError = 4 iconStateError = 4
}; };
} // namespace imagelib
} // namespace mozilla
#endif // nsIconDecoder_h__ #endif // nsIconDecoder_h__

View File

@ -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)

View File

@ -75,8 +75,11 @@ mailing address.
#include <stddef.h> #include <stddef.h>
#include "prmem.h" #include "prmem.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsGIFDecoder2.h" #include "nsGIFDecoder2.h"
#include "nsIInputStream.h" #include "nsIInputStream.h"
#include "nsIComponentManager.h"
#include "imgIContainerObserver.h" #include "imgIContainerObserver.h"
#include "RasterImage.h" #include "RasterImage.h"
@ -84,9 +87,6 @@ mailing address.
#include "gfxPlatform.h" #include "gfxPlatform.h"
#include "qcms.h" #include "qcms.h"
namespace mozilla {
namespace imagelib {
/* /*
* GETN(n, s) requests at least 'n' bytes available from 'q', at start of state 's' * 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 */ /* Get a 16-bit value stored in little-endian format */
#define GETINT16(p) ((p)[1]<<8|(p)[0]) #define GETINT16(p) ((p)[1]<<8|(p)[0])
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
// GIF Decoder Implementation // GIF Decoder Implementation
// This is an adaptor between GIF2 and imgIDecoder
NS_IMPL_ISUPPORTS1(nsGIFDecoder2, imgIDecoder)
nsGIFDecoder2::nsGIFDecoder2() nsGIFDecoder2::nsGIFDecoder2()
: mCurrentRow(-1) : mCurrentRow(-1)
@ -126,14 +131,30 @@ nsGIFDecoder2::nsGIFDecoder2()
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<mozilla::imagelib::RasterImage*>(aImage);
mObserver = aObserver;
mFlags = aFlags;
// Fire OnStartDecode at init time to support bug 512435 // Fire OnStartDecode at init time to support bug 512435
if (!IsSizeDecode() && mObserver) if (!(mFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) && mObserver)
mObserver->OnStartDecode(nsnull); mObserver->OnStartDecode(nsnull);
// Start with the version (GIF89a|GIF87a) // Start with the version (GIF89a|GIF87a)
@ -143,16 +164,34 @@ nsGIFDecoder2::InitInternal()
return NS_OK; return NS_OK;
} }
nsresult
nsGIFDecoder2::FinishInternal() //******************************************************************************
/** nsIOutputStream methods **/
//******************************************************************************
//******************************************************************************
/* void close (); */
NS_IMETHODIMP nsGIFDecoder2::Close(PRUint32 aFlags)
{ {
// Send notifications if appropriate // Send notifications if appropriate
if (!IsSizeDecode() && !mError) { if (!(mFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) &&
!mError && !(aFlags & CLOSE_FLAG_DONTNOTIFY)) {
if (mCurrentFrame == mGIFStruct.images_decoded) if (mCurrentFrame == mGIFStruct.images_decoded)
EndImageFrame(); EndImageFrame();
EndGIF(/* aSuccess = */ PR_TRUE); EndGIF(/* aSuccess = */ PR_TRUE);
} }
PR_FREEIF(mGIFStruct.local_colormap);
mImageContainer = nsnull;
return NS_OK;
}
//******************************************************************************
/* void flush (); */
NS_IMETHODIMP nsGIFDecoder2::Flush()
{
return NS_OK; return NS_OK;
} }
@ -165,7 +204,7 @@ nsGIFDecoder2::FlushImageData(PRUint32 fromRow, PRUint32 rows)
nsIntRect r(mGIFStruct.x_offset, mGIFStruct.y_offset + fromRow, mGIFStruct.width, rows); nsIntRect r(mGIFStruct.x_offset, mGIFStruct.y_offset + fromRow, mGIFStruct.width, rows);
// Update image // Update image
nsresult rv = mImage->FrameUpdated(mGIFStruct.images_decoded, r); nsresult rv = mImageContainer->FrameUpdated(mGIFStruct.images_decoded, r);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
return rv; return rv;
} }
@ -173,7 +212,8 @@ nsGIFDecoder2::FlushImageData(PRUint32 fromRow, PRUint32 rows)
// Offset to the frame position // Offset to the frame position
// Only notify observer(s) for first frame // Only notify observer(s) for first frame
if (!mGIFStruct.images_decoded && mObserver) { if (!mGIFStruct.images_decoded && mObserver) {
PRUint32 imgCurFrame = mImage->GetCurrentFrameIndex(); PRUint32 imgCurFrame;
mImageContainer->GetCurrentFrameIndex(&imgCurFrame);
mObserver->OnDataAvailable(nsnull, imgCurFrame == PRUint32(mGIFStruct.images_decoded), &r); mObserver->OnDataAvailable(nsnull, imgCurFrame == PRUint32(mGIFStruct.images_decoded), &r);
} }
return NS_OK; return NS_OK;
@ -201,8 +241,10 @@ nsGIFDecoder2::FlushImageData()
return rv; 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 // Don't forgive previously flagged errors
if (mError) if (mError)
@ -226,11 +268,15 @@ nsGIFDecoder2::WriteInternal(const char *aBuffer, PRUint32 aCount)
// pretend that we're decoded. Otherwise, we set mError. // pretend that we're decoded. Otherwise, we set mError.
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
// Determine if we want to salvage the situation. // Determine if we want to salvage the situation
// If we're salvaging, send off notifications. 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 // 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). // 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); EndGIF(/* aSuccess = */ PR_TRUE);
} }
@ -254,10 +300,12 @@ void nsGIFDecoder2::BeginGIF()
mGIFOpen = PR_TRUE; 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 we're doing a header-only decode, we have what we came for
if (IsSizeDecode()) if (mFlags & imgIDecoder::DECODER_FLAG_HEADERONLY)
return; return;
} }
@ -268,15 +316,15 @@ void nsGIFDecoder2::EndGIF(PRBool aSuccess)
return; return;
if (aSuccess) if (aSuccess)
mImage->DecodingComplete(); mImageContainer->DecodingComplete();
if (mObserver) { if (mObserver) {
mObserver->OnStopContainer(nsnull, mImage); mObserver->OnStopContainer(nsnull, mImageContainer);
mObserver->OnStopDecode(nsnull, aSuccess ? NS_OK : NS_ERROR_FAILURE, mObserver->OnStopDecode(nsnull, aSuccess ? NS_OK : NS_ERROR_FAILURE,
nsnull); nsnull);
} }
mImage->SetLoopCount(mGIFStruct.loop_count); mImageContainer->SetLoopCount(mGIFStruct.loop_count);
mGIFOpen = PR_FALSE; mGIFOpen = PR_FALSE;
mEnded = PR_TRUE; mEnded = PR_TRUE;
@ -291,8 +339,9 @@ nsresult nsGIFDecoder2::BeginImageFrame(gfx_depth aDepth)
// and the placeholder will remain on the screen. (Bug 37589) // and the placeholder will remain on the screen. (Bug 37589)
if (mGIFStruct.y_offset > 0) { if (mGIFStruct.y_offset > 0) {
PRInt32 imgWidth; PRInt32 imgWidth;
mImage->GetWidth(&imgWidth); mImageContainer->GetWidth(&imgWidth);
PRUint32 imgCurFrame = mImage->GetCurrentFrameIndex(); PRUint32 imgCurFrame;
mImageContainer->GetCurrentFrameIndex(&imgCurFrame);
nsIntRect r(0, 0, imgWidth, mGIFStruct.y_offset); nsIntRect r(0, 0, imgWidth, mGIFStruct.y_offset);
if (mObserver) if (mObserver)
mObserver->OnDataAvailable(nsnull, mObserver->OnDataAvailable(nsnull,
@ -313,13 +362,13 @@ nsresult nsGIFDecoder2::BeginImageFrame(gfx_depth aDepth)
// and include transparency to allow for optimization of opaque images // and include transparency to allow for optimization of opaque images
if (mGIFStruct.images_decoded) { if (mGIFStruct.images_decoded) {
// Image data is stored with original depth and palette // Image data is stored with original depth and palette
rv = mImage->AppendPalettedFrame(mGIFStruct.x_offset, mGIFStruct.y_offset, rv = mImageContainer->AppendPalettedFrame(mGIFStruct.x_offset, mGIFStruct.y_offset,
mGIFStruct.width, mGIFStruct.height, mGIFStruct.width, mGIFStruct.height,
format, aDepth, &mImageData, &imageDataLength, format, aDepth, &mImageData, &imageDataLength,
&mColormap, &mColormapSize); &mColormap, &mColormapSize);
} else { } else {
// Regardless of depth of input, image is decoded into 24bit RGB // Regardless of depth of input, image is decoded into 24bit RGB
rv = mImage->AppendFrame(mGIFStruct.x_offset, mGIFStruct.y_offset, rv = mImageContainer->AppendFrame(mGIFStruct.x_offset, mGIFStruct.y_offset,
mGIFStruct.width, mGIFStruct.height, mGIFStruct.width, mGIFStruct.height,
format, &mImageData, &imageDataLength); format, &mImageData, &imageDataLength);
} }
@ -327,11 +376,11 @@ nsresult nsGIFDecoder2::BeginImageFrame(gfx_depth aDepth)
if (NS_FAILED(rv)) if (NS_FAILED(rv))
return rv; return rv;
mImage->SetFrameDisposalMethod(mGIFStruct.images_decoded, mImageContainer->SetFrameDisposalMethod(mGIFStruct.images_decoded,
mGIFStruct.disposal_method); mGIFStruct.disposal_method);
// Tell the superclass we're starting a frame if (mObserver)
PostFrameStart(); mObserver->OnStartFrame(nsnull, mGIFStruct.images_decoded);
mCurrentFrame = mGIFStruct.images_decoded; mCurrentFrame = mGIFStruct.images_decoded;
return NS_OK; return NS_OK;
@ -351,7 +400,8 @@ void nsGIFDecoder2::EndImageFrame()
// This will clear the remaining bits of the placeholder. (Bug 37589) // This will clear the remaining bits of the placeholder. (Bug 37589)
const PRUint32 realFrameHeight = mGIFStruct.height + mGIFStruct.y_offset; const PRUint32 realFrameHeight = mGIFStruct.height + mGIFStruct.y_offset;
if (realFrameHeight < mGIFStruct.screen_height) { if (realFrameHeight < mGIFStruct.screen_height) {
PRUint32 imgCurFrame = mImage->GetCurrentFrameIndex(); PRUint32 imgCurFrame;
mImageContainer->GetCurrentFrameIndex(&imgCurFrame);
nsIntRect r(0, realFrameHeight, nsIntRect r(0, realFrameHeight,
mGIFStruct.screen_width, mGIFStruct.screen_width,
mGIFStruct.screen_height - realFrameHeight); mGIFStruct.screen_height - realFrameHeight);
@ -362,12 +412,14 @@ void nsGIFDecoder2::EndImageFrame()
} }
// This transparency check is only valid for first frame // This transparency check is only valid for first frame
if (mGIFStruct.is_transparent && !mSawTransparency) { if (mGIFStruct.is_transparent && !mSawTransparency) {
mImage->SetFrameHasNoAlpha(mGIFStruct.images_decoded); mImageContainer->SetFrameHasNoAlpha(mGIFStruct.images_decoded);
} }
} }
mCurrentRow = mLastFlushedRow = -1; mCurrentRow = mLastFlushedRow = -1;
mCurrentPass = mLastFlushedPass = 0; mCurrentPass = mLastFlushedPass = 0;
PRUint32 curframe = mGIFStruct.images_decoded;
// Only add frame if we have any rows at all // Only add frame if we have any rows at all
if (mGIFStruct.rows_remaining != mGIFStruct.height) { if (mGIFStruct.rows_remaining != mGIFStruct.height) {
if (mGIFStruct.rows_remaining && mGIFStruct.images_decoded) { 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 // 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 // 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. // image frame decoded before we go off and try to display another frame.
mImage->SetFrameTimeout(mGIFStruct.images_decoded, mGIFStruct.delay_time); mImageContainer->SetFrameTimeout(mGIFStruct.images_decoded, mGIFStruct.delay_time);
mImage->EndFrameDecode(mGIFStruct.images_decoded); mImageContainer->EndFrameDecode(mGIFStruct.images_decoded);
} }
// Unconditionally increment images_decoded, because we unconditionally // Unconditionally increment images_decoded, because we unconditionally
// append frames in BeginImageFrame(). This ensures that images_decoded // 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. // even if some of them weren't decoded properly and thus are blank.
mGIFStruct.images_decoded++; mGIFStruct.images_decoded++;
// Tell the superclass we finished a frame if (mObserver)
PostFrameStop(); mObserver->OnStopFrame(nsnull, curframe);
// Reset the transparent pixel // Reset the transparent pixel
if (mOldColor) { if (mOldColor) {
@ -1014,8 +1066,8 @@ nsresult nsGIFDecoder2::GifWrite(const PRUint8 *buf, PRUint32 len)
// Create the image container with the right size. // Create the image container with the right size.
BeginGIF(); BeginGIF();
// If we were doing a size decode, we're done // If we were doing header-only, we're done
if (IsSizeDecode()) if (mFlags & imgIDecoder::DECODER_FLAG_HEADERONLY)
return NS_OK; return NS_OK;
} }
@ -1185,6 +1237,3 @@ nsresult nsGIFDecoder2::GifWrite(const PRUint8 *buf, PRUint32 len)
return NS_OK; return NS_OK;
} }
} // namespace imagelib
} // namespace mozilla

View File

@ -42,29 +42,38 @@
#define _nsGIFDecoder2_h #define _nsGIFDecoder2_h
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
#include "Decoder.h" #include "imgIDecoder.h"
#include "imgIContainer.h"
#include "imgIDecoderObserver.h" #include "imgIDecoderObserver.h"
#include "GIF2.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 mozilla {
namespace imagelib { namespace imagelib {
class RasterImage; class RasterImage;
} // namespace imagelib
} // namespace mozilla
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
// nsGIFDecoder2 Definition // nsGIFDecoder2 Definition
class nsGIFDecoder2 : public Decoder class nsGIFDecoder2 : public imgIDecoder
{ {
public: public:
NS_DECL_ISUPPORTS
NS_DECL_IMGIDECODER
nsGIFDecoder2(); nsGIFDecoder2();
~nsGIFDecoder2(); ~nsGIFDecoder2();
virtual nsresult InitInternal();
virtual nsresult WriteInternal(const char* aBuffer, PRUint32 aCount);
virtual nsresult FinishInternal();
private: private:
/* These functions will be called when the decoder has a decoded row, /* These functions will be called when the decoder has a decoded row,
* frame size information, etc. */ * frame size information, etc. */
@ -82,6 +91,11 @@ private:
inline int ClearCode() const { return 1 << mGIFStruct.datasize; } inline int ClearCode() const { return 1 << mGIFStruct.datasize; }
// XXXdholbert This member variable should probably be renamed to "mImage"
// for consistency with nsPNGDecoder
nsRefPtr<mozilla::imagelib::RasterImage> mImageContainer;
nsCOMPtr<imgIDecoderObserver> mObserver;
PRUint32 mFlags;
PRInt32 mCurrentRow; PRInt32 mCurrentRow;
PRInt32 mLastFlushedRow; PRInt32 mLastFlushedRow;
@ -105,7 +119,4 @@ private:
gif_struct mGIFStruct; gif_struct mGIFStruct;
}; };
} // namespace imagelib
} // namespace mozilla
#endif #endif

View File

@ -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

View File

@ -43,17 +43,21 @@
#include "imgIContainerObserver.h" #include "imgIContainerObserver.h"
#include "nsIComponentManager.h"
#include "nsIInputStream.h" #include "nsIInputStream.h"
#include "nspr.h" #include "nspr.h"
#include "nsCRT.h" #include "nsCRT.h"
#include "ImageLogging.h" #include "ImageLogging.h"
#include "nsIInterfaceRequestorUtils.h"
#include "gfxColor.h" #include "gfxColor.h"
#include "jerror.h" #include "jerror.h"
#include "gfxPlatform.h" #include "gfxPlatform.h"
using namespace mozilla::imagelib;
extern "C" { extern "C" {
#include "iccjpeg.h" #include "iccjpeg.h"
@ -71,10 +75,7 @@ ycc_rgb_convert_argb (j_decompress_ptr cinfo,
JSAMPARRAY output_buf, int num_rows); JSAMPARRAY output_buf, int num_rows);
} }
static void cmyk_convert_rgb(JSAMPROW row, JDIMENSION width); NS_IMPL_ISUPPORTS1(nsJPEGDecoder, imgIDecoder)
namespace mozilla {
namespace imagelib {
#if defined(PR_LOGGING) #if defined(PR_LOGGING)
PRLogModuleInfo *gJPEGlog = PR_NewLogModule("JPEGDecoder"); 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) term_source (j_decompress_ptr jd);
METHODDEF(void) my_error_exit (j_common_ptr cinfo); 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. */ /* Normal JFIF markers can't have more bytes than this. */
#define MAX_JPEG_MARKER_LENGTH (((PRUint32)1 << 16) - 1) #define MAX_JPEG_MARKER_LENGTH (((PRUint32)1 << 16) - 1)
@ -123,10 +126,6 @@ nsJPEGDecoder::nsJPEGDecoder()
nsJPEGDecoder::~nsJPEGDecoder() nsJPEGDecoder::~nsJPEGDecoder()
{ {
// Step 8: Release JPEG decompression object
mInfo.src = nsnull;
jpeg_destroy_decompress(&mInfo);
PR_FREEIF(mBackBuffer); PR_FREEIF(mBackBuffer);
if (mTransform) if (mTransform)
qcms_transform_release(mTransform); qcms_transform_release(mTransform);
@ -139,11 +138,25 @@ nsJPEGDecoder::~nsJPEGDecoder()
} }
nsresult /** imgIDecoder methods **/
nsJPEGDecoder::InitInternal()
/* 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<RasterImage*>(aImage);
mObserver = aObserver;
mFlags = aFlags;
/* Fire OnStartDecode at init time to support bug 512435 */ /* Fire OnStartDecode at init time to support bug 512435 */
if (!IsSizeDecode() && mObserver) if (!(mFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) && mObserver)
mObserver->OnStartDecode(nsnull); mObserver->OnStartDecode(nsnull);
/* We set up the normal JPEG error routines, then override error_exit. */ /* We set up the normal JPEG error routines, then override error_exit. */
@ -179,19 +192,17 @@ nsJPEGDecoder::InitInternal()
return NS_OK; 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. PR_LOG(gJPEGlog, PR_LOG_DEBUG,
* ("[this=%p] nsJPEGDecoder::Close\n", this));
* 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 /* Step 8: Release JPEG decompression object */
* we can get rid of it. mInfo.src = nsnull;
*/
if ((mState != JPEG_DONE && mState != JPEG_SINK_NON_JPEG_TRAILER) && jpeg_destroy_decompress(&mInfo);
(mState != JPEG_ERROR) &&
!IsSizeDecode())
this->Write(nsnull, 0);
/* If we already know we're in an error state, don't /* If we already know we're in an error state, don't
bother flagging another one here. */ 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, /* 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. */ * 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); NotifyDone(/* aSuccess = */ PR_FALSE);
/* Otherwise, no problems. */ /* Otherwise, no problems. */
return NS_OK; return NS_OK;
} }
nsresult /* void flush (); */
nsJPEGDecoder::WriteInternal(const char *aBuffer, PRUint32 aCount) 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; mSegment = (const JOCTET *)aBuffer;
mSegmentLen = aCount; mSegmentLen = aCount;
@ -249,11 +273,13 @@ nsJPEGDecoder::WriteInternal(const char *aBuffer, PRUint32 aCount)
return NS_OK; /* I/O suspension */ return NS_OK; /* I/O suspension */
} }
// Post our size to the superclass /* Set Width and height, and notify that the container is ready to go. */
PostSize(mInfo.image_width, mInfo.image_height); 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 we're doing a header-only decode, we're done. */
if (IsSizeDecode()) if (mFlags & imgIDecoder::DECODER_FLAG_HEADERONLY)
return NS_OK; return NS_OK;
/* We're doing a full decode. */ /* 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", (" JPEGDecoderAccounting: nsJPEGDecoder::Write -- created image frame with %ux%u pixels",
mInfo.image_width, mInfo.image_height)); mInfo.image_width, mInfo.image_height));
// Tell the superclass we're starting a frame if (mObserver)
PostFrameStart(); mObserver->OnStartFrame(nsnull, 0);
mState = JPEG_START_DECOMPRESS; mState = JPEG_START_DECOMPRESS;
} }
@ -568,7 +593,8 @@ nsJPEGDecoder::NotifyDone(PRBool aSuccess)
NS_ABORT_IF_FALSE(!mNotifiedDone, "calling NotifyDone twice!"); NS_ABORT_IF_FALSE(!mNotifiedDone, "calling NotifyDone twice!");
// Notify // Notify
PostFrameStop(); if (mObserver)
mObserver->OnStopFrame(nsnull, 0);
if (aSuccess) if (aSuccess)
mImage->DecodingComplete(); mImage->DecodingComplete();
if (mObserver) { if (mObserver) {
@ -902,9 +928,6 @@ term_source (j_decompress_ptr jd)
decoder->NotifyDone(/* aSuccess = */ PR_TRUE); decoder->NotifyDone(/* aSuccess = */ PR_TRUE);
} }
} // namespace imagelib
} // namespace mozilla
/**************** YCbCr -> Cairo's RGB24/ARGB32 conversion: most common case **************/ /**************** YCbCr -> Cairo's RGB24/ARGB32 conversion: most common case **************/

View File

@ -47,7 +47,7 @@
* we need to undefine the version from 'windows.h'. */ * we need to undefine the version from 'windows.h'. */
#undef INT32 #undef INT32
#include "Decoder.h" #include "imgIDecoder.h"
#include "nsAutoPtr.h" #include "nsAutoPtr.h"
@ -62,8 +62,13 @@ extern "C" {
#include <setjmp.h> #include <setjmp.h>
namespace mozilla { #define NS_JPEGDECODER_CID \
namespace imagelib { { /* 5871a422-1dd2-11b2-ab3f-e2e56be5da9c */ \
0x5871a422, \
0x1dd2, \
0x11b2, \
{0xab, 0x3f, 0xe2, 0xe5, 0x6b, 0xe5, 0xda, 0x9c} \
}
typedef struct { typedef struct {
struct jpeg_error_mgr pub; /* "public" fields for IJG library*/ struct jpeg_error_mgr pub; /* "public" fields for IJG library*/
@ -81,24 +86,31 @@ typedef enum {
JPEG_ERROR JPEG_ERROR
} jstate; } jstate;
namespace mozilla {
namespace imagelib {
class RasterImage; class RasterImage;
} // namespace imagelib
} // namespace mozilla
class nsJPEGDecoder : public Decoder class nsJPEGDecoder : public imgIDecoder
{ {
public: public:
NS_DECL_ISUPPORTS
NS_DECL_IMGIDECODER
nsJPEGDecoder(); nsJPEGDecoder();
virtual ~nsJPEGDecoder(); virtual ~nsJPEGDecoder();
virtual nsresult InitInternal();
virtual nsresult WriteInternal(const char* aBuffer, PRUint32 aCount);
virtual nsresult FinishInternal();
void NotifyDone(PRBool aSuccess); void NotifyDone(PRBool aSuccess);
protected: protected:
nsresult OutputScanlines(PRBool* suspend); nsresult OutputScanlines(PRBool* suspend);
public: public:
nsRefPtr<mozilla::imagelib::RasterImage> mImage;
nsCOMPtr<imgIDecoderObserver> mObserver;
PRUint32 mFlags;
PRUint8 *mImageData; PRUint8 *mImageData;
struct jpeg_decompress_struct mInfo; struct jpeg_decompress_struct mInfo;
@ -126,7 +138,4 @@ public:
PRPackedBool mNotifiedDone; PRPackedBool mNotifiedDone;
}; };
} // namespace imagelib
} // namespace mozilla
#endif // nsJPEGDecoder_h__ #endif // nsJPEGDecoder_h__

View File

@ -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

View File

@ -46,10 +46,12 @@
#include "nsMemory.h" #include "nsMemory.h"
#include "nsRect.h" #include "nsRect.h"
#include "nsIComponentManager.h"
#include "nsIInputStream.h" #include "nsIInputStream.h"
#include "RasterImage.h" #include "RasterImage.h"
#include "imgIContainerObserver.h" #include "imgIContainerObserver.h"
#include "nsIInterfaceRequestorUtils.h"
#include "gfxColor.h" #include "gfxColor.h"
#include "nsColor.h" #include "nsColor.h"
@ -59,9 +61,20 @@
#include "gfxPlatform.h" #include "gfxPlatform.h"
namespace mozilla { using namespace mozilla::imagelib;
namespace 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 #ifdef PR_LOGGING
static PRLogModuleInfo *gPNGLog = PR_NewLogModule("PNGDecoder"); static PRLogModuleInfo *gPNGLog = PR_NewLogModule("PNGDecoder");
static PRLogModuleInfo *gPNGDecoderAccountingLog = static PRLogModuleInfo *gPNGDecoderAccountingLog =
@ -71,7 +84,7 @@ static PRLogModuleInfo *gPNGDecoderAccountingLog =
/* limit image dimensions (bug #251381) */ /* limit image dimensions (bug #251381) */
#define MOZ_PNG_MAX_DIMENSION 1000000L #define MOZ_PNG_MAX_DIMENSION 1000000L
// For size decodes // For header-only decodes
#define WIDTH_OFFSET 16 #define WIDTH_OFFSET 16
#define HEIGHT_OFFSET (WIDTH_OFFSET + 4) #define HEIGHT_OFFSET (WIDTH_OFFSET + 4)
#define BYTES_NEEDED_FOR_DIMENSIONS (HEIGHT_OFFSET + 4) #define BYTES_NEEDED_FOR_DIMENSIONS (HEIGHT_OFFSET + 4)
@ -81,6 +94,9 @@ static PRLogModuleInfo *gPNGDecoderAccountingLog =
static const PRUint8 pngSignatureBytes[] = static const PRUint8 pngSignatureBytes[] =
{ 137, 80, 78, 71, 13, 10, 26, 10 }; { 137, 80, 78, 71, 13, 10, 26, 10 };
NS_IMPL_ISUPPORTS1(nsPNGDecoder, imgIDecoder)
nsPNGDecoder::nsPNGDecoder() : nsPNGDecoder::nsPNGDecoder() :
mPNG(nsnull), mInfo(nsnull), mPNG(nsnull), mInfo(nsnull),
mCMSLine(nsnull), interlacebuf(nsnull), mCMSLine(nsnull), interlacebuf(nsnull),
@ -93,8 +109,6 @@ nsPNGDecoder::nsPNGDecoder() :
nsPNGDecoder::~nsPNGDecoder() nsPNGDecoder::~nsPNGDecoder()
{ {
if (mPNG)
png_destroy_read_struct(&mPNG, mInfo ? &mInfo : NULL, NULL);
if (mCMSLine) if (mCMSLine)
nsMemory::Free(mCMSLine); nsMemory::Free(mCMSLine);
if (interlacebuf) if (interlacebuf)
@ -131,8 +145,11 @@ void nsPNGDecoder::CreateFrame(png_uint_32 x_offset, png_uint_32 y_offset,
SetAnimFrameInfo(); SetAnimFrameInfo();
#endif #endif
// Tell the superclass we're starting a frame PRUint32 numFrames = 0;
PostFrameStart(); mImage->GetNumFrames(&numFrames);
if (mObserver)
mObserver->OnStartFrame(nsnull, numFrames - 1);
PR_LOG(gPNGDecoderAccountingLog, PR_LOG_DEBUG, PR_LOG(gPNGDecoderAccountingLog, PR_LOG_DEBUG,
("PNGDecoderAccounting: nsPNGDecoder::CreateFrame -- created " ("PNGDecoderAccounting: nsPNGDecoder::CreateFrame -- created "
@ -170,7 +187,8 @@ void nsPNGDecoder::SetAnimFrameInfo()
(static_cast<PRFloat64>(delay_num) * 1000 / delay_den); (static_cast<PRFloat64>(delay_num) * 1000 / delay_den);
} }
PRUint32 numFrames = mImage->GetNumFrames(); PRUint32 numFrames = 0;
mImage->GetNumFrames(&numFrames);
mImage->SetFrameTimeout(numFrames - 1, timeout); mImage->SetFrameTimeout(numFrames - 1, timeout);
@ -196,7 +214,7 @@ void nsPNGDecoder::EndImageFrame()
{ {
PRUint32 numFrames = 1; PRUint32 numFrames = 1;
#ifdef PNG_APNG_SUPPORTED #ifdef PNG_APNG_SUPPORTED
numFrames = mImage->GetNumFrames(); mImage->GetNumFrames(&numFrames);
// We can't use mPNG->num_frames_read as it may be one ahead. // We can't use mPNG->num_frames_read as it may be one ahead.
if (numFrames > 1) { if (numFrames > 1) {
@ -208,7 +226,8 @@ void nsPNGDecoder::EndImageFrame()
mError = PR_TRUE; mError = PR_TRUE;
// allow the call out to the observers. // allow the call out to the observers.
} }
PRUint32 curFrame = mImage->GetCurrentFrameIndex(); PRUint32 curFrame;
mImage->GetCurrentFrameIndex(&curFrame);
if (mObserver) if (mObserver)
mObserver->OnDataAvailable(nsnull, curFrame == numFrames - 1, mObserver->OnDataAvailable(nsnull, curFrame == numFrames - 1,
&mFrameRect); &mFrameRect);
@ -216,13 +235,20 @@ void nsPNGDecoder::EndImageFrame()
#endif #endif
mImage->EndFrameDecode(numFrames - 1); 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 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
static png_byte color_chunks[]= static png_byte color_chunks[]=
{ 99, 72, 82, 77, '\0', /* cHRM */ { 99, 72, 82, 77, '\0', /* cHRM */
@ -241,13 +267,19 @@ nsPNGDecoder::InitInternal()
116, 73, 77, 69, '\0', /* tIME */ 116, 73, 77, 69, '\0', /* tIME */
122, 84, 88, 116, '\0'}; /* zTXt */ 122, 84, 88, 116, '\0'}; /* zTXt */
#endif #endif
NS_ABORT_IF_FALSE(aImage->GetType() == imgIContainer::TYPE_RASTER,
"wrong type of imgIContainer for decoding into");
mImage = static_cast<RasterImage*>(aImage);
mObserver = aObserver;
mFlags = aFlags;
// Fire OnStartDecode at init time to support bug 512435 // Fire OnStartDecode at init time to support bug 512435
if (!IsSizeDecode() && mObserver) if (!(mFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) && mObserver)
mObserver->OnStartDecode(nsnull); mObserver->OnStartDecode(nsnull);
// For size decodes, we only need a small buffer // For header-only decodes, we only need a small buffer
if (IsSizeDecode()) { if (mFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) {
mHeaderBuf = (PRUint8 *)nsMemory::Alloc(BYTES_NEEDED_FOR_DIMENSIONS); mHeaderBuf = (PRUint8 *)nsMemory::Alloc(BYTES_NEEDED_FOR_DIMENSIONS);
if (!mHeaderBuf) if (!mHeaderBuf)
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
@ -260,8 +292,8 @@ nsPNGDecoder::InitInternal()
/* Always decode to 24 bit pixdepth */ /* Always decode to 24 bit pixdepth */
mPNG = png_create_read_struct(PNG_LIBPNG_VER_STRING, mPNG = png_create_read_struct(PNG_LIBPNG_VER_STRING,
NULL, nsPNGDecoder::error_callback, NULL, error_callback,
nsPNGDecoder::warning_callback); warning_callback);
if (!mPNG) if (!mPNG)
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
@ -287,30 +319,40 @@ nsPNGDecoder::InitInternal()
/* use this as libpng "progressive pointer" (retrieve in callbacks) */ /* use this as libpng "progressive pointer" (retrieve in callbacks) */
png_set_progressive_read_fn(mPNG, static_cast<png_voidp>(this), png_set_progressive_read_fn(mPNG, static_cast<png_voidp>(this),
nsPNGDecoder::info_callback, info_callback, row_callback, end_callback);
nsPNGDecoder::row_callback,
nsPNGDecoder::end_callback);
return NS_OK; return NS_OK;
} }
nsresult /* void close (); */
nsPNGDecoder::FinishInternal() 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, // 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. // 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); NotifyDone(/* aSuccess = */ PR_FALSE);
mImage = nsnull;
return NS_OK; return NS_OK;
} }
nsresult /* void flush (); */
nsPNGDecoder::WriteInternal(const char *aBuffer, PRUint32 aCount) 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 // We use gotos, so we need to declare variables here
nsresult rv;
PRUint32 width = 0; PRUint32 width = 0;
PRUint32 height = 0; PRUint32 height = 0;
@ -319,7 +361,7 @@ nsPNGDecoder::WriteInternal(const char *aBuffer, PRUint32 aCount)
goto error; goto error;
// If we only want width/height, we don't need to go through libpng // 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? // Are we done?
if (mHeaderBytesRead == BYTES_NEEDED_FOR_DIMENSIONS) 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)) if ((width > MOZ_PNG_MAX_DIMENSION) || (height > MOZ_PNG_MAX_DIMENSION))
goto error; goto error;
// Post our size to the superclass // Set the size
PostSize(width, height); 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 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 */ /* int number_passes; NOT USED */
png_uint_32 width, height; png_uint_32 width, height;
@ -528,6 +576,7 @@ nsPNGDecoder::info_callback(png_structp png_ptr, png_infop info_ptr)
nsPNGDecoder *decoder = nsPNGDecoder *decoder =
static_cast<nsPNGDecoder*>(png_get_progressive_ptr(png_ptr)); static_cast<nsPNGDecoder*>(png_get_progressive_ptr(png_ptr));
nsresult rv;
/* always decode to 24-bit RGB or 32-bit RGBA */ /* always decode to 24-bit RGB or 32-bit RGBA */
png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, 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) if (width > MOZ_PNG_MAX_DIMENSION || height > MOZ_PNG_MAX_DIMENSION)
longjmp(png_jmpbuf(decoder->mPNG), 1); longjmp(png_jmpbuf(decoder->mPNG), 1);
// Post our size to the superclass // Set the size and notify that the container is set up
decoder->PostSize(width, height); 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) if (color_type == PNG_COLOR_TYPE_PALETTE)
png_set_expand(png_ptr); png_set_expand(png_ptr);
@ -648,7 +703,7 @@ nsPNGDecoder::info_callback(png_structp png_ptr, png_infop info_ptr)
#ifdef PNG_APNG_SUPPORTED #ifdef PNG_APNG_SUPPORTED
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_acTL)) 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)) { if (png_get_first_frame_is_hidden(png_ptr, info_ptr)) {
decoder->mFrameIsHidden = PR_TRUE; decoder->mFrameIsHidden = PR_TRUE;
@ -689,7 +744,7 @@ nsPNGDecoder::info_callback(png_structp png_ptr, png_infop info_ptr)
} }
void void
nsPNGDecoder::row_callback(png_structp png_ptr, png_bytep new_row, row_callback(png_structp png_ptr, png_bytep new_row,
png_uint_32 row_num, int pass) png_uint_32 row_num, int pass)
{ {
/* libpng comments: /* libpng comments:
@ -726,7 +781,7 @@ nsPNGDecoder::row_callback(png_structp png_ptr, png_bytep new_row,
if (decoder->mFrameIsHidden) if (decoder->mFrameIsHidden)
return; return;
if (row_num >= (png_uint_32) decoder->mFrameRect.height) if (row_num >= decoder->mFrameRect.height)
return; return;
if (new_row) { if (new_row) {
@ -806,7 +861,8 @@ nsPNGDecoder::row_callback(png_structp png_ptr, png_bytep new_row,
if (!rowHasNoAlpha) if (!rowHasNoAlpha)
decoder->mFrameHasNoAlpha = PR_FALSE; decoder->mFrameHasNoAlpha = PR_FALSE;
PRUint32 numFrames = decoder->mImage->GetNumFrames(); PRUint32 numFrames = 0;
decoder->mImage->GetNumFrames(&numFrames);
if (numFrames <= 1) { if (numFrames <= 1) {
// Only do incremental image display for the first frame // Only do incremental image display for the first frame
nsIntRect r(0, row_num, width, 1); 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 */ decoder->mError = PR_TRUE; /* bail */
return; return;
} }
PRUint32 curFrame = decoder->mImage->GetCurrentFrameIndex(); PRUint32 curFrame;
decoder->mImage->GetCurrentFrameIndex(&curFrame);
if (decoder->mObserver) if (decoder->mObserver)
decoder->mObserver->OnDataAvailable(nsnull, decoder->mObserver->OnDataAvailable(nsnull,
curFrame == numFrames - 1, &r); 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 // got the header of a new frame that's coming
void 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 #ifdef PNG_APNG_SUPPORTED
png_uint_32 x_offset, y_offset; 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 void
nsPNGDecoder::end_callback(png_structp png_ptr, png_infop info_ptr) end_callback(png_structp png_ptr, png_infop info_ptr)
{ {
/* libpng comments: /* libpng comments:
* *
@ -882,7 +939,7 @@ nsPNGDecoder::end_callback(png_structp png_ptr, png_infop info_ptr)
void 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)); PR_LOG(gPNGLog, PR_LOG_ERROR, ("libpng error: %s\n", error_msg));
longjmp(png_jmpbuf(png_ptr), 1); longjmp(png_jmpbuf(png_ptr), 1);
@ -890,10 +947,8 @@ nsPNGDecoder::error_callback(png_structp png_ptr, png_const_charp error_msg)
void 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)); PR_LOG(gPNGLog, PR_LOG_WARNING, ("libpng warning: %s\n", warning_msg));
} }
} // namespace imagelib
} // namespace mozilla

View File

@ -41,8 +41,9 @@
#ifndef nsPNGDecoder_h__ #ifndef nsPNGDecoder_h__
#define nsPNGDecoder_h__ #define nsPNGDecoder_h__
#include "Decoder.h" #include "imgIDecoder.h"
#include "imgIContainer.h"
#include "imgIDecoderObserver.h" #include "imgIDecoderObserver.h"
#include "gfxASurface.h" #include "gfxASurface.h"
@ -52,20 +53,29 @@
#include "qcms.h" #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 mozilla {
namespace imagelib { namespace imagelib {
class RasterImage; class RasterImage;
} // namespace imagelib
} // namespace mozilla
class nsPNGDecoder : public Decoder class nsPNGDecoder : public imgIDecoder
{ {
public: public:
NS_DECL_ISUPPORTS
NS_DECL_IMGIDECODER
nsPNGDecoder(); nsPNGDecoder();
virtual ~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, void CreateFrame(png_uint_32 x_offset, png_uint_32 y_offset,
PRInt32 width, PRInt32 height, PRInt32 width, PRInt32 height,
gfxASurface::gfxImageFormat format); gfxASurface::gfxImageFormat format);
@ -75,6 +85,10 @@ public:
void NotifyDone(PRBool aSuccess); void NotifyDone(PRBool aSuccess);
public: public:
nsRefPtr<mozilla::imagelib::RasterImage> mImage;
nsCOMPtr<imgIDecoderObserver> mObserver;
PRUint32 mFlags;
png_structp mPNG; png_structp mPNG;
png_infop mInfo; png_infop mInfo;
nsIntRect mFrameRect; nsIntRect mFrameRect;
@ -86,7 +100,7 @@ public:
gfxASurface::gfxImageFormat format; gfxASurface::gfxImageFormat format;
// For size decodes // For header-only decodes
PRUint8 *mHeaderBuf; PRUint8 *mHeaderBuf;
PRUint32 mHeaderBytesRead; PRUint32 mHeaderBytesRead;
@ -95,27 +109,6 @@ public:
PRPackedBool mFrameHasNoAlpha; PRPackedBool mFrameHasNoAlpha;
PRPackedBool mFrameIsHidden; PRPackedBool mFrameIsHidden;
PRPackedBool mNotifiedDone; 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__ #endif // nsPNGDecoder_h__

View File

@ -53,7 +53,9 @@ ifneq (,$(filter png,$(MOZ_IMG_ENCODERS)))
DEFINES += -DMOZ_PNG_WRITE DEFINES += -DMOZ_PNG_WRITE
endif endif
ifneq (,$(filter png,$(MOZ_IMG_DECODERS)))
DEFINES += -DMOZ_PNG_READ DEFINES += -DMOZ_PNG_READ
endif
CPPSRCS = nsPNGEncoder.cpp CPPSRCS = nsPNGEncoder.cpp

View File

@ -51,6 +51,7 @@ XPIDLSRCS = \
imgICache.idl \ imgICache.idl \
imgIContainer.idl \ imgIContainer.idl \
imgIContainerObserver.idl \ imgIContainerObserver.idl \
imgIDecoder.idl \
imgIDecoderObserver.idl \ imgIDecoderObserver.idl \
imgIEncoder.idl \ imgIEncoder.idl \
imgILoader.idl \ imgILoader.idl \

View File

@ -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 <pavlov@netscape.com>
* Bobby Holley <bobbyholley@gmail.com>
*
* 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 <pavlov@netscape.com>
* @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);
};

View File

@ -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

View File

@ -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 <bobbyholley@gmail.com>
*
* 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<RasterImage> mImage;
nsCOMPtr<imgIDecoderObserver> 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_

View File

@ -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 imagelib
} // namespace mozilla } // namespace mozilla

View File

@ -94,30 +94,18 @@ public:
* The index of the current frame that would be drawn if the image was to be * The index of the current frame that would be drawn if the image was to be
* drawn now. * drawn now.
*/ */
virtual PRUint32 GetCurrentFrameIndex() = 0; virtual nsresult GetCurrentFrameIndex(PRUint32* aCurrentFrameIdx) = 0;
/** /**
* The total number of frames in this image. * 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. * The size, in bytes, occupied by the significant data portions of the image.
* This includes both compressed source data and decoded frames. * This includes both compressed source data and decoded frames.
*/ */
virtual PRUint32 GetDataSize() = 0; virtual nsresult GetDataSize(PRUint32* aDataSize) = 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);
protected: protected:
Image(); Image();

View File

@ -52,7 +52,6 @@ LIBXUL_LIBRARY = 1
CPPSRCS = \ CPPSRCS = \
Image.cpp \ Image.cpp \
Decoder.cpp \
DiscardTracker.cpp \ DiscardTracker.cpp \
RasterImage.cpp \ RasterImage.cpp \
imgFrame.cpp \ imgFrame.cpp \
@ -63,9 +62,6 @@ CPPSRCS = \
imgStatusTracker.cpp \ imgStatusTracker.cpp \
$(NULL) $(NULL)
# We need to instantiate the decoders
LOCAL_INCLUDES += -I$(topsrcdir)/modules/libpr0n/decoders
include $(topsrcdir)/config/rules.mk include $(topsrcdir)/config/rules.mk
# Because imgFrame.cpp includes "cairo.h" # Because imgFrame.cpp includes "cairo.h"

View File

@ -45,7 +45,7 @@
#include "nsComponentManagerUtils.h" #include "nsComponentManagerUtils.h"
#include "imgIContainerObserver.h" #include "imgIContainerObserver.h"
#include "ImageErrors.h" #include "ImageErrors.h"
#include "Decoder.h" #include "imgIDecoder.h"
#include "imgIDecoderObserver.h" #include "imgIDecoderObserver.h"
#include "RasterImage.h" #include "RasterImage.h"
#include "nsIInterfaceRequestor.h" #include "nsIInterfaceRequestor.h"
@ -58,13 +58,6 @@
#include "nsTime.h" #include "nsTime.h"
#include "ImageLogging.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" #include "gfxContext.h"
using namespace mozilla::imagelib; using namespace mozilla::imagelib;
@ -159,6 +152,7 @@ RasterImage::RasterImage() :
mDecoder(nsnull), mDecoder(nsnull),
mWorker(nsnull), mWorker(nsnull),
mBytesDecoded(0), mBytesDecoded(0),
mDecoderFlags(imgIDecoder::DECODER_FLAG_NONE),
mHasSize(PR_FALSE), mHasSize(PR_FALSE),
mDecodeOnDraw(PR_FALSE), mDecodeOnDraw(PR_FALSE),
mMultipart(PR_FALSE), mMultipart(PR_FALSE),
@ -260,12 +254,16 @@ RasterImage::Init(imgIDecoderObserver *aObserver,
return NS_OK; 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 // Instantiate the decoder
// nsresult rv = InitDecoder(dFlags);
// 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);
CONTAINER_ENSURE_SUCCESS(rv); CONTAINER_ENSURE_SUCCESS(rv);
// Mark us as initialized // Mark us as initialized
@ -493,16 +491,30 @@ RasterImage::GetCurrentFrameRect(nsIntRect &aRect)
return NS_OK; return NS_OK;
} }
PRUint32 nsresult
RasterImage::GetCurrentFrameIndex() RasterImage::GetCurrentFrameIndex(PRUint32 *aCurrentFrameIdx)
{ {
return GetCurrentImgFrameIndex(); if (mError)
return NS_ERROR_FAILURE;
NS_ENSURE_ARG_POINTER(aCurrentFrameIdx);
*aCurrentFrameIdx = GetCurrentImgFrameIndex();
return NS_OK;
} }
PRUint32 nsresult
RasterImage::GetNumFrames() 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; return rv;
} }
PRUint32 nsresult
RasterImage::GetDataSize() RasterImage::GetDataSize(PRUint32 *_retval)
{ {
if (mError) if (mError)
return 0; return NS_ERROR_FAILURE;
NS_ENSURE_ARG_POINTER(_retval);
// Start with 0 // Start with 0
PRUint32 size = 0; *_retval = 0;
// Account for any compressed source data // Account for any compressed source data
size += GetSourceDataSize(); *_retval += GetSourceDataSize();
NS_ABORT_IF_FALSE(StoringSourceData() || (size == 0), NS_ABORT_IF_FALSE(StoringSourceData() || (*_retval == 0),
"Non-zero source data size when we aren't storing it?"); "Non-zero source data size when we aren't storing it?");
// Account for any uncompressed frames // Account for any uncompressed frames
size += GetDecodedDataSize(); *_retval += GetDecodedDataSize();
return NS_OK;
return size;
} }
PRUint32 PRUint32
@ -1391,7 +1404,7 @@ RasterImage::NewSourceData()
// We're decode-on-load here. Open up a new decoder just like what happens when // We're decode-on-load here. Open up a new decoder just like what happens when
// we call Init() for decode-on-load images. // we call Init() for decode-on-load images.
rv = InitDecoder(/* aDoSizeDecode = */ false); rv = InitDecoder(imgIDecoder::DECODER_FLAG_NONE);
CONTAINER_ENSURE_SUCCESS(rv); CONTAINER_ENSURE_SUCCESS(rv);
return NS_OK; return NS_OK;
@ -2098,7 +2111,7 @@ RasterImage::StoringSourceData() {
// Sets up a decoder for this image. It is an error to call this function // 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). // when decoding is already in process (ie - when mDecoder is non-null).
nsresult nsresult
RasterImage::InitDecoder(bool aDoSizeDecode) RasterImage::InitDecoder(PRUint32 dFlags)
{ {
// Ensure that the decoder is not already initialized // Ensure that the decoder is not already initialized
NS_ABORT_IF_FALSE(!mDecoder, "Calling InitDecoder() while already decoding!"); 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 // Since we're not decoded, we should not have a discard timer active
NS_ABORT_IF_FALSE(!DiscardingActive(), "Discard Timer active in InitDecoder()!"); NS_ABORT_IF_FALSE(!DiscardingActive(), "Discard Timer active in InitDecoder()!");
// Figure out which decoder we want // Find and instantiate the decoder
eDecoderType type = GetDecoderType(mSourceDataMimeType.get()); nsCAutoString decoderCID(NS_LITERAL_CSTRING("@mozilla.org/image/decoder;3?type=") +
CONTAINER_ENSURE_TRUE(type != eDecoderType_unknown, NS_IMAGELIB_ERROR_NO_DECODER); mSourceDataMimeType);
mDecoder = do_CreateInstance(decoderCID.get());
CONTAINER_ENSURE_TRUE(mDecoder, NS_IMAGELIB_ERROR_NO_DECODER);
// Instantiate the appropriate decoder // Store the flags for this decoder
switch (type) { mDecoderFlags = dFlags;
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!");
}
// Initialize the decoder // Initialize the decoder
nsCOMPtr<imgIDecoderObserver> observer(do_QueryReferent(mObserver)); nsCOMPtr<imgIDecoderObserver> observer(do_QueryReferent(mObserver));
mDecoder->SetSizeDecode(aDoSizeDecode); nsresult result = mDecoder->Init(this, observer, dFlags);
nsresult result = mDecoder->Init(this, observer);
CONTAINER_ENSURE_SUCCESS(result); CONTAINER_ENSURE_SUCCESS(result);
// Create a decode worker // Create a decode worker
@ -2168,16 +2161,30 @@ RasterImage::ShutdownDecoder(eShutdownIntent aIntent)
// Ensure that the decoder is initialized // Ensure that the decoder is initialized
NS_ABORT_IF_FALSE(mDecoder, "Calling ShutdownDecoder() with no active decoder!"); 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 nsresult rv;
bool wasSizeDecode = mDecoder->IsSizeDecode();
// If we're not in error mode, finalize the decoder // If we're "done" _and_ it's a full decode, flush
nsresult rv = NS_OK; if ((aIntent == eShutdownIntent_Done) &&
if (aIntent != eShutdownIntent_Error) { !(mDecoderFlags && imgIDecoder::DECODER_FLAG_HEADERONLY)) {
mInDecoder = PR_TRUE; mInDecoder = PR_TRUE;
rv = mDecoder->Finish(); rv = mDecoder->Flush();
mInDecoder = PR_FALSE; 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 // null out the decoder, _then_ check for errors on the close (otherwise the
// error routine might re-invoke ShutdownDecoder) // error routine might re-invoke ShutdownDecoder)
@ -2193,15 +2200,18 @@ RasterImage::ShutdownDecoder(eShutdownIntent aIntent)
// We just shut down the decoder. If we didn't get what we want, but expected // We just shut down the decoder. If we didn't get what we want, but expected
// to, flag an error // to, flag an error
PRBool failed = PR_FALSE; PRBool failed = PR_FALSE;
if (wasSizeDecode && !mHasSize) if ((mDecoderFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) && !mHasSize)
failed = PR_TRUE; failed = PR_TRUE;
if (!wasSizeDecode && !mDecoded) if (!(mDecoderFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) && !mDecoded)
failed = PR_TRUE; failed = PR_TRUE;
if ((aIntent == eShutdownIntent_Done) && failed) { if ((aIntent == eShutdownIntent_Done) && failed) {
DoError(); DoError();
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
// Clear the flags
mDecoderFlags = imgIDecoder::DECODER_FLAG_NONE;
// Reset number of decoded bytes // Reset number of decoded bytes
mBytesDecoded = 0; mBytesDecoded = 0;
@ -2288,11 +2298,11 @@ RasterImage::RequestDecode()
return NS_OK; return NS_OK;
// If we've already got a full decoder running, we have nothing to do // 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; return NS_OK;
// If our callstack goes through a size decoder, we have a problem. // If our callstack goes through a header-only decoder, we have a problem.
// We need to shutdown the size decode and replace it with a full // 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 // 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 // an asynchronous event to the event loop to do it later. Since
// RequestDecode() is an asynchronous function this works fine (though it's // 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 we have a header-only decoder open, interrupt it and shut it down
if (mDecoder && mDecoder->IsSizeDecode()) { if (mDecoder && (mDecoderFlags & imgIDecoder::DECODER_FLAG_HEADERONLY)) {
rv = ShutdownDecoder(eShutdownIntent_Interrupted); rv = ShutdownDecoder(eShutdownIntent_Interrupted);
CONTAINER_ENSURE_SUCCESS(rv); CONTAINER_ENSURE_SUCCESS(rv);
} }
@ -2314,7 +2324,7 @@ RasterImage::RequestDecode()
// If we don't have a decoder, create one // If we don't have a decoder, create one
if (!mDecoder) { if (!mDecoder) {
NS_ABORT_IF_FALSE(mFrames.IsEmpty(), "Trying to decode to non-empty frame-array"); 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); 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. // 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!"); NS_ABORT_IF_FALSE(!mInDecoder, "Yikes, forcing sync in reentrant call!");
// If we have a size decode open, shut it down // If we have a header-only decoder open, shut it down
if (mDecoder && mDecoder->IsSizeDecode()) { if (mDecoder && (mDecoderFlags & imgIDecoder::DECODER_FLAG_HEADERONLY)) {
rv = ShutdownDecoder(eShutdownIntent_Interrupted); rv = ShutdownDecoder(eShutdownIntent_Interrupted);
CONTAINER_ENSURE_SUCCESS(rv); CONTAINER_ENSURE_SUCCESS(rv);
} }
@ -2361,7 +2371,7 @@ RasterImage::SyncDecode()
// If we don't have a decoder, create one // If we don't have a decoder, create one
if (!mDecoder) { if (!mDecoder) {
NS_ABORT_IF_FALSE(mFrames.IsEmpty(), "Trying to decode to non-empty frame-array"); 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); 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 // There are various indicators that tell us we're finished with the decode
// task at hand and can shut down the decoder. // task at hand and can shut down the decoder.
//
// This method may not be called if there is no decoder.
PRBool PRBool
RasterImage::IsDecodeFinished() RasterImage::IsDecodeFinished()
{ {
// Precondition
NS_ABORT_IF_FALSE(mDecoder, "Can't call IsDecodeFinished() without decoder!");
// Assume it's not finished // Assume it's not finished
PRBool decodeFinished = PR_FALSE; PRBool decodeFinished = PR_FALSE;
@ -2511,7 +2516,7 @@ RasterImage::IsDecodeFinished()
"just shut down on SourceDataComplete!"); "just shut down on SourceDataComplete!");
// The decode is complete if we got what we wanted... // The decode is complete if we got what we wanted...
if (mDecoder->IsSizeDecode()) { if (mDecoderFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) {
if (mHasSize) if (mHasSize)
decodeFinished = PR_TRUE; decodeFinished = PR_TRUE;
} }
@ -2599,10 +2604,11 @@ imgDecodeWorker::Run()
if (!image->mDecoder) if (!image->mDecoder)
return NS_OK; 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 // synchronous. Write all the data in that case, otherwise write a
// chunk // chunk
PRUint32 maxBytes = image->mDecoder->IsSizeDecode() PRUint32 maxBytes =
(image->mDecoderFlags & imgIDecoder::DECODER_FLAG_HEADERONLY)
? image->mSourceData.Length() : DECODE_BYTES_AT_A_TIME; ? image->mSourceData.Length() : DECODE_BYTES_AT_A_TIME;
// Loop control // Loop control
@ -2640,7 +2646,7 @@ imgDecodeWorker::Run()
// If Conditions 1 & 2 are still true, then the only reason we bailed was // 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 // because we hit the deadline. Repost ourselves to the end of the event
// queue. // queue.
if (image->mDecoder && !image->IsDecodeFinished() && haveMoreData) if (!image->IsDecodeFinished() && haveMoreData)
return this->Dispatch(); return this->Dispatch();
// Otherwise, return success // Otherwise, return success

View File

@ -143,7 +143,6 @@ namespace mozilla {
namespace imagelib { namespace imagelib {
class imgDecodeWorker; class imgDecodeWorker;
class Decoder;
class RasterImage : public mozilla::imagelib::Image, class RasterImage : public mozilla::imagelib::Image,
public nsITimerCallback, public nsITimerCallback,
@ -167,9 +166,9 @@ public:
const char* aMimeType, const char* aMimeType,
PRUint32 aFlags); PRUint32 aFlags);
nsresult GetCurrentFrameRect(nsIntRect& aRect); nsresult GetCurrentFrameRect(nsIntRect& aRect);
PRUint32 GetCurrentFrameIndex(); nsresult GetCurrentFrameIndex(PRUint32* aCurrentFrameIdx);
PRUint32 GetNumFrames(); nsresult GetNumFrames(PRUint32* aNumFrames);
PRUint32 GetDataSize(); nsresult GetDataSize(PRUint32* aDataSize);
// Raster-specific methods // Raster-specific methods
static NS_METHOD WriteToRasterImage(nsIInputStream* aIn, void* aClosure, static NS_METHOD WriteToRasterImage(nsIInputStream* aIn, void* aClosure,
@ -459,9 +458,10 @@ private: // data
friend class DiscardTracker; friend class DiscardTracker;
// Decoder and friends // Decoder and friends
nsRefPtr<Decoder> mDecoder; nsCOMPtr<imgIDecoder> mDecoder;
nsRefPtr<imgDecodeWorker> mWorker; nsRefPtr<imgDecodeWorker> mWorker;
PRUint32 mBytesDecoded; PRUint32 mBytesDecoded;
PRUint32 mDecoderFlags;
// Boolean flags (clustered together to conserve space): // Boolean flags (clustered together to conserve space):
PRPackedBool mHasSize:1; // Has SetSize() been called? PRPackedBool mHasSize:1; // Has SetSize() been called?
@ -483,7 +483,7 @@ private: // data
// Decoding // Decoding
nsresult WantDecodedFrames(); nsresult WantDecodedFrames();
nsresult SyncDecode(); nsresult SyncDecode();
nsresult InitDecoder(bool aDoSizeDecode); nsresult InitDecoder(PRUint32 dFlags);
nsresult WriteToDecoder(const char *aBuffer, PRUint32 aCount); nsresult WriteToDecoder(const char *aBuffer, PRUint32 aCount);
nsresult DecodeSomeData(PRUint32 aMaxBytes); nsresult DecodeSomeData(PRUint32 aMaxBytes);
PRBool IsDecodeFinished(); PRBool IsDecodeFinished();

View File

@ -1853,11 +1853,14 @@ NS_IMETHODIMP imgLoader::LoadImageWithChannel(nsIChannel *channel, imgIDecoderOb
NS_IMETHODIMP imgLoader::SupportImageWithMimeType(const char* aMimeType, PRBool *_retval) NS_IMETHODIMP imgLoader::SupportImageWithMimeType(const char* aMimeType, PRBool *_retval)
{ {
*_retval = PR_FALSE; *_retval = PR_FALSE;
nsCOMPtr<nsIComponentRegistrar> reg;
nsresult rv = NS_GetComponentRegistrar(getter_AddRefs(reg));
if (NS_FAILED(rv))
return rv;
nsCAutoString mimeType(aMimeType); nsCAutoString mimeType(aMimeType);
ToLowerCase(mimeType); ToLowerCase(mimeType);
*_retval = (Image::GetDecoderType(mimeType.get()) == Image::eDecoderType_unknown) nsCAutoString decoderId(NS_LITERAL_CSTRING("@mozilla.org/image/decoder;3?type=") + mimeType);
? PR_FALSE : PR_TRUE; return reg->IsContractIDRegistered(decoderId.get(), _retval);
return NS_OK;
} }
NS_IMETHODIMP imgLoader::GetMIMETypeFromContent(nsIRequest* aRequest, NS_IMETHODIMP imgLoader::GetMIMETypeFromContent(nsIRequest* aRequest,

View File

@ -482,7 +482,9 @@ void imgRequest::SetIsInCache(PRBool incache)
void imgRequest::UpdateCacheEntrySize() void imgRequest::UpdateCacheEntrySize()
{ {
if (mCacheEntry) { if (mCacheEntry) {
mCacheEntry->SetDataSize(mImage->GetDataSize()); PRUint32 imageSize = 0;
mImage->GetDataSize(&imageSize);
mCacheEntry->SetDataSize(imageSize);
#ifdef DEBUG_joe #ifdef DEBUG_joe
nsCAutoString url; 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 */ /* now we have mimetype, so we can infer the image type that we want */
imageType = mContentType.EqualsLiteral(SVG_MIMETYPE) ? 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 */ /* set our mimetype as a property */
nsCOMPtr<nsISupportsCString> contentType(do_CreateInstance("@mozilla.org/supports-cstring;1")); nsCOMPtr<nsISupportsCString> contentType(do_CreateInstance("@mozilla.org/supports-cstring;1"));

View File

@ -41,6 +41,7 @@
#ifndef imgRequest_h__ #ifndef imgRequest_h__
#define imgRequest_h__ #define imgRequest_h__
#include "imgIDecoder.h"
#include "imgIDecoderObserver.h" #include "imgIDecoderObserver.h"
#include "nsIChannelEventSink.h" #include "nsIChannelEventSink.h"

View File

@ -44,6 +44,7 @@
#include "imgIDecoderObserver.h" #include "imgIDecoderObserver.h"
#include "nsISecurityInfoProvider.h" #include "nsISecurityInfoProvider.h"
#include "imgIDecoder.h"
#include "nsIRequestObserver.h" #include "nsIRequestObserver.h"
#include "nsIChannel.h" #include "nsIChannel.h"
#include "nsILoadGroup.h" #include "nsILoadGroup.h"

View File

@ -223,8 +223,12 @@ imgStatusTracker::SyncNotify(imgRequestProxy* proxy)
proxy->OnStartDecode(); proxy->OnStartDecode();
// Send frame messages (OnStartFrame, OnDataAvailable, OnStopFrame) // Send frame messages (OnStartFrame, OnDataAvailable, OnStopFrame)
if (mImage->GetNumFrames() > 0) { PRUint32 nframes = 0;
PRUint32 frame = mImage->GetCurrentFrameIndex(); mImage->GetNumFrames(&nframes);
if (nframes > 0) {
PRUint32 frame;
mImage->GetCurrentFrameIndex(&frame);
proxy->OnStartFrame(frame); proxy->OnStartFrame(frame);
// OnDataAvailable // OnDataAvailable

View File

@ -41,6 +41,7 @@
#include "nsString.h" #include "nsString.h"
#include "ImageErrors.h" #include "ImageErrors.h"
#include "imgIContainer.h" #include "imgIContainer.h"
#include "imgIDecoder.h"
#include "imgIEncoder.h" #include "imgIEncoder.h"
#include "imgIDecoderObserver.h" #include "imgIDecoderObserver.h"
#include "imgIContainerObserver.h" #include "imgIContainerObserver.h"

View File

@ -240,12 +240,6 @@ ifeq ($(OS_ARCH),SunOS)
EXTRA_DSO_LDOPTS += -lelf -ldemangle EXTRA_DSO_LDOPTS += -lelf -ldemangle
endif endif
ifeq ($(OS_ARCH),AIX)
ifdef HAVE_64BIT_OS
EXTRA_DSO_LDOPTS += -bbigtoc
endif
endif
ifeq ($(OS_ARCH),WINNT) ifeq ($(OS_ARCH),WINNT)
OS_LIBS += $(call EXPAND_LIBNAME,shell32 ole32 uuid version winspool comdlg32 imm32 winmm wsock32 msimg32 shlwapi psapi) OS_LIBS += $(call EXPAND_LIBNAME,shell32 ole32 uuid version winspool comdlg32 imm32 winmm wsock32 msimg32 shlwapi psapi)
ifneq (,$(MOZ_DEBUG)$(NS_TRACE_MALLOC)) ifneq (,$(MOZ_DEBUG)$(NS_TRACE_MALLOC))

View File

@ -293,8 +293,7 @@ STATIC_LIBS += gtkxtbin
endif endif
endif endif
# Platform-specific icon channel stuff - supported mostly-everywhere ifneq (,$(filter icon,$(MOZ_IMG_DECODERS)))
ifneq (,$(filter beos windows os2 mac cocoa gtk2 qt,$(MOZ_WIDGET_TOOLKIT)))
DEFINES += -DICON_DECODER DEFINES += -DICON_DECODER
COMPONENT_LIBS += imgicon COMPONENT_LIBS += imgicon
endif endif