Compare commits
2 Commits
LEAF_20031
...
IMGLIB2_NE
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c45c2db17b | ||
|
|
ebc0074860 |
33
mozilla/modules/libpr0n/Makefile.in
Normal file
33
mozilla/modules/libpr0n/Makefile.in
Normal file
@@ -0,0 +1,33 @@
|
||||
#
|
||||
# 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 Netscape are
|
||||
# Copyright (C) 2001 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
|
||||
DEPTH = ../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
DIRS = public src decoders
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
|
||||
32
mozilla/modules/libpr0n/decoders/Makefile.in
Normal file
32
mozilla/modules/libpr0n/decoders/Makefile.in
Normal file
@@ -0,0 +1,32 @@
|
||||
#
|
||||
# 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 Netscape are
|
||||
# Copyright (C) 2001 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
|
||||
DEPTH = ../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
DIRS = ppm png gif jpeg
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
1684
mozilla/modules/libpr0n/decoders/gif/GIF2.cpp
Normal file
1684
mozilla/modules/libpr0n/decoders/gif/GIF2.cpp
Normal file
File diff suppressed because it is too large
Load Diff
323
mozilla/modules/libpr0n/decoders/gif/GIF2.h
Normal file
323
mozilla/modules/libpr0n/decoders/gif/GIF2.h
Normal file
@@ -0,0 +1,323 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* 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 Communicator client code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape Communications
|
||||
* Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
#ifndef _GIF_H_
|
||||
#define _GIF_H_
|
||||
|
||||
/* gif2.h
|
||||
The interface for the GIF87/89a decoder.
|
||||
*/
|
||||
// List of possible parsing states
|
||||
typedef enum {
|
||||
gif_gather,
|
||||
gif_init, //1
|
||||
gif_type,
|
||||
gif_version,
|
||||
gif_global_header,
|
||||
gif_global_colormap,
|
||||
gif_image_start, //6
|
||||
gif_image_header,
|
||||
gif_image_colormap,
|
||||
gif_image_body,
|
||||
gif_lzw_start,
|
||||
gif_lzw, //11
|
||||
gif_sub_block,
|
||||
gif_extension,
|
||||
gif_control_extension,
|
||||
gif_consume_block,
|
||||
gif_skip_block,
|
||||
gif_done, //17
|
||||
gif_oom,
|
||||
gif_error,
|
||||
gif_comment_extension,
|
||||
gif_application_extension,
|
||||
gif_netscape_extension_block,
|
||||
gif_consume_netscape_extension,
|
||||
gif_consume_comment,
|
||||
gif_delay,
|
||||
gif_wait_for_buffer_full,
|
||||
gif_stop_animating //added for animation stop
|
||||
} gstate;
|
||||
|
||||
/* "Disposal" method indicates how the image should be handled in the
|
||||
framebuffer before the subsequent image is displayed. */
|
||||
typedef enum
|
||||
{
|
||||
DISPOSE_NOT_SPECIFIED = 0,
|
||||
DISPOSE_KEEP = 1, /* Leave it in the framebuffer */
|
||||
DISPOSE_OVERWRITE_BGCOLOR = 2, /* Overwrite with background color */
|
||||
DISPOSE_OVERWRITE_PREVIOUS = 4 /* Save-under */
|
||||
} gdispose;
|
||||
|
||||
/* A RGB triplet representing a single pixel in the image's colormap
|
||||
(if present.) */
|
||||
typedef struct _GIF_RGB
|
||||
{
|
||||
PRUint8 red, green, blue, pad; /* Windows requires the fourth byte &
|
||||
many compilers pad it anyway. */
|
||||
|
||||
/* XXX: hist_count appears to be unused */
|
||||
//PRUint16 hist_count; /* Histogram frequency count. */
|
||||
} GIF_RGB;
|
||||
|
||||
/* Colormap information. */
|
||||
typedef struct _GIF_ColorMap {
|
||||
int32 num_colors; /* Number of colors in the colormap.
|
||||
A negative value can be used to denote a
|
||||
possibly non-unique set. */
|
||||
GIF_RGB *map; /* Colormap colors. */
|
||||
PRUint8 *index; /* NULL, if map is in index order. Otherwise
|
||||
specifies the indices of the map entries. */
|
||||
void *table; /* Lookup table for this colormap. Private to
|
||||
the Image Library. */
|
||||
} GIF_ColorMap;
|
||||
|
||||
/* An indexed RGB triplet. */
|
||||
typedef struct _GIF_IRGB {
|
||||
PRUint8 index;
|
||||
PRUint8 red, green, blue;
|
||||
} GIF_IRGB;
|
||||
|
||||
/* A GIF decoder's state */
|
||||
typedef struct gif_struct {
|
||||
void* clientptr;
|
||||
/* Callbacks for this decoder instance*/
|
||||
int (PR_CALLBACK *GIFCallback_NewPixmap)();
|
||||
int (PR_CALLBACK *GIFCallback_BeginGIF)(
|
||||
void* aClientData,
|
||||
PRUint32 aLogicalScreenWidth,
|
||||
PRUint32 aLogicalScreenHeight,
|
||||
PRUint8 aLogicalScreenBackgroundRGBIndex);
|
||||
|
||||
int (PR_CALLBACK* GIFCallback_EndGIF)(
|
||||
void* aClientData,
|
||||
int aAnimationLoopCount);
|
||||
|
||||
int (PR_CALLBACK* GIFCallback_BeginImageFrame)(
|
||||
void* aClientData,
|
||||
PRUint32 aFrameNumber, /* Frame number, 1-n */
|
||||
PRUint32 aFrameXOffset, /* X offset in logical screen */
|
||||
PRUint32 aFrameYOffset, /* Y offset in logical screen */
|
||||
PRUint32 aFrameWidth,
|
||||
PRUint32 aFrameHeight,
|
||||
GIF_RGB* aTransparencyChromaKey);
|
||||
int (PR_CALLBACK* GIFCallback_EndImageFrame)(
|
||||
void* aClientData,
|
||||
PRUint32 aFrameNumber,
|
||||
PRUint32 aDelayTimeout);
|
||||
int (PR_CALLBACK* GIFCallback_SetupColorspaceConverter)();
|
||||
int (PR_CALLBACK* GIFCallback_ResetPalette)();
|
||||
int (PR_CALLBACK* GIFCallback_InitTransparentPixel)();
|
||||
int (PR_CALLBACK* GIFCallback_DestroyTransparentPixel)();
|
||||
int (PR_CALLBACK* GIFCallback_HaveDecodedRow)(
|
||||
void* aClientData,
|
||||
PRUint8* aRowBufPtr, /* Pointer to single scanline temporary buffer */
|
||||
PRUint8* aRGBrowBufPtr,/* Pointer to temporary storage for dithering/mapping */
|
||||
int aXOffset, /* With respect to GIF logical screen origin */
|
||||
int aLength, /* Length of the row? */
|
||||
int aRow, /* Row number? */
|
||||
int aDuplicateCount, /* Number of times to duplicate the row? */
|
||||
PRUint8 aDrawMode, /* il_draw_mode */
|
||||
int aInterlacePass);
|
||||
int (PR_CALLBACK *GIFCallback_HaveImageAll)(
|
||||
void* aClientData);
|
||||
|
||||
/* Parsing state machine */
|
||||
gstate state; /* Curent decoder master state */
|
||||
PRUint8 *hold; /* Accumulation buffer */
|
||||
int32 hold_size; /* Capacity, in bytes, of accumulation buffer */
|
||||
PRUint8 *gather_head; /* Next byte to read in accumulation buffer */
|
||||
int32 gather_request_size; /* Number of bytes to accumulate */
|
||||
int32 gathered; /* bytes accumulated so far*/
|
||||
gstate post_gather_state; /* State after requested bytes accumulated */
|
||||
int32 requested_buffer_fullness; /* For netscape application extension */
|
||||
|
||||
/* LZW decoder state machine */
|
||||
PRUint8 *stack; /* Base of decoder stack */
|
||||
PRUint8 *stackp; /* Current stack pointer */
|
||||
PRUint16 *prefix;
|
||||
PRUint8 *suffix;
|
||||
int datasize;
|
||||
int codesize;
|
||||
int codemask;
|
||||
int clear_code; /* Codeword used to trigger dictionary reset */
|
||||
int avail; /* Index of next available slot in dictionary */
|
||||
int oldcode;
|
||||
PRUint8 firstchar;
|
||||
int count; /* Remaining # bytes in sub-block */
|
||||
int bits; /* Number of unread bits in "datum" */
|
||||
int32 datum; /* 32-bit input buffer */
|
||||
|
||||
/* Output state machine */
|
||||
int ipass; /* Interlace pass; Ranges 1-4 if interlaced. */
|
||||
PRUintn rows_remaining; /* Rows remaining to be output */
|
||||
PRUintn irow; /* Current output row, starting at zero */
|
||||
PRUint8 *rgbrow; /* Temporary storage for dithering/mapping */
|
||||
PRUint8 *rowbuf; /* Single scanline temporary buffer */
|
||||
PRUint8 *rowend; /* Pointer to end of rowbuf */
|
||||
PRUint8 *rowp; /* Current output pointer */
|
||||
|
||||
/* Parameters for image frame currently being decoded*/
|
||||
PRUintn x_offset, y_offset; /* With respect to "screen" origin */
|
||||
PRUintn height, width;
|
||||
PRUintn last_x_offset, last_y_offset; /* With respect to "screen" origin */
|
||||
PRUintn last_height, last_width;
|
||||
int interlaced; /* TRUE, if scanlines arrive interlaced order */
|
||||
int tpixel; /* Index of transparent pixel */
|
||||
GIF_IRGB* transparent_pixel;
|
||||
int is_transparent; /* TRUE, if tpixel is valid */
|
||||
int control_extension; /* TRUE, if image control extension present */
|
||||
int is_local_colormap_defined;
|
||||
gdispose disposal_method; /* Restore to background, leave in place, etc.*/
|
||||
gdispose last_disposal_method;
|
||||
GIF_RGB *local_colormap; /* Per-image colormap */
|
||||
int local_colormap_size; /* Size of local colormap array. */
|
||||
PRUint32 delay_time; /* Display time, in milliseconds,
|
||||
for this image in a multi-image GIF */
|
||||
|
||||
/* Global (multi-image) state */
|
||||
int screen_bgcolor; /* Logical screen background color */
|
||||
int version; /* Either 89 for GIF89 or 87 for GIF87 */
|
||||
PRUintn screen_width; /* Logical screen width & height */
|
||||
PRUintn screen_height;
|
||||
GIF_RGB *global_colormap; /* Default colormap if local not supplied */
|
||||
int global_colormap_size; /* Size of global colormap array. */
|
||||
int images_decoded; /* Counts images for multi-part GIFs */
|
||||
int destroy_pending; /* Stream has ended */
|
||||
int progressive_display; /* If TRUE, do Haeberli interlace hack */
|
||||
int loop_count; /* Netscape specific extension block to control
|
||||
the number of animation loops a GIF renders. */
|
||||
} gif_struct;
|
||||
|
||||
|
||||
/* Create a new gif_struct */
|
||||
extern PRBool gif_create(gif_struct **gs);
|
||||
|
||||
/* These are the APIs that the client calls to intialize,
|
||||
push data to, and shut down the GIF decoder. */
|
||||
PRBool GIFInit(
|
||||
gif_struct* gs,
|
||||
|
||||
void* aClientData,
|
||||
|
||||
int (*PR_CALLBACK GIFCallback_NewPixmap)(),
|
||||
|
||||
int (*PR_CALLBACK GIFCallback_BeginGIF)(
|
||||
void* aClientData,
|
||||
PRUint32 aLogicalScreenWidth,
|
||||
PRUint32 aLogicalScreenHeight,
|
||||
PRUint8 aBackgroundRGBIndex),
|
||||
|
||||
int (*PR_CALLBACK GIFCallback_EndGIF)(
|
||||
void* aClientData,
|
||||
int aAnimationLoopCount),
|
||||
|
||||
int (*PR_CALLBACK GIFCallback_BeginImageFrame)(
|
||||
void* aClientData,
|
||||
PRUint32 aFrameNumber, /* Frame number, 1-n */
|
||||
PRUint32 aFrameXOffset, /* X offset in logical screen */
|
||||
PRUint32 aFrameYOffset, /* Y offset in logical screen */
|
||||
PRUint32 aFrameWidth,
|
||||
PRUint32 aFrameHeight,
|
||||
GIF_RGB* aTransparencyChromaKey),
|
||||
|
||||
int (*PR_CALLBACK GIFCallback_EndImageFrame)(
|
||||
void* aClientData,
|
||||
PRUint32 aFrameNumber,
|
||||
PRUint32 aDelayTimeout),
|
||||
|
||||
int (*PR_CALLBACK GIFCallback_SetupColorspaceConverter)(),
|
||||
|
||||
int (*PR_CALLBACK GIFCallback_ResetPalette)(),
|
||||
|
||||
int (*PR_CALLBACK GIFCallback_InitTransparentPixel)(),
|
||||
|
||||
int (*PR_CALLBACK GIFCallback_DestroyTransparentPixel)(),
|
||||
|
||||
int (*PR_CALLBACK GIFCallback_HaveDecodedRow)(
|
||||
void* aClientData,
|
||||
PRUint8* aRowBufPtr, /* Pointer to single scanline temporary buffer */
|
||||
PRUint8* aRGBrowBufPtr,/* Pointer to temporary storage for dithering/mapping */
|
||||
int aXOffset, /* With respect to GIF logical screen origin */
|
||||
int aLength, /* Length of the row? */
|
||||
int aRow, /* Row number? */
|
||||
int aDuplicateCount, /* Number of times to duplicate the row? */
|
||||
PRUint8 aDrawMode, /* il_draw_mode */
|
||||
int aInterlacePass),
|
||||
|
||||
int (*PR_CALLBACK GIFCallback_HaveImageAll)(
|
||||
void* aClientData)
|
||||
);
|
||||
|
||||
extern void gif_destroy(gif_struct* aGIFStruct);
|
||||
|
||||
int gif_write(gif_struct* aGIFStruct, const PRUint8 * buf, PRUint32 numbytes);
|
||||
|
||||
PRUint8 gif_write_ready(gif_struct* aGIFStruct);
|
||||
|
||||
extern void gif_complete(gif_struct** aGIFStruct);
|
||||
extern void gif_delay_time_callback(/* void *closure */);
|
||||
|
||||
|
||||
/* Callback functions that the client must implement and pass in
|
||||
pointers for during the GIFInit call. These will be called back
|
||||
when the decoder has a decoded rows, frame size information, etc.*/
|
||||
|
||||
/* GIFCallback_LogicalScreenSize is called only once to notify the client
|
||||
of the logical screen size, which will be the size of the total image. */
|
||||
typedef int (*PR_CALLBACK BEGINGIF_CALLBACK)(
|
||||
void* aClientData,
|
||||
PRUint32 aLogicalScreenWidth,
|
||||
PRUint32 aLogicalScreenHeight,
|
||||
PRUint8 aLogicalScreenBackgroundRGBIndex);
|
||||
|
||||
typedef int (PR_CALLBACK *GIFCallback_EndGIF)(
|
||||
void* aClientData,
|
||||
int aAnimationLoopCount);
|
||||
|
||||
/* GIFCallback_BeginImageFrame is called at the beginning of each frame of
|
||||
a GIF.*/
|
||||
typedef int (PR_CALLBACK *GIFCallback_BeginImageFrame)(
|
||||
void* aClientData,
|
||||
PRUint32 aFrameNumber, /* Frame number, 1-n */
|
||||
PRUint32 aFrameXOffset, /* X offset in logical screen */
|
||||
PRUint32 aFraqeYOffset, /* Y offset in logical screen */
|
||||
PRUint32 aFrameWidth,
|
||||
PRUint32 aFrameHeight);
|
||||
|
||||
extern int GIFCallback_EndImageFrame(
|
||||
void* aClientData,
|
||||
PRUint32 aFrameNumber,
|
||||
PRUint32 aDelayTimeout); /* Time in milliseconds this frame should be displayed before the next frame.
|
||||
This information appears in a sub control block, so we don't
|
||||
transmit it back to the client until we're done with the frame. */
|
||||
|
||||
/*
|
||||
extern int GIFCallback_SetupColorspaceConverter();
|
||||
extern int GIFCallback_ResetPalette();
|
||||
extern int GIFCallback_InitTransparentPixel();
|
||||
extern int GIFCallback_DestroyTransparentPixel();
|
||||
*/
|
||||
extern int GIFCallback_HaveDecodedRow();
|
||||
extern int GIFCallback_HaveImageAll();
|
||||
|
||||
#endif
|
||||
|
||||
42
mozilla/modules/libpr0n/decoders/gif/Makefile.in
Normal file
42
mozilla/modules/libpr0n/decoders/gif/Makefile.in
Normal file
@@ -0,0 +1,42 @@
|
||||
#
|
||||
# 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 Netscape are
|
||||
# Copyright (C) 2001 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
|
||||
DEPTH = ../../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = imggif
|
||||
LIBRARY_NAME = imggif
|
||||
IS_COMPONENT = 1
|
||||
|
||||
REQUIRES = xpcom necko layout gfx2 imglib2
|
||||
|
||||
CPPSRCS = GIF2.cpp nsGIFDecoder2.cpp nsGIFModule.cpp
|
||||
|
||||
EXTRA_DSO_LDOPTS = $(GIF_LIBS) $(ZLIB_LIBS) \
|
||||
$(MOZ_COMPONENT_LIBS) \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
52
mozilla/modules/libpr0n/decoders/gif/makefile.win
Normal file
52
mozilla/modules/libpr0n/decoders/gif/makefile.win
Normal file
@@ -0,0 +1,52 @@
|
||||
#!nmake
|
||||
#
|
||||
# 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 Netscape are
|
||||
# Copyright (C) 2001 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Stuart Parmenter <pavlov@netscape.com>
|
||||
#
|
||||
|
||||
DEPTH=..\..\..\..
|
||||
include <$(DEPTH)/config/config.mak>
|
||||
|
||||
MODULE = imggif
|
||||
LIBRARY_NAME = imggif
|
||||
DLL = $(OBJDIR)\$(LIBRARY_NAME).dll
|
||||
MAKE_OBJ_TYPE = DLL
|
||||
|
||||
OBJS = \
|
||||
.\$(OBJDIR)\nsGIFDecoder2.obj \
|
||||
.\$(OBJDIR)\GIF2.obj \
|
||||
.\$(OBJDIR)\nsGIFModule.obj \
|
||||
$(NULL)
|
||||
|
||||
LLIBS=\
|
||||
$(LIBNSPR) \
|
||||
$(DIST)\lib\xpcom.lib \
|
||||
$(DIST)\lib\gkgfxwin.lib \
|
||||
$(NULL)
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
|
||||
install:: $(DLL)
|
||||
$(MAKE_INSTALL) .\$(OBJDIR)\$(LIBRARY_NAME).dll $(DIST)\bin\components
|
||||
$(MAKE_INSTALL) .\$(OBJDIR)\$(LIBRARY_NAME).lib $(DIST)\lib
|
||||
|
||||
clobber::
|
||||
rm -f $(DIST)\bin\components\$(LIBRARY_NAME).dll
|
||||
rm -f $(DIST)\lib\$(LIBRARY_NAME).lib
|
||||
506
mozilla/modules/libpr0n/decoders/gif/nsGIFDecoder2.cpp
Normal file
506
mozilla/modules/libpr0n/decoders/gif/nsGIFDecoder2.cpp
Normal file
@@ -0,0 +1,506 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* 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 Netscape are
|
||||
* Copyright (C) 2001 Netscape Communications Corporation.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Chris Saari <saari@netscape.com>
|
||||
*/
|
||||
|
||||
#include "nsGIFDecoder2.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsIImage.h"
|
||||
#include "nsMemory.h"
|
||||
|
||||
#include "imgIContainerObserver.h"
|
||||
|
||||
#include "nsRect.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// GIF Decoder Implementation
|
||||
// This is an adaptor between GIF2 and imgIDecoder
|
||||
|
||||
NS_IMPL_ISUPPORTS2(nsGIFDecoder2, imgIDecoder, nsIOutputStream);
|
||||
|
||||
nsGIFDecoder2::nsGIFDecoder2()
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
mImageFrame = nsnull;
|
||||
|
||||
mGIFStruct = nsnull;
|
||||
|
||||
mAlphaLine = nsnull;
|
||||
}
|
||||
|
||||
nsGIFDecoder2::~nsGIFDecoder2(void)
|
||||
{
|
||||
if (mAlphaLine)
|
||||
nsMemory::Free(mAlphaLine);
|
||||
|
||||
if (mGIFStruct) {
|
||||
gif_destroy(mGIFStruct);
|
||||
mGIFStruct = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
/** imgIDecoder methods **/
|
||||
//******************************************************************************
|
||||
|
||||
//******************************************************************************
|
||||
/* void init (in imgIRequest aRequest); */
|
||||
NS_IMETHODIMP nsGIFDecoder2::Init(imgIRequest *aRequest)
|
||||
{
|
||||
mImageRequest = aRequest;
|
||||
mObserver = do_QueryInterface(aRequest); // we're holding 2 strong refs to the request.
|
||||
|
||||
aRequest->GetImage(getter_AddRefs(mImageContainer));
|
||||
|
||||
/* do gif init stuff */
|
||||
/* Always decode to 24 bit pixdepth */
|
||||
|
||||
PRBool created = gif_create(&mGIFStruct);
|
||||
|
||||
NS_ASSERTION(created, "gif_create failed");
|
||||
|
||||
// Call GIF decoder init routine
|
||||
GIFInit(
|
||||
mGIFStruct,
|
||||
this,
|
||||
NewPixmap,
|
||||
BeginGIF,
|
||||
EndGIF,
|
||||
BeginImageFrame,
|
||||
EndImageFrame,
|
||||
SetupColorspaceConverter,
|
||||
ResetPalette,
|
||||
InitTransparentPixel,
|
||||
DestroyTransparentPixel,
|
||||
HaveDecodedRow,
|
||||
HaveImageAll);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
/* readonly attribute imgIRequest request; */
|
||||
NS_IMETHODIMP nsGIFDecoder2::GetRequest(imgIRequest * *aRequest)
|
||||
{
|
||||
*aRequest = mImageRequest;
|
||||
NS_IF_ADDREF(*aRequest);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
//******************************************************************************
|
||||
/** nsIOutputStream methods **/
|
||||
//******************************************************************************
|
||||
|
||||
//******************************************************************************
|
||||
/* void close (); */
|
||||
NS_IMETHODIMP nsGIFDecoder2::Close()
|
||||
{
|
||||
if (mGIFStruct) {
|
||||
gif_destroy(mGIFStruct);
|
||||
mGIFStruct = nsnull;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
/* void flush (); */
|
||||
NS_IMETHODIMP nsGIFDecoder2::Flush()
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
/* unsigned long write (in string buf, in unsigned long count); */
|
||||
NS_IMETHODIMP nsGIFDecoder2::Write(const char *buf, PRUint32 count, PRUint32 *_retval)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
/* static callback from nsIInputStream::ReadSegments */
|
||||
static NS_METHOD ReadDataOut(nsIInputStream* in,
|
||||
void* closure,
|
||||
const char* fromRawSegment,
|
||||
PRUint32 toOffset,
|
||||
PRUint32 count,
|
||||
PRUint32 *writeCount)
|
||||
{
|
||||
nsGIFDecoder2 *decoder = NS_STATIC_CAST(nsGIFDecoder2*, closure);
|
||||
*writeCount = decoder->ProcessData((unsigned char*)fromRawSegment, count);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
PRUint32 nsGIFDecoder2::ProcessData(unsigned char *data, PRUint32 count)
|
||||
{
|
||||
// Push the data to the GIF decoder
|
||||
|
||||
// First we ask if the gif decoder is ready for more data, and if so, push it.
|
||||
// In the new decoder, we should always be able to process more data since
|
||||
// we don't wait to decode each frame in an animation now.
|
||||
if(gif_write_ready(mGIFStruct)) {
|
||||
gif_write(mGIFStruct, data, count);
|
||||
}
|
||||
|
||||
|
||||
return count; // we always consume all the data
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
/* unsigned long writeFrom (in nsIInputStream inStr, in unsigned long count); */
|
||||
NS_IMETHODIMP nsGIFDecoder2::WriteFrom(nsIInputStream *inStr, PRUint32 count, PRUint32 *_retval)
|
||||
{
|
||||
inStr->ReadSegments(
|
||||
ReadDataOut, // Callback
|
||||
this,
|
||||
count,
|
||||
_retval);
|
||||
|
||||
// if error
|
||||
//mRequest->Cancel(NS_BINDING_ABORTED); // XXX is this the correct error ?
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
/* [noscript] unsigned long writeSegments (in nsReadSegmentFun reader, in voidPtr closure, in unsigned long count); */
|
||||
NS_IMETHODIMP nsGIFDecoder2::WriteSegments(nsReadSegmentFun reader, void * closure, PRUint32 count, PRUint32 *_retval)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
/* attribute boolean nonBlocking; */
|
||||
NS_IMETHODIMP nsGIFDecoder2::GetNonBlocking(PRBool *aNonBlocking)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
//******************************************************************************
|
||||
NS_IMETHODIMP nsGIFDecoder2::SetNonBlocking(PRBool aNonBlocking)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
/* attribute nsIOutputStreamObserver observer; */
|
||||
NS_IMETHODIMP nsGIFDecoder2::GetObserver(nsIOutputStreamObserver * *aObserver)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
NS_IMETHODIMP nsGIFDecoder2::SetObserver(nsIOutputStreamObserver * aObserver)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//******************************************************************************
|
||||
// GIF decoder callback methods. Part of pulic API for GIF2
|
||||
//******************************************************************************
|
||||
|
||||
//******************************************************************************
|
||||
int BeginGIF(
|
||||
void* aClientData,
|
||||
PRUint32 aLogicalScreenWidth,
|
||||
PRUint32 aLogicalScreenHeight,
|
||||
PRUint8 aBackgroundRGBIndex)
|
||||
{
|
||||
// copy GIF info into imagelib structs
|
||||
nsGIFDecoder2 *decoder = NS_STATIC_CAST(nsGIFDecoder2*, aClientData);
|
||||
|
||||
if (decoder->mObserver)
|
||||
decoder->mObserver->OnStartDecode(nsnull, nsnull);
|
||||
|
||||
decoder->mImageContainer->Init(aLogicalScreenWidth, aLogicalScreenHeight, decoder->mObserver);
|
||||
|
||||
if (decoder->mObserver)
|
||||
decoder->mObserver->OnStartContainer(nsnull, nsnull, decoder->mImageContainer);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
int EndGIF(
|
||||
void* aClientData,
|
||||
int aAnimationLoopCount)
|
||||
{
|
||||
nsGIFDecoder2 *decoder = NS_STATIC_CAST(nsGIFDecoder2*, aClientData);
|
||||
if (decoder->mObserver) {
|
||||
decoder->mObserver->OnStopContainer(nsnull, nsnull, decoder->mImageContainer);
|
||||
decoder->mObserver->OnStopDecode(nsnull, nsnull, NS_OK, nsnull);
|
||||
}
|
||||
|
||||
decoder->mImageContainer->SetLoopCount(aAnimationLoopCount);
|
||||
decoder->mImageContainer->DecodingComplete();
|
||||
return 0;
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
int BeginImageFrame(
|
||||
void* aClientData,
|
||||
PRUint32 aFrameNumber, /* Frame number, 1-n */
|
||||
PRUint32 aFrameXOffset, /* X offset in logical screen */
|
||||
PRUint32 aFrameYOffset, /* Y offset in logical screen */
|
||||
PRUint32 aFrameWidth,
|
||||
PRUint32 aFrameHeight,
|
||||
GIF_RGB* aTransparencyChromaKey) /* don't have this info yet */
|
||||
{
|
||||
nsGIFDecoder2* decoder = NS_STATIC_CAST(nsGIFDecoder2*, aClientData);
|
||||
|
||||
decoder->mImageFrame = nsnull; // clear out our current frame reference
|
||||
decoder->mGIFStruct->x_offset = aFrameXOffset;
|
||||
decoder->mGIFStruct->y_offset = aFrameYOffset;
|
||||
decoder->mGIFStruct->width = aFrameWidth;
|
||||
decoder->mGIFStruct->height = aFrameHeight;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
int EndImageFrame(
|
||||
void* aClientData,
|
||||
PRUint32 aFrameNumber,
|
||||
PRUint32 aDelayTimeout) /* Time this frame should be displayed before the next frame
|
||||
we can't have this in the image frame init because it doesn't
|
||||
show up in the GIF frame header, it shows up in a sub control
|
||||
block.*/
|
||||
{
|
||||
nsGIFDecoder2* decoder = NS_STATIC_CAST(nsGIFDecoder2*, aClientData);
|
||||
|
||||
// We actually have the timeout information before we get the lzw encoded image
|
||||
// data, at least according to the spec, but we delay in setting the timeout for
|
||||
// the image until here to help ensure that we have the whole image frame decoded before
|
||||
// we go off and try to display another frame.
|
||||
|
||||
// XXXXXXXX
|
||||
// decoder->mImageFrame->SetTimeout(aDelayTimeout);
|
||||
decoder->mImageContainer->EndFrameDecode(aFrameNumber, aDelayTimeout);
|
||||
|
||||
if (decoder->mObserver)
|
||||
decoder->mObserver->OnStopFrame(nsnull, nsnull, decoder->mImageFrame);
|
||||
|
||||
decoder->mImageFrame = nsnull;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//******************************************************************************
|
||||
// GIF decoder callback
|
||||
int HaveImageAll(
|
||||
void* aClientData)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
// GIF decoder callback notification that it has decoded a row
|
||||
int HaveDecodedRow(
|
||||
void* aClientData,
|
||||
PRUint8* aRowBufPtr, // Pointer to single scanline temporary buffer
|
||||
PRUint8* aRGBrowBufPtr,// Pointer to temporary storage for dithering/mapping
|
||||
int aXOffset, // With respect to GIF logical screen origin
|
||||
int aLength, // Length of the row?
|
||||
int aRowNumber, // Row number?
|
||||
int aDuplicateCount, // Number of times to duplicate the row?
|
||||
PRUint8 aDrawMode, // il_draw_mode
|
||||
int aInterlacePass) // interlace pass (1-4)
|
||||
{
|
||||
nsGIFDecoder2* decoder = NS_STATIC_CAST(nsGIFDecoder2*, aClientData);
|
||||
PRUint32 bpr, abpr;
|
||||
// We have to delay allocation of the image frame until now because
|
||||
// we won't have control block info (transparency) until now. The conrol
|
||||
// block of a GIF stream shows up after the image header since transparency
|
||||
// is added in GIF89a and control blocks are how the extensions are done.
|
||||
// How annoying.
|
||||
if(! decoder->mImageFrame) {
|
||||
gfx_format format = gfxIFormats::RGB;
|
||||
if (decoder->mGIFStruct->is_transparent)
|
||||
format = gfxIFormats::RGB_A1;
|
||||
|
||||
#ifdef XP_PC
|
||||
// XXX this works...
|
||||
format += 1; // RGB to BGR
|
||||
#endif
|
||||
|
||||
// initalize the frame and append it to the container
|
||||
decoder->mImageFrame = do_CreateInstance("@mozilla.org/gfx/image/frame;2");
|
||||
decoder->mImageFrame->Init(
|
||||
decoder->mGIFStruct->x_offset, decoder->mGIFStruct->y_offset,
|
||||
decoder->mGIFStruct->width, decoder->mGIFStruct->height, format);
|
||||
|
||||
decoder->mImageContainer->AppendFrame(decoder->mImageFrame);
|
||||
|
||||
if (decoder->mObserver)
|
||||
decoder->mObserver->OnStartFrame(nsnull, nsnull, decoder->mImageFrame);
|
||||
|
||||
decoder->mImageFrame->GetImageBytesPerRow(&bpr);
|
||||
decoder->mImageFrame->GetAlphaBytesPerRow(&abpr);
|
||||
|
||||
if (format == gfxIFormats::RGB_A1 || format == gfxIFormats::BGR_A1) {
|
||||
if (decoder->mAlphaLine)
|
||||
nsMemory::Free(decoder->mAlphaLine);
|
||||
decoder->mAlphaLine = (PRUint8 *)nsMemory::Alloc(abpr);
|
||||
}
|
||||
} else {
|
||||
decoder->mImageFrame->GetImageBytesPerRow(&bpr);
|
||||
decoder->mImageFrame->GetAlphaBytesPerRow(&abpr);
|
||||
}
|
||||
|
||||
if (aRowBufPtr) {
|
||||
nscoord width;
|
||||
|
||||
decoder->mImageFrame->GetWidth(&width);
|
||||
PRUint32 iwidth = width;
|
||||
|
||||
gfx_format format;
|
||||
decoder->mImageFrame->GetFormat(&format);
|
||||
|
||||
// XXX map the data into colors
|
||||
int cmapsize;
|
||||
GIF_RGB* cmap;
|
||||
if(decoder->mGIFStruct->local_colormap) {
|
||||
cmapsize = decoder->mGIFStruct->local_colormap_size;
|
||||
cmap = decoder->mGIFStruct->local_colormap;
|
||||
} else {
|
||||
cmapsize = decoder->mGIFStruct->global_colormap_size;
|
||||
cmap = decoder->mGIFStruct->global_colormap;
|
||||
}
|
||||
|
||||
PRUint8* rgbRowIndex = aRGBrowBufPtr;
|
||||
PRUint8* rowBufIndex = aRowBufPtr;
|
||||
|
||||
switch (format) {
|
||||
case gfxIFormats::RGB:
|
||||
{
|
||||
while(rowBufIndex != decoder->mGIFStruct->rowend) {
|
||||
#ifdef XP_MAC
|
||||
*rgbRowIndex++ = 0; // Mac is always 32bits per pixel, this is pad
|
||||
#endif
|
||||
*rgbRowIndex++ = cmap[PRUint8(*rowBufIndex)].red;
|
||||
*rgbRowIndex++ = cmap[PRUint8(*rowBufIndex)].green;
|
||||
*rgbRowIndex++ = cmap[PRUint8(*rowBufIndex)].blue;
|
||||
++rowBufIndex;
|
||||
}
|
||||
|
||||
decoder->mImageFrame->SetImageData((PRUint8*)aRGBrowBufPtr, bpr, aRowNumber*bpr);
|
||||
}
|
||||
break;
|
||||
case gfxIFormats::BGR:
|
||||
{
|
||||
while(rowBufIndex != decoder->mGIFStruct->rowend) {
|
||||
*rgbRowIndex++ = cmap[PRUint8(*rowBufIndex)].blue;
|
||||
*rgbRowIndex++ = cmap[PRUint8(*rowBufIndex)].green;
|
||||
*rgbRowIndex++ = cmap[PRUint8(*rowBufIndex)].red;
|
||||
++rowBufIndex;
|
||||
}
|
||||
|
||||
decoder->mImageFrame->SetImageData((PRUint8*)aRGBrowBufPtr, bpr, aRowNumber*bpr);
|
||||
}
|
||||
break;
|
||||
case gfxIFormats::RGB_A1:
|
||||
case gfxIFormats::BGR_A1:
|
||||
{
|
||||
memset(aRGBrowBufPtr, 0, bpr);
|
||||
memset(decoder->mAlphaLine, 0, abpr);
|
||||
PRUint32 iwidth = (PRUint32)width;
|
||||
for (PRUint32 x=0; x<iwidth; x++) {
|
||||
if (*rowBufIndex != decoder->mGIFStruct->tpixel) {
|
||||
#ifdef XP_PC
|
||||
*rgbRowIndex++ = cmap[PRUint8(*rowBufIndex)].blue;
|
||||
*rgbRowIndex++ = cmap[PRUint8(*rowBufIndex)].green;
|
||||
*rgbRowIndex++ = cmap[PRUint8(*rowBufIndex)].red;
|
||||
#else
|
||||
#ifdef XP_MAC
|
||||
*rgbRowIndex++ = 0; // Mac is always 32bits per pixel, this is pad
|
||||
#endif
|
||||
*rgbRowIndex++ = cmap[PRUint8(*rowBufIndex)].red;
|
||||
*rgbRowIndex++ = cmap[PRUint8(*rowBufIndex)].green;
|
||||
*rgbRowIndex++ = cmap[PRUint8(*rowBufIndex)].blue;
|
||||
#endif
|
||||
decoder->mAlphaLine[x>>3] |= 1<<(7-x&0x7);
|
||||
} else {
|
||||
#ifdef XP_MAC
|
||||
rgbRowIndex+=4;
|
||||
#else
|
||||
rgbRowIndex+=3;
|
||||
#endif
|
||||
}
|
||||
|
||||
++rowBufIndex;
|
||||
}
|
||||
decoder->mImageFrame->SetImageData((PRUint8*)aRGBrowBufPtr, bpr, aRowNumber*bpr);
|
||||
decoder->mImageFrame->SetAlphaData(decoder->mAlphaLine, abpr, aRowNumber*abpr);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
nsRect r(0, aRowNumber, width, 1);
|
||||
|
||||
decoder->mObserver->OnDataAvailable(nsnull, nsnull, decoder->mImageFrame, &r);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
int ResetPalette()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
int SetupColorspaceConverter()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
int EndImageFrame()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
int NewPixmap()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
int InitTransparentPixel()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
int DestroyTransparentPixel()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
114
mozilla/modules/libpr0n/decoders/gif/nsGIFDecoder2.h
Normal file
114
mozilla/modules/libpr0n/decoders/gif/nsGIFDecoder2.h
Normal file
@@ -0,0 +1,114 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* 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 Netscape are
|
||||
* Copyright (C) 2001 Netscape Communications Corporation.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Chris Saari <saari@netscape.com>
|
||||
*/
|
||||
|
||||
#ifndef _nsGIFDecoder2_h
|
||||
#define _nsGIFDecoder2_h
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "imgIDecoder.h"
|
||||
#include "imgIContainer.h"
|
||||
#include "imgIDecoderObserver.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
#include "imgIRequest.h"
|
||||
|
||||
#include "GIF2.h"
|
||||
|
||||
#define NS_GIFDECODER2_CID \
|
||||
{ /* 797bec5a-1dd2-11b2-a7f8-ca397e0179c4 */ \
|
||||
0x797bec5a, \
|
||||
0x1dd2, \
|
||||
0x11b2, \
|
||||
{0xa7, 0xf8, 0xca, 0x39, 0x7e, 0x01, 0x79, 0xc4} \
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// nsGIFDecoder2 Definition
|
||||
|
||||
class nsGIFDecoder2 : public imgIDecoder
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_IMGIDECODER
|
||||
NS_DECL_NSIOUTPUTSTREAM
|
||||
|
||||
nsGIFDecoder2();
|
||||
virtual ~nsGIFDecoder2();
|
||||
|
||||
static NS_METHOD Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
|
||||
|
||||
NS_METHOD ProcessData(unsigned char *data, PRUint32 count);
|
||||
|
||||
nsCOMPtr<imgIContainer> mImageContainer;
|
||||
nsCOMPtr<gfxIImageFrame> mImageFrame;
|
||||
nsCOMPtr<imgIRequest> mImageRequest;
|
||||
nsCOMPtr<imgIDecoderObserver> mObserver; // this is just qi'd from mRequest for speed
|
||||
|
||||
gif_struct *mGIFStruct;
|
||||
|
||||
PRUint8 *mAlphaLine;
|
||||
};
|
||||
|
||||
// static callbacks for the GIF decoder
|
||||
static int PR_CALLBACK BeginGIF(
|
||||
void* aClientData,
|
||||
PRUint32 aLogicalScreenWidth,
|
||||
PRUint32 aLogicalScreenHeight,
|
||||
PRUint8 aBackgroundRGBIndex);
|
||||
|
||||
static int PR_CALLBACK HaveDecodedRow(
|
||||
void* aClientData,
|
||||
PRUint8* aRowBufPtr, // Pointer to single scanline temporary buffer
|
||||
PRUint8* aRGBrowBufPtr,// Pointer to temporary storage for dithering/mapping
|
||||
int aXOffset, // With respect to GIF logical screen origin
|
||||
int aLength, // Length of the row?
|
||||
int aRow, // Row number?
|
||||
int aDuplicateCount, // Number of times to duplicate the row?
|
||||
PRUint8 aDrawMode, // il_draw_mode
|
||||
int aInterlacePass);
|
||||
|
||||
static int PR_CALLBACK NewPixmap();
|
||||
|
||||
static int PR_CALLBACK EndGIF(
|
||||
void* aClientData,
|
||||
int aAnimationLoopCount);
|
||||
|
||||
static int PR_CALLBACK BeginImageFrame(
|
||||
void* aClientData,
|
||||
PRUint32 aFrameNumber, /* Frame number, 1-n */
|
||||
PRUint32 aFrameXOffset, /* X offset in logical screen */
|
||||
PRUint32 aFrameYOffset, /* Y offset in logical screen */
|
||||
PRUint32 aFrameWidth,
|
||||
PRUint32 aFrameHeight,
|
||||
GIF_RGB* aTransparencyChromaKey);
|
||||
static int PR_CALLBACK EndImageFrame(
|
||||
void* aClientData,
|
||||
PRUint32 aFrameNumber,
|
||||
PRUint32 aDelayTimeout);
|
||||
static int PR_CALLBACK SetupColorspaceConverter();
|
||||
static int PR_CALLBACK ResetPalette();
|
||||
static int PR_CALLBACK InitTransparentPixel();
|
||||
static int PR_CALLBACK DestroyTransparentPixel();
|
||||
|
||||
static int PR_CALLBACK HaveImageAll(
|
||||
void* aClientData);
|
||||
#endif
|
||||
41
mozilla/modules/libpr0n/decoders/gif/nsGIFModule.cpp
Normal file
41
mozilla/modules/libpr0n/decoders/gif/nsGIFModule.cpp
Normal file
@@ -0,0 +1,41 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* 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 Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Chris Saari <saari@netscape.com>
|
||||
*/
|
||||
|
||||
#include "nsGIFDecoder2.h"
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsIGenericFactory.h"
|
||||
#include "nsISupports.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsGIFDecoder2)
|
||||
|
||||
static nsModuleComponentInfo components[] =
|
||||
{
|
||||
{ "GIF Decoder",
|
||||
NS_GIFDECODER2_CID,
|
||||
"@mozilla.org/image/decoder;2?type=image/gif",
|
||||
nsGIFDecoder2Constructor, },
|
||||
};
|
||||
|
||||
NS_IMPL_NSGETMODULE("nsGIFModule2", components)
|
||||
|
||||
18
mozilla/modules/libpr0n/decoders/gif/win32.order
Normal file
18
mozilla/modules/libpr0n/decoders/gif/win32.order
Normal file
@@ -0,0 +1,18 @@
|
||||
?AddRef@nsGIFDecoder2@@UAGKXZ ; 2550
|
||||
?Release@nsGIFDecoder2@@UAGKXZ ; 2550
|
||||
?gif_write_ready@@YAEPAUgif_struct@@@Z ; 1624
|
||||
?ProcessData@nsGIFDecoder2@@QAGIPAEI@Z ; 1624
|
||||
?gif_write@@YAHPAUgif_struct@@PBEI@Z ; 1624
|
||||
?WriteFrom@nsGIFDecoder2@@UAGIPAVnsIInputStream@@IPAI@Z ; 1309
|
||||
?Close@nsGIFDecoder2@@UAGIXZ ; 1275
|
||||
??_GnsGIFDecoder2@@UAEPAXI@Z ; 1275
|
||||
??0nsGIFDecoder2@@QAE@XZ ; 1275
|
||||
??1nsGIFDecoder2@@UAE@XZ ; 1275
|
||||
?QueryInterface@nsGIFDecoder2@@UAGIABUnsID@@PAPAX@Z ; 1275
|
||||
?GIFInit@@YAHPAUgif_struct@@PAXP6AHXZP6AH1IIE@ZP6AH1H@ZP6AH1IIIIIPAU_GIF_RGB@@@ZP6AH1II@Z2222P6AH1PAE8HHHHEH@ZP6AH1@Z@Z ; 1275
|
||||
?Init@nsGIFDecoder2@@UAGIPAVimgIRequest@@@Z ; 1275
|
||||
?Flush@nsGIFDecoder2@@UAGIXZ ; 1275
|
||||
?gif_destroy@@YAXPAUgif_struct@@@Z ; 1275
|
||||
?gif_create@@YAHPAPAUgif_struct@@@Z ; 1275
|
||||
?il_BACat@@YAPADPAPADIPBDI@Z ; 698
|
||||
_NSGetModule ; 1
|
||||
378
mozilla/modules/libpr0n/decoders/icon/mac/nsIconChannel.cpp
Normal file
378
mozilla/modules/libpr0n/decoders/icon/mac/nsIconChannel.cpp
Normal file
@@ -0,0 +1,378 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* 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 Brian Ryner.
|
||||
* Portions created by Brian Ryner are Copyright (C) 2000 Brian Ryner.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Scott MacGregor <mscott@netscape.com>
|
||||
*/
|
||||
|
||||
|
||||
#include "nsIconChannel.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsXPIDLString.h"
|
||||
#include "nsMimeTypes.h"
|
||||
#include "nsMemory.h"
|
||||
#include "nsIStringStream.h"
|
||||
#include "nsIURL.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsIMimeService.h"
|
||||
#include "nsCExternalHandlerService.h"
|
||||
#include "plstr.h"
|
||||
|
||||
#include <Files.h>
|
||||
#include <QuickDraw.h>
|
||||
|
||||
// nsIconChannel methods
|
||||
nsIconChannel::nsIconChannel()
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
mStatus = NS_OK;
|
||||
}
|
||||
|
||||
nsIconChannel::~nsIconChannel()
|
||||
{}
|
||||
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS2(nsIconChannel,
|
||||
nsIChannel,
|
||||
nsIRequest)
|
||||
|
||||
nsresult nsIconChannel::Init(nsIURI* uri)
|
||||
{
|
||||
nsresult rv;
|
||||
NS_ASSERTION(uri, "no uri");
|
||||
mUrl = uri;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsIRequest methods:
|
||||
|
||||
NS_IMETHODIMP nsIconChannel::GetName(PRUnichar* *result)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsIconChannel::IsPending(PRBool *result)
|
||||
{
|
||||
NS_NOTREACHED("nsIconChannel::IsPending");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsIconChannel::GetStatus(nsresult *status)
|
||||
{
|
||||
*status = mStatus;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsIconChannel::Cancel(nsresult status)
|
||||
{
|
||||
NS_ASSERTION(NS_FAILED(status), "shouldn't cancel with a success code");
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
|
||||
mStatus = status;
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsIconChannel::Suspend(void)
|
||||
{
|
||||
NS_NOTREACHED("nsIconChannel::Suspend");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsIconChannel::Resume(void)
|
||||
{
|
||||
NS_NOTREACHED("nsIconChannel::Resume");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsIChannel methods:
|
||||
|
||||
NS_IMETHODIMP nsIconChannel::GetOriginalURI(nsIURI* *aURI)
|
||||
{
|
||||
*aURI = mOriginalURI ? mOriginalURI : mUrl;
|
||||
NS_ADDREF(*aURI);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsIconChannel::SetOriginalURI(nsIURI* aURI)
|
||||
{
|
||||
mOriginalURI = aURI;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsIconChannel::GetURI(nsIURI* *aURI)
|
||||
{
|
||||
*aURI = mUrl;
|
||||
NS_IF_ADDREF(*aURI);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsIconChannel::SetURI(nsIURI* aURI)
|
||||
{
|
||||
mUrl = aURI;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIconChannel::Open(nsIInputStream **_retval)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP nsIconChannel::AsyncOpen(nsIStreamListener *aListener, nsISupports *ctxt)
|
||||
{
|
||||
// get the file name from the url
|
||||
nsXPIDLCString fileName; // will contain a dummy file we'll use to figure out the type of icon desired.
|
||||
nsXPIDLCString filePath; // will contain an optional parameter for small vs. large icon. default is small
|
||||
mUrl->GetHost(getter_Copies(fileName));
|
||||
nsCOMPtr<nsIURL> url (do_QueryInterface(mUrl));
|
||||
if (url)
|
||||
url->GetFileBaseName(getter_Copies(filePath));
|
||||
nsresult rv = NS_OK;
|
||||
nsCOMPtr<nsIMIMEService> mimeService (do_GetService(NS_MIMESERVICE_CONTRACTID, &rv));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// extract the extension out of the dummy file so we can look it up in the mime service.
|
||||
char * chFileName = fileName.get(); // get the underlying buffer
|
||||
char * fileExtension = PL_strrchr(chFileName, '.');
|
||||
if (!fileExtension) return NS_ERROR_FAILURE; // no file extension to work from.
|
||||
|
||||
// look the file extension up in the registry.
|
||||
nsCOMPtr<nsIMIMEInfo> mimeInfo;
|
||||
mimeService->GetFromExtension(fileExtension, getter_AddRefs(mimeInfo));
|
||||
NS_ENSURE_TRUE(mimeInfo, NS_ERROR_FAILURE);
|
||||
|
||||
// get the mac creator and file type for this mime object
|
||||
PRUint32 macType;
|
||||
PRUint32 macCreator;
|
||||
|
||||
mimeInfo->GetMacType(&macType);
|
||||
mimeInfo->GetMacCreator(&macCreator);
|
||||
|
||||
// get a refernce to the desktop database
|
||||
DTPBRec pb;
|
||||
OSErr err = noErr;
|
||||
|
||||
memset(&pb, 0, sizeof(DTPBRec));
|
||||
pb.ioCompletion = nil;
|
||||
pb.ioVRefNum = 0; // default desktop volume
|
||||
pb.ioNamePtr = nil;
|
||||
err = PBDTGetPath(&pb);
|
||||
if (err != noErr) return NS_ERROR_FAILURE;
|
||||
|
||||
pb.ioFileCreator = macCreator;
|
||||
pb.ioFileType = macType;
|
||||
pb.ioCompletion = nil;
|
||||
pb.ioTagInfo = 0;
|
||||
|
||||
PRUint32 numPixelsInRow = 0;
|
||||
if (filePath && !nsCRT::strcmp(filePath, "large"))
|
||||
{
|
||||
pb.ioDTReqCount = kLarge8BitIconSize;
|
||||
pb.ioIconType = kLarge8BitIcon;
|
||||
numPixelsInRow = 32;
|
||||
}
|
||||
else
|
||||
{
|
||||
pb.ioDTReqCount = kSmall8BitIconSize;
|
||||
pb.ioIconType = kSmall8BitIcon;
|
||||
numPixelsInRow = 16;
|
||||
}
|
||||
|
||||
// allocate a buffer large enough to handle the icon
|
||||
PRUint8 * bitmapData = (PRUint8 *) nsMemory::Alloc (pb.ioDTReqCount);
|
||||
pb.ioDTBuffer = (Ptr) bitmapData;
|
||||
|
||||
err = PBDTGetIcon(&pb, false);
|
||||
if (err != noErr) return NS_ERROR_FAILURE; // unable to fetch the icon....
|
||||
|
||||
nsCString iconBuffer;
|
||||
iconBuffer.Assign((char) numPixelsInRow);
|
||||
iconBuffer.Append((char) numPixelsInRow);
|
||||
CTabHandle cTabHandle = GetCTable(72);
|
||||
if (!cTabHandle) return NS_ERROR_FAILURE;
|
||||
|
||||
HLock((Handle) cTabHandle);
|
||||
CTabPtr colTable = *cTabHandle;
|
||||
RGBColor rgbCol;
|
||||
PRUint8 redValue, greenValue, blueValue;
|
||||
|
||||
for (PRUint32 index = 0; index < pb.ioDTReqCount; index ++)
|
||||
{
|
||||
|
||||
// each byte in bitmapData needs to be converted from an 8 bit system color into
|
||||
// 24 bit RGB data which our special icon image decoder can understand.
|
||||
ColorSpec colSpec = colTable->ctTable[ bitmapData[index]];
|
||||
rgbCol = colSpec.rgb;
|
||||
|
||||
redValue = rgbCol.red & 0xff;
|
||||
greenValue = rgbCol.green & 0xff;
|
||||
blueValue = rgbCol.blue & 0xff;
|
||||
|
||||
// for some reason the image code on the mac expects each RGB pixel value to be padded with a preceding byte.
|
||||
// so add the padding here....
|
||||
iconBuffer.Append((char) 0);
|
||||
iconBuffer.Append((char) redValue);
|
||||
iconBuffer.Append((char) greenValue);
|
||||
iconBuffer.Append((char) blueValue);
|
||||
}
|
||||
|
||||
|
||||
HUnlock((Handle) cTabHandle);
|
||||
DisposeCTable(cTabHandle);
|
||||
nsMemory::Free(bitmapData);
|
||||
|
||||
// now that the color bitmask is taken care of, we need to do the same thing again for the transparency
|
||||
// bit mask....
|
||||
if (filePath && !nsCRT::strcmp(filePath, "large"))
|
||||
{
|
||||
pb.ioDTReqCount = kLargeIconSize;
|
||||
pb.ioIconType = kLargeIcon;
|
||||
}
|
||||
else
|
||||
{
|
||||
pb.ioDTReqCount = kSmallIconSize;
|
||||
pb.ioIconType = kSmallIcon;
|
||||
}
|
||||
|
||||
// allocate a buffer large enough to handle the icon
|
||||
bitmapData = (PRUint8 *) nsMemory::Alloc (pb.ioDTReqCount);
|
||||
pb.ioDTBuffer = (Ptr) bitmapData;
|
||||
err = PBDTGetIcon(&pb, false);
|
||||
PRUint32 index = pb.ioDTReqCount/2;
|
||||
while (index < pb.ioDTReqCount)
|
||||
{
|
||||
iconBuffer.Append((char) bitmapData[index]);
|
||||
iconBuffer.Append((char) bitmapData[index + 1]);
|
||||
if (numPixelsInRow == 32)
|
||||
{
|
||||
iconBuffer.Append((char) bitmapData[index + 2]);
|
||||
iconBuffer.Append((char) bitmapData[index + 3]);
|
||||
index += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
iconBuffer.Append((char) 255); // 2 bytes of padding
|
||||
iconBuffer.Append((char) 255);
|
||||
index += 2;
|
||||
}
|
||||
}
|
||||
|
||||
nsMemory::Free(bitmapData);
|
||||
|
||||
// turn our nsString into a stream looking object...
|
||||
aListener->OnStartRequest(this, ctxt);
|
||||
|
||||
// turn our string into a stream...
|
||||
nsCOMPtr<nsISupports> streamSupports;
|
||||
NS_NewByteInputStream(getter_AddRefs(streamSupports), iconBuffer.get(), iconBuffer.Length());
|
||||
|
||||
nsCOMPtr<nsIInputStream> inputStr (do_QueryInterface(streamSupports));
|
||||
aListener->OnDataAvailable(this, ctxt, inputStr, 0, iconBuffer.Length());
|
||||
aListener->OnStopRequest(this, ctxt, NS_OK, nsnull);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsIconChannel::GetLoadAttributes(PRUint32 *aLoadAttributes)
|
||||
{
|
||||
*aLoadAttributes = mLoadAttributes;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsIconChannel::SetLoadAttributes(PRUint32 aLoadAttributes)
|
||||
{
|
||||
mLoadAttributes = aLoadAttributes;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsIconChannel::GetContentType(char* *aContentType)
|
||||
{
|
||||
if (!aContentType) return NS_ERROR_NULL_POINTER;
|
||||
|
||||
*aContentType = nsCRT::strdup("image/icon");
|
||||
if (!*aContentType) return NS_ERROR_OUT_OF_MEMORY;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIconChannel::SetContentType(const char *aContentType)
|
||||
{
|
||||
//It doesn't make sense to set the content-type on this type
|
||||
// of channel...
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsIconChannel::GetContentLength(PRInt32 *aContentLength)
|
||||
{
|
||||
*aContentLength = mContentLength;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsIconChannel::SetContentLength(PRInt32 aContentLength)
|
||||
{
|
||||
NS_NOTREACHED("nsIconChannel::SetContentLength");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsIconChannel::GetLoadGroup(nsILoadGroup* *aLoadGroup)
|
||||
{
|
||||
*aLoadGroup = mLoadGroup;
|
||||
NS_IF_ADDREF(*aLoadGroup);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsIconChannel::SetLoadGroup(nsILoadGroup* aLoadGroup)
|
||||
{
|
||||
mLoadGroup = aLoadGroup;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsIconChannel::GetOwner(nsISupports* *aOwner)
|
||||
{
|
||||
*aOwner = mOwner.get();
|
||||
NS_IF_ADDREF(*aOwner);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsIconChannel::SetOwner(nsISupports* aOwner)
|
||||
{
|
||||
mOwner = aOwner;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsIconChannel::GetNotificationCallbacks(nsIInterfaceRequestor* *aNotificationCallbacks)
|
||||
{
|
||||
*aNotificationCallbacks = mCallbacks.get();
|
||||
NS_IF_ADDREF(*aNotificationCallbacks);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsIconChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aNotificationCallbacks)
|
||||
{
|
||||
mCallbacks = aNotificationCallbacks;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsIconChannel::GetSecurityInfo(nsISupports * *aSecurityInfo)
|
||||
{
|
||||
*aSecurityInfo = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
56
mozilla/modules/libpr0n/decoders/icon/mac/nsIconChannel.h
Normal file
56
mozilla/modules/libpr0n/decoders/icon/mac/nsIconChannel.h
Normal file
@@ -0,0 +1,56 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* 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 Brian Ryner.
|
||||
* Portions created by Brian Ryner are Copyright (C) 2000 Brian Ryner.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Scott MacGregor <mscott@netscape.com>
|
||||
*/
|
||||
|
||||
#ifndef nsIconChannel_h___
|
||||
#define nsIconChannel_h___
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsXPIDLString.h"
|
||||
#include "nsIChannel.h"
|
||||
#include "nsILoadGroup.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsIURI.h"
|
||||
|
||||
class nsIconChannel : public nsIChannel
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIREQUEST
|
||||
NS_DECL_NSICHANNEL
|
||||
|
||||
nsIconChannel();
|
||||
virtual ~nsIconChannel();
|
||||
|
||||
nsresult Init(nsIURI* uri);
|
||||
|
||||
protected:
|
||||
nsCOMPtr<nsIURI> mUrl;
|
||||
nsCOMPtr<nsIURI> mOriginalURI;
|
||||
PRUint32 mLoadAttributes;
|
||||
PRInt32 mContentLength;
|
||||
nsCOMPtr<nsILoadGroup> mLoadGroup;
|
||||
nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
|
||||
nsCOMPtr<nsISupports> mOwner;
|
||||
nsresult mStatus;
|
||||
};
|
||||
|
||||
#endif /* nsIconChannel_h___ */
|
||||
62
mozilla/modules/libpr0n/decoders/icon/makefile.win
Normal file
62
mozilla/modules/libpr0n/decoders/icon/makefile.win
Normal file
@@ -0,0 +1,62 @@
|
||||
#!nmake
|
||||
#
|
||||
# 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 Netscape are
|
||||
# Copyright (C) 2001 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Scott MacGregor <mscott@netscape.com>
|
||||
#
|
||||
|
||||
DEPTH=..\..\..\..
|
||||
include <$(DEPTH)/config/config.mak>
|
||||
|
||||
DIR=win
|
||||
|
||||
MODULE = imgicon
|
||||
LIBRARY_NAME = imgicon
|
||||
DLL = $(OBJDIR)\$(LIBRARY_NAME).dll
|
||||
MAKE_OBJ_TYPE = DLL
|
||||
|
||||
OBJS = \
|
||||
.\$(OBJDIR)\nsIconDecoder.obj \
|
||||
.\$(OBJDIR)\nsIconModule.obj \
|
||||
.\$(OBJDIR)\nsIconProtocolHandler.obj \
|
||||
$(NULL)
|
||||
|
||||
LLIBS=\
|
||||
$(LIBNSPR) \
|
||||
$(DIST)\lib\xpcom.lib \
|
||||
$(DIST)\lib\gkgfxwin.lib \
|
||||
$(DIST)\lib\imgiconwin_s.lib \
|
||||
$(NULL)
|
||||
|
||||
WIN_LIBS= shell32.lib
|
||||
|
||||
INCS = $(INCS) \
|
||||
-I$(DEPTH)\dist\include \
|
||||
-I$(DEPTH)\modules\libpr0n\decoders\icon\win \
|
||||
$(NULL)
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
|
||||
install:: $(DLL)
|
||||
$(MAKE_INSTALL) .\$(OBJDIR)\$(LIBRARY_NAME).dll $(DIST)\bin\components
|
||||
$(MAKE_INSTALL) .\$(OBJDIR)\$(LIBRARY_NAME).lib $(DIST)\lib
|
||||
|
||||
clobber::
|
||||
rm -f $(DIST)\bin\components\$(LIBRARY_NAME).dll
|
||||
rm -f $(DIST)\lib\$(LIBRARY_NAME).lib
|
||||
195
mozilla/modules/libpr0n/decoders/icon/nsIconDecoder.cpp
Normal file
195
mozilla/modules/libpr0n/decoders/icon/nsIconDecoder.cpp
Normal file
@@ -0,0 +1,195 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* 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 Netscape are
|
||||
* Copyright (C) 2001 Netscape Communications Corporation.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Scott MacGregor <mscott@netscape.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nsIconDecoder.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "imgIContainer.h"
|
||||
#include "imgIContainerObserver.h"
|
||||
#include "nspr.h"
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsRect.h"
|
||||
|
||||
NS_IMPL_THREADSAFE_ADDREF(nsIconDecoder);
|
||||
NS_IMPL_THREADSAFE_RELEASE(nsIconDecoder);
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(nsIconDecoder)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIOutputStream)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIOutputStream)
|
||||
NS_INTERFACE_MAP_ENTRY(imgIDecoder)
|
||||
NS_INTERFACE_MAP_END_THREADSAFE
|
||||
|
||||
nsIconDecoder::nsIconDecoder()
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
}
|
||||
|
||||
nsIconDecoder::~nsIconDecoder()
|
||||
{ }
|
||||
|
||||
|
||||
/** imgIDecoder methods **/
|
||||
|
||||
NS_IMETHODIMP nsIconDecoder::Init(imgIRequest *aRequest)
|
||||
{
|
||||
mRequest = aRequest;
|
||||
|
||||
mObserver = do_QueryInterface(aRequest); // we're holding 2 strong refs to the request.
|
||||
|
||||
aRequest->GetImage(getter_AddRefs(mImage));
|
||||
|
||||
mFrame = do_CreateInstance("@mozilla.org/gfx/image/frame;2");
|
||||
if (!mFrame) return NS_ERROR_FAILURE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsIconDecoder::GetRequest(imgIRequest * *aRequest)
|
||||
{
|
||||
*aRequest = mRequest;
|
||||
NS_ADDREF(*aRequest);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/** nsIOutputStream methods **/
|
||||
|
||||
NS_IMETHODIMP nsIconDecoder::Close()
|
||||
{
|
||||
if (mObserver)
|
||||
{
|
||||
mObserver->OnStopFrame(nsnull, nsnull, mFrame);
|
||||
mObserver->OnStopContainer(nsnull, nsnull, mImage);
|
||||
mObserver->OnStopDecode(nsnull, nsnull, NS_OK, nsnull);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsIconDecoder::Flush()
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsIconDecoder::Write(const char *buf, PRUint32 count, PRUint32 *_retval)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsIconDecoder::WriteFrom(nsIInputStream *inStr, PRUint32 count, PRUint32 *_retval)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
char *buf = (char *)PR_Malloc(count);
|
||||
if (!buf) return NS_ERROR_OUT_OF_MEMORY; /* we couldn't allocate the object */
|
||||
|
||||
// read the data from the input stram...
|
||||
PRUint32 readLen;
|
||||
rv = inStr->Read(buf, count, &readLen);
|
||||
|
||||
char *data = buf;
|
||||
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// since WriteFrom is only called once, go ahead and fire the on start notifications..
|
||||
|
||||
mObserver->OnStartDecode(nsnull, nsnull);
|
||||
PRUint32 i = 0;
|
||||
// Read size
|
||||
PRInt32 w, h;
|
||||
w = data[0];
|
||||
h = data[1];
|
||||
|
||||
data += 2;
|
||||
|
||||
readLen -= i + 2;
|
||||
|
||||
mImage->Init(w, h, mObserver);
|
||||
if (mObserver)
|
||||
mObserver->OnStartContainer(nsnull, nsnull, mImage);
|
||||
|
||||
mFrame->Init(0, 0, w, h, gfxIFormats::RGB_A1);
|
||||
mImage->AppendFrame(mFrame);
|
||||
if (mObserver)
|
||||
mObserver->OnStartFrame(nsnull, nsnull, mFrame);
|
||||
|
||||
PRUint32 bpr, abpr;
|
||||
nscoord width, height;
|
||||
mFrame->GetImageBytesPerRow(&bpr);
|
||||
mFrame->GetAlphaBytesPerRow(&abpr);
|
||||
mFrame->GetWidth(&width);
|
||||
mFrame->GetHeight(&height);
|
||||
|
||||
i = 0;
|
||||
PRInt32 rownum = 0; // XXX this better not have a decimal
|
||||
|
||||
PRInt32 wroteLen = 0;
|
||||
|
||||
do
|
||||
{
|
||||
PRUint8 *line = (PRUint8*)data + i*bpr;
|
||||
mFrame->SetImageData(line, bpr, (rownum++)*bpr);
|
||||
|
||||
nsRect r(0, rownum, width, 1);
|
||||
mObserver->OnDataAvailable(nsnull, nsnull, mFrame, &r);
|
||||
|
||||
wroteLen += bpr ;
|
||||
i++;
|
||||
} while(rownum < height);
|
||||
|
||||
|
||||
// now we want to send in the alpha data...
|
||||
for (rownum = 0; rownum < height; rownum ++)
|
||||
{
|
||||
PRUint8 * line = (PRUint8*) data + abpr * rownum + height*bpr;
|
||||
mFrame->SetAlphaData(line, abpr, (rownum)*abpr);
|
||||
}
|
||||
|
||||
PR_FREEIF(buf);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsIconDecoder::WriteSegments(nsReadSegmentFun reader, void * closure, PRUint32 count, PRUint32 *_retval)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsIconDecoder::GetNonBlocking(PRBool *aNonBlocking)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsIconDecoder::SetNonBlocking(PRBool aNonBlocking)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsIconDecoder::GetObserver(nsIOutputStreamObserver * *aObserver)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsIconDecoder::SetObserver(nsIOutputStreamObserver * aObserver)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
79
mozilla/modules/libpr0n/decoders/icon/nsIconDecoder.h
Normal file
79
mozilla/modules/libpr0n/decoders/icon/nsIconDecoder.h
Normal file
@@ -0,0 +1,79 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* 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 Netscape are
|
||||
* Copyright (C) 2001 Netscape Communications Corporation.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Scott MacGregor <mscott@netscape.com>
|
||||
*/
|
||||
|
||||
#ifndef nsIconDecoder_h__
|
||||
#define nsIconDecoder_h__
|
||||
|
||||
#include "imgIDecoder.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
#include "imgIContainer.h"
|
||||
#include "imgIDecoderObserver.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
#include "imgIRequest.h"
|
||||
|
||||
#define NS_ICONDECODER_CID \
|
||||
{ /* FFC08380-256C-11d5-9905-001083010E9B */ \
|
||||
0xffc08380, \
|
||||
0x256c, \
|
||||
0x11d5, \
|
||||
{ 0x99, 0x5, 0x0, 0x10, 0x83, 0x1, 0xe, 0x9b } \
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// The icon decoder is a decoder specifically tailored for loading icons
|
||||
// from the OS. We've defined our own little format to represent these icons
|
||||
// and this decoder takes that format and converts it into 24-bit RGB with alpha channel
|
||||
// support. It was modeled a bit off the PPM decoder.
|
||||
//
|
||||
// Assumptions about the decoder:
|
||||
// (1) We receive ALL of the data from the icon channel in one OnDataAvailable call. We don't
|
||||
// support multiple ODA calls yet.
|
||||
// (2) the format of the incoming data is as follows:
|
||||
// The first two bytes contain the width and the height of the icon.
|
||||
// Followed by 3 bytes per pixel for the color bitmap row after row. (for heigh * width * 3 bytes)
|
||||
// Followed by bit mask data (used for transparency on the alpha channel).
|
||||
//
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class nsIconDecoder : public imgIDecoder
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_IMGIDECODER
|
||||
NS_DECL_NSIOUTPUTSTREAM
|
||||
|
||||
nsIconDecoder();
|
||||
virtual ~nsIconDecoder();
|
||||
|
||||
private:
|
||||
nsCOMPtr<imgIContainer> mImage;
|
||||
nsCOMPtr<gfxIImageFrame> mFrame;
|
||||
nsCOMPtr<imgIRequest> mRequest;
|
||||
nsCOMPtr<imgIDecoderObserver> mObserver; // this is just qi'd from mRequest for speed
|
||||
};
|
||||
|
||||
#endif // nsIconDecoder_h__
|
||||
54
mozilla/modules/libpr0n/decoders/icon/nsIconModule.cpp
Normal file
54
mozilla/modules/libpr0n/decoders/icon/nsIconModule.cpp
Normal file
@@ -0,0 +1,54 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* 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 Netscape are
|
||||
* Copyright (C) 2001 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Scott MacGregor <mscott@netscape.com>
|
||||
*/
|
||||
|
||||
#include "nsIGenericFactory.h"
|
||||
#include "nsIModule.h"
|
||||
|
||||
#include "nsIconDecoder.h"
|
||||
#include "nsIconProtocolHandler.h"
|
||||
|
||||
// objects that just require generic constructors
|
||||
/******************************************************************************
|
||||
* Protocol CIDs
|
||||
*/
|
||||
#define NS_ICONPROTOCOL_CID { 0xd0f9db12, 0x249c, 0x11d5, { 0x99, 0x5, 0x0, 0x10, 0x83, 0x1, 0xe, 0x9b } }
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsIconDecoder)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsIconProtocolHandler)
|
||||
|
||||
static nsModuleComponentInfo components[] =
|
||||
{
|
||||
{ "icon decoder",
|
||||
NS_ICONDECODER_CID,
|
||||
"@mozilla.org/image/decoder;2?type=image/icon",
|
||||
nsIconDecoderConstructor, },
|
||||
|
||||
{ "Icon Protocol Handler",
|
||||
NS_ICONPROTOCOL_CID,
|
||||
NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "icon",
|
||||
nsIconProtocolHandlerConstructor
|
||||
}
|
||||
};
|
||||
|
||||
NS_IMPL_NSGETMODULE("nsIconDecoderModule", components)
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* 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 Brian Ryner.
|
||||
* Portions created by Brian Ryner are Copyright (C) 2000 Brian Ryner.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Scott MacGregor <mscott@netscape.com>
|
||||
*/
|
||||
|
||||
#include "nsIconChannel.h"
|
||||
#include "nsIconProtocolHandler.h"
|
||||
#include "nsIURL.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsIServiceManager.h"
|
||||
|
||||
static NS_DEFINE_CID(kStandardURICID, NS_STANDARDURL_CID);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsIconProtocolHandler::nsIconProtocolHandler()
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
}
|
||||
|
||||
nsIconProtocolHandler::~nsIconProtocolHandler()
|
||||
{}
|
||||
|
||||
NS_IMPL_ISUPPORTS2(nsIconProtocolHandler, nsIProtocolHandler, nsISupportsWeakReference)
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsIProtocolHandler methods:
|
||||
|
||||
NS_IMETHODIMP nsIconProtocolHandler::GetScheme(char* *result)
|
||||
{
|
||||
*result = nsCRT::strdup("icon");
|
||||
if (!*result) return NS_ERROR_OUT_OF_MEMORY;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsIconProtocolHandler::GetDefaultPort(PRInt32 *result)
|
||||
{
|
||||
*result = 0;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsIconProtocolHandler::NewURI(const char *aSpec, nsIURI *aBaseURI, nsIURI **result)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
// no concept of a relative icon url
|
||||
NS_ASSERTION(!aBaseURI, "base url passed into icon protocol handler");
|
||||
nsCOMPtr<nsIURI> url = do_CreateInstance(kStandardURICID, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
rv = url->SetSpec((char*)aSpec);
|
||||
*result = url;
|
||||
NS_IF_ADDREF(*result);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsIconProtocolHandler::NewChannel(nsIURI* url, nsIChannel* *result)
|
||||
{
|
||||
nsCOMPtr<nsIChannel> channel;
|
||||
NS_NEWXPCOM(channel, nsIconChannel);
|
||||
|
||||
if (channel)
|
||||
NS_STATIC_CAST(nsIconChannel*,NS_STATIC_CAST(nsIChannel*, channel))->Init(url);
|
||||
|
||||
*result = channel;
|
||||
NS_IF_ADDREF(*result);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,43 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* 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 Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Scott MacGregor <mscott@netscape.com>
|
||||
*/
|
||||
|
||||
#ifndef nsIconProtocolHandler_h___
|
||||
#define nsIconProtocolHandler_h___
|
||||
|
||||
#include "nsWeakReference.h"
|
||||
#include "nsIProtocolHandler.h"
|
||||
|
||||
class nsIconProtocolHandler : public nsIProtocolHandler, public nsSupportsWeakReference
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIPROTOCOLHANDLER
|
||||
|
||||
// nsIconProtocolHandler methods:
|
||||
nsIconProtocolHandler();
|
||||
virtual ~nsIconProtocolHandler();
|
||||
|
||||
protected:
|
||||
};
|
||||
|
||||
#endif /* nsIconProtocolHandler_h___ */
|
||||
46
mozilla/modules/libpr0n/decoders/icon/win/makefile.win
Normal file
46
mozilla/modules/libpr0n/decoders/icon/win/makefile.win
Normal file
@@ -0,0 +1,46 @@
|
||||
#!gmake
|
||||
#
|
||||
# The contents of this file are subject to the Netscape 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/NPL/
|
||||
#
|
||||
# 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 Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Scott MacGregor <mscott@netscape.com>
|
||||
|
||||
DEPTH=..\..\..\..\..
|
||||
MODULE=imgicon
|
||||
|
||||
LIBRARY_NAME=imgiconwin_s
|
||||
|
||||
CPP_OBJS=\
|
||||
.\$(OBJDIR)\nsIconChannel.obj \
|
||||
$(NULL)
|
||||
|
||||
INCS = $(INCS) \
|
||||
-I$(DEPTH)\dist\include \
|
||||
-I..\ \
|
||||
$(NULL)
|
||||
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
|
||||
install:: $(LIBRARY)
|
||||
$(MAKE_INSTALL) $(LIBRARY) $(DIST)\lib
|
||||
|
||||
|
||||
clobber::
|
||||
rm -f $(DIST)\lib\$(LIBRARY_NAME).lib
|
||||
|
||||
377
mozilla/modules/libpr0n/decoders/icon/win/nsIconChannel.cpp
Normal file
377
mozilla/modules/libpr0n/decoders/icon/win/nsIconChannel.cpp
Normal file
@@ -0,0 +1,377 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* 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 Brian Ryner.
|
||||
* Portions created by Brian Ryner are Copyright (C) 2000 Brian Ryner.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Scott MacGregor <mscott@netscape.com>
|
||||
*/
|
||||
|
||||
|
||||
#include "nsIconChannel.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsXPIDLString.h"
|
||||
#include "nsMimeTypes.h"
|
||||
#include "nsMemory.h"
|
||||
#include "nsIStringStream.h"
|
||||
#include "nsIURL.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
||||
// we need windows.h to read out registry information...
|
||||
#include <windows.h>
|
||||
#include <shellapi.h>
|
||||
|
||||
// nsIconChannel methods
|
||||
nsIconChannel::nsIconChannel()
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
mStatus = NS_OK;
|
||||
}
|
||||
|
||||
nsIconChannel::~nsIconChannel()
|
||||
{}
|
||||
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS2(nsIconChannel,
|
||||
nsIChannel,
|
||||
nsIRequest)
|
||||
|
||||
nsresult nsIconChannel::Init(nsIURI* uri)
|
||||
{
|
||||
nsresult rv;
|
||||
NS_ASSERTION(uri, "no uri");
|
||||
mUrl = uri;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsIRequest methods:
|
||||
|
||||
NS_IMETHODIMP nsIconChannel::GetName(PRUnichar* *result)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsIconChannel::IsPending(PRBool *result)
|
||||
{
|
||||
NS_NOTREACHED("nsIconChannel::IsPending");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsIconChannel::GetStatus(nsresult *status)
|
||||
{
|
||||
*status = mStatus;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsIconChannel::Cancel(nsresult status)
|
||||
{
|
||||
NS_ASSERTION(NS_FAILED(status), "shouldn't cancel with a success code");
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
|
||||
mStatus = status;
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsIconChannel::Suspend(void)
|
||||
{
|
||||
NS_NOTREACHED("nsIconChannel::Suspend");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsIconChannel::Resume(void)
|
||||
{
|
||||
NS_NOTREACHED("nsIconChannel::Resume");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsIChannel methods:
|
||||
|
||||
NS_IMETHODIMP nsIconChannel::GetOriginalURI(nsIURI* *aURI)
|
||||
{
|
||||
*aURI = mOriginalURI ? mOriginalURI : mUrl;
|
||||
NS_ADDREF(*aURI);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsIconChannel::SetOriginalURI(nsIURI* aURI)
|
||||
{
|
||||
mOriginalURI = aURI;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsIconChannel::GetURI(nsIURI* *aURI)
|
||||
{
|
||||
*aURI = mUrl;
|
||||
NS_IF_ADDREF(*aURI);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsIconChannel::SetURI(nsIURI* aURI)
|
||||
{
|
||||
mUrl = aURI;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIconChannel::Open(nsIInputStream **_retval)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
void InvertRows(unsigned char * aInitialBuffer, PRUint32 sizeOfBuffer, PRUint32 numBytesPerRow)
|
||||
{
|
||||
PRUint32 numRows = sizeOfBuffer / numBytesPerRow;
|
||||
void * temporaryRowHolder = (void *) nsMemory::Alloc(numBytesPerRow);
|
||||
|
||||
PRUint32 currentRow = 0;
|
||||
PRUint32 lastRow = (numRows - 1) * numBytesPerRow;
|
||||
while (currentRow < lastRow)
|
||||
{
|
||||
// store the current row into a temporary buffer
|
||||
nsCRT::memcpy(temporaryRowHolder, (void *) &aInitialBuffer[currentRow], numBytesPerRow);
|
||||
nsCRT::memcpy((void *) &aInitialBuffer[currentRow], (void *)&aInitialBuffer[lastRow], numBytesPerRow);
|
||||
nsCRT::memcpy((void *) &aInitialBuffer[lastRow], temporaryRowHolder, numBytesPerRow);
|
||||
lastRow -= numBytesPerRow;
|
||||
currentRow += numBytesPerRow;
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsIconChannel::AsyncOpen(nsIStreamListener *aListener, nsISupports *ctxt)
|
||||
{
|
||||
// get the file name from the url
|
||||
nsXPIDLCString fileName; // will contain a dummy file we'll use to figure out the type of icon desired.
|
||||
nsXPIDLCString filePath; // will contain an optional parameter for small vs. large icon. default is small
|
||||
mUrl->GetHost(getter_Copies(fileName));
|
||||
nsCOMPtr<nsIURL> url (do_QueryInterface(mUrl));
|
||||
if (url)
|
||||
url->GetFileBaseName(getter_Copies(filePath));
|
||||
|
||||
|
||||
// 1) get a hIcon for the file.
|
||||
SHFILEINFO sfi;
|
||||
UINT infoFlags = SHGFI_USEFILEATTRIBUTES | SHGFI_ICON;
|
||||
if (filePath && !nsCRT::strcmp(filePath, "large"))
|
||||
infoFlags |= SHGFI_LARGEICON;
|
||||
else // default to small
|
||||
infoFlags |= SHGFI_SMALLICON;
|
||||
|
||||
LONG result= SHGetFileInfo(fileName, FILE_ATTRIBUTE_ARCHIVE, &sfi, sizeof(sfi), infoFlags);
|
||||
if (result > 0 && sfi.hIcon)
|
||||
{
|
||||
// we got a handle to an icon. Now we want to get a bitmap for the icon using GetIconInfo....
|
||||
ICONINFO pIconInfo;
|
||||
result = GetIconInfo(sfi.hIcon, &pIconInfo);
|
||||
if (result > 0)
|
||||
{
|
||||
// now we have the bit map we need to get info about the bitmap
|
||||
BITMAPINFO pBitMapInfo;
|
||||
BITMAPINFOHEADER pBitMapInfoHeader;
|
||||
pBitMapInfo.bmiHeader.biBitCount = 0;
|
||||
pBitMapInfo.bmiHeader.biSize = sizeof(pBitMapInfoHeader);
|
||||
|
||||
HDC pDC = CreateCompatibleDC(NULL); // get a device context for the screen.
|
||||
result = GetDIBits(pDC, pIconInfo.hbmColor, 0, 0, NULL, &pBitMapInfo, DIB_RGB_COLORS);
|
||||
if (result > 0 && pBitMapInfo.bmiHeader.biSizeImage > 0)
|
||||
{
|
||||
// allocate a buffer to hold the bit map....this should be a buffer that's biSizeImage...
|
||||
unsigned char * buffer = (PRUint8 *) nsMemory::Alloc(pBitMapInfo.bmiHeader.biSizeImage);
|
||||
result = GetDIBits(pDC, pIconInfo.hbmColor, 0, pBitMapInfo.bmiHeader.biHeight, (void *) buffer, &pBitMapInfo, DIB_RGB_COLORS);
|
||||
if (result > 0)
|
||||
{
|
||||
PRUint32 bytesPerPixel = pBitMapInfo.bmiHeader.biBitCount / 8;
|
||||
InvertRows(buffer, pBitMapInfo.bmiHeader.biSizeImage, pBitMapInfo.bmiHeader.biWidth * bytesPerPixel);
|
||||
// Convert our little icon buffer which is padded to 4 bytes per pixel into a nice 3 byte per pixel
|
||||
// description.
|
||||
nsCString iconBuffer;
|
||||
iconBuffer.Assign((char) pBitMapInfo.bmiHeader.biWidth);
|
||||
iconBuffer.Append((char) pBitMapInfo.bmiHeader.biHeight);
|
||||
|
||||
PRInt32 index = 0;
|
||||
if (pBitMapInfo.bmiHeader.biBitCount == 16)
|
||||
{
|
||||
PRUint8 redValue, greenValue, blueValue, partialGreen;
|
||||
while (index < pBitMapInfo.bmiHeader.biSizeImage)
|
||||
{
|
||||
DWORD dst=(DWORD) buffer[index];
|
||||
PRUint16 num = 0;
|
||||
num = (PRUint8) buffer[index];
|
||||
num <<= 8;
|
||||
num |= (PRUint8) buffer[index+1];
|
||||
|
||||
//blueValue = (PRUint8)((*dst)&(0x1F));
|
||||
//greenValue = (PRUint8)(((*dst)>>5)&(0x1F));
|
||||
//redValue = (PRUint8)(((*dst)>>10)&(0x1F));
|
||||
|
||||
redValue = ((PRUint32) (((float)(num & 0x7c00) / 0x7c00) * 0xFF0000) & 0xFF0000)>> 16;
|
||||
greenValue = ((PRUint32)(((float)(num & 0x03E0) / 0x03E0) * 0x00FF00) & 0x00FF00)>> 8;
|
||||
blueValue = ((PRUint32)(((float)(num & 0x001F) / 0x001F) * 0x0000FF) & 0x0000FF);
|
||||
|
||||
// now we have the right RGB values...
|
||||
iconBuffer.Append((char) redValue);
|
||||
iconBuffer.Append((char) greenValue);
|
||||
iconBuffer.Append((char) blueValue);
|
||||
index += bytesPerPixel;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (index <pBitMapInfo.bmiHeader.biSizeImage)
|
||||
{
|
||||
iconBuffer.Append((char) buffer[index]);
|
||||
iconBuffer.Append((char) buffer[index+1]);
|
||||
iconBuffer.Append((char) buffer[index+2]);
|
||||
index += bytesPerPixel;
|
||||
}
|
||||
}
|
||||
|
||||
// now we need to tack on the alpha data...which is hbmMask
|
||||
pBitMapInfo.bmiHeader.biBitCount = 0;
|
||||
pBitMapInfo.bmiHeader.biSize = sizeof(pBitMapInfoHeader);
|
||||
result = GetDIBits(pDC, pIconInfo.hbmMask, 0, 0, NULL, &pBitMapInfo, DIB_RGB_COLORS);
|
||||
if (result > 0 && pBitMapInfo.bmiHeader.biSizeImage > 0)
|
||||
{
|
||||
// allocate a buffer to hold the bit map....this should be a buffer that's biSizeImage...
|
||||
unsigned char * maskBuffer = (PRUint8 *) nsMemory::Alloc(pBitMapInfo.bmiHeader.biSizeImage);
|
||||
result = GetDIBits(pDC, pIconInfo.hbmMask, 0, pBitMapInfo.bmiHeader.biHeight, (void *) maskBuffer, &pBitMapInfo, DIB_RGB_COLORS);
|
||||
if (result > 0)
|
||||
{
|
||||
InvertRows(maskBuffer, pBitMapInfo.bmiHeader.biSizeImage, 4);
|
||||
index = 0;
|
||||
// for some reason the bit mask on windows are flipped from the values we really want for transparency.
|
||||
// So complement each byte in the bit mask.
|
||||
while (index < pBitMapInfo.bmiHeader.biSizeImage)
|
||||
{
|
||||
maskBuffer[index]^=255;
|
||||
index += 1;
|
||||
}
|
||||
iconBuffer.Append((char *) maskBuffer, pBitMapInfo.bmiHeader.biSizeImage);
|
||||
}
|
||||
|
||||
nsMemory::Free(maskBuffer);
|
||||
} // if we have a mask buffer to apply
|
||||
|
||||
// turn our nsString into a stream looking object...
|
||||
aListener->OnStartRequest(this, ctxt);
|
||||
|
||||
// turn our string into a stream...
|
||||
nsCOMPtr<nsISupports> streamSupports;
|
||||
NS_NewByteInputStream(getter_AddRefs(streamSupports), iconBuffer.get(), iconBuffer.Length());
|
||||
|
||||
nsCOMPtr<nsIInputStream> inputStr (do_QueryInterface(streamSupports));
|
||||
aListener->OnDataAvailable(this, ctxt, inputStr, 0, iconBuffer.Length());
|
||||
aListener->OnStopRequest(this, ctxt, NS_OK, nsnull);
|
||||
|
||||
} // if we got valid bits for the main bitmap mask
|
||||
|
||||
nsMemory::Free(buffer);
|
||||
|
||||
}
|
||||
|
||||
DeleteDC(pDC);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsIconChannel::GetLoadAttributes(PRUint32 *aLoadAttributes)
|
||||
{
|
||||
*aLoadAttributes = mLoadAttributes;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsIconChannel::SetLoadAttributes(PRUint32 aLoadAttributes)
|
||||
{
|
||||
mLoadAttributes = aLoadAttributes;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsIconChannel::GetContentType(char* *aContentType)
|
||||
{
|
||||
if (!aContentType) return NS_ERROR_NULL_POINTER;
|
||||
|
||||
*aContentType = nsCRT::strdup("image/icon");
|
||||
if (!*aContentType) return NS_ERROR_OUT_OF_MEMORY;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIconChannel::SetContentType(const char *aContentType)
|
||||
{
|
||||
//It doesn't make sense to set the content-type on this type
|
||||
// of channel...
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsIconChannel::GetContentLength(PRInt32 *aContentLength)
|
||||
{
|
||||
*aContentLength = mContentLength;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsIconChannel::SetContentLength(PRInt32 aContentLength)
|
||||
{
|
||||
NS_NOTREACHED("nsIconChannel::SetContentLength");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsIconChannel::GetLoadGroup(nsILoadGroup* *aLoadGroup)
|
||||
{
|
||||
*aLoadGroup = mLoadGroup;
|
||||
NS_IF_ADDREF(*aLoadGroup);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsIconChannel::SetLoadGroup(nsILoadGroup* aLoadGroup)
|
||||
{
|
||||
mLoadGroup = aLoadGroup;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsIconChannel::GetOwner(nsISupports* *aOwner)
|
||||
{
|
||||
*aOwner = mOwner.get();
|
||||
NS_IF_ADDREF(*aOwner);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsIconChannel::SetOwner(nsISupports* aOwner)
|
||||
{
|
||||
mOwner = aOwner;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsIconChannel::GetNotificationCallbacks(nsIInterfaceRequestor* *aNotificationCallbacks)
|
||||
{
|
||||
*aNotificationCallbacks = mCallbacks.get();
|
||||
NS_IF_ADDREF(*aNotificationCallbacks);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsIconChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aNotificationCallbacks)
|
||||
{
|
||||
mCallbacks = aNotificationCallbacks;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsIconChannel::GetSecurityInfo(nsISupports * *aSecurityInfo)
|
||||
{
|
||||
*aSecurityInfo = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
56
mozilla/modules/libpr0n/decoders/icon/win/nsIconChannel.h
Normal file
56
mozilla/modules/libpr0n/decoders/icon/win/nsIconChannel.h
Normal file
@@ -0,0 +1,56 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* 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 Brian Ryner.
|
||||
* Portions created by Brian Ryner are Copyright (C) 2000 Brian Ryner.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Scott MacGregor <mscott@netscape.com>
|
||||
*/
|
||||
|
||||
#ifndef nsIconChannel_h___
|
||||
#define nsIconChannel_h___
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsXPIDLString.h"
|
||||
#include "nsIChannel.h"
|
||||
#include "nsILoadGroup.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsIURI.h"
|
||||
|
||||
class nsIconChannel : public nsIChannel
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIREQUEST
|
||||
NS_DECL_NSICHANNEL
|
||||
|
||||
nsIconChannel();
|
||||
virtual ~nsIconChannel();
|
||||
|
||||
nsresult Init(nsIURI* uri);
|
||||
|
||||
protected:
|
||||
nsCOMPtr<nsIURI> mUrl;
|
||||
nsCOMPtr<nsIURI> mOriginalURI;
|
||||
PRUint32 mLoadAttributes;
|
||||
PRInt32 mContentLength;
|
||||
nsCOMPtr<nsILoadGroup> mLoadGroup;
|
||||
nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
|
||||
nsCOMPtr<nsISupports> mOwner;
|
||||
nsresult mStatus;
|
||||
};
|
||||
|
||||
#endif /* nsIconChannel_h___ */
|
||||
42
mozilla/modules/libpr0n/decoders/jpeg/Makefile.in
Normal file
42
mozilla/modules/libpr0n/decoders/jpeg/Makefile.in
Normal file
@@ -0,0 +1,42 @@
|
||||
#
|
||||
# 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 Netscape are
|
||||
# Copyright (C) 2001 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
|
||||
DEPTH = ../../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = imgjpeg
|
||||
LIBRARY_NAME = imgjpeg
|
||||
IS_COMPONENT = 1
|
||||
|
||||
REQUIRES = xpcom string necko layout jpeg gfx2 imglib2
|
||||
|
||||
CPPSRCS = nsJPEGDecoder.cpp nsJPEGFactory.cpp
|
||||
|
||||
EXTRA_DSO_LDOPTS = $(JPEG_LIBS) $(ZLIB_LIBS) \
|
||||
$(MOZ_COMPONENT_LIBS) \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
52
mozilla/modules/libpr0n/decoders/jpeg/makefile.win
Normal file
52
mozilla/modules/libpr0n/decoders/jpeg/makefile.win
Normal file
@@ -0,0 +1,52 @@
|
||||
#!nmake
|
||||
#
|
||||
# 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 Netscape are
|
||||
# Copyright (C) 2001 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Stuart Parmenter <pavlov@netscape.com>
|
||||
#
|
||||
|
||||
DEPTH=..\..\..\..
|
||||
include <$(DEPTH)/config/config.mak>
|
||||
|
||||
MODULE = imgjpeg
|
||||
LIBRARY_NAME = imgjpeg
|
||||
DLL = $(OBJDIR)\$(LIBRARY_NAME).dll
|
||||
MAKE_OBJ_TYPE = DLL
|
||||
|
||||
OBJS = \
|
||||
.\$(OBJDIR)\nsJPEGDecoder.obj \
|
||||
.\$(OBJDIR)\nsJPEGFactory.obj \
|
||||
$(NULL)
|
||||
|
||||
LLIBS=\
|
||||
$(LIBNSPR) \
|
||||
$(DIST)\lib\jpeg3250.lib \
|
||||
$(DIST)\lib\xpcom.lib \
|
||||
$(DIST)\lib\gkgfxwin.lib \
|
||||
$(NULL)
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
|
||||
install:: $(DLL)
|
||||
$(MAKE_INSTALL) .\$(OBJDIR)\$(LIBRARY_NAME).dll $(DIST)\bin\components
|
||||
$(MAKE_INSTALL) .\$(OBJDIR)\$(LIBRARY_NAME).lib $(DIST)\lib
|
||||
|
||||
clobber::
|
||||
rm -f $(DIST)\bin\components\$(LIBRARY_NAME).dll
|
||||
rm -f $(DIST)\lib\$(LIBRARY_NAME).lib
|
||||
829
mozilla/modules/libpr0n/decoders/jpeg/nsJPEGDecoder.cpp
Normal file
829
mozilla/modules/libpr0n/decoders/jpeg/nsJPEGDecoder.cpp
Normal file
@@ -0,0 +1,829 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* 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 Netscape are
|
||||
* Copyright (C) 2001 Netscape Communications Corporation.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Stuart Parmenter <pavlov@netscape.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nsJPEGDecoder.h"
|
||||
|
||||
#include "nsIInputStream.h"
|
||||
|
||||
#include "nspr.h"
|
||||
|
||||
#include "nsCRT.h"
|
||||
|
||||
#include "nsIComponentManager.h"
|
||||
|
||||
#include "imgIContainerObserver.h"
|
||||
|
||||
|
||||
#include "ImageLogging.h"
|
||||
|
||||
|
||||
NS_IMPL_ISUPPORTS2(nsJPEGDecoder, imgIDecoder, nsIOutputStream)
|
||||
|
||||
|
||||
#if defined(PR_LOGGING)
|
||||
PRLogModuleInfo *gJPEGlog = PR_NewLogModule("JPEGDecoder");
|
||||
#else
|
||||
#define gJPEGlog
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
void PR_CALLBACK init_source (j_decompress_ptr jd);
|
||||
boolean PR_CALLBACK fill_input_buffer (j_decompress_ptr jd);
|
||||
void PR_CALLBACK skip_input_data (j_decompress_ptr jd, long num_bytes);
|
||||
void PR_CALLBACK term_source (j_decompress_ptr jd);
|
||||
void PR_CALLBACK my_error_exit (j_common_ptr cinfo);
|
||||
|
||||
/* Normal JFIF markers can't have more bytes than this. */
|
||||
#define MAX_JPEG_MARKER_LENGTH (((PRUint32)1 << 16) - 1)
|
||||
|
||||
|
||||
/* Possible states for JPEG source manager */
|
||||
enum data_source_state {
|
||||
READING_BACK = 0, /* Must be zero for init purposes */
|
||||
READING_NEW
|
||||
};
|
||||
|
||||
/*
|
||||
* Implementation of a JPEG src object that understands our state machine
|
||||
*/
|
||||
typedef struct {
|
||||
/* public fields; must be first in this struct! */
|
||||
struct jpeg_source_mgr pub;
|
||||
|
||||
nsJPEGDecoder *decoder;
|
||||
|
||||
} decoder_source_mgr;
|
||||
|
||||
|
||||
nsJPEGDecoder::nsJPEGDecoder()
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
|
||||
mState = JPEG_HEADER;
|
||||
mFillState = READING_BACK;
|
||||
|
||||
mSamples = nsnull;
|
||||
mSamples3 = nsnull;
|
||||
mRGBPadRow = nsnull;
|
||||
mRGBPadRowLength = 0;
|
||||
|
||||
mBytesToSkip = 0;
|
||||
|
||||
memset(&mInfo, 0, sizeof(jpeg_decompress_struct));
|
||||
|
||||
mCompletedPasses = 0;
|
||||
|
||||
mBuffer = nsnull;
|
||||
mBufferLen = mBufferSize = 0;
|
||||
|
||||
mBackBuffer = nsnull;
|
||||
mBackBufferLen = mBackBufferSize = mBackBufferUnreadLen = 0;
|
||||
|
||||
}
|
||||
|
||||
nsJPEGDecoder::~nsJPEGDecoder()
|
||||
{
|
||||
if (mBuffer)
|
||||
PR_Free(mBuffer);
|
||||
if (mBackBuffer)
|
||||
PR_Free(mBackBuffer);
|
||||
if (mRGBPadRow)
|
||||
PR_Free(mRGBPadRow);
|
||||
}
|
||||
|
||||
|
||||
/** imgIDecoder methods **/
|
||||
|
||||
/* void init (in imgIRequest aRequest); */
|
||||
NS_IMETHODIMP nsJPEGDecoder::Init(imgIRequest *aRequest)
|
||||
{
|
||||
mRequest = aRequest;
|
||||
mObserver = do_QueryInterface(mRequest);
|
||||
|
||||
aRequest->GetImage(getter_AddRefs(mImage));
|
||||
|
||||
/* We set up the normal JPEG error routines, then override error_exit. */
|
||||
mInfo.err = jpeg_std_error(&mErr.pub);
|
||||
/* mInfo.err = jpeg_std_error(&mErr.pub); */
|
||||
mErr.pub.error_exit = my_error_exit;
|
||||
/* Establish the setjmp return context for my_error_exit to use. */
|
||||
if (setjmp(mErr.setjmp_buffer)) {
|
||||
/* If we get here, the JPEG code has signaled an error.
|
||||
* We need to clean up the JPEG object, close the input file, and return.
|
||||
*/
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
/* Step 1: allocate and initialize JPEG decompression object */
|
||||
jpeg_create_decompress(&mInfo);
|
||||
|
||||
decoder_source_mgr *src;
|
||||
if (mInfo.src == NULL) {
|
||||
//mInfo.src = PR_NEWZAP(decoder_source_mgr);
|
||||
src = PR_NEWZAP(decoder_source_mgr);
|
||||
if (!src) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
mInfo.src = (struct jpeg_source_mgr *) src;
|
||||
}
|
||||
|
||||
/* Step 2: specify data source (eg, a file) */
|
||||
|
||||
/* Setup callback functions. */
|
||||
src->pub.init_source = init_source;
|
||||
src->pub.fill_input_buffer = fill_input_buffer;
|
||||
src->pub.skip_input_data = skip_input_data;
|
||||
src->pub.resync_to_restart = jpeg_resync_to_restart;
|
||||
src->pub.term_source = term_source;
|
||||
|
||||
src->decoder = this;
|
||||
|
||||
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute imgIRequest request; */
|
||||
NS_IMETHODIMP nsJPEGDecoder::GetRequest(imgIRequest * *aRequest)
|
||||
{
|
||||
*aRequest = mRequest;
|
||||
NS_ADDREF(*aRequest);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** nsIOutputStream methods **/
|
||||
|
||||
/* void close (); */
|
||||
NS_IMETHODIMP nsJPEGDecoder::Close()
|
||||
{
|
||||
PR_LOG(gJPEGlog, PR_LOG_DEBUG,
|
||||
("[this=%p] nsJPEGDecoder::Close\n", this));
|
||||
|
||||
if (mState != JPEG_DONE && mState != JPEG_SINK_NON_JPEG_TRAILER)
|
||||
NS_WARNING("Never finished decoding the JPEG.");
|
||||
|
||||
/* Step 8: Release JPEG decompression object */
|
||||
|
||||
/* This is an important step since it will release a good deal of memory. */
|
||||
jpeg_destroy_decompress(&mInfo);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void flush (); */
|
||||
NS_IMETHODIMP nsJPEGDecoder::Flush()
|
||||
{
|
||||
LOG_SCOPE(gJPEGlog, "nsJPEGDecoder::Flush");
|
||||
|
||||
PRUint32 ret;
|
||||
if (mState != JPEG_DONE && mState != JPEG_SINK_NON_JPEG_TRAILER)
|
||||
return this->WriteFrom(nsnull, 0, &ret);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* unsigned long write (in string buf, in unsigned long count); */
|
||||
NS_IMETHODIMP nsJPEGDecoder::Write(const char *buf, PRUint32 count, PRUint32 *_retval)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* unsigned long writeFrom (in nsIInputStream inStr, in unsigned long count); */
|
||||
NS_IMETHODIMP nsJPEGDecoder::WriteFrom(nsIInputStream *inStr, PRUint32 count, PRUint32 *_retval)
|
||||
{
|
||||
LOG_SCOPE_WITH_PARAM(gJPEGlog, "nsJPEGDecoder::WriteFrom", "count", count);
|
||||
|
||||
/* We use our private extension JPEG error handler.
|
||||
* Note that this struct must live as long as the main JPEG parameter
|
||||
* struct, to avoid dangling-pointer problems.
|
||||
*/
|
||||
// XXX above what is this?
|
||||
|
||||
|
||||
if (inStr) {
|
||||
if (!mBuffer) {
|
||||
mBuffer = (JOCTET *)PR_Malloc(count);
|
||||
mBufferSize = count;
|
||||
} else if (count > mBufferSize) {
|
||||
mBuffer = (JOCTET *)PR_Realloc(mBuffer, count);
|
||||
mBufferSize = count;
|
||||
}
|
||||
|
||||
nsresult rv = inStr->Read((char*)mBuffer, count, &mBufferLen);
|
||||
*_retval = mBufferLen;
|
||||
|
||||
//nsresult rv = mOutStream->WriteFrom(inStr, count, _retval);
|
||||
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "nsJPEGDecoder::WriteFrom -- mOutStream->WriteFrom failed");
|
||||
}
|
||||
// else no input stream.. Flush() ?
|
||||
|
||||
|
||||
nsresult error_code = NS_ERROR_FAILURE;
|
||||
/* Return here if there is a fatal error. */
|
||||
if ((error_code = setjmp(mErr.setjmp_buffer)) != 0) {
|
||||
return error_code;
|
||||
}
|
||||
|
||||
|
||||
PR_LOG(gJPEGlog, PR_LOG_DEBUG,
|
||||
("[this=%p] nsJPEGDecoder::WriteFrom -- processing JPEG data\n", this));
|
||||
|
||||
decoder_source_mgr *src = NS_REINTERPRET_CAST(decoder_source_mgr *, mInfo.src);
|
||||
|
||||
switch (mState) {
|
||||
case JPEG_HEADER:
|
||||
{
|
||||
LOG_SCOPE(gJPEGlog, "nsJPEGDecoder::WriteFrom -- entering JPEG_HEADER case");
|
||||
|
||||
/* Step 3: read file parameters with jpeg_read_header() */
|
||||
if (jpeg_read_header(&mInfo, TRUE) == JPEG_SUSPENDED)
|
||||
return NS_OK; /* I/O suspension */
|
||||
|
||||
/*
|
||||
* Don't allocate a giant and superfluous memory buffer
|
||||
* when the image is a sequential JPEG.
|
||||
*/
|
||||
mInfo.buffered_image = jpeg_has_multiple_scans(&mInfo);
|
||||
|
||||
/* Used to set up image size so arrays can be allocated */
|
||||
jpeg_calc_output_dimensions(&mInfo);
|
||||
|
||||
mObserver->OnStartDecode(nsnull, nsnull);
|
||||
|
||||
mImage->Init(mInfo.image_width, mInfo.image_height, mObserver);
|
||||
mObserver->OnStartContainer(nsnull, nsnull, mImage);
|
||||
|
||||
mFrame = do_CreateInstance("@mozilla.org/gfx/image/frame;2");
|
||||
gfx_format format;
|
||||
#ifdef XP_PC
|
||||
format = gfxIFormats::BGR;
|
||||
#else
|
||||
format = gfxIFormats::RGB;
|
||||
#endif
|
||||
mFrame->Init(0, 0, mInfo.image_width, mInfo.image_height, format);
|
||||
mImage->AppendFrame(mFrame);
|
||||
mObserver->OnStartFrame(nsnull, nsnull, mFrame);
|
||||
|
||||
|
||||
/*
|
||||
* Make a one-row-high sample array that will go away
|
||||
* when done with image. Always make it big enough to
|
||||
* hold an RGB row. Since this uses the IJG memory
|
||||
* manager, it must be allocated before the call to
|
||||
* jpeg_start_compress().
|
||||
*/
|
||||
int row_stride;
|
||||
|
||||
if(mInfo.output_components == 1)
|
||||
row_stride = mInfo.output_width;
|
||||
else
|
||||
row_stride = mInfo.output_width * 4; // use 4 instead of mInfo.output_components
|
||||
// so we don't have to fuss with byte alignment.
|
||||
// Mac wants 4 anyways.
|
||||
|
||||
mSamples = (*mInfo.mem->alloc_sarray)((j_common_ptr) &mInfo,
|
||||
JPOOL_IMAGE,
|
||||
row_stride, 1);
|
||||
|
||||
#if defined(XP_PC) || defined(XP_MAC)
|
||||
// allocate buffer to do byte flipping if needed
|
||||
if (mInfo.output_components == 3) {
|
||||
mRGBPadRow = (PRUint8*) PR_MALLOC(row_stride);
|
||||
mRGBPadRowLength = row_stride;
|
||||
memset(mRGBPadRow, 0, mRGBPadRowLength);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Allocate RGB buffer for conversion from greyscale. */
|
||||
if (mInfo.output_components != 3) {
|
||||
row_stride = mInfo.output_width * 4;
|
||||
mSamples3 = (*mInfo.mem->alloc_sarray)((j_common_ptr) &mInfo,
|
||||
JPOOL_IMAGE,
|
||||
row_stride, 1);
|
||||
}
|
||||
|
||||
mState = JPEG_START_DECOMPRESS;
|
||||
}
|
||||
case JPEG_START_DECOMPRESS:
|
||||
{
|
||||
LOG_SCOPE(gJPEGlog, "nsJPEGDecoder::WriteFrom -- entering JPEG_START_DECOMPRESS case");
|
||||
/* Step 4: set parameters for decompression */
|
||||
|
||||
/* FIXME -- Should reset dct_method and dither mode
|
||||
* for final pass of progressive JPEG
|
||||
*/
|
||||
mInfo.dct_method = JDCT_FASTEST;
|
||||
mInfo.dither_mode = JDITHER_ORDERED;
|
||||
mInfo.do_fancy_upsampling = FALSE;
|
||||
mInfo.enable_2pass_quant = FALSE;
|
||||
mInfo.do_block_smoothing = TRUE;
|
||||
|
||||
/* Step 5: Start decompressor */
|
||||
if (jpeg_start_decompress(&mInfo) == FALSE)
|
||||
return NS_OK; /* I/O suspension */
|
||||
|
||||
/* If this is a progressive JPEG ... */
|
||||
if (mInfo.buffered_image) {
|
||||
mState = JPEG_DECOMPRESS_PROGRESSIVE;
|
||||
} else {
|
||||
mState = JPEG_DECOMPRESS_SEQUENTIAL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
case JPEG_DECOMPRESS_SEQUENTIAL:
|
||||
{
|
||||
if (mState == JPEG_DECOMPRESS_SEQUENTIAL)
|
||||
{
|
||||
LOG_SCOPE(gJPEGlog, "nsJPEGDecoder::WriteFrom -- JPEG_DECOMPRESS_SEQUENTIAL case");
|
||||
|
||||
if (OutputScanlines(-1) == PR_FALSE)
|
||||
return NS_OK; /* I/O suspension */
|
||||
|
||||
/* If we've completed image output ... */
|
||||
NS_ASSERTION(mInfo.output_scanline == mInfo.output_height, "We didn't process all of the data!");
|
||||
mState = JPEG_DONE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
case JPEG_DECOMPRESS_PROGRESSIVE:
|
||||
{
|
||||
if (mState == JPEG_DECOMPRESS_PROGRESSIVE)
|
||||
{
|
||||
LOG_SCOPE(gJPEGlog, "nsJPEGDecoder::WriteFrom -- JPEG_DECOMPRESS_PROGRESSIVE case");
|
||||
|
||||
int status;
|
||||
do {
|
||||
status = jpeg_consume_input(&mInfo);
|
||||
} while (!((status == JPEG_SUSPENDED) ||
|
||||
(status == JPEG_REACHED_EOI)));
|
||||
|
||||
switch (status) {
|
||||
case JPEG_REACHED_EOI:
|
||||
// End of image
|
||||
mState = JPEG_FINAL_PROGRESSIVE_SCAN_OUTPUT;
|
||||
break;
|
||||
case JPEG_SUSPENDED:
|
||||
PR_LOG(gJPEGlog, PR_LOG_DEBUG,
|
||||
("[this=%p] nsJPEGDecoder::WriteFrom -- suspending\n", this));
|
||||
|
||||
return NS_OK; /* I/O suspension */
|
||||
default:
|
||||
printf("got someo other state!?\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case JPEG_FINAL_PROGRESSIVE_SCAN_OUTPUT:
|
||||
{
|
||||
if (mState == JPEG_FINAL_PROGRESSIVE_SCAN_OUTPUT)
|
||||
{
|
||||
LOG_SCOPE(gJPEGlog, "nsJPEGDecoder::WriteFrom -- entering JPEG_FINAL_PROGRESSIVE_SCAN_OUTPUT case");
|
||||
|
||||
// XXX progressive? ;)
|
||||
// not really progressive according to the state machine... -saari
|
||||
jpeg_start_output(&mInfo, mInfo.input_scan_number);
|
||||
if (OutputScanlines(-1) == PR_FALSE)
|
||||
return NS_OK; /* I/O suspension */
|
||||
jpeg_finish_output(&mInfo);
|
||||
mState = JPEG_DONE;
|
||||
}
|
||||
}
|
||||
|
||||
case JPEG_DONE:
|
||||
{
|
||||
LOG_SCOPE(gJPEGlog, "nsJPEGDecoder::WriteFrom -- entering JPEG_DONE case");
|
||||
|
||||
/* Step 7: Finish decompression */
|
||||
|
||||
if (jpeg_finish_decompress(&mInfo) == FALSE)
|
||||
return NS_OK; /* I/O suspension */
|
||||
|
||||
mState = JPEG_SINK_NON_JPEG_TRAILER;
|
||||
|
||||
/* we're done dude */
|
||||
break;
|
||||
}
|
||||
case JPEG_SINK_NON_JPEG_TRAILER:
|
||||
PR_LOG(gJPEGlog, PR_LOG_DEBUG,
|
||||
("[this=%p] nsJPEGDecoder::WriteFrom -- entering JPEG_SINK_NON_JPEG_TRAILER case\n", this));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
nsJPEGDecoder::OutputScanlines(int num_scanlines)
|
||||
{
|
||||
int pass = 0;
|
||||
|
||||
if (mState == JPEG_FINAL_PROGRESSIVE_SCAN_OUTPUT)
|
||||
pass = -1;
|
||||
else
|
||||
pass = mCompletedPasses + 1;
|
||||
|
||||
while ((mInfo.output_scanline < mInfo.output_height) && num_scanlines--) {
|
||||
JSAMPROW samples;
|
||||
|
||||
/* Request one scanline. Returns 0 or 1 scanlines. */
|
||||
int ns = jpeg_read_scanlines(&mInfo, mSamples, 1);
|
||||
|
||||
if (ns != 1) {
|
||||
return PR_FALSE; /* suspend */
|
||||
}
|
||||
|
||||
/* If grayscale image ... */
|
||||
if (mInfo.output_components == 1) {
|
||||
JSAMPLE j;
|
||||
JSAMPLE *j1 = mSamples[0];
|
||||
const JSAMPLE *j1end = j1 + mInfo.output_width;
|
||||
JSAMPLE *j3 = mSamples3[0];
|
||||
|
||||
/* Convert from grayscale to RGB. */
|
||||
while (j1 < j1end) {
|
||||
#ifdef XP_MAC
|
||||
j = *j1++;
|
||||
j3[0] = 0;
|
||||
j3[1] = j;
|
||||
j3[2] = j;
|
||||
j3[3] = j;
|
||||
j3 += 4;
|
||||
#else
|
||||
j = *j1++;
|
||||
j3[0] = j;
|
||||
j3[1] = j;
|
||||
j3[2] = j;
|
||||
j3 += 3;
|
||||
#endif
|
||||
}
|
||||
samples = mSamples3[0];
|
||||
} else {
|
||||
/* 24-bit color image */
|
||||
#ifdef XP_PC
|
||||
memset(mRGBPadRow, 0, mInfo.output_width * 4);
|
||||
PRUint8 *ptrOutputBuf = mRGBPadRow;
|
||||
|
||||
JSAMPLE *j1 = mSamples[0];
|
||||
for (PRUint32 i=0;i<mInfo.output_width;++i) {
|
||||
ptrOutputBuf[2] = *j1++;
|
||||
ptrOutputBuf[1] = *j1++;
|
||||
ptrOutputBuf[0] = *j1++;
|
||||
ptrOutputBuf += 3;
|
||||
}
|
||||
|
||||
samples = mRGBPadRow;
|
||||
#else
|
||||
#ifdef XP_MAC
|
||||
memset(mRGBPadRow, 0, mInfo.output_width * 4);
|
||||
PRUint8 *ptrOutputBuf = mRGBPadRow;
|
||||
|
||||
JSAMPLE *j1 = mSamples[0];
|
||||
for (PRUint32 i=0;i<mInfo.output_width;++i) {
|
||||
ptrOutputBuf[0] = 0;
|
||||
ptrOutputBuf[1] = *j1++;
|
||||
ptrOutputBuf[2] = *j1++;
|
||||
ptrOutputBuf[3] = *j1++;
|
||||
ptrOutputBuf += 4;
|
||||
}
|
||||
|
||||
samples = mRGBPadRow;
|
||||
#else
|
||||
samples = mSamples[0];
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
PRUint32 bpr;
|
||||
mFrame->GetImageBytesPerRow(&bpr);
|
||||
mFrame->SetImageData(
|
||||
samples, // data
|
||||
bpr, // length
|
||||
(mInfo.output_scanline-1) * bpr); // offset
|
||||
|
||||
nsRect r(0, mInfo.output_scanline, mInfo.output_width, 1);
|
||||
mObserver->OnDataAvailable(nsnull, nsnull, mFrame, &r);
|
||||
|
||||
}
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
|
||||
/* [noscript] unsigned long writeSegments (in nsReadSegmentFun reader, in voidPtr closure, in unsigned long count); */
|
||||
NS_IMETHODIMP nsJPEGDecoder::WriteSegments(nsReadSegmentFun reader, void * closure, PRUint32 count, PRUint32 *_retval)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* attribute boolean nonBlocking; */
|
||||
NS_IMETHODIMP nsJPEGDecoder::GetNonBlocking(PRBool *aNonBlocking)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
NS_IMETHODIMP nsJPEGDecoder::SetNonBlocking(PRBool aNonBlocking)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* attribute nsIOutputStreamObserver observer; */
|
||||
NS_IMETHODIMP nsJPEGDecoder::GetObserver(nsIOutputStreamObserver * *aObserver)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
NS_IMETHODIMP nsJPEGDecoder::SetObserver(nsIOutputStreamObserver * aObserver)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* Override the standard error method in the IJG JPEG decoder code. */
|
||||
void PR_CALLBACK
|
||||
my_error_exit (j_common_ptr cinfo)
|
||||
{
|
||||
nsresult error_code = NS_ERROR_FAILURE;
|
||||
decoder_error_mgr *err = (decoder_error_mgr *) cinfo->err;
|
||||
|
||||
#if 0
|
||||
#ifdef DEBUG
|
||||
/*ptn fix later */
|
||||
if (il_debug >= 1) {
|
||||
char buffer[JMSG_LENGTH_MAX];
|
||||
|
||||
/* Create the message */
|
||||
(*cinfo->err->format_message) (cinfo, buffer);
|
||||
|
||||
ILTRACE(1,("%s\n", buffer));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* Convert error to a browser error code */
|
||||
if (cinfo->err->msg_code == JERR_OUT_OF_MEMORY)
|
||||
error_code = MK_OUT_OF_MEMORY;
|
||||
else
|
||||
error_code = MK_IMAGE_LOSSAGE;
|
||||
#endif
|
||||
|
||||
char buffer[JMSG_LENGTH_MAX];
|
||||
|
||||
/* Create the message */
|
||||
(*cinfo->err->format_message) (cinfo, buffer);
|
||||
|
||||
fprintf(stderr, "my_error_exit()\n%s\n", buffer);
|
||||
|
||||
/* Return control to the setjmp point. */
|
||||
longjmp(err->setjmp_buffer, error_code);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/*-----------------------------------------------------------------------------
|
||||
* This is the callback routine from the IJG JPEG library used to supply new
|
||||
* data to the decompressor when its input buffer is exhausted. It juggles
|
||||
* multiple buffers in an attempt to avoid unnecessary copying of input data.
|
||||
*
|
||||
* (A simpler scheme is possible: It's much easier to use only a single
|
||||
* buffer; when fill_input_buffer() is called, move any unconsumed data
|
||||
* (beyond the current pointer/count) down to the beginning of this buffer and
|
||||
* then load new data into the remaining buffer space. This approach requires
|
||||
* a little more data copying but is far easier to get right.)
|
||||
*
|
||||
* At any one time, the JPEG decompressor is either reading from the necko
|
||||
* input buffer, which is volatile across top-level calls to the IJG library,
|
||||
* or the "backtrack" buffer. The backtrack buffer contains the remaining
|
||||
* unconsumed data from the necko buffer after parsing was suspended due
|
||||
* to insufficient data in some previous call to the IJG library.
|
||||
*
|
||||
* When suspending, the decompressor will back up to a convenient restart
|
||||
* point (typically the start of the current MCU). The variables
|
||||
* next_input_byte & bytes_in_buffer indicate where the restart point will be
|
||||
* if the current call returns FALSE. Data beyond this point must be
|
||||
* rescanned after resumption, so it must be preserved in case the decompressor
|
||||
* decides to backtrack.
|
||||
*
|
||||
* Returns:
|
||||
* TRUE if additional data is available, FALSE if no data present and
|
||||
* the JPEG library should therefore suspend processing of input stream
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
/******************************************************************************/
|
||||
/* data source manager method
|
||||
/******************************************************************************/
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* data source manager method
|
||||
Initialize source. This is called by jpeg_read_header() before any
|
||||
data is actually read. May leave
|
||||
bytes_in_buffer set to 0 (in which case a fill_input_buffer() call
|
||||
will occur immediately).
|
||||
*/
|
||||
void PR_CALLBACK
|
||||
init_source (j_decompress_ptr jd)
|
||||
{
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* data source manager method
|
||||
Skip num_bytes worth of data. The buffer pointer and count should
|
||||
be advanced over num_bytes input bytes, refilling the buffer as
|
||||
needed. This is used to skip over a potentially large amount of
|
||||
uninteresting data (such as an APPn marker). In some applications
|
||||
it may be possible to optimize away the reading of the skipped data,
|
||||
but it's not clear that being smart is worth much trouble; large
|
||||
skips are uncommon. bytes_in_buffer may be zero on return.
|
||||
A zero or negative skip count should be treated as a no-op.
|
||||
*/
|
||||
void PR_CALLBACK
|
||||
skip_input_data (j_decompress_ptr jd, long num_bytes)
|
||||
{
|
||||
decoder_source_mgr *src = (decoder_source_mgr *)jd->src;
|
||||
|
||||
if (num_bytes > (long)src->pub.bytes_in_buffer) {
|
||||
/*
|
||||
* Can't skip it all right now until we get more data from
|
||||
* network stream. Set things up so that fill_input_buffer
|
||||
* will skip remaining amount.
|
||||
*/
|
||||
src->decoder->mBytesToSkip = (size_t)num_bytes - src->pub.bytes_in_buffer;
|
||||
src->pub.next_input_byte += src->pub.bytes_in_buffer;
|
||||
src->pub.bytes_in_buffer = 0;
|
||||
|
||||
} else {
|
||||
/* Simple case. Just advance buffer pointer */
|
||||
|
||||
src->pub.bytes_in_buffer -= (size_t)num_bytes;
|
||||
src->pub.next_input_byte += num_bytes;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* data source manager method
|
||||
This is called whenever bytes_in_buffer has reached zero and more
|
||||
data is wanted. In typical applications, it should read fresh data
|
||||
into the buffer (ignoring the current state of next_input_byte and
|
||||
bytes_in_buffer), reset the pointer & count to the start of the
|
||||
buffer, and return TRUE indicating that the buffer has been reloaded.
|
||||
It is not necessary to fill the buffer entirely, only to obtain at
|
||||
least one more byte. bytes_in_buffer MUST be set to a positive value
|
||||
if TRUE is returned. A FALSE return should only be used when I/O
|
||||
suspension is desired.
|
||||
*/
|
||||
boolean PR_CALLBACK
|
||||
fill_input_buffer (j_decompress_ptr jd)
|
||||
{
|
||||
decoder_source_mgr *src = (decoder_source_mgr *)jd->src;
|
||||
|
||||
unsigned char *new_buffer = (unsigned char *)src->decoder->mBuffer;
|
||||
PRUint32 new_buflen = src->decoder->mBufferLen;
|
||||
PRUint32 bytesToSkip = src->decoder->mBytesToSkip;
|
||||
|
||||
switch(src->decoder->mFillState) {
|
||||
case READING_BACK:
|
||||
{
|
||||
if (!new_buffer || new_buflen == 0)
|
||||
return PR_FALSE; /* suspend */
|
||||
|
||||
src->decoder->mBufferLen = 0;
|
||||
|
||||
if (bytesToSkip != 0) {
|
||||
if (bytesToSkip < new_buflen) {
|
||||
/* All done skipping bytes; Return what's left. */
|
||||
new_buffer += bytesToSkip;
|
||||
new_buflen -= bytesToSkip;
|
||||
src->decoder->mBytesToSkip = 0;
|
||||
} else {
|
||||
/* Still need to skip some more data in the future */
|
||||
src->decoder->mBytesToSkip -= (size_t)new_buflen;
|
||||
return PR_FALSE; /* suspend */
|
||||
}
|
||||
}
|
||||
|
||||
src->decoder->mBackBufferUnreadLen = src->pub.bytes_in_buffer;
|
||||
|
||||
src->pub.next_input_byte = new_buffer;
|
||||
src->pub.bytes_in_buffer = (size_t)new_buflen;
|
||||
src->decoder->mFillState = READING_NEW;
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case READING_NEW:
|
||||
{
|
||||
if (src->pub.next_input_byte != src->decoder->mBuffer) {
|
||||
/* Backtrack data has been permanently consumed. */
|
||||
src->decoder->mBackBufferUnreadLen = 0;
|
||||
src->decoder->mBackBufferLen = 0;
|
||||
}
|
||||
|
||||
/* Save remainder of netlib buffer in backtrack buffer */
|
||||
PRUint32 new_backtrack_buflen = src->pub.bytes_in_buffer + src->decoder->mBackBufferLen;
|
||||
|
||||
|
||||
/* Make sure backtrack buffer is big enough to hold new data. */
|
||||
if (src->decoder->mBackBufferSize < new_backtrack_buflen) {
|
||||
|
||||
/* Round up to multiple of 16 bytes. */
|
||||
PRUint32 roundup_buflen = ((new_backtrack_buflen + 15) >> 4) << 4;
|
||||
if (src->decoder->mBackBufferSize) {
|
||||
src->decoder->mBackBuffer =
|
||||
(JOCTET *)PR_REALLOC(src->decoder->mBackBuffer, roundup_buflen);
|
||||
} else {
|
||||
src->decoder->mBackBuffer = (JOCTET*)PR_MALLOC(roundup_buflen);
|
||||
}
|
||||
|
||||
/* Check for OOM */
|
||||
if (!src->decoder->mBackBuffer) {
|
||||
#if 0
|
||||
j_common_ptr cinfo = (j_common_ptr)(&src->js->jd);
|
||||
cinfo->err->msg_code = JERR_OUT_OF_MEMORY;
|
||||
my_error_exit(cinfo);
|
||||
#endif
|
||||
}
|
||||
|
||||
src->decoder->mBackBufferSize = (size_t)roundup_buflen;
|
||||
|
||||
/* Check for malformed MARKER segment lengths. */
|
||||
if (new_backtrack_buflen > MAX_JPEG_MARKER_LENGTH) {
|
||||
my_error_exit((j_common_ptr)(&src->decoder->mInfo));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Copy remainder of netlib buffer into backtrack buffer. */
|
||||
nsCRT::memmove(src->decoder->mBackBuffer + src->decoder->mBackBufferLen,
|
||||
src->pub.next_input_byte,
|
||||
src->pub.bytes_in_buffer);
|
||||
|
||||
|
||||
/* Point to start of data to be rescanned. */
|
||||
src->pub.next_input_byte = src->decoder->mBackBuffer + src->decoder->mBackBufferLen - src->decoder->mBackBufferUnreadLen;
|
||||
src->pub.bytes_in_buffer += src->decoder->mBackBufferUnreadLen;
|
||||
src->decoder->mBackBufferLen = (size_t)new_backtrack_buflen;
|
||||
|
||||
src->decoder->mFillState = READING_BACK;
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* data source manager method */
|
||||
/*
|
||||
* Terminate source --- called by jpeg_finish_decompress() after all
|
||||
* data has been read to clean up JPEG source manager. NOT called by
|
||||
* jpeg_abort() or jpeg_destroy().
|
||||
*/
|
||||
void PR_CALLBACK
|
||||
term_source (j_decompress_ptr jd)
|
||||
{
|
||||
decoder_source_mgr *src = (decoder_source_mgr *)jd->src;
|
||||
|
||||
if (src->decoder->mObserver) {
|
||||
src->decoder->mObserver->OnStopFrame(nsnull, nsnull, src->decoder->mFrame);
|
||||
src->decoder->mObserver->OnStopContainer(nsnull, nsnull, src->decoder->mImage);
|
||||
src->decoder->mObserver->OnStopDecode(nsnull, nsnull, NS_OK, nsnull);
|
||||
}
|
||||
|
||||
/* No work necessary here */
|
||||
}
|
||||
121
mozilla/modules/libpr0n/decoders/jpeg/nsJPEGDecoder.h
Normal file
121
mozilla/modules/libpr0n/decoders/jpeg/nsJPEGDecoder.h
Normal file
@@ -0,0 +1,121 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* 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 Netscape are
|
||||
* Copyright (C) 2001 Netscape Communications Corporation.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Stuart Parmenter <pavlov@netscape.com>
|
||||
*/
|
||||
|
||||
#ifndef nsJPEGDecoder_h__
|
||||
#define nsJPEGDecoder_h__
|
||||
|
||||
#include "imgIDecoder.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
#include "imgIContainer.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
#include "imgIDecoderObserver.h"
|
||||
#include "imgIRequest.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsIPipe.h"
|
||||
|
||||
extern "C" {
|
||||
#include "jpeglib.h"
|
||||
}
|
||||
|
||||
#include <setjmp.h>
|
||||
|
||||
#define NS_JPEGDECODER_CID \
|
||||
{ /* 5871a422-1dd2-11b2-ab3f-e2e56be5da9c */ \
|
||||
0x5871a422, \
|
||||
0x1dd2, \
|
||||
0x11b2, \
|
||||
{0xab, 0x3f, 0xe2, 0xe5, 0x6b, 0xe5, 0xda, 0x9c} \
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
struct jpeg_error_mgr pub; /* "public" fields for IJG library*/
|
||||
jmp_buf setjmp_buffer; /* For handling catastropic errors */
|
||||
} decoder_error_mgr;
|
||||
|
||||
|
||||
typedef enum {
|
||||
JPEG_HEADER, /* Reading JFIF headers */
|
||||
JPEG_START_DECOMPRESS,
|
||||
JPEG_DECOMPRESS_PROGRESSIVE, /* Output progressive pixels */
|
||||
JPEG_DECOMPRESS_SEQUENTIAL, /* Output sequential pixels */
|
||||
JPEG_FINAL_PROGRESSIVE_SCAN_OUTPUT,
|
||||
JPEG_DONE,
|
||||
JPEG_SINK_NON_JPEG_TRAILER, /* Some image files have a */
|
||||
/* non-JPEG trailer */
|
||||
JPEG_ERROR
|
||||
} jstate;
|
||||
|
||||
class nsJPEGDecoder : public imgIDecoder
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_IMGIDECODER
|
||||
NS_DECL_NSIOUTPUTSTREAM
|
||||
|
||||
nsJPEGDecoder();
|
||||
virtual ~nsJPEGDecoder();
|
||||
|
||||
PRBool FillInput(j_decompress_ptr jd);
|
||||
|
||||
PRUint32 mBytesToSkip;
|
||||
|
||||
protected:
|
||||
int OutputScanlines(int num_scanlines);
|
||||
|
||||
public:
|
||||
nsCOMPtr<imgIContainer> mImage;
|
||||
nsCOMPtr<gfxIImageFrame> mFrame;
|
||||
nsCOMPtr<imgIRequest> mRequest;
|
||||
|
||||
nsCOMPtr<imgIDecoderObserver> mObserver;
|
||||
|
||||
struct jpeg_decompress_struct mInfo;
|
||||
decoder_error_mgr mErr;
|
||||
jstate mState;
|
||||
|
||||
JSAMPARRAY mSamples;
|
||||
JSAMPARRAY mSamples3;
|
||||
PRUint8* mRGBPadRow;
|
||||
PRUint32 mRGBPadRowLength;
|
||||
|
||||
PRInt32 mCompletedPasses;
|
||||
PRInt32 mPasses;
|
||||
|
||||
int mFillState;
|
||||
|
||||
JOCTET *mBuffer;
|
||||
PRUint32 mBufferLen; // amount of data currently in mBuffer
|
||||
PRUint32 mBufferSize; // size in bytes what mBuffer was created with
|
||||
|
||||
JOCTET *mBackBuffer;
|
||||
PRUint32 mBackBufferLen; // Offset of end of active backtrack data
|
||||
PRUint32 mBackBufferSize; // size in bytes what mBackBuffer was created with
|
||||
PRUint32 mBackBufferUnreadLen; // amount of data currently in mBackBuffer
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif // nsJPEGDecoder_h__
|
||||
42
mozilla/modules/libpr0n/decoders/jpeg/nsJPEGFactory.cpp
Normal file
42
mozilla/modules/libpr0n/decoders/jpeg/nsJPEGFactory.cpp
Normal file
@@ -0,0 +1,42 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* 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 Netscape are
|
||||
* Copyright (C) 2001 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Stuart Parmenter <pavlov@netscape.com>
|
||||
*/
|
||||
|
||||
#include "nsIGenericFactory.h"
|
||||
#include "nsIModule.h"
|
||||
|
||||
#include "nsJPEGDecoder.h"
|
||||
|
||||
// objects that just require generic constructors
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsJPEGDecoder)
|
||||
|
||||
static nsModuleComponentInfo components[] =
|
||||
{
|
||||
{ "ppm decoder",
|
||||
NS_JPEGDECODER_CID,
|
||||
"@mozilla.org/image/decoder;2?type=image/jpeg",
|
||||
nsJPEGDecoderConstructor, },
|
||||
};
|
||||
|
||||
NS_IMPL_NSGETMODULE("nsJPEGDecoderModule", components)
|
||||
|
||||
16
mozilla/modules/libpr0n/decoders/jpeg/win32.order
Normal file
16
mozilla/modules/libpr0n/decoders/jpeg/win32.order
Normal file
@@ -0,0 +1,16 @@
|
||||
?Release@nsJPEGDecoder@@UAGKXZ ; 172
|
||||
?AddRef@nsJPEGDecoder@@UAGKXZ ; 172
|
||||
?fill_input_buffer@@YAEPAUjpeg_decompress_struct@@@Z ; 126
|
||||
?skip_input_data@@YAXPAUjpeg_decompress_struct@@J@Z ; 109
|
||||
?WriteFrom@nsJPEGDecoder@@UAGIPAVnsIInputStream@@IPAI@Z ; 106
|
||||
?OutputScanlines@nsJPEGDecoder@@IAEHH@Z ; 93
|
||||
?init_source@@YAXPAUjpeg_decompress_struct@@@Z ; 86
|
||||
??1nsJPEGDecoder@@UAE@XZ ; 86
|
||||
?Close@nsJPEGDecoder@@UAGIXZ ; 86
|
||||
?term_source@@YAXPAUjpeg_decompress_struct@@@Z ; 86
|
||||
?Init@nsJPEGDecoder@@UAGIPAVimgIRequest@@@Z ; 86
|
||||
??0nsJPEGDecoder@@QAE@XZ ; 86
|
||||
?Flush@nsJPEGDecoder@@UAGIXZ ; 86
|
||||
?QueryInterface@nsJPEGDecoder@@UAGIABUnsID@@PAPAX@Z ; 86
|
||||
??_EnsJPEGDecoder@@UAEPAXI@Z ; 86
|
||||
_NSGetModule ; 1
|
||||
26
mozilla/modules/libpr0n/decoders/makefile.win
Normal file
26
mozilla/modules/libpr0n/decoders/makefile.win
Normal file
@@ -0,0 +1,26 @@
|
||||
#
|
||||
# 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 Netscape are
|
||||
# Copyright (C) 2001 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
|
||||
DEPTH=..\..\..
|
||||
|
||||
DIRS = ppm gif png jpeg
|
||||
|
||||
!include $(DEPTH)\config\rules.mak
|
||||
42
mozilla/modules/libpr0n/decoders/png/Makefile.in
Normal file
42
mozilla/modules/libpr0n/decoders/png/Makefile.in
Normal file
@@ -0,0 +1,42 @@
|
||||
#
|
||||
# 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 Netscape are
|
||||
# Copyright (C) 2001 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
|
||||
DEPTH = ../../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = imgpng
|
||||
LIBRARY_NAME = imgpng
|
||||
IS_COMPONENT = 1
|
||||
|
||||
REQUIRES = xpcom necko layout png gfx2 imglib2
|
||||
|
||||
CPPSRCS = nsPNGDecoder.cpp nsPNGFactory.cpp
|
||||
|
||||
EXTRA_DSO_LDOPTS = $(PNG_LIBS) $(ZLIB_LIBS) \
|
||||
$(MOZ_COMPONENT_LIBS) \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
53
mozilla/modules/libpr0n/decoders/png/makefile.win
Normal file
53
mozilla/modules/libpr0n/decoders/png/makefile.win
Normal file
@@ -0,0 +1,53 @@
|
||||
#!nmake
|
||||
#
|
||||
# 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 Netscape are
|
||||
# Copyright (C) 2001 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Stuart Parmenter <pavlov@netscape.com>
|
||||
#
|
||||
|
||||
DEPTH=..\..\..\..
|
||||
include <$(DEPTH)/config/config.mak>
|
||||
|
||||
MODULE = imgpng
|
||||
LIBRARY_NAME = imgpng
|
||||
DLL = $(OBJDIR)\$(LIBRARY_NAME).dll
|
||||
MAKE_OBJ_TYPE = DLL
|
||||
|
||||
OBJS = \
|
||||
.\$(OBJDIR)\nsPNGDecoder.obj \
|
||||
.\$(OBJDIR)\nsPNGFactory.obj \
|
||||
$(NULL)
|
||||
|
||||
LLIBS=\
|
||||
$(LIBNSPR) \
|
||||
$(DIST)\lib\xpcom.lib \
|
||||
$(DIST)\lib\png.lib \
|
||||
$(DIST)\lib\zlib.lib \
|
||||
$(DIST)\lib\gkgfxwin.lib \
|
||||
$(NULL)
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
|
||||
install:: $(DLL)
|
||||
$(MAKE_INSTALL) .\$(OBJDIR)\$(LIBRARY_NAME).dll $(DIST)\bin\components
|
||||
$(MAKE_INSTALL) .\$(OBJDIR)\$(LIBRARY_NAME).lib $(DIST)\lib
|
||||
|
||||
clobber::
|
||||
rm -f $(DIST)\bin\components\$(LIBRARY_NAME).dll
|
||||
rm -f $(DIST)\lib\$(LIBRARY_NAME).lib
|
||||
553
mozilla/modules/libpr0n/decoders/png/nsPNGDecoder.cpp
Normal file
553
mozilla/modules/libpr0n/decoders/png/nsPNGDecoder.cpp
Normal file
@@ -0,0 +1,553 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* 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 Netscape are
|
||||
* Copyright (C) 2001 Netscape Communications Corporation.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Stuart Parmenter <pavlov@netscape.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nsPNGDecoder.h"
|
||||
|
||||
#include "nsIInputStream.h"
|
||||
|
||||
#include "nspr.h"
|
||||
|
||||
#include "nsIComponentManager.h"
|
||||
|
||||
#include "png.h"
|
||||
|
||||
#include "nsIStreamObserver.h"
|
||||
|
||||
#include "nsRect.h"
|
||||
|
||||
#include "nsMemory.h"
|
||||
|
||||
#include "imgIContainerObserver.h"
|
||||
|
||||
// XXX we need to be sure to fire onStopDecode messages to mObserver in error cases.
|
||||
|
||||
|
||||
NS_IMPL_ISUPPORTS2(nsPNGDecoder, imgIDecoder, nsIOutputStream)
|
||||
|
||||
|
||||
nsPNGDecoder::nsPNGDecoder()
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
|
||||
mPNG = nsnull;
|
||||
mInfo = nsnull;
|
||||
colorLine = 0;
|
||||
alphaLine = 0;
|
||||
interlacebuf = 0;
|
||||
}
|
||||
|
||||
nsPNGDecoder::~nsPNGDecoder()
|
||||
{
|
||||
if (colorLine)
|
||||
nsMemory::Free(colorLine);
|
||||
if (alphaLine)
|
||||
nsMemory::Free(alphaLine);
|
||||
if (interlacebuf)
|
||||
nsMemory::Free(interlacebuf);
|
||||
}
|
||||
|
||||
|
||||
/** imgIDecoder methods **/
|
||||
|
||||
/* void init (in imgIRequest aRequest); */
|
||||
NS_IMETHODIMP nsPNGDecoder::Init(imgIRequest *aRequest)
|
||||
{
|
||||
mRequest = aRequest;
|
||||
mObserver = do_QueryInterface(aRequest); // we're holding 2 strong refs to the request.
|
||||
|
||||
aRequest->GetImage(getter_AddRefs(mImage));
|
||||
|
||||
/* do png init stuff */
|
||||
|
||||
/* Initialize the container's source image header. */
|
||||
/* Always decode to 24 bit pixdepth */
|
||||
|
||||
|
||||
mPNG = png_create_read_struct(PNG_LIBPNG_VER_STRING,
|
||||
NULL, NULL,
|
||||
NULL);
|
||||
if (!mPNG) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mInfo = png_create_info_struct(mPNG);
|
||||
if (!mInfo) {
|
||||
png_destroy_read_struct(&mPNG, NULL, NULL);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
/* use ic as libpng "progressive pointer" (retrieve in callbacks) */
|
||||
png_set_progressive_read_fn(mPNG, NS_STATIC_CAST(png_voidp, this), nsPNGDecoder::info_callback, nsPNGDecoder::row_callback, nsPNGDecoder::end_callback);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
/* readonly attribute imgIRequest request; */
|
||||
NS_IMETHODIMP nsPNGDecoder::GetRequest(imgIRequest * *aRequest)
|
||||
{
|
||||
*aRequest = mRequest;
|
||||
NS_ADDREF(*aRequest);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** nsIOutputStream methods **/
|
||||
|
||||
/* void close (); */
|
||||
NS_IMETHODIMP nsPNGDecoder::Close()
|
||||
{
|
||||
if (mPNG)
|
||||
png_destroy_read_struct(&mPNG, mInfo ? &mInfo : NULL, NULL);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void flush (); */
|
||||
NS_IMETHODIMP nsPNGDecoder::Flush()
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* unsigned long write (in string buf, in unsigned long count); */
|
||||
NS_IMETHODIMP nsPNGDecoder::Write(const char *buf, PRUint32 count, PRUint32 *_retval)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
static NS_METHOD ReadDataOut(nsIInputStream* in,
|
||||
void* closure,
|
||||
const char* fromRawSegment,
|
||||
PRUint32 toOffset,
|
||||
PRUint32 count,
|
||||
PRUint32 *writeCount)
|
||||
{
|
||||
nsPNGDecoder *decoder = NS_STATIC_CAST(nsPNGDecoder*, closure);
|
||||
|
||||
// we need to do the setjmp here otherwise bad things will happen
|
||||
if (setjmp(decoder->mPNG->jmpbuf)) {
|
||||
png_destroy_read_struct(&decoder->mPNG, &decoder->mInfo, NULL);
|
||||
// is this NS_ERROR_FAILURE enough?
|
||||
|
||||
decoder->mRequest->Cancel(NS_BINDING_ABORTED); // XXX is this the correct error ?
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
*writeCount = decoder->ProcessData((unsigned char*)fromRawSegment, count);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRUint32 nsPNGDecoder::ProcessData(unsigned char *data, PRUint32 count)
|
||||
{
|
||||
png_process_data(mPNG, mInfo, data, count);
|
||||
|
||||
return count; // we always consume all the data
|
||||
}
|
||||
|
||||
/* unsigned long writeFrom (in nsIInputStream inStr, in unsigned long count); */
|
||||
NS_IMETHODIMP nsPNGDecoder::WriteFrom(nsIInputStream *inStr, PRUint32 count, PRUint32 *_retval)
|
||||
{
|
||||
// PRUint32 sourceOffset = *_retval;
|
||||
|
||||
inStr->ReadSegments(ReadDataOut, this, count, _retval);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* [noscript] unsigned long writeSegments (in nsReadSegmentFun reader, in voidPtr closure, in unsigned long count); */
|
||||
NS_IMETHODIMP nsPNGDecoder::WriteSegments(nsReadSegmentFun reader, void * closure, PRUint32 count, PRUint32 *_retval)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* attribute boolean nonBlocking; */
|
||||
NS_IMETHODIMP nsPNGDecoder::GetNonBlocking(PRBool *aNonBlocking)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
NS_IMETHODIMP nsPNGDecoder::SetNonBlocking(PRBool aNonBlocking)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* attribute nsIOutputStreamObserver observer; */
|
||||
NS_IMETHODIMP nsPNGDecoder::GetObserver(nsIOutputStreamObserver * *aObserver)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
NS_IMETHODIMP nsPNGDecoder::SetObserver(nsIOutputStreamObserver * aObserver)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void
|
||||
nsPNGDecoder::info_callback(png_structp png_ptr, png_infop info_ptr)
|
||||
{
|
||||
/* int number_passes; NOT USED */
|
||||
png_uint_32 width, height;
|
||||
int bit_depth, color_type, interlace_type, compression_type, filter_type;
|
||||
int channels;
|
||||
double LUT_exponent, CRT_exponent = 2.2, display_exponent, aGamma;
|
||||
|
||||
png_bytep trans=NULL;
|
||||
int num_trans =0;
|
||||
|
||||
/* always decode to 24-bit RGB or 32-bit RGBA */
|
||||
png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
|
||||
&interlace_type, &compression_type, &filter_type);
|
||||
|
||||
if (color_type == PNG_COLOR_TYPE_PALETTE)
|
||||
png_set_expand(png_ptr);
|
||||
|
||||
if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
|
||||
png_set_expand(png_ptr);
|
||||
|
||||
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
|
||||
png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, NULL);
|
||||
png_set_expand(png_ptr);
|
||||
}
|
||||
|
||||
if (bit_depth == 16)
|
||||
png_set_strip_16(png_ptr);
|
||||
|
||||
if (color_type == PNG_COLOR_TYPE_GRAY ||
|
||||
color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
|
||||
png_set_gray_to_rgb(png_ptr);
|
||||
|
||||
|
||||
#ifdef XP_PC
|
||||
// windows likes BGR
|
||||
png_set_bgr(png_ptr);
|
||||
#endif
|
||||
|
||||
/* set up gamma correction for Mac, Unix and (Win32 and everything else)
|
||||
* using educated guesses for display-system exponents; do preferences
|
||||
* later */
|
||||
|
||||
#if defined(XP_MAC)
|
||||
LUT_exponent = 1.8 / 2.61;
|
||||
#elif defined(XP_UNIX)
|
||||
# if defined(__sgi)
|
||||
LUT_exponent = 1.0 / 1.7; /* typical default for SGI console */
|
||||
# elif defined(NeXT)
|
||||
LUT_exponent = 1.0 / 2.2; /* typical default for NeXT cube */
|
||||
# else
|
||||
LUT_exponent = 1.0; /* default for most other Unix workstations */
|
||||
# endif
|
||||
#else
|
||||
LUT_exponent = 1.0; /* virtually all PCs and most other systems */
|
||||
#endif
|
||||
|
||||
/* (alternatively, could check for SCREEN_GAMMA environment variable) */
|
||||
display_exponent = LUT_exponent * CRT_exponent;
|
||||
|
||||
if (png_get_gAMA(png_ptr, info_ptr, &aGamma))
|
||||
png_set_gamma(png_ptr, display_exponent, aGamma);
|
||||
else
|
||||
png_set_gamma(png_ptr, display_exponent, 0.45455);
|
||||
|
||||
/* let libpng expand interlaced images */
|
||||
if (interlace_type == PNG_INTERLACE_ADAM7) {
|
||||
/* number_passes = */
|
||||
png_set_interlace_handling(png_ptr);
|
||||
}
|
||||
|
||||
/* now all of those things we set above are used to update various struct
|
||||
* members and whatnot, after which we can get channels, rowbytes, etc. */
|
||||
png_read_update_info(png_ptr, info_ptr);
|
||||
channels = png_get_channels(png_ptr, info_ptr);
|
||||
PR_ASSERT(channels == 3 || channels == 4);
|
||||
|
||||
/*---------------------------------------------------------------*/
|
||||
/* copy PNG info into imagelib structs (formerly png_set_dims()) */
|
||||
/*---------------------------------------------------------------*/
|
||||
|
||||
PRInt32 alpha_bits = 1;
|
||||
|
||||
if (channels > 3) {
|
||||
/* check if alpha is coming from a tRNS chunk and is binary */
|
||||
if (num_trans) {
|
||||
/* if it's not a indexed color image, tRNS means binary */
|
||||
if (color_type == PNG_COLOR_TYPE_PALETTE) {
|
||||
for (int i=0; i<num_trans; i++) {
|
||||
if ((trans[i] != 0) && (trans[i] != 255)) {
|
||||
alpha_bits = 8;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
alpha_bits = 8;
|
||||
}
|
||||
}
|
||||
|
||||
nsPNGDecoder *decoder = NS_STATIC_CAST(nsPNGDecoder*, png_get_progressive_ptr(png_ptr));
|
||||
|
||||
if (decoder->mObserver)
|
||||
decoder->mObserver->OnStartDecode(nsnull, nsnull);
|
||||
|
||||
// since the png is only 1 frame, initalize the container to the width and height of the frame
|
||||
decoder->mImage->Init(width, height, decoder->mObserver);
|
||||
|
||||
if (decoder->mObserver)
|
||||
decoder->mObserver->OnStartContainer(nsnull, nsnull, decoder->mImage);
|
||||
|
||||
decoder->mFrame = do_CreateInstance("@mozilla.org/gfx/image/frame;2");
|
||||
#if 0
|
||||
// XXX should we longjmp to png_ptr->jumpbuf here if we failed?
|
||||
if (!decoder->mFrame)
|
||||
return NS_ERROR_FAILURE;
|
||||
#endif
|
||||
|
||||
gfx_format format;
|
||||
|
||||
if (channels == 3) {
|
||||
format = gfxIFormats::RGB;
|
||||
} else if (channels > 3) {
|
||||
if (alpha_bits == 8) {
|
||||
decoder->mImage->GetPreferredAlphaChannelFormat(&format);
|
||||
} else if (alpha_bits == 1) {
|
||||
format = gfxIFormats::RGB_A1;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef XP_PC
|
||||
// XXX this works...
|
||||
format += 1; // RGB to BGR
|
||||
#endif
|
||||
|
||||
// then initalize the frame and append it to the container
|
||||
decoder->mFrame->Init(0, 0, width, height, format);
|
||||
|
||||
decoder->mImage->AppendFrame(decoder->mFrame);
|
||||
|
||||
if (decoder->mObserver)
|
||||
decoder->mObserver->OnStartFrame(nsnull, nsnull, decoder->mFrame);
|
||||
|
||||
PRUint32 bpr, abpr;
|
||||
decoder->mFrame->GetImageBytesPerRow(&bpr);
|
||||
decoder->mFrame->GetAlphaBytesPerRow(&abpr);
|
||||
decoder->colorLine = (PRUint8 *)nsMemory::Alloc(bpr);
|
||||
if (channels > 3)
|
||||
decoder->alphaLine = (PRUint8 *)nsMemory::Alloc(abpr);
|
||||
|
||||
if (interlace_type == PNG_INTERLACE_ADAM7) {
|
||||
decoder->interlacebuf = (PRUint8 *)nsMemory::Alloc(channels*width*height);
|
||||
decoder->ibpr = channels*width;
|
||||
if (!decoder->interlacebuf) {
|
||||
// return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void
|
||||
nsPNGDecoder::row_callback(png_structp png_ptr, png_bytep new_row,
|
||||
png_uint_32 row_num, int pass)
|
||||
{
|
||||
/* libpng comments:
|
||||
*
|
||||
* this function is called for every row in the image. If the
|
||||
* image is interlacing, and you turned on the interlace handler,
|
||||
* this function will be called for every row in every pass.
|
||||
* Some of these rows will not be changed from the previous pass.
|
||||
* When the row is not changed, the new_row variable will be NULL.
|
||||
* The rows and passes are called in order, so you don't really
|
||||
* need the row_num and pass, but I'm supplying them because it
|
||||
* may make your life easier.
|
||||
*
|
||||
* For the non-NULL rows of interlaced images, you must call
|
||||
* png_progressive_combine_row() passing in the row and the
|
||||
* old row. You can call this function for NULL rows (it will
|
||||
* just return) and for non-interlaced images (it just does the
|
||||
* memcpy for you) if it will make the code easier. Thus, you
|
||||
* can just do this for all cases:
|
||||
*
|
||||
* png_progressive_combine_row(png_ptr, old_row, new_row);
|
||||
*
|
||||
* where old_row is what was displayed for previous rows. Note
|
||||
* that the first pass (pass == 0 really) will completely cover
|
||||
* the old row, so the rows do not have to be initialized. After
|
||||
* the first pass (and only for interlaced images), you will have
|
||||
* to pass the current row, and the function will combine the
|
||||
* old row and the new row.
|
||||
*/
|
||||
nsPNGDecoder *decoder = NS_STATIC_CAST(nsPNGDecoder*, png_get_progressive_ptr(png_ptr));
|
||||
|
||||
PRUint32 bpr, abpr;
|
||||
decoder->mFrame->GetImageBytesPerRow(&bpr);
|
||||
decoder->mFrame->GetAlphaBytesPerRow(&abpr);
|
||||
|
||||
png_bytep line;
|
||||
if (decoder->interlacebuf) {
|
||||
line = decoder->interlacebuf+(row_num*decoder->ibpr);
|
||||
png_progressive_combine_row(png_ptr, line, new_row);
|
||||
}
|
||||
else
|
||||
line = new_row;
|
||||
|
||||
if (new_row) {
|
||||
nscoord width;
|
||||
decoder->mFrame->GetWidth(&width);
|
||||
PRUint32 iwidth = width;
|
||||
|
||||
gfx_format format;
|
||||
decoder->mFrame->GetFormat(&format);
|
||||
PRUint8 *aptr, *cptr;
|
||||
|
||||
// The mac specific ifdefs in the code below are there to make sure we
|
||||
// always fill in 4 byte pixels right now, which is what the mac always
|
||||
// allocates for its pixel buffers in true color mode. This will change
|
||||
// when we start storing images with color palettes when they don't need
|
||||
// true color support (GIFs).
|
||||
switch (format) {
|
||||
case gfxIFormats::RGB:
|
||||
case gfxIFormats::BGR:
|
||||
#ifdef XP_MAC
|
||||
cptr = decoder->colorLine;
|
||||
for (PRUint32 x=0; x<iwidth; x++) {
|
||||
*cptr++ = 0;
|
||||
*cptr++ = *line++;
|
||||
*cptr++ = *line++;
|
||||
*cptr++ = *line++;
|
||||
}
|
||||
decoder->mFrame->SetImageData(decoder->colorLine, bpr, row_num*bpr);
|
||||
#else
|
||||
decoder->mFrame->SetImageData((PRUint8*)line, bpr, row_num*bpr);
|
||||
#endif
|
||||
break;
|
||||
case gfxIFormats::RGB_A1:
|
||||
case gfxIFormats::BGR_A1:
|
||||
{
|
||||
cptr = decoder->colorLine;
|
||||
aptr = decoder->alphaLine;
|
||||
memset(aptr, 0, abpr);
|
||||
for (PRUint32 x=0; x<iwidth; x++) {
|
||||
#ifdef XP_MAC
|
||||
*cptr++ = 0;
|
||||
#endif
|
||||
*cptr++ = *line++;
|
||||
*cptr++ = *line++;
|
||||
*cptr++ = *line++;
|
||||
if (*line++) {
|
||||
aptr[x>>3] |= 1<<(7-x&0x7);
|
||||
}
|
||||
}
|
||||
decoder->mFrame->SetImageData(decoder->colorLine, bpr, row_num*bpr);
|
||||
decoder->mFrame->SetAlphaData(decoder->alphaLine, abpr, row_num*abpr);
|
||||
}
|
||||
break;
|
||||
case gfxIFormats::RGB_A8:
|
||||
case gfxIFormats::BGR_A8:
|
||||
{
|
||||
cptr = decoder->colorLine;
|
||||
aptr = decoder->alphaLine;
|
||||
for (PRUint32 x=0; x<iwidth; x++) {
|
||||
#ifdef XP_MAC
|
||||
*cptr++ = 0;
|
||||
#endif
|
||||
*cptr++ = *line++;
|
||||
*cptr++ = *line++;
|
||||
*cptr++ = *line++;
|
||||
*aptr++ = *line++;
|
||||
}
|
||||
decoder->mFrame->SetImageData(decoder->colorLine, bpr, row_num*bpr);
|
||||
decoder->mFrame->SetAlphaData(decoder->alphaLine, abpr, row_num*abpr);
|
||||
}
|
||||
break;
|
||||
case gfxIFormats::RGBA:
|
||||
case gfxIFormats::BGRA:
|
||||
#ifdef XP_MAC
|
||||
{
|
||||
cptr = decoder->colorLine;
|
||||
aptr = decoder->alphaLine;
|
||||
for (PRUint32 x=0; x<iwidth; x++) {
|
||||
*cptr++ = 0;
|
||||
*cptr++ = *line++;
|
||||
*cptr++ = *line++;
|
||||
*cptr++ = *line++;
|
||||
*aptr++ = *line++;
|
||||
}
|
||||
decoder->mFrame->SetImageData(decoder->colorLine, bpr, row_num*bpr);
|
||||
decoder->mFrame->SetAlphaData(decoder->alphaLine, abpr, row_num*abpr);
|
||||
}
|
||||
#else
|
||||
decoder->mFrame->SetImageData(line, bpr, row_num*bpr);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
nsRect r(0, row_num, width, 1);
|
||||
decoder->mObserver->OnDataAvailable(nsnull, nsnull, decoder->mFrame, &r);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
nsPNGDecoder::end_callback(png_structp png_ptr, png_infop info_ptr)
|
||||
{
|
||||
/* libpng comments:
|
||||
*
|
||||
* this function is called when the whole image has been read,
|
||||
* including any chunks after the image (up to and including
|
||||
* the IEND). You will usually have the same info chunk as you
|
||||
* had in the header, although some data may have been added
|
||||
* to the comments and time fields.
|
||||
*
|
||||
* Most people won't do much here, perhaps setting a flag that
|
||||
* marks the image as finished.
|
||||
*/
|
||||
|
||||
nsPNGDecoder *decoder = NS_STATIC_CAST(nsPNGDecoder*, png_get_progressive_ptr(png_ptr));
|
||||
|
||||
if (decoder->mObserver) {
|
||||
decoder->mObserver->OnStopFrame(nsnull, nsnull, decoder->mFrame);
|
||||
decoder->mObserver->OnStopContainer(nsnull, nsnull, decoder->mImage);
|
||||
decoder->mObserver->OnStopDecode(nsnull, nsnull, NS_OK, nsnull);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
82
mozilla/modules/libpr0n/decoders/png/nsPNGDecoder.h
Normal file
82
mozilla/modules/libpr0n/decoders/png/nsPNGDecoder.h
Normal file
@@ -0,0 +1,82 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* 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 Netscape are
|
||||
* Copyright (C) 2001 Netscape Communications Corporation.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Stuart Parmenter <pavlov@netscape.com>
|
||||
*/
|
||||
|
||||
#ifndef nsPNGDecoder_h__
|
||||
#define nsPNGDecoder_h__
|
||||
|
||||
#include "imgIDecoder.h"
|
||||
|
||||
#include "imgIContainer.h"
|
||||
#include "imgIDecoderObserver.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
#include "imgIRequest.h"
|
||||
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
#include "png.h"
|
||||
|
||||
#define NS_PNGDECODER_CID \
|
||||
{ /* 36fa00c2-1dd2-11b2-be07-d16eeb4c50ed */ \
|
||||
0x36fa00c2, \
|
||||
0x1dd2, \
|
||||
0x11b2, \
|
||||
{0xbe, 0x07, 0xd1, 0x6e, 0xeb, 0x4c, 0x50, 0xed} \
|
||||
}
|
||||
|
||||
class nsPNGDecoder : public imgIDecoder
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_IMGIDECODER
|
||||
NS_DECL_NSIOUTPUTSTREAM
|
||||
|
||||
nsPNGDecoder();
|
||||
virtual ~nsPNGDecoder();
|
||||
|
||||
PR_STATIC_CALLBACK(void)
|
||||
info_callback(png_structp png_ptr, png_infop info_ptr);
|
||||
PR_STATIC_CALLBACK(void)
|
||||
row_callback(png_structp png_ptr, png_bytep new_row,
|
||||
png_uint_32 row_num, int pass);
|
||||
|
||||
PR_STATIC_CALLBACK(void)
|
||||
end_callback(png_structp png_ptr, png_infop info_ptr);
|
||||
|
||||
inline PRUint32 ProcessData(unsigned char *data, PRUint32 count);
|
||||
|
||||
|
||||
public:
|
||||
nsCOMPtr<imgIContainer> mImage;
|
||||
nsCOMPtr<gfxIImageFrame> mFrame;
|
||||
nsCOMPtr<imgIRequest> mRequest;
|
||||
nsCOMPtr<imgIDecoderObserver> mObserver; // this is just qi'd from mRequest for speed
|
||||
|
||||
png_structp mPNG;
|
||||
png_infop mInfo;
|
||||
PRUint8 *colorLine, *alphaLine;
|
||||
PRUint8 *interlacebuf;
|
||||
PRUint32 ibpr;
|
||||
};
|
||||
|
||||
#endif // nsPNGDecoder_h__
|
||||
46
mozilla/modules/libpr0n/decoders/png/nsPNGFactory.cpp
Normal file
46
mozilla/modules/libpr0n/decoders/png/nsPNGFactory.cpp
Normal file
@@ -0,0 +1,46 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* 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 Netscape are
|
||||
* Copyright (C) 2001 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Stuart Parmenter <pavlov@netscape.com>
|
||||
*/
|
||||
|
||||
#include "nsIGenericFactory.h"
|
||||
#include "nsIModule.h"
|
||||
|
||||
#include "nsPNGDecoder.h"
|
||||
|
||||
// objects that just require generic constructors
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsPNGDecoder)
|
||||
|
||||
static nsModuleComponentInfo components[] =
|
||||
{
|
||||
{ "PNG decoder",
|
||||
NS_PNGDECODER_CID,
|
||||
"@mozilla.org/image/decoder;2?type=image/png",
|
||||
nsPNGDecoderConstructor, },
|
||||
{ "PNG decoder",
|
||||
NS_PNGDECODER_CID,
|
||||
"@mozilla.org/image/decoder;2?type=image/x-png",
|
||||
nsPNGDecoderConstructor, },
|
||||
};
|
||||
|
||||
NS_IMPL_NSGETMODULE("nsPNGDecoderModule", components)
|
||||
|
||||
42
mozilla/modules/libpr0n/decoders/ppm/Makefile.in
Normal file
42
mozilla/modules/libpr0n/decoders/ppm/Makefile.in
Normal file
@@ -0,0 +1,42 @@
|
||||
#
|
||||
# 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 Netscape are
|
||||
# Copyright (C) 2001 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
|
||||
DEPTH = ../../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = imgppm
|
||||
LIBRARY_NAME = imgppm
|
||||
IS_COMPONENT = 1
|
||||
|
||||
REQUIRES = xpcom layout necko gfx2 imglib2
|
||||
|
||||
CPPSRCS = nsPPMDecoder.cpp nsPPMFactory.cpp
|
||||
|
||||
EXTRA_DSO_LDOPTS = \
|
||||
$(MOZ_COMPONENT_LIBS) \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
51
mozilla/modules/libpr0n/decoders/ppm/makefile.win
Normal file
51
mozilla/modules/libpr0n/decoders/ppm/makefile.win
Normal file
@@ -0,0 +1,51 @@
|
||||
#!nmake
|
||||
#
|
||||
# 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 Netscape are
|
||||
# Copyright (C) 2001 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Stuart Parmenter <pavlov@netscape.com>
|
||||
#
|
||||
|
||||
DEPTH=..\..\..\..
|
||||
include <$(DEPTH)/config/config.mak>
|
||||
|
||||
MODULE = imgppm
|
||||
LIBRARY_NAME = imgppm
|
||||
DLL = $(OBJDIR)\$(LIBRARY_NAME).dll
|
||||
MAKE_OBJ_TYPE = DLL
|
||||
|
||||
OBJS = \
|
||||
.\$(OBJDIR)\nsPPMDecoder.obj \
|
||||
.\$(OBJDIR)\nsPPMFactory.obj \
|
||||
$(NULL)
|
||||
|
||||
LLIBS=\
|
||||
$(LIBNSPR) \
|
||||
$(DIST)\lib\xpcom.lib \
|
||||
$(DIST)\lib\gkgfxwin.lib \
|
||||
$(NULL)
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
|
||||
install:: $(DLL)
|
||||
$(MAKE_INSTALL) .\$(OBJDIR)\$(LIBRARY_NAME).dll $(DIST)\bin\components
|
||||
$(MAKE_INSTALL) .\$(OBJDIR)\$(LIBRARY_NAME).lib $(DIST)\lib
|
||||
|
||||
clobber::
|
||||
rm -f $(DIST)\bin\components\$(LIBRARY_NAME).dll
|
||||
rm -f $(DIST)\lib\$(LIBRARY_NAME).lib
|
||||
305
mozilla/modules/libpr0n/decoders/ppm/nsPPMDecoder.cpp
Normal file
305
mozilla/modules/libpr0n/decoders/ppm/nsPPMDecoder.cpp
Normal file
@@ -0,0 +1,305 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* 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 Netscape are
|
||||
* Copyright (C) 2001 Netscape Communications Corporation.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Stuart Parmenter <pavlov@netscape.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nsPPMDecoder.h"
|
||||
|
||||
#include "nsIInputStream.h"
|
||||
#include "imgIContainer.h"
|
||||
#include "imgIContainerObserver.h"
|
||||
|
||||
#include "nspr.h"
|
||||
|
||||
#include "nsIComponentManager.h"
|
||||
|
||||
#include "nsRect.h"
|
||||
|
||||
NS_IMPL_ISUPPORTS2(nsPPMDecoder, imgIDecoder, nsIOutputStream)
|
||||
|
||||
|
||||
nsPPMDecoder::nsPPMDecoder()
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
mDataReceived = 0;
|
||||
mDataWritten = 0;
|
||||
|
||||
mDataLeft = 0;
|
||||
mPrevData = nsnull;
|
||||
}
|
||||
|
||||
nsPPMDecoder::~nsPPMDecoder()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
/** imgIDecoder methods **/
|
||||
|
||||
/* void init (in imgIRequest aRequest); */
|
||||
NS_IMETHODIMP nsPPMDecoder::Init(imgIRequest *aRequest)
|
||||
{
|
||||
mRequest = aRequest;
|
||||
|
||||
mObserver = do_QueryInterface(aRequest); // we're holding 2 strong refs to the request.
|
||||
|
||||
aRequest->GetImage(getter_AddRefs(mImage));
|
||||
|
||||
mFrame = do_CreateInstance("@mozilla.org/gfx/image/frame;2");
|
||||
if (!mFrame)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute imgIRequest request; */
|
||||
NS_IMETHODIMP nsPPMDecoder::GetRequest(imgIRequest * *aRequest)
|
||||
{
|
||||
*aRequest = mRequest;
|
||||
NS_ADDREF(*aRequest);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** nsIOutputStream methods **/
|
||||
|
||||
/* void close (); */
|
||||
NS_IMETHODIMP nsPPMDecoder::Close()
|
||||
{
|
||||
if (mObserver) {
|
||||
mObserver->OnStopFrame(nsnull, nsnull, mFrame);
|
||||
mObserver->OnStopContainer(nsnull, nsnull, mImage);
|
||||
mObserver->OnStopDecode(nsnull, nsnull, NS_OK, nsnull);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void flush (); */
|
||||
NS_IMETHODIMP nsPPMDecoder::Flush()
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* unsigned long write (in string buf, in unsigned long count); */
|
||||
NS_IMETHODIMP nsPPMDecoder::Write(const char *buf, PRUint32 count, PRUint32 *_retval)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
static char *__itoa(int n)
|
||||
{
|
||||
char *s;
|
||||
int i, j, sign, tmp;
|
||||
|
||||
/* check sign and convert to positive to stringify numbers */
|
||||
if ( (sign = n) < 0)
|
||||
n = -n;
|
||||
i = 0;
|
||||
s = (char*) malloc(sizeof(char));
|
||||
|
||||
/* grow string as needed to add numbers from powers of 10
|
||||
* down till none left
|
||||
*/
|
||||
do
|
||||
{
|
||||
s = (char*) realloc(s, (i+1)*sizeof(char));
|
||||
s[i++] = n % 10 + '0'; /* '0' or 30 is where ASCII numbers start */
|
||||
s[i] = '\0';
|
||||
}
|
||||
while( (n /= 10) > 0);
|
||||
|
||||
/* tack on minus sign if we found earlier that this was negative */
|
||||
if (sign < 0)
|
||||
{
|
||||
s = (char*) realloc(s, (i+1)*sizeof(char));
|
||||
s[i++] = '-';
|
||||
}
|
||||
s[i] = '\0';
|
||||
|
||||
/* pop numbers (and sign) off of string to push back into right direction */
|
||||
for (i = 0, j = strlen(s) - 1; i < j; i++, j--)
|
||||
{
|
||||
tmp = s[i];
|
||||
s[i] = s[j];
|
||||
s[j] = tmp;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
/* unsigned long writeFrom (in nsIInputStream inStr, in unsigned long count); */
|
||||
NS_IMETHODIMP nsPPMDecoder::WriteFrom(nsIInputStream *inStr, PRUint32 count, PRUint32 *_retval)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
char *buf = (char *)PR_Malloc(count + mDataLeft);
|
||||
if (!buf)
|
||||
return NS_ERROR_OUT_OF_MEMORY; /* we couldn't allocate the object */
|
||||
|
||||
|
||||
// read the data from the input stram...
|
||||
PRUint32 readLen;
|
||||
rv = inStr->Read(buf+mDataLeft, count, &readLen);
|
||||
|
||||
PRUint32 dataLen = readLen + mDataLeft;
|
||||
|
||||
if (mPrevData) {
|
||||
strncpy(buf, mPrevData, mDataLeft);
|
||||
PR_Free(mPrevData);
|
||||
mPrevData = nsnull;
|
||||
mDataLeft = 0;
|
||||
}
|
||||
|
||||
char *data = buf;
|
||||
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
if (mDataReceived == 0) {
|
||||
|
||||
mObserver->OnStartDecode(nsnull, nsnull);
|
||||
|
||||
// Check the magic number
|
||||
char type;
|
||||
if ((sscanf(data, "P%c\n", &type) !=1) || (type != '6')) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
int i = 3;
|
||||
data += i;
|
||||
|
||||
#if 0
|
||||
// XXX
|
||||
// Ignore comments
|
||||
while ((input = fgetc(f)) == '#')
|
||||
fgets(junk, 512, f);
|
||||
ungetc(input, f);
|
||||
#endif
|
||||
|
||||
// Read size
|
||||
int w, h, mcv;
|
||||
|
||||
if (sscanf(data, "%d %d\n%d\n", &w, &h, &mcv) != 3) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
char *ws = __itoa(w), *hs = __itoa(h), *mcvs = __itoa(mcv);
|
||||
int j = strlen(ws) + strlen(hs) + strlen(mcvs) + 3;
|
||||
data += j;
|
||||
// free(ws);
|
||||
// free(hs);
|
||||
// free(mcvs);
|
||||
|
||||
readLen -= i + j;
|
||||
dataLen = readLen; // since this is the first pass, we don't have any data waiting that we need to keep track of
|
||||
|
||||
mImage->Init(w, h, mObserver);
|
||||
if (mObserver)
|
||||
mObserver->OnStartContainer(nsnull, nsnull, mImage);
|
||||
|
||||
mFrame->Init(0, 0, w, h, gfxIFormats::RGB);
|
||||
mImage->AppendFrame(mFrame);
|
||||
if (mObserver)
|
||||
mObserver->OnStartFrame(nsnull, nsnull, mFrame);
|
||||
}
|
||||
|
||||
PRUint32 bpr;
|
||||
nscoord width;
|
||||
mFrame->GetImageBytesPerRow(&bpr);
|
||||
mFrame->GetWidth(&width);
|
||||
|
||||
// XXX ceil?
|
||||
PRUint32 real_bpr = width * 3;
|
||||
|
||||
PRUint32 i = 0;
|
||||
PRUint32 rownum = mDataWritten / real_bpr; // XXX this better not have a decimal
|
||||
|
||||
PRUint32 wroteLen = 0;
|
||||
|
||||
if (readLen > real_bpr) {
|
||||
|
||||
do {
|
||||
PRUint8 *line = (PRUint8*)data + i*real_bpr;
|
||||
mFrame->SetImageData(line, real_bpr, (rownum++)*bpr);
|
||||
|
||||
nsRect r(0, rownum, width, 1);
|
||||
mObserver->OnDataAvailable(nsnull, nsnull, mFrame, &r);
|
||||
|
||||
|
||||
wroteLen += real_bpr ;
|
||||
i++;
|
||||
} while(dataLen >= real_bpr * (i+1));
|
||||
|
||||
}
|
||||
|
||||
mDataReceived += readLen; // don't double count previous data that is in 'dataLen'
|
||||
mDataWritten += wroteLen;
|
||||
|
||||
PRUint32 dataLeft = dataLen - wroteLen;
|
||||
|
||||
if (dataLeft > 0) {
|
||||
if (mPrevData) {
|
||||
mPrevData = (char *)PR_Realloc(mPrevData, mDataLeft + dataLeft);
|
||||
strncpy(mPrevData + mDataLeft, data+wroteLen, dataLeft);
|
||||
mDataLeft += dataLeft;
|
||||
|
||||
} else {
|
||||
mDataLeft = dataLeft;
|
||||
mPrevData = (char *)PR_Malloc(mDataLeft);
|
||||
strncpy(mPrevData, data+wroteLen, mDataLeft);
|
||||
}
|
||||
}
|
||||
|
||||
PR_FREEIF(buf);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* [noscript] unsigned long writeSegments (in nsReadSegmentFun reader, in voidPtr closure, in unsigned long count); */
|
||||
NS_IMETHODIMP nsPPMDecoder::WriteSegments(nsReadSegmentFun reader, void * closure, PRUint32 count, PRUint32 *_retval)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* attribute boolean nonBlocking; */
|
||||
NS_IMETHODIMP nsPPMDecoder::GetNonBlocking(PRBool *aNonBlocking)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
NS_IMETHODIMP nsPPMDecoder::SetNonBlocking(PRBool aNonBlocking)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* attribute nsIOutputStreamObserver observer; */
|
||||
NS_IMETHODIMP nsPPMDecoder::GetObserver(nsIOutputStreamObserver * *aObserver)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
NS_IMETHODIMP nsPPMDecoder::SetObserver(nsIOutputStreamObserver * aObserver)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
67
mozilla/modules/libpr0n/decoders/ppm/nsPPMDecoder.h
Normal file
67
mozilla/modules/libpr0n/decoders/ppm/nsPPMDecoder.h
Normal file
@@ -0,0 +1,67 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* 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 Netscape are
|
||||
* Copyright (C) 2001 Netscape Communications Corporation.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Stuart Parmenter <pavlov@netscape.com>
|
||||
*/
|
||||
|
||||
#ifndef nsPPMDecoder_h__
|
||||
#define nsPPMDecoder_h__
|
||||
|
||||
#include "imgIDecoder.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
#include "imgIContainer.h"
|
||||
#include "imgIDecoderObserver.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
#include "imgIRequest.h"
|
||||
|
||||
#define NS_PPMDECODER_CID \
|
||||
{ /* e90bfa06-1dd1-11b2-8217-f38fe5d431a2 */ \
|
||||
0xe90bfa06, \
|
||||
0x1dd1, \
|
||||
0x11b2, \
|
||||
{0x82, 0x17, 0xf3, 0x8f, 0xe5, 0xd4, 0x31, 0xa2} \
|
||||
}
|
||||
|
||||
class nsPPMDecoder : public imgIDecoder
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_IMGIDECODER
|
||||
NS_DECL_NSIOUTPUTSTREAM
|
||||
|
||||
nsPPMDecoder();
|
||||
virtual ~nsPPMDecoder();
|
||||
|
||||
private:
|
||||
nsCOMPtr<imgIContainer> mImage;
|
||||
nsCOMPtr<gfxIImageFrame> mFrame;
|
||||
nsCOMPtr<imgIRequest> mRequest;
|
||||
nsCOMPtr<imgIDecoderObserver> mObserver; // this is just qi'd from mRequest for speed
|
||||
|
||||
PRUint32 mDataReceived;
|
||||
PRUint32 mDataWritten;
|
||||
|
||||
PRUint32 mDataLeft;
|
||||
char *mPrevData;
|
||||
};
|
||||
|
||||
#endif // nsPPMDecoder_h__
|
||||
42
mozilla/modules/libpr0n/decoders/ppm/nsPPMFactory.cpp
Normal file
42
mozilla/modules/libpr0n/decoders/ppm/nsPPMFactory.cpp
Normal file
@@ -0,0 +1,42 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* 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 Netscape are
|
||||
* Copyright (C) 2001 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Stuart Parmenter <pavlov@netscape.com>
|
||||
*/
|
||||
|
||||
#include "nsIGenericFactory.h"
|
||||
#include "nsIModule.h"
|
||||
|
||||
#include "nsPPMDecoder.h"
|
||||
|
||||
// objects that just require generic constructors
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsPPMDecoder)
|
||||
|
||||
static nsModuleComponentInfo components[] =
|
||||
{
|
||||
{ "ppm decoder",
|
||||
NS_PPMDECODER_CID,
|
||||
"@mozilla.org/image/decoder;2?type=image/x-portable-pixmap",
|
||||
nsPPMDecoderConstructor, },
|
||||
};
|
||||
|
||||
NS_IMPL_NSGETMODULE("nsPPMDecoderModule", components)
|
||||
|
||||
BIN
mozilla/modules/libpr0n/macbuild/gifdecoder2.mcp
Normal file
BIN
mozilla/modules/libpr0n/macbuild/gifdecoder2.mcp
Normal file
Binary file not shown.
BIN
mozilla/modules/libpr0n/macbuild/jpegdecoder2.mcp
Normal file
BIN
mozilla/modules/libpr0n/macbuild/jpegdecoder2.mcp
Normal file
Binary file not shown.
BIN
mozilla/modules/libpr0n/macbuild/libimg2.mcp
Normal file
BIN
mozilla/modules/libpr0n/macbuild/libimg2.mcp
Normal file
Binary file not shown.
BIN
mozilla/modules/libpr0n/macbuild/libimg2IDL.mcp
Normal file
BIN
mozilla/modules/libpr0n/macbuild/libimg2IDL.mcp
Normal file
Binary file not shown.
BIN
mozilla/modules/libpr0n/macbuild/pngdecoder2.mcp
Normal file
BIN
mozilla/modules/libpr0n/macbuild/pngdecoder2.mcp
Normal file
Binary file not shown.
25
mozilla/modules/libpr0n/makefile.win
Normal file
25
mozilla/modules/libpr0n/makefile.win
Normal file
@@ -0,0 +1,25 @@
|
||||
#
|
||||
# The contents of this file are subject to the Netscape 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/NPL/
|
||||
#
|
||||
# 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 Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
|
||||
DEPTH=..\..
|
||||
|
||||
DIRS = public src decoders
|
||||
|
||||
!include $(DEPTH)\config\rules.mak
|
||||
111
mozilla/modules/libpr0n/public/ImageLogging.h
Normal file
111
mozilla/modules/libpr0n/public/ImageLogging.h
Normal file
@@ -0,0 +1,111 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* 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 Netscape are
|
||||
* Copyright (C) 2001 Netscape Communications Corporation.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Stuart Parmenter <pavlov@netscape.com>
|
||||
*/
|
||||
|
||||
#include "prlog.h"
|
||||
|
||||
#include "nsString.h"
|
||||
|
||||
#if defined(PR_LOGGING)
|
||||
extern PRLogModuleInfo *gImgLog;
|
||||
|
||||
class LogScope {
|
||||
public:
|
||||
LogScope(PRLogModuleInfo *aLog, void *from, const nsAReadableCString &fn) :
|
||||
mLog(aLog), mFrom(from), mFunc(fn)
|
||||
{
|
||||
PR_LOG(mLog, PR_LOG_DEBUG, ("[this=%p] %s {ENTER}\n",
|
||||
mFrom, mFunc.get()));
|
||||
}
|
||||
|
||||
/* const char * constructor */
|
||||
LogScope(PRLogModuleInfo *aLog, void *from, const nsAReadableCString &fn,
|
||||
const nsLiteralCString ¶mName, const char *paramValue) :
|
||||
mLog(aLog), mFrom(from), mFunc(fn)
|
||||
{
|
||||
PR_LOG(mLog, PR_LOG_DEBUG, ("[this=%p] %s (%s=\"%s\") {ENTER}\n",
|
||||
mFrom, mFunc.get(),
|
||||
paramName.get(),
|
||||
paramValue));
|
||||
}
|
||||
|
||||
/* void ptr constructor */
|
||||
LogScope(PRLogModuleInfo *aLog, void *from, const nsAReadableCString &fn,
|
||||
const nsLiteralCString ¶mName, const void *paramValue) :
|
||||
mLog(aLog), mFrom(from), mFunc(fn)
|
||||
{
|
||||
PR_LOG(mLog, PR_LOG_DEBUG, ("[this=%p] %s (%s=%p) {ENTER}\n",
|
||||
mFrom, mFunc.get(),
|
||||
paramName.get(),
|
||||
paramValue));
|
||||
}
|
||||
|
||||
/* PRInt32 constructor */
|
||||
LogScope(PRLogModuleInfo *aLog, void *from, const nsAReadableCString &fn,
|
||||
const nsLiteralCString ¶mName, PRInt32 paramValue) :
|
||||
mLog(aLog), mFrom(from), mFunc(fn)
|
||||
{
|
||||
PR_LOG(mLog, PR_LOG_DEBUG, ("[this=%p] %s (%s=\"%d\") {ENTER}\n",
|
||||
mFrom, mFunc.get(),
|
||||
paramName.get(),
|
||||
paramValue));
|
||||
}
|
||||
|
||||
/* PRUint32 constructor */
|
||||
LogScope(PRLogModuleInfo *aLog, void *from, const nsAReadableCString &fn,
|
||||
const nsLiteralCString ¶mName, PRUint32 paramValue) :
|
||||
mLog(aLog), mFrom(from), mFunc(fn)
|
||||
{
|
||||
PR_LOG(mLog, PR_LOG_DEBUG, ("[this=%p] %s (%s=\"%d\") {ENTER}\n",
|
||||
mFrom, mFunc.get(),
|
||||
paramName.get(),
|
||||
paramValue));
|
||||
}
|
||||
|
||||
|
||||
~LogScope() {
|
||||
PR_LOG(mLog, PR_LOG_DEBUG, ("[this=%p] %s {EXIT}\n",
|
||||
mFrom, mFunc.get()));
|
||||
}
|
||||
|
||||
private:
|
||||
PRLogModuleInfo *mLog;
|
||||
void *mFrom;
|
||||
nsCAutoString mFunc;
|
||||
};
|
||||
|
||||
|
||||
#define LOG_SCOPE(l, s) \
|
||||
LogScope LOG_SCOPE_TMP_VAR ##__LINE__ (l, \
|
||||
NS_STATIC_CAST(void *, this), \
|
||||
NS_LITERAL_CSTRING(s))
|
||||
|
||||
#define LOG_SCOPE_WITH_PARAM(l, s, pn, pv) \
|
||||
LogScope LOG_SCOPE_TMP_VAR ##__LINE__ (l, \
|
||||
NS_STATIC_CAST(void *, this), \
|
||||
NS_LITERAL_CSTRING(s), \
|
||||
NS_LITERAL_CSTRING(pn), pv)
|
||||
|
||||
#else
|
||||
#define LOG_SCOPE(l, s)
|
||||
#define LOG_SCOPE_WITH_PARAM(l, s, pn, pv)
|
||||
#endif
|
||||
1
mozilla/modules/libpr0n/public/MANIFEST
Normal file
1
mozilla/modules/libpr0n/public/MANIFEST
Normal file
@@ -0,0 +1 @@
|
||||
ImageLogging.h
|
||||
6
mozilla/modules/libpr0n/public/MANIFEST_IDL
Normal file
6
mozilla/modules/libpr0n/public/MANIFEST_IDL
Normal file
@@ -0,0 +1,6 @@
|
||||
imgIContainer.idl
|
||||
imgIContainerObserver.idl
|
||||
imgIDecoder.idl
|
||||
imgIDecoderObserver.idl
|
||||
imgILoader.idl
|
||||
imgIRequest.idl
|
||||
41
mozilla/modules/libpr0n/public/Makefile.in
Normal file
41
mozilla/modules/libpr0n/public/Makefile.in
Normal file
@@ -0,0 +1,41 @@
|
||||
#
|
||||
# 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 Netscape are
|
||||
# Copyright (C) 2001 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
|
||||
DEPTH = ../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = imglib2
|
||||
|
||||
EXPORTS = ImageLogging.h
|
||||
|
||||
XPIDLSRCS = imgIContainer.idl \
|
||||
imgIContainerObserver.idl \
|
||||
imgIDecoder.idl \
|
||||
imgIDecoderObserver.idl \
|
||||
imgILoader.idl \
|
||||
imgIRequest.idl
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
109
mozilla/modules/libpr0n/public/imgIContainer.idl
Normal file
109
mozilla/modules/libpr0n/public/imgIContainer.idl
Normal file
@@ -0,0 +1,109 @@
|
||||
/** -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* 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 Netscape are
|
||||
* Copyright (C) 2001 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Stuart Parmenter <pavlov@netscape.com>
|
||||
*/
|
||||
|
||||
#include "nsISupports.idl"
|
||||
#include "gfxtypes.idl"
|
||||
#include "gfxIFormats.idl"
|
||||
|
||||
interface gfxIImageFrame;
|
||||
interface nsIEnumerator;
|
||||
interface imgIContainerObserver;
|
||||
|
||||
/**
|
||||
* gfxIImageContainer interface
|
||||
*
|
||||
* @author Stuart Parmenter <pavlov@netscape.com>
|
||||
* @version 0.1
|
||||
* @see "gfx2"
|
||||
*/
|
||||
[scriptable, uuid(5e8405a4-1dd2-11b2-8385-bc8e3446cad3)]
|
||||
interface imgIContainer : nsISupports
|
||||
{
|
||||
/**
|
||||
* Create a new \a aWidth x \a aHeight sized image container.
|
||||
*
|
||||
* @param aWidth The width of the container in which all the
|
||||
* gfxIImageFrame children will fit.
|
||||
* @param aHeight The height of the container in which all the
|
||||
* gfxIImageFrame children will fit.
|
||||
* @param aObserver Observer to send animation notifications to.
|
||||
*/
|
||||
void init(in nscoord aWidth,
|
||||
in nscoord aHeight,
|
||||
in imgIContainerObserver aObserver);
|
||||
|
||||
|
||||
/* this should probably be on the device context (or equiv) */
|
||||
readonly attribute gfx_format preferredAlphaChannelFormat;
|
||||
|
||||
/**
|
||||
* The width of the container rectangle.
|
||||
*/
|
||||
readonly attribute nscoord width;
|
||||
|
||||
/**
|
||||
* The height of the container rectangle.
|
||||
*/
|
||||
readonly attribute nscoord height;
|
||||
|
||||
|
||||
/**
|
||||
* Get the current frame that would be drawn if the image was to be drawn now
|
||||
*/
|
||||
readonly attribute gfxIImageFrame currentFrame;
|
||||
|
||||
|
||||
readonly attribute unsigned long numFrames;
|
||||
|
||||
gfxIImageFrame getFrameAt(in unsigned long index);
|
||||
|
||||
/**
|
||||
* Adds \a item to the end of the list of frames.
|
||||
* @param item frame to add.
|
||||
*/
|
||||
void appendFrame(in gfxIImageFrame item);
|
||||
|
||||
void removeFrame(in gfxIImageFrame item);
|
||||
|
||||
/* notification when the current frame is done decoding */
|
||||
void endFrameDecode(in unsigned long framenumber, in unsigned long timeout);
|
||||
|
||||
/* notification that the entire image has been decoded */
|
||||
void decodingComplete();
|
||||
|
||||
nsIEnumerator enumerate();
|
||||
|
||||
void clear();
|
||||
|
||||
void startAnimation();
|
||||
|
||||
void stopAnimation();
|
||||
|
||||
/* animation stuff */
|
||||
|
||||
/**
|
||||
* number of times to loop the image.
|
||||
* @note -1 means forever.
|
||||
*/
|
||||
attribute long loopCount;
|
||||
};
|
||||
46
mozilla/modules/libpr0n/public/imgIContainerObserver.idl
Normal file
46
mozilla/modules/libpr0n/public/imgIContainerObserver.idl
Normal file
@@ -0,0 +1,46 @@
|
||||
/** -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* 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 Netscape are
|
||||
* Copyright (C) 2001 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Stuart Parmenter <pavlov@netscape.com>
|
||||
*/
|
||||
|
||||
#include "nsISupports.idl"
|
||||
#include "gfxtypes.idl"
|
||||
|
||||
%{C++
|
||||
#include "nsRect.h"
|
||||
%}
|
||||
|
||||
interface imgIContainer;
|
||||
|
||||
interface gfxIImageFrame;
|
||||
|
||||
/**
|
||||
* imgIContainerObserver interface
|
||||
*
|
||||
* @author Stuart Parmenter <pavlov@netscape.com>
|
||||
* @version 0.1
|
||||
*/
|
||||
[uuid(153f1518-1dd2-11b2-b9cd-b16eb63e0471)]
|
||||
interface imgIContainerObserver : nsISupports
|
||||
{
|
||||
[noscript] void frameChanged(in imgIContainer aContainer, in nsISupports aCX,
|
||||
in gfxIImageFrame aFrame, in nsRect aDirtyRect);
|
||||
};
|
||||
53
mozilla/modules/libpr0n/public/imgIDecoder.idl
Normal file
53
mozilla/modules/libpr0n/public/imgIDecoder.idl
Normal file
@@ -0,0 +1,53 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* 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 Netscape are
|
||||
* Copyright (C) 2001 Netscape Communications Corporation.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Stuart Parmenter <pavlov@netscape.com>
|
||||
*/
|
||||
|
||||
#include "nsISupports.idl"
|
||||
#include "nsIOutputStream.idl"
|
||||
#include "gfxtypes.idl"
|
||||
|
||||
interface imgIRequest;
|
||||
|
||||
/**
|
||||
* imgIDecoder interface
|
||||
*
|
||||
* @author Stuart Parmenter <pavlov@netscape.com>
|
||||
* @version 0.1
|
||||
* @see imagelib2
|
||||
*/
|
||||
[scriptable, uuid(9eebf43a-1dd1-11b2-953e-f1782f4cbad3)]
|
||||
interface imgIDecoder : nsIOutputStream
|
||||
{
|
||||
/**
|
||||
* Initalize an image decoder.
|
||||
* @param aRequest the request that owns the decoder.
|
||||
*
|
||||
* @note The decode should QI \a aRequest to an imgIDecoderObserver
|
||||
* and should send decoder notifications to the request.
|
||||
* The decoder should always pass NULL as the first two parameters to
|
||||
* all of the imgIDecoderObserver APIs.
|
||||
*/
|
||||
void init(in imgIRequest aRequest);
|
||||
|
||||
/// allows access to the nsIImage we have to put bits in to.
|
||||
readonly attribute imgIRequest request;
|
||||
};
|
||||
80
mozilla/modules/libpr0n/public/imgIDecoderObserver.idl
Normal file
80
mozilla/modules/libpr0n/public/imgIDecoderObserver.idl
Normal file
@@ -0,0 +1,80 @@
|
||||
/** -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* 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 Netscape are
|
||||
* Copyright (C) 2001 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Stuart Parmenter <pavlov@netscape.com>
|
||||
*/
|
||||
|
||||
#include "imgIContainerObserver.idl"
|
||||
|
||||
interface imgIRequest;
|
||||
interface imgIContainer;
|
||||
interface gfxIImageFrame;
|
||||
|
||||
%{C++
|
||||
#include "nsRect.h"
|
||||
%}
|
||||
|
||||
/**
|
||||
* imgIDecoderObserver interface
|
||||
*
|
||||
* @author Stuart Parmenter <pavlov@netscape.com>
|
||||
* @version 0.1
|
||||
* @see imagelib2
|
||||
*/
|
||||
[scriptable, uuid(350163d2-1dd2-11b2-9e69-89959ecec1f3)]
|
||||
interface imgIDecoderObserver : imgIContainerObserver
|
||||
{
|
||||
/**
|
||||
* called as soon as the image begins getting decoded
|
||||
*/
|
||||
void onStartDecode(in imgIRequest aRequest, in nsISupports cx);
|
||||
|
||||
/**
|
||||
* called once the image has been inited and therefore has a width and height
|
||||
*/
|
||||
void onStartContainer(in imgIRequest aRequest, in nsISupports cx, in imgIContainer aContainer);
|
||||
|
||||
/**
|
||||
* called when each frame is created
|
||||
*/
|
||||
void onStartFrame(in imgIRequest aRequest, in nsISupports cx, in gfxIImageFrame aFrame);
|
||||
|
||||
/**
|
||||
* called when some part of the frame has new data in it
|
||||
*/
|
||||
[noscript] void onDataAvailable(in imgIRequest aRequest, in nsISupports cx, in gfxIImageFrame aFrame, [const] in nsRect aRect);
|
||||
|
||||
/**
|
||||
* called when a frame is finished decoding
|
||||
*/
|
||||
void onStopFrame(in imgIRequest aRequest, in nsISupports cx, in gfxIImageFrame aFrame);
|
||||
|
||||
/**
|
||||
* probably not needed. called right before onStopDecode
|
||||
*/
|
||||
void onStopContainer(in imgIRequest aRequest, in nsISupports cx, in imgIContainer aContainer);
|
||||
|
||||
/**
|
||||
* called when the decoder is dying off
|
||||
*/
|
||||
void onStopDecode(in imgIRequest aRequest, in nsISupports cx,
|
||||
in nsresult status, in wstring statusArg);
|
||||
|
||||
};
|
||||
62
mozilla/modules/libpr0n/public/imgILoader.idl
Normal file
62
mozilla/modules/libpr0n/public/imgILoader.idl
Normal file
@@ -0,0 +1,62 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* 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 Netscape are
|
||||
* Copyright (C) 2001 Netscape Communications Corporation.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Stuart Parmenter <pavlov@netscape.com>
|
||||
*/
|
||||
|
||||
#include "nsISupports.idl"
|
||||
#include "gfxtypes.idl"
|
||||
|
||||
interface imgIDecoderObserver;
|
||||
interface imgIRequest;
|
||||
|
||||
interface nsIChannel;
|
||||
interface nsILoadGroup;
|
||||
interface nsIStreamListener;
|
||||
interface nsIURI;
|
||||
|
||||
interface nsISimpleEnumerator;
|
||||
|
||||
/**
|
||||
* imgILoader interface
|
||||
*
|
||||
* @author Stuart Parmenter <pavlov@netscape.com>
|
||||
* @version 0.1
|
||||
* @see imagelib2
|
||||
*/
|
||||
[scriptable, uuid(4c8cf1e0-1dd2-11b2-aff9-c51cdbfcb6da)]
|
||||
interface imgILoader : nsISupports
|
||||
{
|
||||
/**
|
||||
* Start the load and decode of an image.
|
||||
* @param uri the URI to load
|
||||
* @param aObserver the observer
|
||||
* @param cx some random data
|
||||
*/
|
||||
imgIRequest loadImage(in nsIURI uri, in nsILoadGroup aLoadGroup, in imgIDecoderObserver aObserver, in nsISupports cx);
|
||||
|
||||
/**
|
||||
* Start the load and decode of an image.
|
||||
* @param uri the URI to load
|
||||
* @param aObserver the observer
|
||||
* @param cx some random data
|
||||
*/
|
||||
imgIRequest loadImageWithChannel(in nsIChannel aChannel, in imgIDecoderObserver aObserver, in nsISupports cx, out nsIStreamListener aListener);
|
||||
};
|
||||
80
mozilla/modules/libpr0n/public/imgIRequest.idl
Normal file
80
mozilla/modules/libpr0n/public/imgIRequest.idl
Normal file
@@ -0,0 +1,80 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* 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 Netscape are
|
||||
* Copyright (C) 2001 Netscape Communications Corporation.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Stuart Parmenter <pavlov@netscape.com>
|
||||
*/
|
||||
|
||||
#include "nsISupports.idl"
|
||||
#include "nsIRequest.idl"
|
||||
|
||||
interface imgIContainer;
|
||||
interface imgIDecoderObserver;
|
||||
interface nsIURI;
|
||||
|
||||
/**
|
||||
* imgIRequest interface
|
||||
*
|
||||
* @author Stuart Parmenter <pavlov@netscape.com>
|
||||
* @version 0.1
|
||||
* @see imagelib2
|
||||
*/
|
||||
[scriptable, uuid(ccf705f6-1dd1-11b2-82ef-e18eccf7f7ec)]
|
||||
interface imgIRequest : nsIRequest
|
||||
{
|
||||
/**
|
||||
* the image container...
|
||||
* @return the image object associated with the request.
|
||||
* @attention NEED DOCS
|
||||
*/
|
||||
readonly attribute imgIContainer image;
|
||||
|
||||
/**
|
||||
* Bits set in the return value from imageStatus
|
||||
* @name statusflags
|
||||
*/
|
||||
//@{
|
||||
const long STATUS_NONE = 0x0;
|
||||
const long STATUS_SIZE_AVAILABLE = 0x1;
|
||||
const long STATUS_LOAD_COMPLETE = 0x2;
|
||||
const long STATUS_ERROR = 0x4;
|
||||
//@}
|
||||
|
||||
/**
|
||||
* something
|
||||
* @attention NEED DOCS
|
||||
*/
|
||||
readonly attribute unsigned long imageStatus;
|
||||
|
||||
readonly attribute nsIURI URI;
|
||||
|
||||
readonly attribute imgIDecoderObserver decoderObserver;
|
||||
};
|
||||
|
||||
%{C++
|
||||
|
||||
/**
|
||||
* imagelib specific nsresult success and error codes
|
||||
*/
|
||||
#define NS_IMAGELIB_SUCCESS_LOAD_FINISHED NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_IMGLIB, 0)
|
||||
|
||||
#define NS_IMAGELIB_ERROR_FAILURE NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_IMGLIB, 5)
|
||||
#define NS_IMAGELIB_ERROR_NO_DECODER NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_IMGLIB, 6)
|
||||
|
||||
%}
|
||||
43
mozilla/modules/libpr0n/public/makefile.win
Normal file
43
mozilla/modules/libpr0n/public/makefile.win
Normal file
@@ -0,0 +1,43 @@
|
||||
#
|
||||
# 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 Netscape are
|
||||
# Copyright (C) 2001 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Stuart Parmenter <pavlov@netscape.com>
|
||||
#
|
||||
|
||||
DEPTH = ..\..\..
|
||||
|
||||
include <$(DEPTH)/config/config.mak>
|
||||
|
||||
MODULE = imglib2
|
||||
XPIDL_MODULE = imglib2
|
||||
|
||||
EXPORTS = ImageLogging.h
|
||||
|
||||
XPIDLSRCS = \
|
||||
.\imgIContainer.idl \
|
||||
.\imgIContainerObserver.idl \
|
||||
.\imgIDecoder.idl \
|
||||
.\imgIDecoderObserver.idl \
|
||||
.\imgILoader.idl \
|
||||
.\imgIRequest.idl \
|
||||
$(NULL)
|
||||
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
|
||||
146
mozilla/modules/libpr0n/src/DummyChannel.cpp
Normal file
146
mozilla/modules/libpr0n/src/DummyChannel.cpp
Normal file
@@ -0,0 +1,146 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* 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 Netscape are
|
||||
* Copyright (C) 2001 Netscape Communications Corporation.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Stuart Parmenter <pavlov@netscape.com>
|
||||
*/
|
||||
|
||||
#include "DummyChannel.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIServiceManager.h"
|
||||
|
||||
|
||||
NS_IMPL_ISUPPORTS1(DummyChannel, nsIChannel)
|
||||
|
||||
DummyChannel::DummyChannel(imgIRequest *aRequest, nsILoadGroup *aLoadGroup) :
|
||||
mRequest(aRequest),
|
||||
mLoadGroup(aLoadGroup),
|
||||
mLoadFlags(nsIChannel::LOAD_NORMAL)
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
/* member initializers and constructor code */
|
||||
}
|
||||
|
||||
DummyChannel::~DummyChannel()
|
||||
{
|
||||
/* destructor code */
|
||||
}
|
||||
|
||||
/* attribute nsIURI originalURI; */
|
||||
NS_IMETHODIMP DummyChannel::GetOriginalURI(nsIURI * *aOriginalURI)
|
||||
{
|
||||
return mRequest->GetURI(aOriginalURI);
|
||||
}
|
||||
NS_IMETHODIMP DummyChannel::SetOriginalURI(nsIURI * aOriginalURI)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
/* attribute nsIURI URI; */
|
||||
NS_IMETHODIMP DummyChannel::GetURI(nsIURI * *aURI)
|
||||
{
|
||||
return mRequest->GetURI(aURI);
|
||||
}
|
||||
NS_IMETHODIMP DummyChannel::SetURI(nsIURI * aURI)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
/* attribute nsISupports owner; */
|
||||
NS_IMETHODIMP DummyChannel::GetOwner(nsISupports * *aOwner)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
NS_IMETHODIMP DummyChannel::SetOwner(nsISupports * aOwner)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* attribute nsILoadGroup loadGroup; */
|
||||
NS_IMETHODIMP DummyChannel::GetLoadGroup(nsILoadGroup * *aLoadGroup)
|
||||
{
|
||||
*aLoadGroup = mLoadGroup;
|
||||
NS_IF_ADDREF(*aLoadGroup);
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHODIMP DummyChannel::SetLoadGroup(nsILoadGroup * aLoadGroup)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
/* attribute nsLoadFlags loadAttributes; */
|
||||
NS_IMETHODIMP DummyChannel::GetLoadAttributes(nsLoadFlags *aLoadAttributes)
|
||||
{
|
||||
*aLoadAttributes = mLoadFlags;
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHODIMP DummyChannel::SetLoadAttributes(nsLoadFlags aLoadAttributes)
|
||||
{
|
||||
mLoadFlags = aLoadAttributes;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* attribute nsIInterfaceRequestor notificationCallbacks; */
|
||||
NS_IMETHODIMP DummyChannel::GetNotificationCallbacks(nsIInterfaceRequestor * *aNotificationCallbacks)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHODIMP DummyChannel::SetNotificationCallbacks(nsIInterfaceRequestor * aNotificationCallbacks)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute nsISupports securityInfo; */
|
||||
NS_IMETHODIMP DummyChannel::GetSecurityInfo(nsISupports * *aSecurityInfo)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* attribute string contentType; */
|
||||
NS_IMETHODIMP DummyChannel::GetContentType(char * *aContentType)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
NS_IMETHODIMP DummyChannel::SetContentType(const char * aContentType)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* attribute long contentLength; */
|
||||
NS_IMETHODIMP DummyChannel::GetContentLength(PRInt32 *aContentLength)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
NS_IMETHODIMP DummyChannel::SetContentLength(PRInt32 aContentLength)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* nsIInputStream open (); */
|
||||
NS_IMETHODIMP DummyChannel::Open(nsIInputStream **_retval)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* void asyncOpen (in nsIStreamListener listener, in nsISupports ctxt); */
|
||||
NS_IMETHODIMP DummyChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *ctxt)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
54
mozilla/modules/libpr0n/src/DummyChannel.h
Normal file
54
mozilla/modules/libpr0n/src/DummyChannel.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* 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 Netscape are
|
||||
* Copyright (C) 2001 Netscape Communications Corporation.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Stuart Parmenter <pavlov@netscape.com>
|
||||
*/
|
||||
|
||||
#ifndef DummyChannel_h__
|
||||
#define DummyChannel_h__
|
||||
|
||||
#include "nsIChannel.h"
|
||||
#include "nsIRequest.h"
|
||||
#include "nsILoadGroup.h"
|
||||
|
||||
#include "imgIRequest.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
class DummyChannel : public nsIChannel
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSICHANNEL
|
||||
NS_FORWARD_NSIREQUEST(mRequest->)
|
||||
|
||||
DummyChannel(imgIRequest *aRequest, nsILoadGroup *aLoadGroup);
|
||||
~DummyChannel();
|
||||
|
||||
private:
|
||||
/* additional members */
|
||||
nsCOMPtr<imgIRequest> mRequest;
|
||||
nsCOMPtr<nsILoadGroup> mLoadGroup;
|
||||
|
||||
nsLoadFlags mLoadFlags;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
166
mozilla/modules/libpr0n/src/ImageCache.cpp
Normal file
166
mozilla/modules/libpr0n/src/ImageCache.cpp
Normal file
@@ -0,0 +1,166 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* 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 Netscape are
|
||||
* Copyright (C) 2001 Netscape Communications Corporation.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Stuart Parmenter <pavlov@netscape.com>
|
||||
*/
|
||||
|
||||
#include "ImageCache.h"
|
||||
|
||||
#ifdef MOZ_NEW_CACHE
|
||||
|
||||
#include "prlog.h"
|
||||
|
||||
#if defined(PR_LOGGING)
|
||||
extern PRLogModuleInfo *gImgLog;
|
||||
#else
|
||||
#define gImgLog
|
||||
#endif
|
||||
|
||||
#include "nsXPIDLString.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIServiceManager.h"
|
||||
|
||||
#include "nsICache.h"
|
||||
#include "nsICacheService.h"
|
||||
#include "nsICacheSession.h"
|
||||
#include "nsICacheEntryDescriptor.h"
|
||||
|
||||
static nsCOMPtr<nsICacheSession> gSession = nsnull;
|
||||
|
||||
ImageCache::ImageCache()
|
||||
{
|
||||
/* member initializers and constructor code */
|
||||
}
|
||||
|
||||
ImageCache::~ImageCache()
|
||||
{
|
||||
/* destructor code */
|
||||
}
|
||||
|
||||
void GetCacheSession(nsICacheSession **_retval)
|
||||
{
|
||||
if (!gSession) {
|
||||
nsCOMPtr<nsICacheService> cacheService(do_GetService("@mozilla.org/network/cache-service;1"));
|
||||
NS_ASSERTION(cacheService, "Unable to get the cache service");
|
||||
|
||||
cacheService->CreateSession("images", nsICache::NOT_STREAM_BASED, PR_FALSE, getter_AddRefs(gSession));
|
||||
NS_ASSERTION(gSession, "Unable to create a cache session");
|
||||
}
|
||||
|
||||
*_retval = gSession;
|
||||
NS_IF_ADDREF(*_retval);
|
||||
}
|
||||
|
||||
|
||||
void ImageCache::Shutdown()
|
||||
{
|
||||
gSession = nsnull;
|
||||
}
|
||||
|
||||
PRBool ImageCache::Put(nsIURI *aKey, imgRequest *request, nsICacheEntryDescriptor **aEntry)
|
||||
{
|
||||
PR_LOG(gImgLog, PR_LOG_DEBUG,
|
||||
("ImageCache::Put\n"));
|
||||
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsICacheSession> ses;
|
||||
GetCacheSession(getter_AddRefs(ses));
|
||||
|
||||
nsXPIDLCString spec;
|
||||
aKey->GetSpec(getter_Copies(spec));
|
||||
|
||||
nsCOMPtr<nsICacheEntryDescriptor> entry;
|
||||
|
||||
rv = ses->OpenCacheEntry(spec, nsICache::ACCESS_WRITE, getter_AddRefs(entry));
|
||||
|
||||
if (!entry || NS_FAILED(rv))
|
||||
return PR_FALSE;
|
||||
|
||||
entry->SetCacheElement(NS_STATIC_CAST(nsISupports *, NS_STATIC_CAST(imgIRequest*, request)));
|
||||
|
||||
entry->MarkValid();
|
||||
|
||||
*aEntry = entry;
|
||||
NS_ADDREF(*aEntry);
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
PRBool ImageCache::Get(nsIURI *aKey, imgRequest **aRequest, nsICacheEntryDescriptor **aEntry)
|
||||
{
|
||||
PR_LOG(gImgLog, PR_LOG_DEBUG,
|
||||
("ImageCache::Get\n"));
|
||||
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsICacheSession> ses;
|
||||
GetCacheSession(getter_AddRefs(ses));
|
||||
|
||||
nsXPIDLCString spec;
|
||||
aKey->GetSpec(getter_Copies(spec));
|
||||
|
||||
nsCOMPtr<nsICacheEntryDescriptor> entry;
|
||||
|
||||
rv = ses->OpenCacheEntry(spec, nsICache::ACCESS_READ, getter_AddRefs(entry));
|
||||
|
||||
if (!entry || NS_FAILED(rv))
|
||||
return PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsISupports> sup;
|
||||
entry->GetCacheElement(getter_AddRefs(sup));
|
||||
|
||||
nsCOMPtr<imgIRequest> req(do_QueryInterface(sup));
|
||||
*aRequest = NS_REINTERPRET_CAST(imgRequest*, req.get());
|
||||
NS_IF_ADDREF(*aRequest);
|
||||
|
||||
*aEntry = entry;
|
||||
NS_ADDREF(*aEntry);
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
|
||||
PRBool ImageCache::Remove(nsIURI *aKey)
|
||||
{
|
||||
PR_LOG(gImgLog, PR_LOG_DEBUG,
|
||||
("ImageCache::Remove\n"));
|
||||
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsICacheSession> ses;
|
||||
GetCacheSession(getter_AddRefs(ses));
|
||||
|
||||
nsXPIDLCString spec;
|
||||
aKey->GetSpec(getter_Copies(spec));
|
||||
|
||||
nsCOMPtr<nsICacheEntryDescriptor> entry;
|
||||
|
||||
rv = ses->OpenCacheEntry(spec, nsICache::ACCESS_READ, getter_AddRefs(entry));
|
||||
|
||||
if (!entry || NS_FAILED(rv))
|
||||
return PR_FALSE;
|
||||
|
||||
entry->Doom();
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
#endif /* MOZ_NEW_CACHE */
|
||||
72
mozilla/modules/libpr0n/src/ImageCache.h
Normal file
72
mozilla/modules/libpr0n/src/ImageCache.h
Normal file
@@ -0,0 +1,72 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* 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 Netscape are
|
||||
* Copyright (C) 2001 Netscape Communications Corporation.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Stuart Parmenter <pavlov@netscape.com>
|
||||
*/
|
||||
|
||||
#ifndef ImageCache_h__
|
||||
#define ImageCache_h__
|
||||
|
||||
#include "nsIURI.h"
|
||||
#include "imgRequest.h"
|
||||
#include "prtypes.h"
|
||||
|
||||
#ifdef MOZ_NEW_CACHE
|
||||
#include "nsICacheEntryDescriptor.h"
|
||||
#else
|
||||
class nsICacheEntryDescriptor;
|
||||
#endif
|
||||
|
||||
|
||||
class ImageCache
|
||||
{
|
||||
public:
|
||||
#ifdef MOZ_NEW_CACHE
|
||||
ImageCache();
|
||||
~ImageCache();
|
||||
|
||||
static void Shutdown(); // for use by the factory
|
||||
|
||||
/* additional members */
|
||||
static PRBool Put(nsIURI *aKey, imgRequest *request, nsICacheEntryDescriptor **aEntry);
|
||||
static PRBool Get(nsIURI *aKey, imgRequest **aRequest, nsICacheEntryDescriptor **aEntry);
|
||||
static PRBool Remove(nsIURI *aKey);
|
||||
|
||||
#else
|
||||
|
||||
ImageCache() { }
|
||||
~ImageCache() { }
|
||||
|
||||
static void Shutdown() { }
|
||||
|
||||
/* additional members */
|
||||
static PRBool Put(nsIURI *aKey, imgRequest *request, nsICacheEntryDescriptor **aEntry) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
static PRBool Get(nsIURI *aKey, imgRequest **aRequest, nsICacheEntryDescriptor **aEntry) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
static PRBool Remove(nsIURI *aKey) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
#endif /* MOZ_NEW_CACHE */
|
||||
};
|
||||
|
||||
#endif
|
||||
67
mozilla/modules/libpr0n/src/ImageFactory.cpp
Normal file
67
mozilla/modules/libpr0n/src/ImageFactory.cpp
Normal file
@@ -0,0 +1,67 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* 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 Netscape are
|
||||
* Copyright (C) 2001 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Stuart Parmenter <pavlov@netscape.com>
|
||||
*/
|
||||
|
||||
#include "nsIGenericFactory.h"
|
||||
#include "nsIModule.h"
|
||||
|
||||
#include "imgContainer.h"
|
||||
#include "imgLoader.h"
|
||||
#include "imgRequest.h"
|
||||
#include "imgRequestProxy.h"
|
||||
|
||||
#include "ImageCache.h"
|
||||
|
||||
// objects that just require generic constructors
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(imgContainer)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(imgLoader)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(imgRequest)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(imgRequestProxy)
|
||||
|
||||
static nsModuleComponentInfo components[] =
|
||||
{
|
||||
{ "image container",
|
||||
NS_IMGCONTAINER_CID,
|
||||
"@mozilla.org/image/container;1",
|
||||
imgContainerConstructor, },
|
||||
{ "image loader",
|
||||
NS_IMGLOADER_CID,
|
||||
"@mozilla.org/image/loader;1",
|
||||
imgLoaderConstructor, },
|
||||
{ "image request",
|
||||
NS_IMGREQUEST_CID,
|
||||
"@mozilla.org/image/request/real;1",
|
||||
imgRequestConstructor, },
|
||||
{ "image request proxy",
|
||||
NS_IMGREQUESTPROXY_CID,
|
||||
"@mozilla.org/image/request/proxy;1",
|
||||
imgRequestProxyConstructor, },
|
||||
};
|
||||
|
||||
PR_STATIC_CALLBACK(void)
|
||||
ImageModuleDestructor(nsIModule *self)
|
||||
{
|
||||
ImageCache::Shutdown();
|
||||
}
|
||||
|
||||
NS_IMPL_NSGETMODULE_WITH_DTOR("nsImageLib2Module", components, ImageModuleDestructor)
|
||||
49
mozilla/modules/libpr0n/src/Makefile.in
Normal file
49
mozilla/modules/libpr0n/src/Makefile.in
Normal file
@@ -0,0 +1,49 @@
|
||||
#
|
||||
# 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 Netscape are
|
||||
# Copyright (C) 2001 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
|
||||
DEPTH = ../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = imglib2
|
||||
LIBRARY_NAME = imglib2
|
||||
IS_COMPONENT = 1
|
||||
|
||||
REQUIRES = xpcom string necko nkcache layout timer gfx2
|
||||
|
||||
CPPSRCS = \
|
||||
DummyChannel.cpp \
|
||||
ImageCache.cpp \
|
||||
ImageFactory.cpp \
|
||||
imgContainer.cpp \
|
||||
imgLoader.cpp \
|
||||
imgRequest.cpp \
|
||||
imgRequestProxy.cpp
|
||||
|
||||
EXTRA_DSO_LDOPTS = \
|
||||
$(MOZ_COMPONENT_LIBS) \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
555
mozilla/modules/libpr0n/src/imgContainer.cpp
Normal file
555
mozilla/modules/libpr0n/src/imgContainer.cpp
Normal file
@@ -0,0 +1,555 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* 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 Netscape are
|
||||
* Copyright (C) 2001 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Stuart Parmenter <pavlov@netscape.com>
|
||||
* Chris Saari <saari@netscape.com>
|
||||
*/
|
||||
|
||||
#include "imgContainer.h"
|
||||
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
#include "nsIImage.h"
|
||||
|
||||
NS_IMPL_ISUPPORTS3(imgContainer, imgIContainer, nsITimerCallback,imgIDecoderObserver)
|
||||
|
||||
//******************************************************************************
|
||||
imgContainer::imgContainer()
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
/* member initializers and constructor code */
|
||||
mCurrentDecodingFrameIndex = 0;
|
||||
mCurrentAnimationFrameIndex = 0;
|
||||
mCurrentFrameIsFinishedDecoding = PR_FALSE;
|
||||
mDoneDecoding = PR_FALSE;
|
||||
mAnimating = PR_FALSE;
|
||||
mObserver = nsnull;
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
imgContainer::~imgContainer()
|
||||
{
|
||||
if (mTimer)
|
||||
mTimer->Cancel();
|
||||
|
||||
/* destructor code */
|
||||
mFrames.Clear();
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
/* void init (in nscoord aWidth, in nscoord aHeight, in imgIContainerObserver aObserver); */
|
||||
NS_IMETHODIMP imgContainer::Init(nscoord aWidth, nscoord aHeight, imgIContainerObserver *aObserver)
|
||||
{
|
||||
if (aWidth <= 0 || aHeight <= 0) {
|
||||
NS_WARNING("error - negative image size\n");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mSize.SizeTo(aWidth, aHeight);
|
||||
|
||||
mObserver = getter_AddRefs(NS_GetWeakReference(aObserver));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
/* readonly attribute gfx_format preferredAlphaChannelFormat; */
|
||||
NS_IMETHODIMP imgContainer::GetPreferredAlphaChannelFormat(gfx_format *aFormat)
|
||||
{
|
||||
/* default.. platform's should probably overwrite this */
|
||||
*aFormat = gfxIFormats::RGB_A8;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
/* readonly attribute nscoord width; */
|
||||
NS_IMETHODIMP imgContainer::GetWidth(nscoord *aWidth)
|
||||
{
|
||||
*aWidth = mSize.width;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
/* readonly attribute nscoord height; */
|
||||
NS_IMETHODIMP imgContainer::GetHeight(nscoord *aHeight)
|
||||
{
|
||||
*aHeight = mSize.height;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
/* readonly attribute gfxIImageFrame currentFrame; */
|
||||
NS_IMETHODIMP imgContainer::GetCurrentFrame(gfxIImageFrame * *aCurrentFrame)
|
||||
{
|
||||
if(mCompositingFrame)
|
||||
return mCompositingFrame->QueryInterface(NS_GET_IID(gfxIImageFrame), (void**)aCurrentFrame); // addrefs again
|
||||
else
|
||||
return this->GetFrameAt(mCurrentAnimationFrameIndex, aCurrentFrame);
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
/* readonly attribute unsigned long numFrames; */
|
||||
NS_IMETHODIMP imgContainer::GetNumFrames(PRUint32 *aNumFrames)
|
||||
{
|
||||
return mFrames.Count(aNumFrames);
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
/* gfxIImageFrame getFrameAt (in unsigned long index); */
|
||||
NS_IMETHODIMP imgContainer::GetFrameAt(PRUint32 index, gfxIImageFrame **_retval)
|
||||
{
|
||||
nsISupports *sup = mFrames.ElementAt(index); // addrefs
|
||||
if (!sup)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsresult rv;
|
||||
rv = sup->QueryInterface(NS_GET_IID(gfxIImageFrame), (void**)_retval); // addrefs again
|
||||
|
||||
NS_RELEASE(sup);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
/* void appendFrame (in gfxIImageFrame item); */
|
||||
NS_IMETHODIMP imgContainer::AppendFrame(gfxIImageFrame *item)
|
||||
{
|
||||
// If we don't have a composite frame already allocated, make sure that our container
|
||||
// size is the same the frame size. Otherwise, we'll either need the composite frame
|
||||
// for animation compositing (GIF) or for filling in with a background color.
|
||||
// XXX IMPORTANT: this means that the frame should be initialized BEFORE appending to container
|
||||
PRUint32 numFrames;
|
||||
this->GetNumFrames(&numFrames);
|
||||
|
||||
if(!mCompositingFrame) {
|
||||
nsRect frameRect;
|
||||
item->GetRect(frameRect);
|
||||
// We used to create a compositing frame if any frame was smaller than the logical
|
||||
// image size. You could create a single frame that was 10x10 in the middle of
|
||||
// an 20x20 logical screen and have the extra screen space filled by the image
|
||||
// background color. However, it turns out that neither NS4.x nor IE correctly
|
||||
// support this, and as a result there are many GIFs out there that look "wrong"
|
||||
// when this is correctly supported. So for now, we only create a compositing frame
|
||||
// if we have more than one frame in the image.
|
||||
if(/*(frameRect.x != 0) ||
|
||||
(frameRect.y != 0) ||
|
||||
(frameRect.width != mSize.width) ||
|
||||
(frameRect.height != mSize.height) ||*/
|
||||
(numFrames >= 1)) // Not sure if I want to create a composite frame for every anim. Could be smarter.
|
||||
{
|
||||
mCompositingFrame = do_CreateInstance("@mozilla.org/gfx/image/frame;2");
|
||||
mCompositingFrame->Init(0, 0, mSize.width, mSize.height, gfxIFormats::RGB);
|
||||
nsCOMPtr<nsIImage> img(do_GetInterface(mCompositingFrame));
|
||||
img->SetDecodedRect(0, 0, mSize.width, mSize.height);
|
||||
|
||||
nsCOMPtr<gfxIImageFrame> firstFrame;
|
||||
this->GetFrameAt(0, getter_AddRefs(firstFrame));
|
||||
firstFrame->DrawTo(mCompositingFrame, 0, 0, mSize.width, mSize.height);
|
||||
}
|
||||
}
|
||||
// If this is our second frame, init a timer so we don't display
|
||||
// the next frame until the delay timer has expired for the current
|
||||
// frame.
|
||||
|
||||
if (!mTimer && (numFrames >= 1)) {
|
||||
PRInt32 timeout;
|
||||
nsCOMPtr<gfxIImageFrame> currentFrame;
|
||||
this->GetFrameAt(mCurrentDecodingFrameIndex, getter_AddRefs(currentFrame));
|
||||
currentFrame->GetTimeout(&timeout);
|
||||
if (timeout != -1 &&
|
||||
timeout >= 0) { // -1 means display this frame forever
|
||||
|
||||
if(mAnimating) {
|
||||
// Since we have more than one frame we need a timer
|
||||
mTimer = do_CreateInstance("@mozilla.org/timer;1");
|
||||
mTimer->Init(
|
||||
NS_STATIC_CAST(nsITimerCallback*, this),
|
||||
timeout, NS_PRIORITY_NORMAL, NS_TYPE_REPEATING_SLACK);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (numFrames > 0) mCurrentDecodingFrameIndex++;
|
||||
|
||||
mCurrentFrameIsFinishedDecoding = PR_FALSE;
|
||||
|
||||
return mFrames.AppendElement(NS_STATIC_CAST(nsISupports*, item));
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
/* void removeFrame (in gfxIImageFrame item); */
|
||||
NS_IMETHODIMP imgContainer::RemoveFrame(gfxIImageFrame *item)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
/* void endFrameDecode (in gfxIImageFrame item, in unsigned long timeout); */
|
||||
NS_IMETHODIMP imgContainer::EndFrameDecode(PRUint32 aFrameNum, PRUint32 aTimeout)
|
||||
{
|
||||
// It is now okay to start the timer for the next frame in the animation
|
||||
mCurrentFrameIsFinishedDecoding = PR_TRUE;
|
||||
|
||||
nsCOMPtr<gfxIImageFrame> currentFrame;
|
||||
this->GetFrameAt(aFrameNum-1, getter_AddRefs(currentFrame));
|
||||
currentFrame->SetTimeout(aTimeout);
|
||||
|
||||
if (!mTimer && mAnimating){
|
||||
PRUint32 numFrames;
|
||||
this->GetNumFrames(&numFrames);
|
||||
if (numFrames > 1) {
|
||||
if (aTimeout != -1 &&
|
||||
aTimeout >= 0) { // -1 means display this frame forever
|
||||
|
||||
mAnimating = PR_TRUE;
|
||||
mTimer = do_CreateInstance("@mozilla.org/timer;1");
|
||||
|
||||
mTimer->Init(NS_STATIC_CAST(nsITimerCallback*, this),
|
||||
aTimeout, NS_PRIORITY_NORMAL, NS_TYPE_REPEATING_SLACK);
|
||||
}
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
/* void decodingComplete (); */
|
||||
NS_IMETHODIMP imgContainer::DecodingComplete(void)
|
||||
{
|
||||
mDoneDecoding = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
/* nsIEnumerator enumerate (); */
|
||||
NS_IMETHODIMP imgContainer::Enumerate(nsIEnumerator **_retval)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* void clear (); */
|
||||
NS_IMETHODIMP imgContainer::Clear()
|
||||
{
|
||||
return mFrames.Clear();
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
/* void startAnimation () */
|
||||
NS_IMETHODIMP imgContainer::StartAnimation()
|
||||
{
|
||||
mAnimating = PR_TRUE;
|
||||
|
||||
if (mTimer)
|
||||
return NS_OK;
|
||||
|
||||
PRUint32 numFrames;
|
||||
this->GetNumFrames(&numFrames);
|
||||
|
||||
if (numFrames > 1) {
|
||||
PRInt32 timeout;
|
||||
nsCOMPtr<gfxIImageFrame> currentFrame;
|
||||
this->GetCurrentFrame(getter_AddRefs(currentFrame));
|
||||
if (currentFrame) {
|
||||
currentFrame->GetTimeout(&timeout);
|
||||
if (timeout != -1 &&
|
||||
timeout >= 0) { // -1 means display this frame forever
|
||||
|
||||
mAnimating = PR_TRUE;
|
||||
if(!mTimer) mTimer = do_CreateInstance("@mozilla.org/timer;1");
|
||||
|
||||
mTimer->Init(NS_STATIC_CAST(nsITimerCallback*, this),
|
||||
timeout, NS_PRIORITY_NORMAL, NS_TYPE_REPEATING_SLACK);
|
||||
}
|
||||
} else {
|
||||
// XXX hack.. the timer notify code will do the right thing, so just get that started
|
||||
mAnimating = PR_TRUE;
|
||||
if(!mTimer) mTimer = do_CreateInstance("@mozilla.org/timer;1");
|
||||
|
||||
mTimer->Init(NS_STATIC_CAST(nsITimerCallback*, this),
|
||||
100, NS_PRIORITY_NORMAL, NS_TYPE_REPEATING_SLACK);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
/* void stopAnimation (); */
|
||||
NS_IMETHODIMP imgContainer::StopAnimation()
|
||||
{
|
||||
mAnimating = PR_FALSE;
|
||||
|
||||
if (!mTimer)
|
||||
return NS_OK;
|
||||
|
||||
mTimer->Cancel();
|
||||
|
||||
mTimer = nsnull;
|
||||
|
||||
// don't bother trying to change the frame (to 0, etc.) here.
|
||||
// No one is listening.
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
/* attribute long loopCount; */
|
||||
NS_IMETHODIMP imgContainer::GetLoopCount(PRInt32 *aLoopCount)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
NS_IMETHODIMP imgContainer::SetLoopCount(PRInt32 aLoopCount)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
|
||||
NS_IMETHODIMP_(void) imgContainer::Notify(nsITimer *timer)
|
||||
{
|
||||
NS_ASSERTION(mTimer == timer, "uh");
|
||||
|
||||
if(!mAnimating || !mTimer)
|
||||
return;
|
||||
|
||||
nsCOMPtr<imgIContainerObserver> observer(do_QueryReferent(mObserver));
|
||||
if (!observer) {
|
||||
// the imgRequest that owns us is dead, we should die now too.
|
||||
this->StopAnimation();
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<gfxIImageFrame> nextFrame;
|
||||
PRInt32 timeout = 100;
|
||||
PRUint32 numFrames;
|
||||
GetNumFrames(&numFrames);
|
||||
if(!numFrames)
|
||||
return;
|
||||
|
||||
// If we're done decoding the next frame, go ahead and display it now and reinit
|
||||
// the timer with the next frame's delay time.
|
||||
PRUint32 previousAnimationFrameIndex = mCurrentAnimationFrameIndex;
|
||||
if (mCurrentFrameIsFinishedDecoding && !mDoneDecoding) {
|
||||
// If we have the next frame in the sequence set the timer callback from it
|
||||
GetFrameAt(mCurrentAnimationFrameIndex+1, getter_AddRefs(nextFrame));
|
||||
if (nextFrame) {
|
||||
// Go to next frame in sequence
|
||||
nextFrame->GetTimeout(&timeout);
|
||||
mCurrentAnimationFrameIndex++;
|
||||
} else {
|
||||
// twiddle our thumbs
|
||||
GetFrameAt(mCurrentAnimationFrameIndex, getter_AddRefs(nextFrame));
|
||||
if(!nextFrame) return;
|
||||
|
||||
nextFrame->GetTimeout(&timeout);
|
||||
}
|
||||
} else if (mDoneDecoding){
|
||||
if ((numFrames-1) == mCurrentAnimationFrameIndex) {
|
||||
// Go back to the beginning of the animation
|
||||
GetFrameAt(0, getter_AddRefs(nextFrame));
|
||||
if(!nextFrame) return;
|
||||
|
||||
mCurrentAnimationFrameIndex = 0;
|
||||
nextFrame->GetTimeout(&timeout);
|
||||
} else {
|
||||
mCurrentAnimationFrameIndex++;
|
||||
GetFrameAt(mCurrentAnimationFrameIndex, getter_AddRefs(nextFrame));
|
||||
if(!nextFrame) return;
|
||||
|
||||
nextFrame->GetTimeout(&timeout);
|
||||
}
|
||||
} else {
|
||||
GetFrameAt(mCurrentAnimationFrameIndex, getter_AddRefs(nextFrame));
|
||||
if(!nextFrame) return;
|
||||
}
|
||||
|
||||
if(timeout >= 0)
|
||||
mTimer->SetDelay(timeout);
|
||||
else
|
||||
this->StopAnimation();
|
||||
|
||||
|
||||
nsRect dirtyRect;
|
||||
|
||||
// update the composited frame
|
||||
if(mCompositingFrame && (previousAnimationFrameIndex != mCurrentAnimationFrameIndex)) {
|
||||
nsCOMPtr<gfxIImageFrame> frameToUse;
|
||||
DoComposite(getter_AddRefs(frameToUse), &dirtyRect, previousAnimationFrameIndex, mCurrentAnimationFrameIndex);
|
||||
|
||||
// do notification to FE to draw this frame, but hand it the compositing frame
|
||||
observer->FrameChanged(this, nsnull, mCompositingFrame, &dirtyRect);
|
||||
}
|
||||
else {
|
||||
nextFrame->GetRect(dirtyRect);
|
||||
|
||||
// do notification to FE to draw this frame
|
||||
observer->FrameChanged(this, nsnull, nextFrame, &dirtyRect);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
//******************************************************************************
|
||||
// DoComposite gets called when the timer for animation get fired and we have to
|
||||
// update the composited frame of the animation.
|
||||
void imgContainer::DoComposite(gfxIImageFrame** aFrameToUse, nsRect* aDirtyRect, PRInt32 aPrevFrame, PRInt32 aNextFrame)
|
||||
{
|
||||
NS_ASSERTION(aDirtyRect, "DoComposite aDirtyRect is null");
|
||||
NS_ASSERTION(mCompositingFrame, "DoComposite mCompositingFrame is null");
|
||||
|
||||
*aFrameToUse = nsnull;
|
||||
|
||||
PRUint32 numFrames;
|
||||
this->GetNumFrames(&numFrames);
|
||||
PRInt32 nextFrameIndex = aNextFrame;
|
||||
PRInt32 prevFrameIndex = aPrevFrame;
|
||||
|
||||
if(nextFrameIndex >= numFrames) nextFrameIndex = numFrames-1;
|
||||
if(prevFrameIndex >= numFrames) prevFrameIndex = numFrames-1;
|
||||
|
||||
nsCOMPtr<gfxIImageFrame> prevFrame;
|
||||
this->GetFrameAt(prevFrameIndex, getter_AddRefs(prevFrame));
|
||||
PRInt32 prevFrameDisposalMethod;
|
||||
prevFrame->GetFrameDisposalMethod(&prevFrameDisposalMethod);
|
||||
|
||||
nsCOMPtr<gfxIImageFrame> nextFrame;
|
||||
this->GetFrameAt(nextFrameIndex, getter_AddRefs(nextFrame));
|
||||
|
||||
PRInt32 x;
|
||||
PRInt32 y;
|
||||
PRInt32 width;
|
||||
PRInt32 height;
|
||||
nextFrame->GetX(&x);
|
||||
nextFrame->GetY(&y);
|
||||
nextFrame->GetWidth(&width);
|
||||
nextFrame->GetHeight(&height);
|
||||
|
||||
switch (prevFrameDisposalMethod) {
|
||||
default:
|
||||
case 0: // DISPOSE_NOT_SPECIFIED
|
||||
case 1: // DISPOSE_KEEP Leave previous frame in the framebuffer
|
||||
mCompositingFrame->QueryInterface(NS_GET_IID(gfxIImageFrame), (void**)aFrameToUse); // addrefs again
|
||||
//XXX blit into the composite frame too!!!
|
||||
nextFrame->DrawTo(mCompositingFrame, x, y, width, height);
|
||||
|
||||
// we're drawing only the updated frame
|
||||
(*aDirtyRect).x = x;
|
||||
(*aDirtyRect).y = y;
|
||||
(*aDirtyRect).width = width;
|
||||
(*aDirtyRect).height = height;
|
||||
break;
|
||||
|
||||
case 2: // DISPOSE_OVERWRITE_BGCOLOR Overwrite with background color
|
||||
//XXX overwrite mCompositeFrame with background color
|
||||
gfx_color backgroundColor;
|
||||
nextFrame->GetBackgroundColor(&backgroundColor);
|
||||
//XXX Do background color overwrite of mCompositeFrame here
|
||||
|
||||
// blit next frame into this clean slate
|
||||
nextFrame->DrawTo(mCompositingFrame, x, y, width, height);
|
||||
|
||||
// In this case we need to blit the whole composite frame
|
||||
(*aDirtyRect).x = 0;
|
||||
(*aDirtyRect).y = 0;
|
||||
(*aDirtyRect).width = mSize.width;
|
||||
(*aDirtyRect).height = mSize.height;
|
||||
mCompositingFrame->QueryInterface(NS_GET_IID(gfxIImageFrame), (void**)aFrameToUse); // addrefs again
|
||||
break;
|
||||
|
||||
case 4: // DISPOSE_OVERWRITE_PREVIOUS Save-under
|
||||
//XXX Reblit previous composite into frame buffer
|
||||
//
|
||||
(*aDirtyRect).x = 0;
|
||||
(*aDirtyRect).y = 0;
|
||||
(*aDirtyRect).width = mSize.width;
|
||||
(*aDirtyRect).height = mSize.height;
|
||||
break;
|
||||
}
|
||||
|
||||
// Get the next frame's disposal method, if it is it DISPOSE_OVER, save off
|
||||
// this mCompositeFrame for reblitting when this timer gets fired again and
|
||||
// we
|
||||
PRInt32 nextFrameDisposalMethod;
|
||||
nextFrame->GetFrameDisposalMethod(&nextFrameDisposalMethod);
|
||||
//XXX if(nextFrameDisposalMethod == 4)
|
||||
// blit mPreviousCompositeFrame with this frame
|
||||
}
|
||||
//******************************************************************************
|
||||
/* void onStartDecode (in imgIRequest aRequest, in nsISupports cx); */
|
||||
NS_IMETHODIMP imgContainer::OnStartDecode(imgIRequest *aRequest, nsISupports *cx)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
/* void onStartContainer (in imgIRequest aRequest, in nsISupports cx, in imgIContainer aContainer); */
|
||||
NS_IMETHODIMP imgContainer::OnStartContainer(imgIRequest *aRequest, nsISupports *cx, imgIContainer *aContainer)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
/* void onStartFrame (in imgIRequest aRequest, in nsISupports cx, in gfxIImageFrame aFrame); */
|
||||
NS_IMETHODIMP imgContainer::OnStartFrame(imgIRequest *aRequest, nsISupports *cx, gfxIImageFrame *aFrame)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
/* [noscript] void onDataAvailable (in imgIRequest aRequest, in nsISupports cx, in gfxIImageFrame aFrame, [const] in nsRect aRect); */
|
||||
NS_IMETHODIMP imgContainer::OnDataAvailable(imgIRequest *aRequest, nsISupports *cx, gfxIImageFrame *aFrame, const nsRect * aRect)
|
||||
{
|
||||
if(mCompositingFrame && !mCurrentDecodingFrameIndex) {
|
||||
// Update the composite frame
|
||||
PRInt32 x;
|
||||
aFrame->GetX(&x);
|
||||
aFrame->DrawTo(mCompositingFrame, x, aRect->y, aRect->width, aRect->height);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
/* void onStopFrame (in imgIRequest aRequest, in nsISupports cx, in gfxIImageFrame aFrame); */
|
||||
NS_IMETHODIMP imgContainer::OnStopFrame(imgIRequest *aRequest, nsISupports *cx, gfxIImageFrame *aFrame)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
/* void onStopContainer (in imgIRequest aRequest, in nsISupports cx, in imgIContainer aContainer); */
|
||||
NS_IMETHODIMP imgContainer::OnStopContainer(imgIRequest *aRequest, nsISupports *cx, imgIContainer *aContainer)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
/* void onStopDecode (in imgIRequest aRequest, in nsISupports cx, in nsresult status, in wstring statusArg); */
|
||||
NS_IMETHODIMP imgContainer::OnStopDecode(imgIRequest *aRequest, nsISupports *cx, nsresult status, const PRUnichar *statusArg)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
/* [noscript] void frameChanged (in imgIContainer aContainer, in nsISupports aCX, in gfxIImageFrame aFrame, in nsRect aDirtyRect); */
|
||||
NS_IMETHODIMP imgContainer::FrameChanged(imgIContainer *aContainer, nsISupports *aCX, gfxIImageFrame *aFrame, nsRect * aDirtyRect)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
95
mozilla/modules/libpr0n/src/imgContainer.h
Normal file
95
mozilla/modules/libpr0n/src/imgContainer.h
Normal file
@@ -0,0 +1,95 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* 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 Netscape are
|
||||
* Copyright (C) 2001 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Stuart Parmenter <pavlov@netscape.com>
|
||||
* Chris Saari <saari@netscape.com>
|
||||
*/
|
||||
|
||||
#ifndef __imgContainer_h__
|
||||
#define __imgContainer_h__
|
||||
|
||||
#include "imgIContainer.h"
|
||||
|
||||
#include "imgIContainerObserver.h"
|
||||
|
||||
#include "nsSize.h"
|
||||
|
||||
#include "nsSupportsArray.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsITimer.h"
|
||||
#include "nsITimerCallback.h"
|
||||
#include "imgIDecoderObserver.h"
|
||||
|
||||
#include "gfxIImageFrame.h"
|
||||
|
||||
#include "nsWeakReference.h"
|
||||
|
||||
#define NS_IMGCONTAINER_CID \
|
||||
{ /* 5e04ec5e-1dd2-11b2-8fda-c4db5fb666e0 */ \
|
||||
0x5e04ec5e, \
|
||||
0x1dd2, \
|
||||
0x11b2, \
|
||||
{0x8f, 0xda, 0xc4, 0xdb, 0x5f, 0xb6, 0x66, 0xe0} \
|
||||
}
|
||||
|
||||
class imgContainer : public imgIContainer,
|
||||
public nsITimerCallback,
|
||||
public imgIDecoderObserver
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_IMGICONTAINER
|
||||
NS_DECL_IMGIDECODEROBSERVER
|
||||
NS_DECL_IMGICONTAINEROBSERVER
|
||||
|
||||
NS_IMETHOD_(void) Notify(nsITimer *timer);
|
||||
|
||||
imgContainer();
|
||||
virtual ~imgContainer();
|
||||
|
||||
private:
|
||||
/* additional members */
|
||||
nsSupportsArray mFrames;
|
||||
nsSize mSize;
|
||||
PRUint32 mCurrentDecodingFrameIndex; // 0 to numFrames-1
|
||||
PRUint32 mCurrentAnimationFrameIndex; // 0 to numFrames-1
|
||||
PRBool mCurrentFrameIsFinishedDecoding;
|
||||
PRBool mDoneDecoding;
|
||||
PRBool mAnimating;
|
||||
|
||||
nsWeakPtr mObserver;
|
||||
|
||||
// GIF specific bits
|
||||
nsCOMPtr<nsITimer> mTimer;
|
||||
|
||||
// GIF animations will use the mCompositingFrame to composite images
|
||||
// and just hand this back to the caller when it is time to draw the frame.
|
||||
nsCOMPtr<gfxIImageFrame> mCompositingFrame;
|
||||
|
||||
// Private function for doing the frame compositing of animations and in cases
|
||||
// where there is a backgound color and single frame placed withing a larger
|
||||
// logical screen size. Smart GIF compressors may do this to save space.
|
||||
void DoComposite(gfxIImageFrame** aFrameToUse, nsRect* aDirtyRect,
|
||||
PRInt32 aPrevFrame, PRInt32 aNextFrame);
|
||||
};
|
||||
|
||||
#endif /* __imgContainer_h__ */
|
||||
|
||||
242
mozilla/modules/libpr0n/src/imgLoader.cpp
Normal file
242
mozilla/modules/libpr0n/src/imgLoader.cpp
Normal file
@@ -0,0 +1,242 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* 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 Netscape are
|
||||
* Copyright (C) 2001 Netscape Communications Corporation.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Stuart Parmenter <pavlov@netscape.com>
|
||||
*/
|
||||
|
||||
#include "imgLoader.h"
|
||||
|
||||
#include "imgIRequest.h"
|
||||
|
||||
#include "nsIServiceManager.h"
|
||||
|
||||
#include "nsIChannel.h"
|
||||
#include "nsIIOService.h"
|
||||
#include "nsILoadGroup.h"
|
||||
#include "nsIStreamListener.h"
|
||||
#include "nsIURI.h"
|
||||
|
||||
#include "imgRequest.h"
|
||||
#include "imgRequestProxy.h"
|
||||
|
||||
#include "ImageCache.h"
|
||||
|
||||
#include "nsXPIDLString.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
#include "ImageLogging.h"
|
||||
|
||||
NS_IMPL_ISUPPORTS1(imgLoader, imgILoader)
|
||||
|
||||
imgLoader::imgLoader()
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
/* member initializers and constructor code */
|
||||
}
|
||||
|
||||
imgLoader::~imgLoader()
|
||||
{
|
||||
/* destructor code */
|
||||
}
|
||||
|
||||
/* imgIRequest loadImage (in nsIURI uri, in nsILoadGroup aLoadGroup, in imgIDecoderObserver aObserver, in nsISupports cx); */
|
||||
NS_IMETHODIMP imgLoader::LoadImage(nsIURI *aURI, nsILoadGroup *aLoadGroup, imgIDecoderObserver *aObserver, nsISupports *cx, imgIRequest **_retval)
|
||||
{
|
||||
NS_ASSERTION(aURI, "imgLoader::LoadImage -- NULL URI pointer");
|
||||
|
||||
if (!aURI)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
#if defined(PR_LOGGING)
|
||||
nsXPIDLCString spec;
|
||||
aURI->GetSpec(getter_Copies(spec));
|
||||
LOG_SCOPE_WITH_PARAM(gImgLog, "imgLoader::LoadImage", "aURI", spec.get());
|
||||
#endif
|
||||
|
||||
imgRequest *request = nsnull;
|
||||
|
||||
#ifdef MOZ_NEW_CACHE
|
||||
nsCOMPtr<nsICacheEntryDescriptor> entry;
|
||||
ImageCache::Get(aURI, &request, getter_AddRefs(entry)); // addrefs request
|
||||
|
||||
if (request && entry && aLoadGroup) {
|
||||
/* this isn't exactly what I want here. This code will re-doom every cache hit in a document while
|
||||
it is force reloading. So for multiple copies of an image on a page, when you force reload, this
|
||||
will cause you to get seperate loads for each copy of the image... this sucks.
|
||||
*/
|
||||
PRUint32 flags = 0;
|
||||
PRBool doomRequest = PR_FALSE;
|
||||
aLoadGroup->GetDefaultLoadAttributes(&flags);
|
||||
if (flags & nsIChannel::FORCE_RELOAD)
|
||||
doomRequest = PR_TRUE;
|
||||
else {
|
||||
nsCOMPtr<nsIRequest> r;
|
||||
aLoadGroup->GetDefaultLoadRequest(getter_AddRefs(r));
|
||||
if (r) {
|
||||
nsCOMPtr<nsIChannel> c(do_QueryInterface(r));
|
||||
if (c) {
|
||||
c->GetLoadAttributes(&flags);
|
||||
if (flags & nsIChannel::FORCE_RELOAD)
|
||||
doomRequest = PR_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (doomRequest) {
|
||||
entry->Doom(); // doom this thing.
|
||||
entry = nsnull;
|
||||
NS_RELEASE(request);
|
||||
request = nsnull;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!request) {
|
||||
/* no request from the cache. do a new load */
|
||||
LOG_SCOPE(gImgLog, "imgLoader::LoadImage |cache miss|");
|
||||
|
||||
nsCOMPtr<nsIIOService> ioserv(do_GetService("@mozilla.org/network/io-service;1"));
|
||||
if (!ioserv) return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIChannel> newChannel;
|
||||
ioserv->NewChannelFromURI(aURI, getter_AddRefs(newChannel));
|
||||
if (!newChannel) return NS_ERROR_FAILURE;
|
||||
|
||||
if (aLoadGroup) {
|
||||
PRUint32 flags;
|
||||
aLoadGroup->GetDefaultLoadAttributes(&flags);
|
||||
newChannel->SetLoadAttributes(flags);
|
||||
}
|
||||
|
||||
NS_NEWXPCOM(request, imgRequest);
|
||||
if (!request) return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
NS_ADDREF(request);
|
||||
|
||||
PR_LOG(gImgLog, PR_LOG_DEBUG,
|
||||
("[this=%p] imgLoader::LoadImage -- Created new imgRequest [request=%p]\n", this, request));
|
||||
|
||||
#ifdef MOZ_NEW_CACHE
|
||||
ImageCache::Put(aURI, request, getter_AddRefs(entry));
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_NEW_CACHE
|
||||
request->Init(newChannel, entry);
|
||||
#else
|
||||
request->Init(newChannel, nsnull);
|
||||
#endif
|
||||
|
||||
PR_LOG(gImgLog, PR_LOG_DEBUG,
|
||||
("[this=%p] imgLoader::LoadImage -- Calling channel->AsyncOpen()\n", this));
|
||||
|
||||
// XXX are we calling this too early?
|
||||
newChannel->AsyncOpen(NS_STATIC_CAST(nsIStreamListener *, request), nsnull);
|
||||
|
||||
} else {
|
||||
/* request found in cache. use it */
|
||||
PR_LOG(gImgLog, PR_LOG_DEBUG,
|
||||
("[this=%p] imgLoader::LoadImage |cache hit| [request=%p]\n",
|
||||
this, request));
|
||||
}
|
||||
|
||||
PR_LOG(gImgLog, PR_LOG_DEBUG,
|
||||
("[this=%p] imgLoader::LoadImage -- creating proxy request.\n", this));
|
||||
|
||||
imgRequestProxy *proxyRequest;
|
||||
NS_NEWXPCOM(proxyRequest, imgRequestProxy);
|
||||
if (!proxyRequest) return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
NS_ADDREF(proxyRequest);
|
||||
|
||||
// init adds itself to imgRequest's list of observers
|
||||
proxyRequest->Init(request, aLoadGroup, aObserver, cx);
|
||||
|
||||
NS_RELEASE(request);
|
||||
|
||||
*_retval = NS_STATIC_CAST(imgIRequest*, proxyRequest);
|
||||
NS_ADDREF(*_retval);
|
||||
|
||||
NS_RELEASE(proxyRequest);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* imgIRequest loadImageWithChannel(in nsIChannel, in imgIDecoderObserver aObserver, in nsISupports cx, out nsIStreamListener); */
|
||||
NS_IMETHODIMP imgLoader::LoadImageWithChannel(nsIChannel *channel, imgIDecoderObserver *aObserver, nsISupports *cx, nsIStreamListener **listener, imgIRequest **_retval)
|
||||
{
|
||||
NS_ASSERTION(channel, "imgLoader::LoadImageWithChannel -- NULL channel pointer");
|
||||
|
||||
imgRequest *request = nsnull;
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
channel->GetOriginalURI(getter_AddRefs(uri));
|
||||
|
||||
#ifdef MOZ_NEW_CACHE
|
||||
nsCOMPtr<nsICacheEntryDescriptor> entry;
|
||||
ImageCache::Get(uri, &request, getter_AddRefs(entry)); // addrefs request
|
||||
#endif
|
||||
if (request) {
|
||||
// we have this in our cache already.. cancel the current (document) load
|
||||
|
||||
// XXX
|
||||
// if *listener is null when we return here, the caller should probably cancel
|
||||
// the channel instead of us doing it here.
|
||||
channel->Cancel(NS_BINDING_ABORTED); // this should fire an OnStopRequest
|
||||
|
||||
*listener = nsnull; // give them back a null nsIStreamListener
|
||||
} else {
|
||||
NS_NEWXPCOM(request, imgRequest);
|
||||
if (!request) return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
NS_ADDREF(request);
|
||||
|
||||
#ifdef MOZ_NEW_CACHE
|
||||
ImageCache::Put(uri, request, getter_AddRefs(entry));
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_NEW_CACHE
|
||||
request->Init(channel, entry);
|
||||
#else
|
||||
request->Init(channel, nsnull);
|
||||
#endif
|
||||
|
||||
*listener = NS_STATIC_CAST(nsIStreamListener*, request);
|
||||
NS_IF_ADDREF(*listener);
|
||||
}
|
||||
|
||||
imgRequestProxy *proxyRequest;
|
||||
NS_NEWXPCOM(proxyRequest, imgRequestProxy);
|
||||
if (!proxyRequest) return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
NS_ADDREF(proxyRequest);
|
||||
|
||||
// init adds itself to imgRequest's list of observers
|
||||
proxyRequest->Init(request, nsnull, aObserver, cx);
|
||||
|
||||
NS_RELEASE(request);
|
||||
|
||||
*_retval = NS_STATIC_CAST(imgIRequest*, proxyRequest);
|
||||
NS_ADDREF(*_retval);
|
||||
|
||||
NS_RELEASE(proxyRequest);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
48
mozilla/modules/libpr0n/src/imgLoader.h
Normal file
48
mozilla/modules/libpr0n/src/imgLoader.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* 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 Netscape are
|
||||
* Copyright (C) 2001 Netscape Communications Corporation.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Stuart Parmenter <pavlov@netscape.com>
|
||||
*/
|
||||
|
||||
#include "imgILoader.h"
|
||||
|
||||
#ifdef LOADER_THREADSAFE
|
||||
#include "prlock.h"
|
||||
#endif
|
||||
|
||||
#define NS_IMGLOADER_CID \
|
||||
{ /* 9f6a0d2e-1dd1-11b2-a5b8-951f13c846f7 */ \
|
||||
0x9f6a0d2e, \
|
||||
0x1dd1, \
|
||||
0x11b2, \
|
||||
{0xa5, 0xb8, 0x95, 0x1f, 0x13, 0xc8, 0x46, 0xf7} \
|
||||
}
|
||||
|
||||
class imgLoader : public imgILoader
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_IMGILOADER
|
||||
|
||||
imgLoader();
|
||||
virtual ~imgLoader();
|
||||
|
||||
private:
|
||||
};
|
||||
821
mozilla/modules/libpr0n/src/imgRequest.cpp
Normal file
821
mozilla/modules/libpr0n/src/imgRequest.cpp
Normal file
@@ -0,0 +1,821 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* 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 Netscape are
|
||||
* Copyright (C) 2001 Netscape Communications Corporation.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Stuart Parmenter <pavlov@netscape.com>
|
||||
*/
|
||||
|
||||
#include "imgRequest.h"
|
||||
|
||||
#include "nsIAtom.h"
|
||||
#include "nsIChannel.h"
|
||||
#include "nsILoadGroup.h"
|
||||
#include "nsIHTTPChannel.h"
|
||||
#include "nsIInputStream.h"
|
||||
|
||||
#include "imgILoader.h"
|
||||
#include "nsIComponentManager.h"
|
||||
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsIServiceManager.h"
|
||||
|
||||
#include "nsString.h"
|
||||
#include "nsXPIDLString.h"
|
||||
|
||||
#include "gfxIImageFrame.h"
|
||||
|
||||
#ifdef MOZ_NEW_CACHE
|
||||
#include "nsICachingChannel.h"
|
||||
#endif
|
||||
#include "ImageCache.h"
|
||||
|
||||
#include "ImageLogging.h"
|
||||
|
||||
#if defined(PR_LOGGING)
|
||||
PRLogModuleInfo *gImgLog = PR_NewLogModule("imgRequest");
|
||||
#endif
|
||||
|
||||
NS_IMPL_ISUPPORTS7(imgRequest, imgIRequest, nsIRequest,
|
||||
imgIDecoderObserver, imgIContainerObserver,
|
||||
nsIStreamListener, nsIStreamObserver,
|
||||
nsISupportsWeakReference)
|
||||
|
||||
imgRequest::imgRequest() :
|
||||
mObservers(0), mLoading(PR_FALSE), mProcessing(PR_FALSE), mStatus(imgIRequest::STATUS_NONE), mState(0)
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
/* member initializers and constructor code */
|
||||
}
|
||||
|
||||
imgRequest::~imgRequest()
|
||||
{
|
||||
/* destructor code */
|
||||
}
|
||||
|
||||
|
||||
nsresult imgRequest::Init(nsIChannel *aChannel, nsICacheEntryDescriptor *aCacheEntry)
|
||||
{
|
||||
// XXX we should save off the thread we are getting called on here so that we can proxy all calls to mDecoder to it.
|
||||
|
||||
PR_LOG(gImgLog, PR_LOG_DEBUG,
|
||||
("[this=%p] imgRequest::Init\n", this));
|
||||
|
||||
NS_ASSERTION(!mImage, "imgRequest::Init -- Multiple calls to init");
|
||||
NS_ASSERTION(aChannel, "imgRequest::Init -- No channel");
|
||||
|
||||
mChannel = aChannel;
|
||||
|
||||
#ifdef MOZ_NEW_CACHE
|
||||
mCacheEntry = aCacheEntry;
|
||||
#endif
|
||||
|
||||
// XXX do not init the image here. this has to be done from the image decoder.
|
||||
mImage = do_CreateInstance("@mozilla.org/image/container;1");
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult imgRequest::AddObserver(imgIDecoderObserver *observer)
|
||||
{
|
||||
LOG_SCOPE_WITH_PARAM(gImgLog, "imgRequest::AddObserver", "observer", observer);
|
||||
|
||||
mObservers.AppendElement(NS_STATIC_CAST(void*, observer));
|
||||
|
||||
// OnStartDecode
|
||||
if (mState & onStartDecode)
|
||||
observer->OnStartDecode(nsnull, nsnull);
|
||||
|
||||
// OnStartContainer
|
||||
if (mState & onStartContainer)
|
||||
observer->OnStartContainer(nsnull, nsnull, mImage);
|
||||
|
||||
// Send frame messages (OnStartFrame, OnDataAvailable, OnStopFrame)
|
||||
PRUint32 nframes;
|
||||
mImage->GetNumFrames(&nframes);
|
||||
|
||||
if (nframes > 0) {
|
||||
nsCOMPtr<gfxIImageFrame> frame;
|
||||
|
||||
// Is this a single frame image?
|
||||
if (nframes == 1) {
|
||||
// Get the first frame
|
||||
mImage->GetFrameAt(0, getter_AddRefs(frame));
|
||||
NS_ASSERTION(frame, "GetFrameAt gave back a null frame!");
|
||||
} else if (nframes > 1) {
|
||||
/* multiple frames, we'll use the current one */
|
||||
mImage->GetCurrentFrame(getter_AddRefs(frame));
|
||||
NS_ASSERTION(frame, "GetCurrentFrame gave back a null frame!");
|
||||
}
|
||||
|
||||
// OnStartFrame
|
||||
observer->OnStartFrame(nsnull, nsnull, frame);
|
||||
|
||||
if (!(mState & onStopContainer)) {
|
||||
// OnDataAvailable
|
||||
nsRect r;
|
||||
frame->GetRect(r); // XXX we shouldn't send the whole rect here
|
||||
observer->OnDataAvailable(nsnull, nsnull, frame, &r);
|
||||
} else {
|
||||
// OnDataAvailable
|
||||
nsRect r;
|
||||
frame->GetRect(r); // We're done loading this image, send the the whole rect
|
||||
observer->OnDataAvailable(nsnull, nsnull, frame, &r);
|
||||
|
||||
// OnStopFrame
|
||||
observer->OnStopFrame(nsnull, nsnull, frame);
|
||||
}
|
||||
}
|
||||
|
||||
// OnStopContainer
|
||||
if (mState & onStopContainer)
|
||||
observer->OnStopContainer(nsnull, nsnull, mImage);
|
||||
|
||||
nsresult status;
|
||||
if (mStatus & imgIRequest::STATUS_LOAD_COMPLETE)
|
||||
status = NS_IMAGELIB_SUCCESS_LOAD_FINISHED;
|
||||
else if (mStatus & imgIRequest::STATUS_ERROR)
|
||||
status = NS_IMAGELIB_ERROR_FAILURE;
|
||||
|
||||
// OnStopDecode
|
||||
if (mState & onStopDecode)
|
||||
observer->OnStopDecode(nsnull, nsnull, status, nsnull);
|
||||
|
||||
if (mImage && (mObservers.Count() == 1)) {
|
||||
PRUint32 nframes;
|
||||
mImage->GetNumFrames(&nframes);
|
||||
PR_LOG(gImgLog, PR_LOG_DEBUG,
|
||||
("[this=%p] imgRequest::AddObserver -- starting animation\n", this));
|
||||
|
||||
mImage->StartAnimation();
|
||||
}
|
||||
|
||||
if (mState & onStopRequest) {
|
||||
nsCOMPtr<nsIStreamObserver> ob(do_QueryInterface(observer));
|
||||
PR_ASSERT(observer);
|
||||
ob->OnStopRequest(nsnull, nsnull, status, nsnull);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult imgRequest::RemoveObserver(imgIDecoderObserver *observer, nsresult status)
|
||||
{
|
||||
LOG_SCOPE_WITH_PARAM(gImgLog, "imgRequest::RemoveObserver", "observer", observer);
|
||||
|
||||
mObservers.RemoveElement(NS_STATIC_CAST(void*, observer));
|
||||
|
||||
if (mObservers.Count() == 0) {
|
||||
if (mImage) {
|
||||
PRUint32 nframes;
|
||||
mImage->GetNumFrames(&nframes);
|
||||
if (nframes > 1) {
|
||||
PR_LOG(gImgLog, PR_LOG_DEBUG,
|
||||
("[this=%p] imgRequest::RemoveObserver -- stopping animation\n", this));
|
||||
|
||||
mImage->StopAnimation();
|
||||
}
|
||||
}
|
||||
|
||||
if (mChannel && mLoading) {
|
||||
PR_LOG(gImgLog, PR_LOG_DEBUG,
|
||||
("[this=%p] imgRequest::RemoveObserver -- load in progress. canceling\n", this));
|
||||
|
||||
this->RemoveFromCache();
|
||||
this->Cancel(NS_BINDING_ABORTED);
|
||||
|
||||
if (!(mState & onStopDecode)) {
|
||||
// make sure that observer gets an onStopRequest message sent to it
|
||||
observer->OnStopDecode(nsnull, nsnull, NS_IMAGELIB_ERROR_FAILURE, nsnull);
|
||||
}
|
||||
|
||||
if (!(mState & onStopRequest)) {
|
||||
// make sure that observer gets an onStopRequest message sent to it
|
||||
nsCOMPtr<nsIStreamObserver> ob(do_QueryInterface(observer));
|
||||
PR_ASSERT(observer);
|
||||
ob->OnStopRequest(nsnull, nsnull, NS_BINDING_ABORTED, nsnull);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRBool imgRequest::RemoveFromCache()
|
||||
{
|
||||
LOG_SCOPE(gImgLog, "imgRequest::RemoveFromCache");
|
||||
|
||||
#ifdef MOZ_NEW_CACHE
|
||||
|
||||
if (mCacheEntry) {
|
||||
mCacheEntry->Doom();
|
||||
mCacheEntry = nsnull;
|
||||
} else {
|
||||
NS_WARNING("imgRequest::RemoveFromCache -- no entry!");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
|
||||
/** nsIRequest / imgIRequest methods **/
|
||||
|
||||
/* readonly attribute wstring name; */
|
||||
NS_IMETHODIMP imgRequest::GetName(PRUnichar * *aName)
|
||||
{
|
||||
NS_NOTYETIMPLEMENTED("imgRequest::GetName");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* boolean isPending (); */
|
||||
NS_IMETHODIMP imgRequest::IsPending(PRBool *_retval)
|
||||
{
|
||||
NS_NOTYETIMPLEMENTED("imgRequest::IsPending");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* readonly attribute nsresult status; */
|
||||
NS_IMETHODIMP imgRequest::GetStatus(nsresult *aStatus)
|
||||
{
|
||||
NS_NOTYETIMPLEMENTED("imgRequest::GetStatus");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* void cancel (in nsresult status); */
|
||||
NS_IMETHODIMP imgRequest::Cancel(nsresult status)
|
||||
{
|
||||
LOG_SCOPE(gImgLog, "imgRequest::Cancel");
|
||||
|
||||
if (mImage) {
|
||||
PRUint32 nframes;
|
||||
mImage->GetNumFrames(&nframes);
|
||||
if (nframes > 1) {
|
||||
PR_LOG(gImgLog, PR_LOG_DEBUG,
|
||||
("[this=%p] imgRequest::RemoveObserver -- stopping animation\n", this));
|
||||
|
||||
mImage->StopAnimation();
|
||||
}
|
||||
}
|
||||
|
||||
if (mChannel && mLoading)
|
||||
mChannel->Cancel(NS_BINDING_ABORTED); // should prolly use status here
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void suspend (); */
|
||||
NS_IMETHODIMP imgRequest::Suspend()
|
||||
{
|
||||
NS_NOTYETIMPLEMENTED("imgRequest::Suspend");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* void resume (); */
|
||||
NS_IMETHODIMP imgRequest::Resume()
|
||||
{
|
||||
NS_NOTYETIMPLEMENTED("imgRequest::Resume");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/** imgIRequest methods **/
|
||||
|
||||
/* readonly attribute imgIContainer image; */
|
||||
NS_IMETHODIMP imgRequest::GetImage(imgIContainer * *aImage)
|
||||
{
|
||||
PR_LOG(gImgLog, PR_LOG_DEBUG,
|
||||
("[this=%p] imgRequest::GetImage\n", this));
|
||||
|
||||
*aImage = mImage;
|
||||
NS_IF_ADDREF(*aImage);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute unsigned long imageStatus; */
|
||||
NS_IMETHODIMP imgRequest::GetImageStatus(PRUint32 *aStatus)
|
||||
{
|
||||
PR_LOG(gImgLog, PR_LOG_DEBUG,
|
||||
("[this=%p] imgRequest::GetImageStatus\n", this));
|
||||
|
||||
*aStatus = mStatus;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute nsIURI URI; */
|
||||
NS_IMETHODIMP imgRequest::GetURI(nsIURI **aURI)
|
||||
{
|
||||
PR_LOG(gImgLog, PR_LOG_DEBUG,
|
||||
("[this=%p] imgRequest::GetURI\n", this));
|
||||
|
||||
if (mChannel)
|
||||
return mChannel->GetOriginalURI(aURI);
|
||||
else if (mURI) {
|
||||
*aURI = mURI;
|
||||
NS_ADDREF(*aURI);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
/* readonly attribute imgIDecoderObserver decoderObserver; */
|
||||
NS_IMETHODIMP imgRequest::GetDecoderObserver(imgIDecoderObserver **aDecoderObserver)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
/** imgIContainerObserver methods **/
|
||||
|
||||
/* [noscript] void frameChanged (in imgIContainer container, in nsISupports cx, in gfxIImageFrame newframe, in nsRect dirtyRect); */
|
||||
NS_IMETHODIMP imgRequest::FrameChanged(imgIContainer *container, nsISupports *cx, gfxIImageFrame *newframe, nsRect * dirtyRect)
|
||||
{
|
||||
LOG_SCOPE(gImgLog, "imgRequest::FrameChanged");
|
||||
|
||||
PRInt32 i = -1;
|
||||
PRInt32 count = mObservers.Count();
|
||||
|
||||
while (++i < count) {
|
||||
imgIDecoderObserver *ob = NS_STATIC_CAST(imgIDecoderObserver*, mObservers[i]);
|
||||
if (ob) ob->FrameChanged(container, cx, newframe, dirtyRect);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/** imgIDecoderObserver methods **/
|
||||
|
||||
/* void onStartDecode (in imgIRequest request, in nsISupports cx); */
|
||||
NS_IMETHODIMP imgRequest::OnStartDecode(imgIRequest *request, nsISupports *cx)
|
||||
{
|
||||
LOG_SCOPE(gImgLog, "imgRequest::OnStartDecode");
|
||||
|
||||
mState |= onStartDecode;
|
||||
|
||||
PRInt32 i = -1;
|
||||
PRInt32 count = mObservers.Count();
|
||||
|
||||
while (++i < count) {
|
||||
imgIDecoderObserver *ob = NS_STATIC_CAST(imgIDecoderObserver*, mObservers[i]);
|
||||
if (ob) ob->OnStartDecode(request, cx);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onStartContainer (in imgIRequest request, in nsISupports cx, in imgIContainer image); */
|
||||
NS_IMETHODIMP imgRequest::OnStartContainer(imgIRequest *request, nsISupports *cx, imgIContainer *image)
|
||||
{
|
||||
LOG_SCOPE(gImgLog, "imgRequest::OnStartContainer");
|
||||
|
||||
mState |= onStartContainer;
|
||||
|
||||
mStatus |= imgIRequest::STATUS_SIZE_AVAILABLE;
|
||||
|
||||
PRInt32 i = -1;
|
||||
PRInt32 count = mObservers.Count();
|
||||
|
||||
while (++i < count) {
|
||||
imgIDecoderObserver *ob = NS_STATIC_CAST(imgIDecoderObserver*, mObservers[i]);
|
||||
if (ob) ob->OnStartContainer(request, cx, image);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onStartFrame (in imgIRequest request, in nsISupports cx, in gfxIImageFrame frame); */
|
||||
NS_IMETHODIMP imgRequest::OnStartFrame(imgIRequest *request, nsISupports *cx, gfxIImageFrame *frame)
|
||||
{
|
||||
LOG_SCOPE(gImgLog, "imgRequest::OnStartFrame");
|
||||
|
||||
PRInt32 i = -1;
|
||||
PRInt32 count = mObservers.Count();
|
||||
|
||||
while (++i < count) {
|
||||
imgIDecoderObserver *ob = NS_STATIC_CAST(imgIDecoderObserver*, mObservers[i]);
|
||||
if (ob) ob->OnStartFrame(request, cx, frame);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* [noscript] void onDataAvailable (in imgIRequest request, in nsISupports cx, in gfxIImageFrame frame, [const] in nsRect rect); */
|
||||
NS_IMETHODIMP imgRequest::OnDataAvailable(imgIRequest *request, nsISupports *cx, gfxIImageFrame *frame, const nsRect * rect)
|
||||
{
|
||||
LOG_SCOPE(gImgLog, "imgRequest::OnDataAvailable");
|
||||
|
||||
nsCOMPtr<imgIDecoderObserver> container = do_QueryInterface(mImage);
|
||||
container->OnDataAvailable(request, cx, frame, rect);
|
||||
|
||||
PRInt32 i = -1;
|
||||
PRInt32 count = mObservers.Count();
|
||||
|
||||
while (++i < count) {
|
||||
imgIDecoderObserver *ob = NS_STATIC_CAST(imgIDecoderObserver*, mObservers[i]);
|
||||
if (ob) ob->OnDataAvailable(request, cx, frame, rect);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onStopFrame (in imgIRequest request, in nsISupports cx, in gfxIImageFrame frame); */
|
||||
NS_IMETHODIMP imgRequest::OnStopFrame(imgIRequest *request, nsISupports *cx, gfxIImageFrame *frame)
|
||||
{
|
||||
NS_ASSERTION(frame, "imgRequest::OnStopFrame called with NULL frame");
|
||||
|
||||
LOG_SCOPE(gImgLog, "imgRequest::OnStopFrame");
|
||||
|
||||
PRInt32 i = -1;
|
||||
PRInt32 count = mObservers.Count();
|
||||
|
||||
#ifdef MOZ_NEW_CACHE
|
||||
if (mCacheEntry) {
|
||||
PRUint32 cacheSize = 0;
|
||||
|
||||
mCacheEntry->GetDataSize(&cacheSize);
|
||||
|
||||
PRUint32 imageSize = 0;
|
||||
PRUint32 alphaSize = 0;
|
||||
|
||||
frame->GetImageDataLength(&imageSize);
|
||||
frame->GetAlphaDataLength(&alphaSize);
|
||||
|
||||
mCacheEntry->SetDataSize(cacheSize + imageSize + alphaSize);
|
||||
}
|
||||
#endif
|
||||
|
||||
while (++i < count) {
|
||||
imgIDecoderObserver *ob = NS_STATIC_CAST(imgIDecoderObserver*, mObservers[i]);
|
||||
if (ob) ob->OnStopFrame(request, cx, frame);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onStopContainer (in imgIRequest request, in nsISupports cx, in imgIContainer image); */
|
||||
NS_IMETHODIMP imgRequest::OnStopContainer(imgIRequest *request, nsISupports *cx, imgIContainer *image)
|
||||
{
|
||||
LOG_SCOPE(gImgLog, "imgRequest::OnStopContainer");
|
||||
|
||||
mState |= onStopContainer;
|
||||
|
||||
PRInt32 i = -1;
|
||||
PRInt32 count = mObservers.Count();
|
||||
|
||||
while (++i < count) {
|
||||
imgIDecoderObserver *ob = NS_STATIC_CAST(imgIDecoderObserver*, mObservers[i]);
|
||||
if (ob) ob->OnStopContainer(request, cx, image);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onStopDecode (in imgIRequest request, in nsISupports cx, in nsresult status, in wstring statusArg); */
|
||||
NS_IMETHODIMP imgRequest::OnStopDecode(imgIRequest *aRequest, nsISupports *aCX, nsresult aStatus, const PRUnichar *aStatusArg)
|
||||
{
|
||||
LOG_SCOPE(gImgLog, "imgRequest::OnStopDecode");
|
||||
|
||||
if (mState & onStopDecode) {
|
||||
NS_WARNING("OnStopDecode called multiple times.");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
mState |= onStopDecode;
|
||||
|
||||
if (!(mStatus & imgIRequest::STATUS_ERROR) && NS_FAILED(aStatus))
|
||||
mStatus |= imgIRequest::STATUS_ERROR;
|
||||
|
||||
PRInt32 i = -1;
|
||||
PRInt32 count = mObservers.Count();
|
||||
|
||||
nsresult status;
|
||||
if (mStatus & imgIRequest::STATUS_LOAD_COMPLETE)
|
||||
status = NS_IMAGELIB_SUCCESS_LOAD_FINISHED;
|
||||
else if (mStatus & imgIRequest::STATUS_ERROR)
|
||||
status = NS_IMAGELIB_ERROR_FAILURE;
|
||||
|
||||
while (++i < count) {
|
||||
imgIDecoderObserver *ob = NS_STATIC_CAST(imgIDecoderObserver*, mObservers[i]);
|
||||
if (ob) ob->OnStopDecode(aRequest, aCX, status, aStatusArg);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** nsIStreamObserver methods **/
|
||||
|
||||
/* void onStartRequest (in nsIRequest request, in nsISupports ctxt); */
|
||||
NS_IMETHODIMP imgRequest::OnStartRequest(nsIRequest *aRequest, nsISupports *ctxt)
|
||||
{
|
||||
LOG_SCOPE(gImgLog, "imgRequest::OnStartRequest");
|
||||
|
||||
NS_ASSERTION(!mDecoder, "imgRequest::OnStartRequest -- we already have a decoder");
|
||||
NS_ASSERTION(!mLoading, "imgRequest::OnStartRequest -- we are loading again?");
|
||||
|
||||
/* set our loading flag to true */
|
||||
mLoading = PR_TRUE;
|
||||
|
||||
/* notify our kids */
|
||||
PRInt32 i = -1;
|
||||
PRInt32 count = mObservers.Count();
|
||||
|
||||
while (++i < count) {
|
||||
imgIDecoderObserver *iob = NS_STATIC_CAST(imgIDecoderObserver*, mObservers[i]);
|
||||
if (iob) {
|
||||
nsCOMPtr<nsIStreamObserver> ob(do_QueryInterface(iob));
|
||||
if (ob) ob->OnStartRequest(aRequest, ctxt);
|
||||
}
|
||||
}
|
||||
|
||||
/* do our real work */
|
||||
nsCOMPtr<nsIChannel> chan(do_QueryInterface(aRequest));
|
||||
|
||||
if (!mChannel) {
|
||||
PR_LOG(gImgLog, PR_LOG_ALWAYS,
|
||||
(" `-> Channel already stopped or no channel!?.\n"));
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIHTTPChannel> httpChannel(do_QueryInterface(chan));
|
||||
if (httpChannel) {
|
||||
PRUint32 httpStatus;
|
||||
httpChannel->GetResponseStatus(&httpStatus);
|
||||
if (httpStatus == 404) {
|
||||
PR_LOG(gImgLog, PR_LOG_DEBUG,
|
||||
("[this=%p] imgRequest::OnStartRequest -- http status = 404. canceling.\n", this));
|
||||
|
||||
mStatus |= imgIRequest::STATUS_ERROR;
|
||||
this->Cancel(NS_BINDING_ABORTED);
|
||||
this->RemoveFromCache();
|
||||
|
||||
return NS_BINDING_ABORTED;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* get the expires info */
|
||||
#if defined(MOZ_NEW_CACHE)
|
||||
if (mCacheEntry) {
|
||||
nsCOMPtr<nsICachingChannel> cacheChannel(do_QueryInterface(chan));
|
||||
if (cacheChannel) {
|
||||
nsCOMPtr<nsISupports> cacheToken;
|
||||
cacheChannel->GetCacheToken(getter_AddRefs(cacheToken));
|
||||
if (cacheToken) {
|
||||
nsCOMPtr<nsICacheEntryDescriptor> entryDesc(do_QueryInterface(cacheToken));
|
||||
if (entryDesc) {
|
||||
PRUint32 expiration;
|
||||
/* get the expiration time from the caching channel's token */
|
||||
entryDesc->GetExpirationTime(&expiration);
|
||||
|
||||
/* set the expiration time on our entry */
|
||||
mCacheEntry->SetExpirationTime(expiration);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onStopRequest (in nsIRequest request, in nsISupports ctxt, in nsresult status, in wstring statusArg); */
|
||||
NS_IMETHODIMP imgRequest::OnStopRequest(nsIRequest *aRequest, nsISupports *ctxt, nsresult status, const PRUnichar *statusArg)
|
||||
{
|
||||
PR_LOG(gImgLog, PR_LOG_DEBUG,
|
||||
("[this=%p] imgRequest::OnStopRequest\n", this));
|
||||
|
||||
NS_ASSERTION(mChannel && mLoading, "imgRequest::OnStopRequest -- received multiple OnStopRequest");
|
||||
|
||||
mState |= onStopRequest;
|
||||
|
||||
/* set our loading flag to false */
|
||||
mLoading = PR_FALSE;
|
||||
|
||||
/* set our processing flag to false */
|
||||
mProcessing = PR_FALSE;
|
||||
|
||||
#ifdef MOZ_NEW_CACHE
|
||||
/* break the cycle from the cache entry. */
|
||||
mCacheEntry = nsnull;
|
||||
#endif
|
||||
|
||||
if (NS_FAILED(status)) {
|
||||
mStatus |= imgIRequest::STATUS_ERROR;
|
||||
this->RemoveFromCache();
|
||||
this->Cancel(status); // stops animations
|
||||
} else {
|
||||
mStatus |= imgIRequest::STATUS_LOAD_COMPLETE;
|
||||
}
|
||||
|
||||
mChannel->GetOriginalURI(getter_AddRefs(mURI));
|
||||
mChannel = nsnull; // we no longer need the channel
|
||||
|
||||
if (mDecoder) {
|
||||
mDecoder->Flush();
|
||||
mDecoder->Close();
|
||||
mDecoder = nsnull; // release the decoder so that it can rest peacefully ;)
|
||||
}
|
||||
|
||||
/* notify the kids */
|
||||
PRInt32 i = -1;
|
||||
PRInt32 count = mObservers.Count();
|
||||
|
||||
while (++i < count) {
|
||||
void *item = NS_STATIC_CAST(void *, mObservers[i]);
|
||||
if (item) {
|
||||
imgIDecoderObserver *iob = NS_STATIC_CAST(imgIDecoderObserver*, item);
|
||||
if (iob) {
|
||||
nsCOMPtr<nsIStreamObserver> ob(do_QueryInterface(iob));
|
||||
if (ob) ob->OnStopRequest(aRequest, ctxt, status, statusArg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if there was an error loading the image, (mState & onStopDecode) won't be true.
|
||||
// Send an onStopDecode message
|
||||
if (!(mState & onStopDecode)) {
|
||||
this->OnStopDecode(nsnull, nsnull, status, statusArg);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* prototype for this defined below */
|
||||
static NS_METHOD sniff_mimetype_callback(nsIInputStream* in, void* closure, const char* fromRawSegment,
|
||||
PRUint32 toOffset, PRUint32 count, PRUint32 *writeCount);
|
||||
|
||||
|
||||
/** nsIStreamListener methods **/
|
||||
|
||||
/* void onDataAvailable (in nsIRequest request, in nsISupports ctxt, in nsIInputStream inStr, in unsigned long sourceOffset, in unsigned long count); */
|
||||
NS_IMETHODIMP imgRequest::OnDataAvailable(nsIRequest *aRequest, nsISupports *ctxt, nsIInputStream *inStr, PRUint32 sourceOffset, PRUint32 count)
|
||||
{
|
||||
PR_LOG(gImgLog, PR_LOG_DEBUG,
|
||||
("[this=%p] imgRequest::OnDataAvailable\n", this));
|
||||
|
||||
NS_ASSERTION(mChannel, "imgRequest::OnDataAvailable -- no channel!");
|
||||
|
||||
|
||||
if (!mProcessing) {
|
||||
/* set our processing flag to true if this is the first OnDataAvailable() */
|
||||
mProcessing = PR_TRUE;
|
||||
|
||||
/* look at the first few bytes and see if we can tell what the data is from that
|
||||
* since servers tend to lie. :(
|
||||
*/
|
||||
PRUint32 out;
|
||||
inStr->ReadSegments(sniff_mimetype_callback, this, count, &out);
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
/* NS_WARNING if the content type from the channel isn't the same if the sniffing */
|
||||
#endif
|
||||
|
||||
if (!mContentType.get()) {
|
||||
nsXPIDLCString contentType;
|
||||
nsresult rv = mChannel->GetContentType(getter_Copies(contentType));
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
PR_LOG(gImgLog, PR_LOG_ERROR,
|
||||
("[this=%p] imgRequest::OnStartRequest -- Content type unavailable from the channel\n",
|
||||
this));
|
||||
|
||||
this->RemoveFromCache();
|
||||
|
||||
return NS_BINDING_ABORTED; //NS_BASE_STREAM_CLOSED;
|
||||
}
|
||||
|
||||
mContentType = contentType;
|
||||
}
|
||||
|
||||
#if defined(PR_LOGGING)
|
||||
PR_LOG(gImgLog, PR_LOG_DEBUG,
|
||||
("[this=%p] imgRequest::OnStartRequest -- Content type is %s\n", this, mContentType.get()));
|
||||
#endif
|
||||
|
||||
nsCAutoString conid("@mozilla.org/image/decoder;2?type=");
|
||||
conid += mContentType.get();
|
||||
|
||||
mDecoder = do_CreateInstance(conid);
|
||||
|
||||
if (!mDecoder) {
|
||||
PR_LOG(gImgLog, PR_LOG_WARNING,
|
||||
("[this=%p] imgRequest::OnStartRequest -- Decoder not available\n", this));
|
||||
|
||||
// no image decoder for this mimetype :(
|
||||
this->Cancel(NS_BINDING_ABORTED);
|
||||
this->RemoveFromCache();
|
||||
|
||||
// XXX notify the person that owns us now that wants the imgIContainer off of us?
|
||||
return NS_IMAGELIB_ERROR_NO_DECODER;
|
||||
}
|
||||
|
||||
mDecoder->Init(NS_STATIC_CAST(imgIRequest*, this));
|
||||
|
||||
}
|
||||
|
||||
if (!mDecoder) {
|
||||
PR_LOG(gImgLog, PR_LOG_WARNING,
|
||||
("[this=%p] imgRequest::OnDataAvailable -- no decoder\n", this));
|
||||
|
||||
return NS_BASE_STREAM_CLOSED;
|
||||
}
|
||||
|
||||
PRUint32 wrote;
|
||||
nsresult rv = mDecoder->WriteFrom(inStr, count, &wrote);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static NS_METHOD sniff_mimetype_callback(nsIInputStream* in,
|
||||
void* closure,
|
||||
const char* fromRawSegment,
|
||||
PRUint32 toOffset,
|
||||
PRUint32 count,
|
||||
PRUint32 *writeCount)
|
||||
{
|
||||
imgRequest *request = NS_STATIC_CAST(imgRequest*, closure);
|
||||
|
||||
NS_ASSERTION(request, "request is null!");
|
||||
|
||||
if (count > 0)
|
||||
request->SniffMimeType(fromRawSegment, count);
|
||||
|
||||
*writeCount = 0;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
void
|
||||
imgRequest::SniffMimeType(const char *buf, PRUint32 len)
|
||||
{
|
||||
/* Is it a GIF? */
|
||||
if (len >= 4 && !nsCRT::strncmp(buf, "GIF8", 4)) {
|
||||
mContentType = NS_LITERAL_CSTRING("image/gif");
|
||||
return;
|
||||
}
|
||||
|
||||
/* or a PNG? */
|
||||
if (len >= 4 && ((unsigned char)buf[0]==0x89 &&
|
||||
(unsigned char)buf[1]==0x50 &&
|
||||
(unsigned char)buf[2]==0x4E &&
|
||||
(unsigned char)buf[3]==0x47))
|
||||
{
|
||||
mContentType = NS_LITERAL_CSTRING("image/png");
|
||||
return;
|
||||
}
|
||||
|
||||
/* maybe a JPEG (JFIF)? */
|
||||
/* JFIF files start with SOI APP0 but older files can start with SOI DQT
|
||||
* so we test for SOI followed by any marker, i.e. FF D8 FF
|
||||
* this will also work for SPIFF JPEG files if they appear in the future.
|
||||
*
|
||||
* (JFIF is 0XFF 0XD8 0XFF 0XE0 <skip 2> 0X4A 0X46 0X49 0X46 0X00)
|
||||
*/
|
||||
if (len >= 3 &&
|
||||
((unsigned char)buf[0])==0xFF &&
|
||||
((unsigned char)buf[1])==0xD8 &&
|
||||
((unsigned char)buf[2])==0xFF)
|
||||
{
|
||||
mContentType = NS_LITERAL_CSTRING("image/jpeg");
|
||||
return;
|
||||
}
|
||||
|
||||
/* or how about ART? */
|
||||
/* ART begins with JG (4A 47). Major version offset 2.
|
||||
* Minor version offset 3. Offset 4 must be NULL.
|
||||
*/
|
||||
if (len >= 5 &&
|
||||
((unsigned char) buf[0])==0x4a &&
|
||||
((unsigned char) buf[1])==0x47 &&
|
||||
((unsigned char) buf[4])==0x00 )
|
||||
{
|
||||
mContentType = NS_LITERAL_CSTRING("image/x-jg");
|
||||
return;
|
||||
}
|
||||
|
||||
/* none of the above? I give up */
|
||||
}
|
||||
113
mozilla/modules/libpr0n/src/imgRequest.h
Normal file
113
mozilla/modules/libpr0n/src/imgRequest.h
Normal file
@@ -0,0 +1,113 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* 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 Netscape are
|
||||
* Copyright (C) 2001 Netscape Communications Corporation.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Stuart Parmenter <pavlov@netscape.com>
|
||||
*/
|
||||
|
||||
#ifndef imgRequest_h__
|
||||
#define imgRequest_h__
|
||||
|
||||
#include "imgIRequest.h"
|
||||
|
||||
#include "nsIRunnable.h"
|
||||
|
||||
#include "nsIChannel.h"
|
||||
#include "nsIURI.h"
|
||||
#include "imgIContainer.h"
|
||||
#include "imgIDecoder.h"
|
||||
#include "imgIDecoderObserver.h"
|
||||
#include "nsIStreamListener.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
#include "nsVoidArray.h"
|
||||
#include "nsWeakReference.h"
|
||||
|
||||
#include "nsString.h"
|
||||
|
||||
#ifdef MOZ_NEW_CACHE
|
||||
#include "nsICacheEntryDescriptor.h"
|
||||
#else
|
||||
class nsICacheEntryDescriptor;
|
||||
#endif
|
||||
|
||||
#define NS_IMGREQUEST_CID \
|
||||
{ /* 9f733dd6-1dd1-11b2-8cdf-effb70d1ea71 */ \
|
||||
0x9f733dd6, \
|
||||
0x1dd1, \
|
||||
0x11b2, \
|
||||
{0x8c, 0xdf, 0xef, 0xfb, 0x70, 0xd1, 0xea, 0x71} \
|
||||
}
|
||||
|
||||
enum {
|
||||
onStartDecode = 0x1,
|
||||
onStartContainer = 0x2,
|
||||
onStopContainer = 0x4,
|
||||
onStopDecode = 0x8,
|
||||
onStopRequest = 0x16
|
||||
};
|
||||
|
||||
class imgRequest : public imgIRequest,
|
||||
public imgIDecoderObserver,
|
||||
public nsIStreamListener,
|
||||
public nsSupportsWeakReference
|
||||
{
|
||||
public:
|
||||
imgRequest();
|
||||
virtual ~imgRequest();
|
||||
|
||||
/* additional members */
|
||||
nsresult Init(nsIChannel *aChannel, nsICacheEntryDescriptor *aCacheEntry);
|
||||
nsresult AddObserver(imgIDecoderObserver *observer);
|
||||
nsresult RemoveObserver(imgIDecoderObserver *observer, nsresult status);
|
||||
|
||||
PRBool RemoveFromCache();
|
||||
|
||||
void SniffMimeType(const char *buf, PRUint32 len);
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_IMGIREQUEST
|
||||
NS_DECL_NSIREQUEST
|
||||
NS_DECL_IMGIDECODEROBSERVER
|
||||
NS_DECL_IMGICONTAINEROBSERVER
|
||||
NS_DECL_NSISTREAMLISTENER
|
||||
NS_DECL_NSISTREAMOBSERVER
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsIChannel> mChannel;
|
||||
nsCOMPtr<nsIURI> mURI;
|
||||
nsCOMPtr<imgIContainer> mImage;
|
||||
nsCOMPtr<imgIDecoder> mDecoder;
|
||||
|
||||
nsVoidArray mObservers;
|
||||
|
||||
PRBool mLoading;
|
||||
PRBool mProcessing;
|
||||
|
||||
PRUint32 mStatus;
|
||||
PRUint32 mState;
|
||||
|
||||
nsCString mContentType;
|
||||
|
||||
#ifdef MOZ_NEW_CACHE
|
||||
nsCOMPtr<nsICacheEntryDescriptor> mCacheEntry; /* we hold on to this to this so long as we have observers */
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
316
mozilla/modules/libpr0n/src/imgRequestProxy.cpp
Normal file
316
mozilla/modules/libpr0n/src/imgRequestProxy.cpp
Normal file
@@ -0,0 +1,316 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* 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 Netscape are
|
||||
* Copyright (C) 2001 Netscape Communications Corporation.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Stuart Parmenter <pavlov@netscape.com>
|
||||
*/
|
||||
|
||||
#include "imgRequestProxy.h"
|
||||
|
||||
#include "nsXPIDLString.h"
|
||||
|
||||
#include "nsIInputStream.h"
|
||||
#include "imgILoader.h"
|
||||
#include "nsIComponentManager.h"
|
||||
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsIServiceManager.h"
|
||||
|
||||
#include "imgRequest.h"
|
||||
|
||||
#include "nsString.h"
|
||||
|
||||
#include "DummyChannel.h"
|
||||
|
||||
#include "nspr.h"
|
||||
|
||||
#include "ImageLogging.h"
|
||||
|
||||
NS_IMPL_ISUPPORTS5(imgRequestProxy, imgIRequest, nsIRequest, imgIDecoderObserver, imgIContainerObserver, nsIStreamObserver)
|
||||
|
||||
imgRequestProxy::imgRequestProxy() :
|
||||
mCanceled(PR_FALSE)
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
/* member initializers and constructor code */
|
||||
}
|
||||
|
||||
imgRequestProxy::~imgRequestProxy()
|
||||
{
|
||||
/* destructor code */
|
||||
|
||||
// XXX pav
|
||||
// it isn't the job of the request proxy to cancel itself.
|
||||
// if your object goes away and you want to cancel the load, then do it yourself.
|
||||
|
||||
// cancel here for now until i make this work right like the above comment
|
||||
Cancel(NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
nsresult imgRequestProxy::Init(imgRequest *request, nsILoadGroup *aLoadGroup, imgIDecoderObserver *aObserver, nsISupports *cx)
|
||||
{
|
||||
PR_ASSERT(request);
|
||||
|
||||
LOG_SCOPE_WITH_PARAM(gImgLog, "imgRequestProxy::Init", "request", request);
|
||||
|
||||
mOwner = NS_STATIC_CAST(imgIRequest*, request);
|
||||
|
||||
mObserver = aObserver;
|
||||
// XXX we should save off the thread we are getting called on here so that we can proxy all calls to mDecoder to it.
|
||||
|
||||
mContext = cx;
|
||||
|
||||
// XXX we should only create a channel, etc if the image isn't finished loading already.
|
||||
|
||||
nsISupports *inst = nsnull;
|
||||
inst = new DummyChannel(this, aLoadGroup);
|
||||
NS_ADDREF(inst);
|
||||
nsresult res = inst->QueryInterface(NS_GET_IID(nsIChannel), getter_AddRefs(mDummyChannel));
|
||||
NS_RELEASE(inst);
|
||||
|
||||
nsCOMPtr<nsILoadGroup> loadGroup;
|
||||
mDummyChannel->GetLoadGroup(getter_AddRefs(loadGroup));
|
||||
if (loadGroup) {
|
||||
loadGroup->AddRequest(mDummyChannel, cx);
|
||||
}
|
||||
|
||||
request->AddObserver(this);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/** nsIRequest / imgIRequest methods **/
|
||||
|
||||
/* readonly attribute wstring name; */
|
||||
NS_IMETHODIMP imgRequestProxy::GetName(PRUnichar * *aName)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* boolean isPending (); */
|
||||
NS_IMETHODIMP imgRequestProxy::IsPending(PRBool *_retval)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* readonly attribute nsresult status; */
|
||||
NS_IMETHODIMP imgRequestProxy::GetStatus(nsresult *aStatus)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* void cancel (in nsresult status); */
|
||||
NS_IMETHODIMP imgRequestProxy::Cancel(nsresult status)
|
||||
{
|
||||
if (mCanceled)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
LOG_SCOPE(gImgLog, "imgRequestProxy::Cancel");
|
||||
|
||||
mCanceled = PR_TRUE;
|
||||
|
||||
NS_ASSERTION(mOwner, "canceling request proxy twice");
|
||||
|
||||
nsresult rv = NS_REINTERPRET_CAST(imgRequest*, mOwner.get())->RemoveObserver(this, status);
|
||||
|
||||
mOwner = nsnull;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* void suspend (); */
|
||||
NS_IMETHODIMP imgRequestProxy::Suspend()
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* void resume (); */
|
||||
NS_IMETHODIMP imgRequestProxy::Resume()
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/** imgIRequest methods **/
|
||||
|
||||
/* readonly attribute imgIContainer image; */
|
||||
NS_IMETHODIMP imgRequestProxy::GetImage(imgIContainer * *aImage)
|
||||
{
|
||||
if (!mOwner)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return mOwner->GetImage(aImage);
|
||||
}
|
||||
|
||||
/* readonly attribute unsigned long imageStatus; */
|
||||
NS_IMETHODIMP imgRequestProxy::GetImageStatus(PRUint32 *aStatus)
|
||||
{
|
||||
if (!mOwner) {
|
||||
*aStatus = imgIRequest::STATUS_ERROR;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return mOwner->GetImageStatus(aStatus);
|
||||
}
|
||||
|
||||
/* readonly attribute nsIURI URI; */
|
||||
NS_IMETHODIMP imgRequestProxy::GetURI(nsIURI **aURI)
|
||||
{
|
||||
if (!mOwner)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return mOwner->GetURI(aURI);
|
||||
}
|
||||
|
||||
/* readonly attribute imgIDecoderObserver decoderObserver; */
|
||||
NS_IMETHODIMP imgRequestProxy::GetDecoderObserver(imgIDecoderObserver **aDecoderObserver)
|
||||
{
|
||||
*aDecoderObserver = mObserver;
|
||||
NS_IF_ADDREF(*aDecoderObserver);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
/** imgIContainerObserver methods **/
|
||||
|
||||
/* [noscript] void frameChanged (in imgIContainer container, in nsISupports cx, in gfxIImageFrame newframe, in nsRect dirtyRect); */
|
||||
NS_IMETHODIMP imgRequestProxy::FrameChanged(imgIContainer *container, nsISupports *cx, gfxIImageFrame *newframe, nsRect * dirtyRect)
|
||||
{
|
||||
PR_LOG(gImgLog, PR_LOG_DEBUG,
|
||||
("[this=%p] imgRequestProxy::FrameChanged\n", this));
|
||||
|
||||
if (mObserver)
|
||||
mObserver->FrameChanged(container, mContext, newframe, dirtyRect);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/** imgIDecoderObserver methods **/
|
||||
|
||||
/* void onStartDecode (in imgIRequest request, in nsISupports cx); */
|
||||
NS_IMETHODIMP imgRequestProxy::OnStartDecode(imgIRequest *request, nsISupports *cx)
|
||||
{
|
||||
PR_LOG(gImgLog, PR_LOG_DEBUG,
|
||||
("[this=%p] imgRequestProxy::OnStartDecode\n", this));
|
||||
|
||||
if (mObserver)
|
||||
mObserver->OnStartDecode(this, mContext);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onStartContainer (in imgIRequest request, in nsISupports cx, in imgIContainer image); */
|
||||
NS_IMETHODIMP imgRequestProxy::OnStartContainer(imgIRequest *request, nsISupports *cx, imgIContainer *image)
|
||||
{
|
||||
PR_LOG(gImgLog, PR_LOG_DEBUG,
|
||||
("[this=%p] imgRequestProxy::OnStartContainer\n", this));
|
||||
|
||||
if (mObserver)
|
||||
mObserver->OnStartContainer(this, mContext, image);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onStartFrame (in imgIRequest request, in nsISupports cx, in gfxIImageFrame frame); */
|
||||
NS_IMETHODIMP imgRequestProxy::OnStartFrame(imgIRequest *request, nsISupports *cx, gfxIImageFrame *frame)
|
||||
{
|
||||
PR_LOG(gImgLog, PR_LOG_DEBUG,
|
||||
("[this=%p] imgRequestProxy::OnStartFrame\n", this));
|
||||
|
||||
if (mObserver)
|
||||
mObserver->OnStartFrame(this, mContext, frame);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* [noscript] void onDataAvailable (in imgIRequest request, in nsISupports cx, in gfxIImageFrame frame, [const] in nsRect rect); */
|
||||
NS_IMETHODIMP imgRequestProxy::OnDataAvailable(imgIRequest *request, nsISupports *cx, gfxIImageFrame *frame, const nsRect * rect)
|
||||
{
|
||||
PR_LOG(gImgLog, PR_LOG_DEBUG,
|
||||
("[this=%p] imgRequestProxy::OnDataAvailable\n", this));
|
||||
|
||||
if (mObserver)
|
||||
mObserver->OnDataAvailable(this, mContext, frame, rect);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onStopFrame (in imgIRequest request, in nsISupports cx, in gfxIImageFrame frame); */
|
||||
NS_IMETHODIMP imgRequestProxy::OnStopFrame(imgIRequest *request, nsISupports *cx, gfxIImageFrame *frame)
|
||||
{
|
||||
PR_LOG(gImgLog, PR_LOG_DEBUG,
|
||||
("[this=%p] imgRequestProxy::OnStopFrame\n", this));
|
||||
|
||||
if (mObserver)
|
||||
mObserver->OnStopFrame(this, mContext, frame);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onStopContainer (in imgIRequest request, in nsISupports cx, in imgIContainer image); */
|
||||
NS_IMETHODIMP imgRequestProxy::OnStopContainer(imgIRequest *request, nsISupports *cx, imgIContainer *image)
|
||||
{
|
||||
PR_LOG(gImgLog, PR_LOG_DEBUG,
|
||||
("[this=%p] imgRequestProxy::OnStopContainer\n", this));
|
||||
|
||||
if (mObserver)
|
||||
mObserver->OnStopContainer(this, mContext, image);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onStopDecode (in imgIRequest request, in nsISupports cx, in nsresult status, in wstring statusArg); */
|
||||
NS_IMETHODIMP imgRequestProxy::OnStopDecode(imgIRequest *request, nsISupports *cx, nsresult status, const PRUnichar *statusArg)
|
||||
{
|
||||
PR_LOG(gImgLog, PR_LOG_DEBUG,
|
||||
("[this=%p] imgRequestProxy::OnStopDecode\n", this));
|
||||
|
||||
if (mObserver)
|
||||
mObserver->OnStopDecode(this, mContext, status, statusArg);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* void onStartRequest (in nsIRequest request, in nsISupports ctxt); */
|
||||
NS_IMETHODIMP imgRequestProxy::OnStartRequest(nsIRequest *request, nsISupports *ctxt)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onStopRequest (in nsIRequest request, in nsISupports ctxt, in nsresult statusCode, in wstring statusText); */
|
||||
NS_IMETHODIMP imgRequestProxy::OnStopRequest(nsIRequest *request, nsISupports *ctxt, nsresult statusCode, const PRUnichar *statusText)
|
||||
{
|
||||
if (!mDummyChannel)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsILoadGroup> loadGroup;
|
||||
mDummyChannel->GetLoadGroup(getter_AddRefs(loadGroup));
|
||||
if (loadGroup) {
|
||||
loadGroup->RemoveRequest(mDummyChannel, mContext, statusCode, statusText);
|
||||
}
|
||||
mDummyChannel = nsnull;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
70
mozilla/modules/libpr0n/src/imgRequestProxy.h
Normal file
70
mozilla/modules/libpr0n/src/imgRequestProxy.h
Normal file
@@ -0,0 +1,70 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* 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 Netscape are
|
||||
* Copyright (C) 2001 Netscape Communications Corporation.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Stuart Parmenter <pavlov@netscape.com>
|
||||
*/
|
||||
|
||||
#include "imgRequest.h"
|
||||
#include "imgIDecoderObserver.h"
|
||||
|
||||
#include "imgIContainer.h"
|
||||
#include "imgIDecoder.h"
|
||||
#include "nsIStreamObserver.h"
|
||||
#include "nsIChannel.h"
|
||||
#include "nsILoadGroup.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
#define NS_IMGREQUESTPROXY_CID \
|
||||
{ /* 20557898-1dd2-11b2-8f65-9c462ee2bc95 */ \
|
||||
0x20557898, \
|
||||
0x1dd2, \
|
||||
0x11b2, \
|
||||
{0x8f, 0x65, 0x9c, 0x46, 0x2e, 0xe2, 0xbc, 0x95} \
|
||||
}
|
||||
|
||||
class imgRequestProxy : public imgIRequest,
|
||||
public imgIDecoderObserver,
|
||||
public nsIStreamObserver
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_IMGIREQUEST
|
||||
NS_DECL_NSIREQUEST
|
||||
NS_DECL_IMGIDECODEROBSERVER
|
||||
NS_DECL_IMGICONTAINEROBSERVER
|
||||
NS_DECL_NSISTREAMOBSERVER
|
||||
|
||||
imgRequestProxy();
|
||||
virtual ~imgRequestProxy();
|
||||
|
||||
/* additional members */
|
||||
nsresult Init(imgRequest *request, nsILoadGroup *aLoadGroup, imgIDecoderObserver *aObserver, nsISupports *cx);
|
||||
|
||||
private:
|
||||
nsCOMPtr<imgIDecoderObserver> mObserver;
|
||||
|
||||
nsCOMPtr<nsISupports> mContext;
|
||||
|
||||
nsCOMPtr<imgIRequest> mOwner;
|
||||
|
||||
nsCOMPtr<nsIChannel> mDummyChannel;
|
||||
|
||||
PRBool mCanceled;
|
||||
};
|
||||
56
mozilla/modules/libpr0n/src/makefile.win
Normal file
56
mozilla/modules/libpr0n/src/makefile.win
Normal file
@@ -0,0 +1,56 @@
|
||||
#!nmake
|
||||
#
|
||||
# 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 Netscape are
|
||||
# Copyright (C) 2001 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Stuart Parmenter <pavlov@netscape.com>
|
||||
#
|
||||
|
||||
DEPTH=..\..\..
|
||||
include <$(DEPTH)/config/config.mak>
|
||||
|
||||
MODULE = imglib2
|
||||
LIBRARY_NAME = imglib2
|
||||
DLL = $(OBJDIR)\$(LIBRARY_NAME).dll
|
||||
MAKE_OBJ_TYPE = DLL
|
||||
|
||||
OBJS = \
|
||||
.\$(OBJDIR)\DummyChannel.obj \
|
||||
.\$(OBJDIR)\ImageCache.obj \
|
||||
.\$(OBJDIR)\ImageFactory.obj \
|
||||
.\$(OBJDIR)\imgContainer.obj \
|
||||
.\$(OBJDIR)\imgLoader.obj \
|
||||
.\$(OBJDIR)\imgRequest.obj \
|
||||
.\$(OBJDIR)\imgRequestProxy.obj \
|
||||
$(NULL)
|
||||
|
||||
LLIBS=\
|
||||
$(LIBNSPR) \
|
||||
$(DIST)\lib\xpcom.lib \
|
||||
$(DIST)\lib\gkgfxwin.lib \
|
||||
$(NULL)
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
|
||||
install:: $(DLL)
|
||||
$(MAKE_INSTALL) .\$(OBJDIR)\$(LIBRARY_NAME).dll $(DIST)\bin\components
|
||||
$(MAKE_INSTALL) .\$(OBJDIR)\$(LIBRARY_NAME).lib $(DIST)\lib
|
||||
|
||||
clobber::
|
||||
rm -f $(DIST)\bin\components\$(LIBRARY_NAME).dll
|
||||
rm -f $(DIST)\lib\$(LIBRARY_NAME).lib
|
||||
90
mozilla/modules/libpr0n/src/win32.order
Normal file
90
mozilla/modules/libpr0n/src/win32.order
Normal file
@@ -0,0 +1,90 @@
|
||||
?AddRef@imgRequestProxy@@UAGKXZ ; 143798
|
||||
?Release@imgContainer@@UAGKXZ ; 120291
|
||||
?OnDataAvailable@imgRequestProxy@@UAGIPAVimgIRequest@@PAVnsISupports@@PAVgfxIImageFrame@@PBUnsRect@@@Z ; 84442
|
||||
?QueryInterface@imgContainer@@UAGIABUnsID@@PAPAX@Z ; 76980
|
||||
?OnDataAvailable@imgContainer@@UAGIPAVimgIRequest@@PAVnsISupports@@PAVgfxIImageFrame@@PBUnsRect@@@Z ; 75604
|
||||
?OnDataAvailable@imgRequest@@UAGIPAVimgIRequest@@PAVnsISupports@@PAVgfxIImageFrame@@PBUnsRect@@@Z ; 75604
|
||||
?AddRef@DummyChannel@@UAGKXZ ; 45629
|
||||
?QueryInterface@DummyChannel@@UAGIABUnsID@@PAPAX@Z ; 45310
|
||||
?GetImage@imgRequest@@UAGIPAPAVimgIContainer@@@Z ; 41814
|
||||
?Release@DummyChannel@@UAGKXZ ; 41716
|
||||
?GetImage@imgRequestProxy@@UAGIPAPAVimgIContainer@@@Z ; 40453
|
||||
?GetFrameAt@imgContainer@@UAGIIPAPAVgfxIImageFrame@@@Z ; 39613
|
||||
?GetHeight@imgContainer@@UAGIPAH@Z ; 32348
|
||||
?Release@imgRequest@@UAGKXZ ; 31603
|
||||
?AddRef@imgRequest@@UAGKXZ ; 31603
|
||||
?GetNumFrames@imgContainer@@UAGIPAI@Z ; 28342
|
||||
?GetImageStatus@imgRequestProxy@@UAGIPAI@Z ; 27464
|
||||
?Release@imgRequestProxy@@UAGKXZ ; 23383
|
||||
?GetCurrentFrame@imgContainer@@UAGIPAPAVgfxIImageFrame@@@Z ; 19319
|
||||
?QueryInterface@imgRequest@@UAGIABUnsID@@PAPAX@Z ; 16120
|
||||
?assign_assuming_AddRef@nsCOMPtr_base@@IAEXPAVnsISupports@@@Z ; 13764
|
||||
?FrameChanged@imgRequestProxy@@UAGIPAVimgIContainer@@PAVnsISupports@@PAVgfxIImageFrame@@PAUnsRect@@@Z ; 13455
|
||||
?QueryInterface@imgRequestProxy@@UAGIABUnsID@@PAPAX@Z ; 10170
|
||||
?Notify@imgContainer@@UAGXPAVnsITimer@@@Z ; 9611
|
||||
??0nsQueryReferent@@QAE@PAVnsIWeakReference@@PAI@Z ; 9611
|
||||
?FrameChanged@imgRequest@@UAGIPAVimgIContainer@@PAVnsISupports@@PAVgfxIImageFrame@@PAUnsRect@@@Z ; 9609
|
||||
?DoComposite@imgContainer@@AAEXPAPAVgfxIImageFrame@@PAUnsRect@@HH@Z ; 9608
|
||||
?GetLoadAttributes@DummyChannel@@UAGIPAI@Z ; 8258
|
||||
?Cancel@imgRequestProxy@@UAGII@Z ; 7509
|
||||
?GetLoadGroup@DummyChannel@@UAGIPAPAVnsILoadGroup@@@Z ; 7456
|
||||
?GetURI@imgRequest@@UAGIPAPAVnsIURI@@@Z ; 5395
|
||||
?GetURI@imgRequestProxy@@UAGIPAPAVnsIURI@@@Z ; 5395
|
||||
?GetCacheSession@@YAXPAPAVnsICacheSession@@@Z ; 5165
|
||||
?GetWidth@imgContainer@@UAGIPAH@Z ; 4675
|
||||
?Release@imgLoader@@UAGKXZ ; 3791
|
||||
?AddObserver@imgRequest@@QAEIPAVimgIDecoderObserver@@@Z ; 3789
|
||||
?Get@ImageCache@@SAHPAVnsIURI@@PAPAVimgRequest@@PAPAVnsICacheEntryDescriptor@@@Z ; 3789
|
||||
?RemoveObserver@imgRequest@@QAEIPAVimgIDecoderObserver@@I@Z ; 3789
|
||||
?Init@imgRequestProxy@@QAEIPAVimgRequest@@PAVnsILoadGroup@@PAVimgIDecoderObserver@@PAVnsISupports@@@Z ; 3789
|
||||
?QueryInterface@imgLoader@@UAGIABUnsID@@PAPAX@Z ; 3789
|
||||
??0imgRequestProxy@@QAE@XZ ; 3789
|
||||
??0DummyChannel@@QAE@PAVimgIRequest@@PAVnsILoadGroup@@@Z ; 3789
|
||||
?LoadImage@imgLoader@@UAGIPAVnsIURI@@PAVnsILoadGroup@@PAVimgIDecoderObserver@@PAVnsISupports@@PAPAVimgIRequest@@@Z ; 3789
|
||||
??1imgRequestProxy@@UAE@XZ ; 3667
|
||||
??1DummyChannel@@QAE@XZ ; 3667
|
||||
??_EimgRequestProxy@@UAEPAXI@Z ; 3667
|
||||
?OnStopRequest@imgRequestProxy@@UAGIPAVnsIRequest@@PAVnsISupports@@IPBG@Z ; 3667
|
||||
?OnStopDecode@imgRequestProxy@@UAGIPAVimgIRequest@@PAVnsISupports@@IPBG@Z ; 3652
|
||||
?OnStartContainer@imgRequestProxy@@UAGIPAVimgIRequest@@PAVnsISupports@@PAVimgIContainer@@@Z ; 3652
|
||||
?OnStopContainer@imgRequestProxy@@UAGIPAVimgIRequest@@PAVnsISupports@@PAVimgIContainer@@@Z ; 3652
|
||||
?OnStartDecode@imgRequestProxy@@UAGIPAVimgIRequest@@PAVnsISupports@@@Z ; 3652
|
||||
?OnStopFrame@imgRequestProxy@@UAGIPAVimgIRequest@@PAVnsISupports@@PAVgfxIImageFrame@@@Z ; 3491
|
||||
?OnStartFrame@imgRequestProxy@@UAGIPAVimgIRequest@@PAVnsISupports@@PAVgfxIImageFrame@@@Z ; 3491
|
||||
?OnStartRequest@imgRequestProxy@@UAGIPAVnsIRequest@@PAVnsISupports@@@Z ; 2714
|
||||
?OnStopFrame@imgRequest@@UAGIPAVimgIRequest@@PAVnsISupports@@PAVgfxIImageFrame@@@Z ; 2082
|
||||
?AppendFrame@imgContainer@@UAGIPAVgfxIImageFrame@@@Z ; 2082
|
||||
?OnStartFrame@imgRequest@@UAGIPAVimgIRequest@@PAVnsISupports@@PAVgfxIImageFrame@@@Z ; 2082
|
||||
?EndFrameDecode@imgContainer@@UAGIII@Z ; 1996
|
||||
?StartAnimation@imgContainer@@UAGIXZ ; 1747
|
||||
?OnDataAvailable@imgRequest@@UAGIPAVnsIRequest@@PAVnsISupports@@PAVnsIInputStream@@II@Z ; 1415
|
||||
??0imgContainer@@QAE@XZ ; 1376
|
||||
??1imgRequest@@UAE@XZ ; 1376
|
||||
?OnStopRequest@imgRequest@@UAGIPAVnsIRequest@@PAVnsISupports@@IPBG@Z ; 1376
|
||||
?Init@imgRequest@@QAEIPAVnsIChannel@@PAVnsICacheEntryDescriptor@@@Z ; 1376
|
||||
??1imgContainer@@UAE@XZ ; 1376
|
||||
?Put@ImageCache@@SAHPAVnsIURI@@PAVimgRequest@@PAPAVnsICacheEntryDescriptor@@@Z ; 1376
|
||||
??_GimgRequest@@UAEPAXI@Z ; 1376
|
||||
??_EimgContainer@@UAEPAXI@Z ; 1376
|
||||
??0imgRequest@@QAE@XZ ; 1376
|
||||
?OnStartRequest@imgRequest@@UAGIPAVnsIRequest@@PAVnsISupports@@@Z ; 1367
|
||||
?OnStartContainer@imgRequest@@UAGIPAVimgIRequest@@PAVnsISupports@@PAVimgIContainer@@@Z ; 1361
|
||||
?Init@imgContainer@@UAGIHHPAVimgIContainerObserver@@@Z ; 1361
|
||||
?OnStartDecode@imgRequest@@UAGIPAVimgIRequest@@PAVnsISupports@@@Z ; 1361
|
||||
?SniffMimeType@imgRequest@@QAEXPBDI@Z ; 1361
|
||||
?OnStopContainer@imgRequest@@UAGIPAVimgIRequest@@PAVnsISupports@@PAVimgIContainer@@@Z ; 1361
|
||||
?OnStopDecode@imgRequest@@UAGIPAVimgIRequest@@PAVnsISupports@@IPBG@Z ; 1361
|
||||
?GetContentType@DummyChannel@@UAGIPAPAD@Z ; 1275
|
||||
?DecodingComplete@imgContainer@@UAGIXZ ; 1275
|
||||
?Cancel@DummyChannel@@UAGII@Z ; 122
|
||||
?StopAnimation@imgContainer@@UAGIXZ ; 121
|
||||
?GetDecoderObserver@imgRequestProxy@@UAGIPAPAVimgIDecoderObserver@@@Z ; 84
|
||||
??0nsGetInterface@@QAE@PAVnsISupports@@PAI@Z ; 77
|
||||
_NSGetModule ; 1
|
||||
??_EimgLoader@@UAEPAXI@Z ; 1
|
||||
??1imgLoader@@UAE@XZ ; 1
|
||||
?Shutdown@ImageCache@@SAXXZ ; 1
|
||||
??0imgLoader@@QAE@XZ ; 1
|
||||
?do_GetService@@YA?BVnsGetServiceByContractID@@PBDPAI@Z ; 1
|
||||
?Cancel@imgRequest@@UAGII@Z ; 1
|
||||
?RemoveFromCache@imgRequest@@QAEHXZ ; 1
|
||||
@@ -1,26 +0,0 @@
|
||||
|
||||
To install a fresh tinderbox:
|
||||
|
||||
1) Checkout the latest copy of the tinderbox scripts
|
||||
cd /builds/cvs; cvs -z3 co mozilla/tools/tinderbox
|
||||
|
||||
2) Change to the location that you wish to run the tinderbox from.
|
||||
cd /builds/tinderbox
|
||||
|
||||
3) Create links from the cvs directory to your build directory
|
||||
ln -s /builds/cvs/mozilla/tools/tinderbox/*.pl .
|
||||
|
||||
4) Create your tinderbox config file
|
||||
perl ./build-seamonkey.pl --example-config > tinder-config.pl
|
||||
|
||||
5) Create your mozconfig build file in the current dir
|
||||
mozilla -remote http://webtools.mozilla.org/build/config.cgi
|
||||
|
||||
6) Customize your tinderbox configuration
|
||||
vi tinder-config.pl
|
||||
|
||||
7) Test your tinderbox configuration on the test tree
|
||||
perl ./build-seamonkey.pl --depend -t MozillaTest
|
||||
|
||||
8) Once you are satisfied with the results run your tinderbox
|
||||
perl ./build-seamonkey.pl --depend
|
||||
@@ -1,74 +0,0 @@
|
||||
mozilla/tools/tinderbox
|
||||
===================
|
||||
|
||||
This directory is for the scripts associated with the client-side of
|
||||
tinderbox (scripts to checkout, build, and report the status of the tree
|
||||
to a tinderbox server).
|
||||
|
||||
|
||||
Table of Contents
|
||||
=================
|
||||
|
||||
* README
|
||||
This file.
|
||||
|
||||
* build-seamonkey.pl
|
||||
A perl script to drive the client side of tinderbox (unix variants).
|
||||
usage:
|
||||
build-seamonkey.pl [--clobber | --depend] [-t TreeName] [--testonly] [--once]
|
||||
|
||||
* bloatdiff.pl
|
||||
Script used to process leak data in the logs.
|
||||
|
||||
* build-seamonkey-util.pl
|
||||
Core unix tinderbox stuff.
|
||||
|
||||
* post-mozilla-sample.pl
|
||||
Example of post-build test script
|
||||
|
||||
* tinder-defaults.pl
|
||||
Default script variables.
|
||||
|
||||
* gettime.pl
|
||||
Wrapper to get hires time, if available.
|
||||
|
||||
* tinderbox
|
||||
Wrapper script to start unix builds.
|
||||
|
||||
* install-links
|
||||
Create links to a tinderbox install directory.
|
||||
|
||||
|
||||
Tinderbox example for SeaMonkey build
|
||||
=====================================
|
||||
|
||||
Here is an example of how to set up a "SeaMonkey" tinderbox
|
||||
build of mozilla.
|
||||
|
||||
# Create tinderbox source files in mozilla,
|
||||
# then SeaMonkey directory where mozilla tree will live.
|
||||
cvs co mozilla/tools/tinderbox
|
||||
mkdir SeaMonkey
|
||||
cd SeaMonkey; ../mozilla/tools/tinderbox/install-links
|
||||
|
||||
#
|
||||
# Create tinder-config.pl file in SeaMonkey directory.
|
||||
# Copy one from an existing build, or create a sample one and edit it:
|
||||
#
|
||||
./build-seamonkey.pl --example-config > tinder-config.pl
|
||||
|
||||
#
|
||||
# mozconfig. If you have configure options, add them to a
|
||||
# file named "mozconfig" in the SeaMonkey directory.
|
||||
# Again, you can copy one from a build, or create one.
|
||||
# For a default stock build, this file is not needed or
|
||||
# can be blank.
|
||||
#
|
||||
|
||||
# Start the tinderbox! From the SeaMonkey directory:
|
||||
./tinderbox depend start
|
||||
|
||||
# You can watch the build run the first time with:
|
||||
tail -f <objdir>/<logname>
|
||||
|
||||
|
||||
@@ -1,332 +0,0 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
#
|
||||
# Munges the output from
|
||||
# XPCOM_MEM_BLOAT_LOG=1; mozilla-bin -f bloaturls.txt
|
||||
# so that it does some summary and stats stuff.
|
||||
#
|
||||
# To show leak test results for a set of changes, do something like this:
|
||||
#
|
||||
# XPCOM_MEM_BLOAT_LOG=1
|
||||
# mozilla -f bloaturls.txt > a.out
|
||||
# **make change**
|
||||
# mozilla -f bloaturls.txt > b.out
|
||||
# bloatdiff.pl a.out b.out
|
||||
#
|
||||
|
||||
$OLDFILE = $ARGV[0];
|
||||
$NEWFILE = $ARGV[1];
|
||||
$LABEL = $ARGV[2];
|
||||
|
||||
sub processFile {
|
||||
my ($filename, $map, $prevMap) = @_;
|
||||
open(FH, $filename);
|
||||
while (<FH>) {
|
||||
if (m{
|
||||
^\s*(\d+)\s # Line number
|
||||
([\w:]+)\s+ # Name
|
||||
(-?\d+)\s+ # Size
|
||||
(-?\d+)\s+ # Leaked
|
||||
(-?\d+)\s+ # Objects Total
|
||||
(-?\d+)\s+ # Objects Rem
|
||||
\(\s*(-?[\d.]+)\s+ # Objects Mean
|
||||
\+/-\s+
|
||||
([\w.]+)\)\s+ # Objects StdDev
|
||||
(-?\d+)\s+ # Reference Total
|
||||
(-?\d+)\s+ # Reference Rem
|
||||
\(\s*(-?[\d.]+)\s+ # Reference Mean
|
||||
\+/-\s+
|
||||
([\w\.]+)\) # Reference StdDev
|
||||
}x) {
|
||||
$$map{$2} = { name => $2,
|
||||
size => $3,
|
||||
leaked => $4,
|
||||
objTotal => $5,
|
||||
objRem => $6,
|
||||
objMean => $7,
|
||||
objStdDev => $8,
|
||||
refTotal => $9,
|
||||
refRem => $10,
|
||||
refMean => $11,
|
||||
refStdDev => $12,
|
||||
bloat => $3 * $5 # size * objTotal
|
||||
};
|
||||
} else {
|
||||
# print "failed to parse: $_\n";
|
||||
}
|
||||
}
|
||||
close(FH);
|
||||
}
|
||||
|
||||
%oldMap = ();
|
||||
processFile($OLDFILE, \%oldMap);
|
||||
|
||||
%newMap = ();
|
||||
processFile($NEWFILE, \%newMap);
|
||||
|
||||
################################################################################
|
||||
|
||||
$inf = 9999999.99;
|
||||
|
||||
sub getLeaksDelta {
|
||||
my ($key) = @_;
|
||||
my $oldLeaks = $oldMap{$key}{leaked} || 0;
|
||||
my $newLeaks = $newMap{$key}{leaked};
|
||||
my $percentLeaks = 0;
|
||||
if ($oldLeaks == 0) {
|
||||
if ($newLeaks != 0) {
|
||||
# there weren't any leaks before, but now there are!
|
||||
$percentLeaks = $inf;
|
||||
}
|
||||
}
|
||||
else {
|
||||
$percentLeaks = ($newLeaks - $oldLeaks) / $oldLeaks * 100;
|
||||
}
|
||||
# else we had no record of this class before
|
||||
return ($newLeaks - $oldLeaks, $percentLeaks);
|
||||
}
|
||||
|
||||
################################################################################
|
||||
|
||||
sub getBloatDelta {
|
||||
my ($key) = @_;
|
||||
my $newBloat = $newMap{$key}{bloat};
|
||||
my $percentBloat = 0;
|
||||
my $oldSize = $oldMap{$key}{size} || 0;
|
||||
my $oldTotal = $oldMap{$key}{objTotal} || 0;
|
||||
my $oldBloat = $oldTotal * $oldSize;
|
||||
if ($oldBloat == 0) {
|
||||
if ($newBloat != 0) {
|
||||
# this class wasn't used before, but now it is
|
||||
$percentBloat = $inf;
|
||||
}
|
||||
}
|
||||
else {
|
||||
$percentBloat = ($newBloat - $oldBloat) / $oldBloat * 100;
|
||||
}
|
||||
# else we had no record of this class before
|
||||
return ($newBloat - $oldBloat, $percentBloat);
|
||||
}
|
||||
|
||||
################################################################################
|
||||
|
||||
foreach $key (keys %newMap) {
|
||||
my ($newLeaks, $percentLeaks) = getLeaksDelta($key);
|
||||
my ($newBloat, $percentBloat) = getBloatDelta($key);
|
||||
$newMap{$key}{leakDelta} = $newLeaks;
|
||||
$newMap{$key}{leakPercent} = $percentLeaks;
|
||||
$newMap{$key}{bloatDelta} = $newBloat;
|
||||
$newMap{$key}{bloatPercent} = $percentBloat;
|
||||
}
|
||||
|
||||
################################################################################
|
||||
|
||||
# Print a value of bytes out in a reasonable
|
||||
# KB, MB, or GB form. Copied from build-seamonkey-util.pl, sorry. -mcafee
|
||||
sub PrintSize($) {
|
||||
|
||||
# print a number with 3 significant figures
|
||||
sub PrintNum($) {
|
||||
my ($num) = @_;
|
||||
my $rv;
|
||||
if ($num < 1) {
|
||||
$rv = sprintf "%.3f", ($num);
|
||||
} elsif ($num < 10) {
|
||||
$rv = sprintf "%.2f", ($num);
|
||||
} elsif ($num < 100) {
|
||||
$rv = sprintf "%.1f", ($num);
|
||||
} else {
|
||||
$rv = sprintf "%d", ($num);
|
||||
}
|
||||
}
|
||||
|
||||
my ($size) = @_;
|
||||
my $rv;
|
||||
if ($size > 1000000000) {
|
||||
$rv = PrintNum($size / 1000000000.0) . "G";
|
||||
} elsif ($size > 1000000) {
|
||||
$rv = PrintNum($size / 1000000.0) . "M";
|
||||
} elsif ($size > 1000) {
|
||||
$rv = PrintNum($size / 1000.0) . "K";
|
||||
} else {
|
||||
$rv = PrintNum($size);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
print "Bloat/Leak Delta Report\n";
|
||||
print "--------------------------------------------------------------------------------------\n";
|
||||
print "Current file: $NEWFILE\n";
|
||||
print "Previous file: $OLDFILE\n";
|
||||
print "----------------------------------------------leaks------leaks%------bloat------bloat%\n";
|
||||
printf "%-40s %10s %10.2f%% %10s %10.2f%%\n",
|
||||
("TOTAL",
|
||||
$newMap{"TOTAL"}{leaked}, $newMap{"TOTAL"}{leakPercent},
|
||||
$newMap{"TOTAL"}{bloat}, $newMap{"TOTAL"}{bloatPercent});
|
||||
|
||||
################################################################################
|
||||
|
||||
sub percentStr {
|
||||
my ($p) = @_;
|
||||
if ($p == $inf) {
|
||||
return "-";
|
||||
}
|
||||
else {
|
||||
return sprintf "%10.2f%%", $p;
|
||||
}
|
||||
}
|
||||
|
||||
# NEW LEAKS
|
||||
@keys = sort { $newMap{$b}{leakPercent} <=> $newMap{$a}{leakPercent} } keys %newMap;
|
||||
my $needsHeading = 1;
|
||||
my $total = 0;
|
||||
foreach $key (@keys) {
|
||||
my $percentLeaks = $newMap{$key}{leakPercent};
|
||||
my $leaks = $newMap{$key}{leaked};
|
||||
if ($percentLeaks > 0 && $key !~ /TOTAL/) {
|
||||
if ($needsHeading) {
|
||||
printf "--NEW-LEAKS-----------------------------------leaks------leaks%%-----------------------\n";
|
||||
$needsHeading = 0;
|
||||
}
|
||||
printf "%-40s %10s %10s\n", ($key, $leaks, percentStr($percentLeaks));
|
||||
$total += $leaks;
|
||||
}
|
||||
}
|
||||
if (!$needsHeading) {
|
||||
printf "%-40s %10s\n", ("TOTAL", $total);
|
||||
}
|
||||
|
||||
# FIXED LEAKS
|
||||
@keys = sort { $newMap{$b}{leakPercent} <=> $newMap{$a}{leakPercent} } keys %newMap;
|
||||
$needsHeading = 1;
|
||||
$total = 0;
|
||||
foreach $key (@keys) {
|
||||
my $percentLeaks = $newMap{$key}{leakPercent};
|
||||
my $leaks = $newMap{$key}{leaked};
|
||||
if ($percentLeaks < 0 && $key !~ /TOTAL/) {
|
||||
if ($needsHeading) {
|
||||
printf "--FIXED-LEAKS---------------------------------leaks------leaks%%-----------------------\n";
|
||||
$needsHeading = 0;
|
||||
}
|
||||
printf "%-40s %10s %10s\n", ($key, $leaks, percentStr($percentLeaks));
|
||||
$total += $leaks;
|
||||
}
|
||||
}
|
||||
if (!$needsHeading) {
|
||||
printf "%-40s %10s\n", ("TOTAL", $total);
|
||||
}
|
||||
|
||||
# NEW BLOAT
|
||||
@keys = sort { $newMap{$b}{bloatPercent} <=> $newMap{$a}{bloatPercent} } keys %newMap;
|
||||
$needsHeading = 1;
|
||||
$total = 0;
|
||||
foreach $key (@keys) {
|
||||
my $percentBloat = $newMap{$key}{bloatPercent};
|
||||
my $bloat = $newMap{$key}{bloat};
|
||||
if ($percentBloat > 0 && $key !~ /TOTAL/) {
|
||||
if ($needsHeading) {
|
||||
printf "--NEW-BLOAT-----------------------------------bloat------bloat%%-----------------------\n";
|
||||
$needsHeading = 0;
|
||||
}
|
||||
printf "%-40s %10s %10s\n", ($key, $bloat, percentStr($percentBloat));
|
||||
$total += $bloat;
|
||||
}
|
||||
}
|
||||
if (!$needsHeading) {
|
||||
printf "%-40s %10s\n", ("TOTAL", $total);
|
||||
}
|
||||
|
||||
# ALL LEAKS
|
||||
@keys = sort { $newMap{$b}{leaked} <=> $newMap{$a}{leaked} } keys %newMap;
|
||||
$needsHeading = 1;
|
||||
$total = 0;
|
||||
foreach $key (@keys) {
|
||||
my $leaks = $newMap{$key}{leaked};
|
||||
my $percentLeaks = $newMap{$key}{leakPercent};
|
||||
if ($leaks > 0) {
|
||||
if ($needsHeading) {
|
||||
printf "--ALL-LEAKS-----------------------------------leaks------leaks%%-----------------------\n";
|
||||
$needsHeading = 0;
|
||||
}
|
||||
printf "%-40s %10s %10s\n", ($key, $leaks, percentStr($percentLeaks));
|
||||
if ($key !~ /TOTAL/) {
|
||||
$total += $leaks;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!$needsHeading) {
|
||||
# printf "%-40s %10s\n", ("TOTAL", $total);
|
||||
}
|
||||
|
||||
# ALL BLOAT
|
||||
@keys = sort { $newMap{$b}{bloat} <=> $newMap{$a}{bloat} } keys %newMap;
|
||||
$needsHeading = 1;
|
||||
$total = 0;
|
||||
foreach $key (@keys) {
|
||||
my $bloat = $newMap{$key}{bloat};
|
||||
my $percentBloat = $newMap{$key}{bloatPercent};
|
||||
if ($bloat > 0) {
|
||||
if ($needsHeading) {
|
||||
printf "--ALL-BLOAT-----------------------------------bloat------bloat%%-----------------------\n";
|
||||
$needsHeading = 0;
|
||||
}
|
||||
printf "%-40s %10s %10s\n", ($key, $bloat, percentStr($percentBloat));
|
||||
if ($key !~ /TOTAL/) {
|
||||
$total += $bloat;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!$needsHeading) {
|
||||
# printf "%-40s %10s\n", ("TOTAL", $total);
|
||||
}
|
||||
|
||||
# NEW CLASSES
|
||||
@keys = sort { $newMap{$b}{bloatDelta} <=> $newMap{$a}{bloatDelta} } keys %newMap;
|
||||
$needsHeading = 1;
|
||||
my $ltotal = 0;
|
||||
my $btotal = 0;
|
||||
foreach $key (@keys) {
|
||||
my $leaks = $newMap{$key}{leaked};
|
||||
my $bloat = $newMap{$key}{bloat};
|
||||
my $percentBloat = $newMap{$key}{bloatPercent};
|
||||
if ($percentBloat == $inf && $key !~ /TOTAL/) {
|
||||
if ($needsHeading) {
|
||||
printf "--CLASSES-NOT-REPORTED-LAST-TIME--------------leaks------bloat------------------------\n";
|
||||
$needsHeading = 0;
|
||||
}
|
||||
printf "%-40s %10s %10s\n", ($key, $leaks, $bloat);
|
||||
if ($key !~ /TOTAL/) {
|
||||
$ltotal += $leaks;
|
||||
$btotal += $bloat;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!$needsHeading) {
|
||||
printf "%-40s %10s %10s\n", ("TOTAL", $ltotal, $btotal);
|
||||
}
|
||||
|
||||
# OLD CLASSES
|
||||
@keys = sort { ($oldMap{$b}{bloat} || 0) <=> ($oldMap{$a}{bloat} || 0) } keys %oldMap;
|
||||
$needsHeading = 1;
|
||||
$ltotal = 0;
|
||||
$btotal = 0;
|
||||
foreach $key (@keys) {
|
||||
if (!defined($newMap{$key})) {
|
||||
my $leaks = $oldMap{$key}{leaked};
|
||||
my $bloat = $oldMap{$key}{bloat};
|
||||
if ($needsHeading) {
|
||||
printf "--CLASSES-THAT-WENT-AWAY----------------------leaks------bloat------------------------\n";
|
||||
$needsHeading = 0;
|
||||
}
|
||||
printf "%-40s %10s %10s\n", ($key, $leaks, $bloat);
|
||||
if ($key !~ /TOTAL/) {
|
||||
$ltotal += $leaks;
|
||||
$btotal += $bloat;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!$needsHeading) {
|
||||
printf "%-40s %10s %10s\n", ("TOTAL", $ltotal, $btotal);
|
||||
}
|
||||
|
||||
print "--------------------------------------------------------------------------------------\n";
|
||||
@@ -1,488 +0,0 @@
|
||||
#!/usr/bin/perl
|
||||
# -*- Mode: perl; indent-tabs-mode: nil -*-
|
||||
#
|
||||
|
||||
#
|
||||
# This script gets called after a full mozilla build & test.
|
||||
# Use this to build and test an embedded or commercial branding of Mozilla.
|
||||
#
|
||||
# ./build-seamonkey-utils.pl will call PostMozilla::main() after
|
||||
# a successful build and testing of mozilla. This package can report
|
||||
# status via the $TinderUtils::build_status variable. Yeah this is a hack,
|
||||
# but it works for now. Feel free to improve this mechanism to properly
|
||||
# return values & stuff. -mcafee
|
||||
#
|
||||
# Things to do:
|
||||
# * Get pull by branch working
|
||||
#
|
||||
#
|
||||
use strict;
|
||||
use File::Path; # for rmtree();
|
||||
|
||||
package PostMozilla;
|
||||
|
||||
sub checkout {
|
||||
my ($mozilla_build_dir) = @_;
|
||||
|
||||
# chdir to build directory
|
||||
chdir "$mozilla_build_dir";
|
||||
|
||||
# Next, do the checkout:
|
||||
print "Settings::CVS = $Settings::CVS\n";
|
||||
my $status = TinderUtils::run_shell_command("$Settings::CVS checkout mozilla/camino");
|
||||
|
||||
# hack in the camino prefs, if needed
|
||||
|
||||
return $status;
|
||||
}
|
||||
|
||||
|
||||
sub ReadHeapDumpToHash($$)
|
||||
{
|
||||
my($dumpfile, $hashref) = @_;
|
||||
|
||||
local(*DUMP_FILE);
|
||||
open(DUMP_FILE, "< $dumpfile") || die "Can't open heap output file $dumpfile\n";
|
||||
|
||||
my $section = 0;
|
||||
my $zone = "";
|
||||
my $default_zone_bytes = 0;
|
||||
|
||||
while (<DUMP_FILE>)
|
||||
{
|
||||
my($line) = $_;
|
||||
chomp($line);
|
||||
|
||||
if ($line =~ /^\#/ || $line =~ /^\s*$/ || $line =~ /------------------------/) { # ignore comments and empty lines
|
||||
next;
|
||||
}
|
||||
|
||||
# use the 'All zones' lines as section markers
|
||||
if ($line =~ /^All zones:/) {
|
||||
$section ++;
|
||||
next;
|
||||
}
|
||||
|
||||
if ($section == 2) # we're in the detailed section
|
||||
{
|
||||
if ($line =~ /^Zone ([^_]+).+\((\d+).+\)/)
|
||||
{
|
||||
$zone = $1;
|
||||
if ($zone eq "DefaultMallocZone") {
|
||||
$default_zone_bytes = $2;
|
||||
}
|
||||
TinderUtils::print_log(" $line\n");
|
||||
next;
|
||||
}
|
||||
|
||||
if ($zone eq "DefaultMallocZone")
|
||||
{
|
||||
if ($line =~ /(\w+)\s*=\s*(\d+)\s*\((\d+).+\)/)
|
||||
{
|
||||
my(%entry_hash) = ("count", $2,
|
||||
"bytes", $3);
|
||||
$hashref->{$1} = \%entry_hash;
|
||||
}
|
||||
elsif ($line =~ /^<not.+>\s*=\s*(\d+)\s*\((\d+).+\)/)
|
||||
{
|
||||
my(%entry_hash) = ("count", $1,
|
||||
"bytes", $2);
|
||||
$hashref->{"malloc_block"} = \%entry_hash;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
close(DUMP_FILE);
|
||||
|
||||
return $default_zone_bytes;
|
||||
}
|
||||
|
||||
sub DumpHash($)
|
||||
{
|
||||
my($hashref) = @_;
|
||||
|
||||
print "Dumping values\n";
|
||||
|
||||
my($key);
|
||||
foreach $key (keys %{$hashref})
|
||||
{
|
||||
my($value) = $hashref->{$key};
|
||||
print "Class $key count $value->{'count'} bytes $value->{'bytes'}\n";
|
||||
}
|
||||
}
|
||||
|
||||
sub ClassEntriesEqual($$)
|
||||
{
|
||||
my($hashone, $hashtwo) = @_;
|
||||
|
||||
return ($hashone->{"count"} == $hashtwo->{"count"}) and ($hashone->{"bytes"} == $hashtwo->{"bytes"})
|
||||
}
|
||||
|
||||
|
||||
sub DumpHashDiffs($$)
|
||||
{
|
||||
my($beforehash, $afterhash) = @_;
|
||||
|
||||
my($name_width) = 50;
|
||||
my($print_format) = "%10s %-${name_width}s %8d %8d\n";
|
||||
|
||||
TinderUtils::print_log(sprintf "%10s %-${name_width}s %8s %8s\n", "", "Class", "Count", "Bytes");
|
||||
TinderUtils::print_log("--------------------------------------------------------------------------------\n");
|
||||
|
||||
my($key);
|
||||
foreach $key (keys %{$beforehash})
|
||||
{
|
||||
my($beforevalue) = $beforehash->{$key};
|
||||
|
||||
if (exists $afterhash->{$key})
|
||||
{
|
||||
my($aftervalue) = $afterhash->{$key};
|
||||
if (!ClassEntriesEqual($beforevalue, $aftervalue))
|
||||
{
|
||||
my($count_change) = $aftervalue->{"count"} - $beforevalue->{"count"};
|
||||
my($bytes_change) = $aftervalue->{"bytes"} - $beforevalue->{"bytes"};
|
||||
|
||||
if ($bytes_change > 0) {
|
||||
TinderUtils::print_log(sprintf $print_format, "Leaked", $key, $count_change, $bytes_change);
|
||||
} else {
|
||||
TinderUtils::print_log(sprintf $print_format, "Freed", $key, $count_change, $bytes_change);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#$before_only{$key} = $beforevalue;
|
||||
TinderUtils::print_log(sprintf $print_format, "Freed", $key, $beforevalue->{'count'}, $beforevalue->{'bytes'});
|
||||
}
|
||||
}
|
||||
|
||||
# now look for things only in the after cache
|
||||
foreach $key (keys %{$afterhash})
|
||||
{
|
||||
my($value) = $afterhash->{$key};
|
||||
|
||||
if (!exists $beforehash->{$key})
|
||||
{
|
||||
#$after_only{$key} = $value;
|
||||
TinderUtils::print_log(sprintf $print_format, "Leaked", $key, $value->{'count'}, $value->{'bytes'});
|
||||
}
|
||||
}
|
||||
|
||||
TinderUtils::print_log("--------------------------------------------------------------------------------\n");
|
||||
|
||||
}
|
||||
|
||||
|
||||
sub ParseHeapOutput($$)
|
||||
{
|
||||
my($beforedump, $afterdump) = @_;
|
||||
|
||||
TinderUtils::print_log("Before window open:\n");
|
||||
my %before_data;
|
||||
my $before_heap = ReadHeapDumpToHash($beforedump, \%before_data);
|
||||
|
||||
TinderUtils::print_log("After window open and close:\n");
|
||||
my %after_data;
|
||||
my $after_heap = ReadHeapDumpToHash($afterdump, \%after_data);
|
||||
|
||||
# DumpHash(\%before_data);
|
||||
# DumpHash(\%after_data);
|
||||
|
||||
TinderUtils::print_log("Open/close window leaks:\n");
|
||||
DumpHashDiffs(\%before_data, \%after_data);
|
||||
|
||||
my $heap_diff = $after_heap - $before_heap;
|
||||
TinderUtils::print_log("TinderboxPrint:<acronym title=\"Per-window leaks\">Lw:".TinderUtils::PrintSize($heap_diff, 3)."B</acronym>\n");
|
||||
}
|
||||
|
||||
|
||||
sub CaminoWindowLeaksTest($$$$$)
|
||||
{
|
||||
my ($test_name, $build_dir, $binary, $args, $timeout_secs) = @_;
|
||||
|
||||
my($status) = 'success';
|
||||
|
||||
my $beforefile = "/tmp/nav_before_heap.dat";
|
||||
my $afterfile = "/tmp/nav_after_heap.dat";
|
||||
|
||||
my $run_test = 1; # useful for testing parsing code
|
||||
if ($run_test)
|
||||
{
|
||||
my $close_window_script =<<END_SCRIPT;
|
||||
tell application "Camino"
|
||||
delay 5
|
||||
close the first window
|
||||
end tell
|
||||
END_SCRIPT
|
||||
|
||||
my $new_window_script =<<END_SCRIPT;
|
||||
tell application "Camino"
|
||||
Get URL "about:blank"
|
||||
delay 20
|
||||
close the first window
|
||||
end tell
|
||||
END_SCRIPT
|
||||
|
||||
TinderUtils::print_log("Window leak test\n");
|
||||
|
||||
my $binary_basename = File::Basename::basename($binary);
|
||||
my $binary_dir = File::Basename::dirname($binary);
|
||||
my $binary_log = "$build_dir/$test_name.log";
|
||||
my $cmd = $binary_basename;
|
||||
|
||||
my $pid = TinderUtils::fork_and_log($build_dir, $binary_dir, $cmd, $binary_log);
|
||||
|
||||
# close the existing window
|
||||
system("echo '$close_window_script' | osascript");
|
||||
# open and close few window to get to a stable point
|
||||
system("echo '$new_window_script' | osascript");
|
||||
|
||||
# dump before data
|
||||
system("heap $pid > $beforefile");
|
||||
|
||||
# run the test
|
||||
system("echo '$new_window_script' | osascript");
|
||||
|
||||
# dump after data
|
||||
system("heap $pid > $afterfile");
|
||||
|
||||
my $result = TinderUtils::wait_for_pid($pid, $timeout_secs);
|
||||
}
|
||||
|
||||
ParseHeapOutput($beforefile, $afterfile);
|
||||
|
||||
return $status;
|
||||
}
|
||||
|
||||
|
||||
sub main {
|
||||
my ($mozilla_build_dir) = @_;
|
||||
|
||||
TinderUtils::print_log("Starting camino build.\n");
|
||||
|
||||
# Tell camino to unbuffer stdio, otherwise when we kill the child process
|
||||
# stdout & stderr won't get flushed.
|
||||
$ENV{MOZ_UNBUFFERED_STDIO} = 1;
|
||||
|
||||
# Pending a config file, stuff things here.
|
||||
my $post_status = 'success'; # Success until we report a failure.
|
||||
my $status = 0; # 0 = success
|
||||
|
||||
# Control tests from here, sorry no config file yet.
|
||||
my $camino_alive_test = 1;
|
||||
my $camino_test8_test = 1;
|
||||
my $camino_layout_performance_test = 1;
|
||||
my $camino_startup_test = 1;
|
||||
my $camino_window_leaks_test = 0;
|
||||
|
||||
my $safari_layout_performance_test = 0;
|
||||
|
||||
my $camino_clean_profile = 1;
|
||||
|
||||
# Build flags
|
||||
my $camino_build_static = 0;
|
||||
my $camino_build_opt = 1;
|
||||
|
||||
my $camino_dir = "$mozilla_build_dir/mozilla/camino";
|
||||
my $embedding_dir = "$mozilla_build_dir/mozilla/embedding/config";
|
||||
my $camino_binary = "Camino";
|
||||
|
||||
unless ($Settings::TestOnly) {
|
||||
# Checkout/update the camino code.
|
||||
$status = checkout($mozilla_build_dir);
|
||||
TinderUtils::print_log("Status from checkout: $status\n");
|
||||
if ($status != 0) {
|
||||
$post_status = 'busted';
|
||||
}
|
||||
|
||||
# Build camino if we passed the checkout command.
|
||||
if ($post_status ne 'busted') {
|
||||
|
||||
#
|
||||
# Build embedding/config.
|
||||
#
|
||||
|
||||
chdir $embedding_dir;
|
||||
|
||||
if ($status == 0) {
|
||||
$status = TinderUtils::run_shell_command("make");
|
||||
TinderUtils::print_log("Status from make: $status\n");
|
||||
}
|
||||
|
||||
#
|
||||
# Build camino.
|
||||
#
|
||||
|
||||
chdir $camino_dir;
|
||||
|
||||
if ($status == 0) {
|
||||
TinderUtils::print_log("Deleting binary...\n");
|
||||
TinderUtils::DeleteBinary("$camino_dir/build/Camino.app/Contents/MacOS/$camino_binary");
|
||||
|
||||
# Always do a clean build; gecko dependencies don't work correctly
|
||||
# for Camino.
|
||||
|
||||
TinderUtils::print_log("Clobbering camino...\n");
|
||||
TinderUtils::run_shell_command("make clean");
|
||||
|
||||
$status = TinderUtils::run_shell_command("make");
|
||||
TinderUtils::print_log("Status from pbxbuild: $status\n");
|
||||
}
|
||||
|
||||
TinderUtils::print_log("Testing build status...\n");
|
||||
if ($status != 0) {
|
||||
TinderUtils::print_log("busted, pbxbuild status non-zero\n");
|
||||
$post_status = 'busted';
|
||||
} elsif (not TinderUtils::BinaryExists("$camino_dir/build/Camino.app/Contents/MacOS/$camino_binary")) {
|
||||
TinderUtils::print_log("Error: binary not found: $camino_dir/build/Camino.app/Contents/MacOS/$camino_binary\n");
|
||||
$post_status = 'busted';
|
||||
} else {
|
||||
$post_status = 'success';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
# Tests...
|
||||
#
|
||||
|
||||
# Clean profile out, if set.
|
||||
# Assume Camino always uses ~/Library/Application Support/Chimera/Profiles/default for now.
|
||||
if ($camino_clean_profile) {
|
||||
# Warning: workaround camino bug, delete whole Camino dir.
|
||||
my $chim_profile_dir = "$ENV{HOME}/Library/Application Support/Chimera";
|
||||
#my $chim_profile_dir = "$ENV{HOME}/Library/Application Support/Chimera/Profiles/default";
|
||||
|
||||
TinderUtils::print_log("Deleting $chim_profile_dir...\n");
|
||||
print "Deleting $chim_profile_dir...\n";
|
||||
File::Path::rmtree([$chim_profile_dir], 0, 0);
|
||||
|
||||
if (-e "$chim_profile_dir") {
|
||||
TinderUtils::print_log("Error: rmtree('$chim_profile_dir') failed\n");
|
||||
}
|
||||
|
||||
# Re-create profile. We have no -CreateProfile, so we instead
|
||||
# run the AliveTest first.
|
||||
}
|
||||
|
||||
# AliveTest for camino, about:blank
|
||||
if ($camino_alive_test and $post_status eq 'success') {
|
||||
|
||||
$post_status = TinderUtils::AliveTest("CaminoAliveTest",
|
||||
"$camino_dir/build/Camino.app/Contents/MacOS",
|
||||
["Camino", "-url", "about:blank"],
|
||||
45);
|
||||
}
|
||||
|
||||
# Find the prefs file, remember we have the secret/random salt dir,
|
||||
# e.g. /Users/cltbld/Library/Application Support/Chimera/Profiles/default/dyrs1ar8.slt/prefs.js
|
||||
# so File::Path::find will find the prefs.js file.
|
||||
#
|
||||
my $pref_file = "prefs.js";
|
||||
my $start_dir = "/Users/cltbld/Library/Application Support/Chimera/Profiles/default";
|
||||
my $found = undef;
|
||||
my $sub = sub {$pref_file = $File::Find::name, $found++ if $pref_file eq $_};
|
||||
|
||||
File::Find::find($sub, $start_dir); # Find prefs.js, write this to $pref_file.
|
||||
|
||||
# Set up performance prefs.
|
||||
if ($pref_file and ($camino_layout_performance_test or 1)) {
|
||||
|
||||
# Some tests need browser.dom.window.dump.enabled set to true, so
|
||||
# that JS dump() will work in optimized builds.
|
||||
if (system("\\grep -s browser.dom.window.dump.enabled $pref_file > /dev/null")) {
|
||||
TinderUtils::print_log("Setting browser.dom.window.dump.enabled\n");
|
||||
open PREFS, ">>$pref_file" or die "can't open $pref_file ($?)\n";
|
||||
print PREFS "user_pref(\"browser.dom.window.dump.enabled\", true);\n";
|
||||
close PREFS;
|
||||
} else {
|
||||
TinderUtils::print_log("Already set browser.dom.window.dump.enabled\n");
|
||||
}
|
||||
|
||||
# Set security prefs to allow us to close our own window,
|
||||
# pageloader test (and possibly other tests) needs this on.
|
||||
if (system("\\grep -s dom.allow_scripts_to_close_windows $pref_file > /dev/null")) {
|
||||
TinderUtils::print_log("Setting dom.allow_scripts_to_close_windows to true.\n");
|
||||
open PREFS, ">>$pref_file" or die "can't open $pref_file ($?)\n";
|
||||
print PREFS "user_pref(\"dom.allow_scripts_to_close_windows\", true);\n";
|
||||
close PREFS;
|
||||
} else {
|
||||
TinderUtils::print_log("Already set dom.allow_scripts_to_close_windows\n");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
# LayoutTest8
|
||||
# resource:///res/samples/test8.html
|
||||
if ($camino_test8_test and $post_status eq 'success') {
|
||||
|
||||
if(0) {
|
||||
open STDOUT, ">/tmp/foo";
|
||||
open STDERR, ">&/tmp/foo";
|
||||
select STDOUT; $| = 1; # make STDOUT unbuffered
|
||||
select STDERR; $| = 1; # make STDERR unbuffered
|
||||
print STDERR "hello, world\n";
|
||||
chdir("$camino_dir/build/Camino.app/Contents/MacOS");
|
||||
exec "./Camino -url \"http://lxr.mozilla.org/seamonkey/source/webshell/tests/viewer/samples/test8.html\"";
|
||||
#exec "foo";
|
||||
} else {
|
||||
$post_status = TinderUtils::AliveTest("CaminoLayoutTest8Test",
|
||||
"$camino_dir/build/Camino.app/Contents/MacOS",
|
||||
["Camino", "-url", "http://lxr.mozilla.org/seamonkey/source/webshell/tests/viewer/samples/test8.html"],
|
||||
20);
|
||||
}
|
||||
}
|
||||
|
||||
# Pageload test.
|
||||
if ($camino_layout_performance_test and $post_status eq 'success') {
|
||||
|
||||
$post_status =
|
||||
TinderUtils::LayoutPerformanceTest("CaminoLayoutPerformanceTest",
|
||||
"$camino_dir/build/Camino.app/Contents/MacOS",
|
||||
["Camino", "-url"]);
|
||||
|
||||
}
|
||||
|
||||
|
||||
# Pageload test -- Safari.
|
||||
if ($safari_layout_performance_test) {
|
||||
|
||||
TinderUtils::run_system_cmd("/Applications/Utilities/Safari.app/Contents/MacOS/Safari-wrap.pl http://$Settings::pageload_server/page-loader/loader.pl?delay=1000%26nocache=0%26maxcyc=4%26timeout=$Settings::LayoutPerformanceTestPageTimeout%26auto=1", 30);
|
||||
|
||||
# This is a hack.
|
||||
TinderUtils::run_system_cmd("sync; sleep 400", 405);
|
||||
|
||||
TinderUtils::run_system_cmd("/Applications/Utilities/Safari.app/Contents/MacOS/Safari-wrap.pl quit", 30);
|
||||
|
||||
TinderUtils::print_log "TinderboxPrint:" .
|
||||
"<a title=\"Avg of the median per url pageload time\" href=\"http://$Settings::results_server/graph/query.cgi?testname=pageload&tbox=" . ::hostname() . "-aux&autoscale=1&days=7&avg=1\">~Tp" . "</a>\n";
|
||||
|
||||
}
|
||||
|
||||
# Startup test.
|
||||
if ($camino_startup_test and $post_status eq 'success') {
|
||||
$post_status =
|
||||
TinderUtils::StartupPerformanceTest("CaminoStartupPerformanceTest",
|
||||
"Camino",
|
||||
"$camino_dir/build/Camino.app/Contents/MacOS",
|
||||
["-url"],
|
||||
"file:$camino_dir/../../../startup-test.html");
|
||||
}
|
||||
|
||||
if ($camino_window_leaks_test and $post_status eq 'success') {
|
||||
$post_status = CaminoWindowLeaksTest("CaminoWindowLeakTest",
|
||||
"$camino_dir/build/Camino.app/Contents/MacOS/",
|
||||
"./Camino",
|
||||
"-url \"http://www.mozilla.org\"",
|
||||
20);
|
||||
|
||||
}
|
||||
|
||||
# Pass our status back to calling script.
|
||||
return $post_status;
|
||||
}
|
||||
|
||||
# Need to end with a true value, (since we're using "require").
|
||||
1;
|
||||
@@ -1,148 +0,0 @@
|
||||
#!/usr/bin/perl
|
||||
#
|
||||
|
||||
#
|
||||
# This script gets called after a full mozilla build & test.
|
||||
# Use this to build and test an embedded or commercial branding of Mozilla.
|
||||
#
|
||||
# ./build-seamonkey-utils.pl will call PostMozilla::main() after
|
||||
# a successful build and testing of mozilla. This package can report
|
||||
# status via the $TinderUtils::build_status variable. Yeah this is a hack,
|
||||
# but it works for now. Feel free to improve this mechanism to properly
|
||||
# return values & stuff. -mcafee
|
||||
#
|
||||
# Things to do:
|
||||
# * Get pull by branch working
|
||||
#
|
||||
#
|
||||
use strict;
|
||||
|
||||
package PostMozilla;
|
||||
|
||||
sub checkout {
|
||||
my ($mozilla_build_dir) = @_;
|
||||
|
||||
# chdir to build directory
|
||||
chdir "$mozilla_build_dir";
|
||||
|
||||
# Hack to get around po/ChangeLog cvs conflict bug in gettext lib.
|
||||
my $status = TinderUtils::run_shell_command("\\rm -f galeon/po/ChangeLog");
|
||||
|
||||
# Checkout galeon source. First set up cvsroot:
|
||||
# Both of these as of 10/2001 are kinda flakey:
|
||||
# $ENV{CVSROOT} = ":pserver:anonymous\@anoncvs.gnome.org:/cvs/gnome";
|
||||
# $ENV{CVSROOT} = ":pserver:anonymous@cvs.galeon.sourceforge.net:/cvsroot/galeon";
|
||||
#
|
||||
# Asked for direct cvs access and got it:
|
||||
$ENV{CVSROOT} = ":pserver:mcafee\@cvs.gnome.org:/cvs/gnome";
|
||||
|
||||
# Next, actually do the checkout:
|
||||
my $status = TinderUtils::run_shell_command("$Settings::CVS checkout galeon");
|
||||
|
||||
# hack in the galeon prefs, if needed
|
||||
|
||||
return $status;
|
||||
}
|
||||
|
||||
|
||||
sub main {
|
||||
my ($mozilla_build_dir) = @_;
|
||||
|
||||
TinderUtils::print_log "Post-Mozilla build goes here.\n";
|
||||
|
||||
# Pending a config file, stuff things here.
|
||||
my $post_status = 'success'; # Success until we report a failure.
|
||||
my $status = 0; # 0 = success
|
||||
my $galeon_alive_test = 1;
|
||||
my $galeon_test8_test = 1;
|
||||
my $galeon_dir = "$mozilla_build_dir/galeon";
|
||||
my $galeon_binary = "galeon-bin";
|
||||
|
||||
# Checkout/update the galeon code.
|
||||
$status = checkout($mozilla_build_dir);
|
||||
TinderUtils::print_log "Status from checkout: $status\n";
|
||||
if ($status != 0) {
|
||||
$post_status = 'busted';
|
||||
}
|
||||
|
||||
# Build galeon if we passed the checkout command.
|
||||
if ($post_status ne 'busted') {
|
||||
# Build galeon.
|
||||
|
||||
chdir $galeon_dir;
|
||||
|
||||
# Make sure we have a configure
|
||||
unless (-e "configure" and $post_status ne 'busted') {
|
||||
$status = TinderUtils::run_shell_command("./autogen.sh");
|
||||
TinderUtils::print_log "Status from autogen: $status\n";
|
||||
}
|
||||
|
||||
# Not sure how to only do this when we need to.
|
||||
# Force a configure for now.
|
||||
if ($status == 0) {
|
||||
TinderUtils::print_log "configuring...\n";
|
||||
$status = TinderUtils::run_shell_command("./configure --sysconfdir=/etc --with-mozilla-libs=$mozilla_build_dir/mozilla/dist/bin --with-mozilla-includes=$mozilla_build_dir/mozilla/dist/include --with-nspr-includes=$mozilla_build_dir/mozilla/dist/include/nspr --with-mozilla-home=$mozilla_build_dir/mozilla/dist/bin");
|
||||
TinderUtils::print_log "Status from configure: $status\n";
|
||||
}
|
||||
|
||||
if ($status == 0) {
|
||||
TinderUtils::print_log "Deleting, gmake...\n";
|
||||
TinderUtils::DeleteBinary("$galeon_dir/src/$galeon_binary");
|
||||
|
||||
my $foo = Cwd::getcwd();
|
||||
TinderUtils::print_log "cwd = $foo\n";
|
||||
$status = TinderUtils::run_shell_command("gmake");
|
||||
TinderUtils::print_log "Status from gmake: $status\n";
|
||||
}
|
||||
|
||||
TinderUtils::print_log "Testing build status...\n";
|
||||
if ($status != 0) {
|
||||
TinderUtils::print_log "busted, gmake status non-zero\n";
|
||||
$post_status = 'busted';
|
||||
} elsif (not TinderUtils::BinaryExists("$galeon_dir/src/$galeon_binary")) {
|
||||
TinderUtils::print_log "Error: binary not found: $galeon_dir/src/$galeon_binary\n";
|
||||
$post_status = 'busted';
|
||||
} else {
|
||||
$post_status = 'success';
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
# Need a way to bypass initial setup dialog stuff, or
|
||||
# we'll need to manually run this by hand the first time.
|
||||
#
|
||||
# Also, have to set crash_recovery=0 in ~/.gnome/galeon to avoid
|
||||
# getting the crash dialog after the alive test times out.
|
||||
#
|
||||
|
||||
# Test galeon, about:blank
|
||||
if ($galeon_alive_test and $post_status eq 'success') {
|
||||
$post_status = TinderUtils::AliveTest("GaleonAliveTest",
|
||||
"$galeon_dir/src",
|
||||
["galeon", "about:blank"],
|
||||
45);
|
||||
}
|
||||
|
||||
# Test galeon, test8
|
||||
if ($galeon_test8_test and $post_status eq 'success') {
|
||||
$post_status = TinderUtils::AliveTest("GaleonTest8Test",
|
||||
"$galeon_dir/src",
|
||||
["galeon", "resource:///res/samples/test8.html"],
|
||||
45);
|
||||
}
|
||||
|
||||
# Startup test
|
||||
if ($galeon_startup_test and $post_status eq 'success') {
|
||||
TinderUtils::StartupPerformanceTest("GaleonStartupPerformanceTest",
|
||||
"galeon",
|
||||
"$galeon_dir/src",
|
||||
["", "$galeon_dir/src/../../../startup-test.html"]);
|
||||
|
||||
}
|
||||
|
||||
# Pass our status back to calling script.
|
||||
return $post_status;
|
||||
}
|
||||
|
||||
# Need to end with a true value, (since we're using "require").
|
||||
1;
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,338 +0,0 @@
|
||||
|
||||
#!d:/nstools/bin/perl5
|
||||
|
||||
use Cwd;
|
||||
|
||||
$build_depend=1; #depend or clobber
|
||||
$build_tree = '';
|
||||
$build_tag = '';
|
||||
$build_name = '';
|
||||
$build_continue = 0;
|
||||
$build_sleep=10;
|
||||
$no32 = 0;
|
||||
$original_path = $ENV{'PATH'};
|
||||
$early_exit = 1;
|
||||
$doawt11 = 0;
|
||||
|
||||
$do_clobber = '';
|
||||
$client_param = '';
|
||||
|
||||
&parse_args;
|
||||
|
||||
if( $build_test ){
|
||||
$build_sleep=1;
|
||||
}
|
||||
|
||||
$dirname = ($build_depend?'dep':'clob');
|
||||
|
||||
|
||||
$logfile = "${dirname}.log";
|
||||
|
||||
if( $build_depend ){
|
||||
$clobber_str = 'depend';
|
||||
}
|
||||
else {
|
||||
$clobber_str = 'clobber_all';
|
||||
}
|
||||
|
||||
|
||||
mkdir("$dirname", 0777);
|
||||
chdir("$dirname") || die "couldn't cd to $dirname";
|
||||
|
||||
$start_dir = cwd;
|
||||
$start_dir =~ s/\//\\/ ;
|
||||
$last_time = 0;
|
||||
|
||||
print "starting dir is: $start_dir\n";
|
||||
|
||||
while( $early_exit ){
|
||||
chdir("$start_dir");
|
||||
if( time - $last_time < (60 * $build_sleep) ){
|
||||
$sleep_time = (60 * $build_sleep) - (time - $last_time);
|
||||
print "\n\nSleeping $sleep_time seconds ...\n";
|
||||
sleep( $sleep_time );
|
||||
}
|
||||
$last_time = time;
|
||||
|
||||
$start_time = time;
|
||||
$start_time = adjust_start_time($start_time);
|
||||
$start_time_str = `unix_date +"%m/%d/%Y %H:%M"`;
|
||||
chop($start_time_str);
|
||||
# call setup_env here in the loop, to update MOZ_DATE with each pass.
|
||||
# setup_env uses start_time_str for MOZ_DATE.
|
||||
&setup_env;
|
||||
|
||||
$cur_dir = cwd;
|
||||
$cur_dir =~ s/\//\\/ ;
|
||||
|
||||
if( $cur_dir ne $start_dir ){
|
||||
print "startdir: $start_dir, curdir $cur_dir\n";
|
||||
die "curdir != startdir";
|
||||
}
|
||||
|
||||
if ($build_test) {
|
||||
$early_exit = 0; # stops this while loop after one pass.
|
||||
}
|
||||
|
||||
# strip_conf fails to strip any variables from the real environemnt
|
||||
# &strip_config;
|
||||
&do_build(1,$do_clobber);
|
||||
# &restore_config;
|
||||
|
||||
}
|
||||
|
||||
sub setup32 {
|
||||
local ($awt) = @_;
|
||||
|
||||
$ENV{"MOZ_BITS"} = '32';
|
||||
$ENV{"WINOS"} = 'WINNT';
|
||||
$ENV{"STANDALONE_IMAGE_LIB"} = '1';
|
||||
$ENV{"MODULAR_NETLIB"} = '1';
|
||||
$ENV{"OS_TARGET"} = 'WIN95';
|
||||
$ENV{"PATH"} = $original_path;
|
||||
$ENV{"_MSC_VER"} = '1200';
|
||||
$moz_src = $ENV{'MOZ_SRC'} = $start_dir;
|
||||
$build_name = 'Win32 VC6.0' . ($build_depend?'Depend':'Clobber');
|
||||
$do_clobber = $clobber_str;
|
||||
$logname = "win32.log";
|
||||
}
|
||||
|
||||
|
||||
sub do_build {
|
||||
local ($pull, $do_clobber) = @_;
|
||||
|
||||
print "pull = $pull, do_clobber = $do_clobber\n";
|
||||
&start_build;
|
||||
|
||||
print "opening log file ${logname}\n";
|
||||
open( LOG, ">${logname}" ) || print "can't open $logname\n";
|
||||
print LOG "current dir is: $cur_dir\n";
|
||||
|
||||
&print_env;
|
||||
$build_status = 0;
|
||||
if( $pull ){
|
||||
if ( $build_tag eq '' ){
|
||||
# print LOG "cvs -d %MOZ_CVSROOT% co -A mozilla/config 2>&1 |\n";
|
||||
# open( PULL, "cvs -d %MOZ_CVSROOT% co -A mozilla/config 2>&1 |") || print "couldn't execute cvs\n";;
|
||||
print LOG "cvs -d $moz_cvsroot co -A mozilla/client.mak 2>&1 |\n";
|
||||
open( PULL, "cvs -d $moz_cvsroot co -A mozilla/client.mak 2>&1 |") || print "couldn't execute cvs\n";;
|
||||
} else{
|
||||
print LOG "cvs -d $moz_cvsroot co -A -r $build_tag mozilla/config 2>&1 |\n";
|
||||
open( PULL, "cvs -d $moz_cvsroot co -A -r $build_tag mozilla/config 2>&1 |") || print "couldn't execute cvs\n";;
|
||||
print LOG "cvs -d $moz_cvsroot co -A -r $build_tag mozilla/client.mak 2>&1 |\n";
|
||||
open( PULL, "cvs -d $moz_cvsroot co -A -r $build_tag mozilla/client.mak 2>&1 |") || print "couldn't execute cvs\n";;
|
||||
}
|
||||
|
||||
# tee the output
|
||||
while( <PULL> ){
|
||||
print $_;
|
||||
print LOG $_;
|
||||
}
|
||||
close( PULL );
|
||||
|
||||
$build_status = $?;
|
||||
}
|
||||
|
||||
chdir("$moz_src/mozilla") || die "couldn't chdir to '$moz_src/mozilla'";
|
||||
|
||||
# if( $do_clobber ne '' ){
|
||||
# print LOG "nmake -f client.mak $do_clobber |\n";
|
||||
# print "nmake -f client.mak $do_clobber |\n";
|
||||
# open( CLOBBER, "nmake -f client.mak $do_clobber 2>&1 |") || print "couldn't execute nmake\n";;
|
||||
|
||||
# tee the output
|
||||
# while( <CLOBBER> ){
|
||||
# print $_;
|
||||
# print LOG $_;
|
||||
# }
|
||||
# close( CLOBBER );
|
||||
# }
|
||||
|
||||
|
||||
if (!$pull) {
|
||||
$client_param = $do_clobber . ' build_all';
|
||||
}
|
||||
else {
|
||||
$client_param = 'pull_all ' . $do_clobber . ' build_all';
|
||||
}
|
||||
|
||||
print LOG "nmake -f client.mak $client_param 2>&1 |\n";
|
||||
open( BUILD, "nmake -f client.mak $client_param 2>&1 |");
|
||||
|
||||
# tee the output
|
||||
while( <BUILD> ){
|
||||
print $_;
|
||||
print LOG $_;
|
||||
}
|
||||
close( BUILD );
|
||||
$build_status |= $?;
|
||||
$build_status_str = ( $build_status ? 'busted' : 'success' );
|
||||
|
||||
print LOG "\n";
|
||||
print LOG "tinderbox: tree: $build_tree\n";
|
||||
print LOG "tinderbox: builddate: $start_time\n";
|
||||
print LOG "tinderbox: status: $build_status_str\n";
|
||||
print LOG "tinderbox: build: $build_name\n";
|
||||
print LOG "tinderbox: errorparser: windows\n";
|
||||
print LOG "tinderbox: buildfamily: windows\n";
|
||||
|
||||
close( LOG );
|
||||
chdir("$start_dir");
|
||||
system( "$nstools\\bin\\blat ${logname} -t tinderbox-daemon\@cvs-mirror.mozilla.org" );
|
||||
|
||||
# we should save at least one log back
|
||||
system("copy ${logname} last-${logname}");
|
||||
}
|
||||
|
||||
sub cvs_time {
|
||||
local( $ret_time );
|
||||
|
||||
($sec,$minute,$hour,$mday,$mon,$year) = localtime( $_[0] );
|
||||
$mon++; # month is 0 based.
|
||||
|
||||
sprintf("%02d/%02d/%04d %02d:%02d:00",
|
||||
$mon,$mday,$year,$hour,$minute );
|
||||
}
|
||||
|
||||
|
||||
sub start_build {
|
||||
open( LOG, ">logfile" );
|
||||
print LOG "\n";
|
||||
print LOG "tinderbox: tree: $build_tree\n";
|
||||
print LOG "tinderbox: builddate: $start_time\n";
|
||||
print LOG "tinderbox: status: building\n";
|
||||
print LOG "tinderbox: build: $build_name\n";
|
||||
print LOG "tinderbox: errorparser: windows\n";
|
||||
print LOG "tinderbox: buildfamily: windows\n";
|
||||
print LOG "\n";
|
||||
close( LOG );
|
||||
system("$nstools\\bin\\blat logfile -t tinderbox-daemon\@cvs-mirror.mozilla.org" );
|
||||
}
|
||||
|
||||
sub parse_args {
|
||||
local($i);
|
||||
|
||||
if( @ARGV == 0 ){
|
||||
&usage;
|
||||
}
|
||||
$i = 0;
|
||||
while( $i < @ARGV ){
|
||||
if( $ARGV[$i] eq '--depend' ){
|
||||
$build_depend = 1;
|
||||
}
|
||||
elsif ( $ARGV[$i] eq '--clobber' ){
|
||||
$build_depend = 0;
|
||||
}
|
||||
elsif ( $ARGV[$i] eq '--continue' ){
|
||||
$build_continue = 1;
|
||||
}
|
||||
elsif ( $ARGV[$i] eq '--test' ){
|
||||
$build_test = 1;
|
||||
}
|
||||
elsif ( $ARGV[$i] eq '-tag' ){
|
||||
$i++;
|
||||
$build_tag = $ARGV[$i];
|
||||
if( $build_tag eq '' || $build_tag eq '-t'){
|
||||
&usage;
|
||||
}
|
||||
}
|
||||
elsif ( $ARGV[$i] eq '-t' ){
|
||||
$i++;
|
||||
$build_tree = $ARGV[$i];
|
||||
if( $build_tree eq '' ){
|
||||
&usage;
|
||||
}
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
if( $build_tree eq '' ){
|
||||
&usage;
|
||||
}
|
||||
}
|
||||
|
||||
sub usage {
|
||||
die "usage: buildit.pl [--depend | --clobber] [--continue] [--test] [-tag TAGNAME] -t TREENAME\n";
|
||||
}
|
||||
|
||||
sub setup_env {
|
||||
local($p);
|
||||
|
||||
# $ENV{"MOZ_DEBUG"} = '1';
|
||||
$ENV{"MOZ_MFC"} = '1';
|
||||
$ENV{"CVSROOT"} = ':pserver:cltbld%netscape.com@cvs.mozilla.org:/cvsroot';
|
||||
$moz_cvsroot = $ENV{"CVSROOT"};
|
||||
# $ENV{"MOZ_EDITOR"} = '1';
|
||||
$ENV{"VERBOSE"} = '1';
|
||||
$ENV{"NGLAYOUT_PLUGINS"} = '1';
|
||||
$nstools = $ENV{"MOZ_TOOLS"};
|
||||
if( $nstools eq '' ){
|
||||
print "warning: environment variable MOZ_TOOLS not set\n";
|
||||
$ENV{"MOZ_TOOLS"} = 'C:\nstools';
|
||||
$nstools = $ENV{"MOZ_TOOLS"};
|
||||
print "using MOZ_TOOLS = $nstools \n";
|
||||
|
||||
}
|
||||
# $msdev = $ENV{"MOZ_MSDEV"} = 'c:\msdev';
|
||||
# if( $msdev eq '' ){
|
||||
# die "error: environment variable MOZ_MSDEV not set\n";
|
||||
# }
|
||||
# $msvc = $ENV{"MOZ_MSVC"} = 'c:\msvc';
|
||||
# if( $msvc eq '' ){
|
||||
# die "error: environment variable MOZ_VC not set\n";
|
||||
# }
|
||||
if ( $build_tag ne '' ) {
|
||||
$ENV{"MOZ_BRANCH"} = $build_tag;
|
||||
}
|
||||
$moz_src = $ENV{"MOZ_SRC"} = $start_dir;
|
||||
# $ENV{"INCLUDE"}='c:\devstudio\vc\lib;C:\DevStudio\VC\INCLUDE;C:\DevStudio\VC\MFC\INCLUDE;C:\DevStudio\VC\lib;C:\DevStudio\VC\ATL\INCLUDE';
|
||||
# $ENV{"LIB"}='C:\DevStudio\VC\MFC\LIB;C:\DevStudio\VC\lib';
|
||||
# $ENV{"PATH"}='C:\DevStudio\SharedIDE\BIN;C:\DevStudio\VC\bin;C:\DevStudio\VC\lib;C:\DevStudio\VC\BIN\WINNT;.;%MOZ_TOOLS%\perl5\bin;C:\WINNT\system32;C:\WINNT;c:\usr\local\bin;%MOZ_TOOLS%\bin';
|
||||
##
|
||||
## We should pull by date to avoid mid-checkin disasters
|
||||
##
|
||||
$ENV{"MOZ_DATE"} = $start_time_str;
|
||||
|
||||
&setup32
|
||||
}
|
||||
|
||||
sub print_env {
|
||||
local( $k, $v);
|
||||
print LOG "\nEnvironment\n";
|
||||
print "\nEnvironment\n";
|
||||
for $k (sort keys %ENV){
|
||||
$v = $ENV{$k};
|
||||
print LOG " $k=$v\n";
|
||||
print " $k=$v\n";
|
||||
}
|
||||
print LOG "\n";
|
||||
print "\n";
|
||||
system 'set';
|
||||
}
|
||||
|
||||
sub strip_config {
|
||||
$save_compname=$ENV{"COMPUTERNAME"};
|
||||
$save_userdomain=$ENV{"USERDOMAIN"};
|
||||
$save_username=$ENV{"USERNAME"};
|
||||
$save_userprofile=$ENV{"USERPROFILE"};
|
||||
}
|
||||
|
||||
sub restore_config {
|
||||
$ENV{"COMPUTERNAME"}=$save_compname;
|
||||
$ENV{"USERDOMAIN"}=$save_userdomain;
|
||||
$ENV{"USERNAME"}=$save_username;
|
||||
$ENV{"MSDevDir"}=$save_userprofile;
|
||||
&print_env;
|
||||
}
|
||||
|
||||
sub adjust_start_time {
|
||||
# Allows the start time to match up with the update times of a mirror.
|
||||
my ($start_time) = @_;
|
||||
|
||||
# Since we are not pulling for cvs-mirror anymore, just round times
|
||||
# to 1 minute intervals to make them nice and even.
|
||||
my $cycle = 1 * 60; # Updates every 1 minutes.
|
||||
my $begin = 0 * 60; # Starts 0 minutes after the hour.
|
||||
my $lag = 0 * 60; # Takes 0 minute to update.
|
||||
return int(($start_time - $begin - $lag) / $cycle) * $cycle + $begin;
|
||||
}
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
require 5.003;
|
||||
|
||||
# This script has split some functions off into a util
|
||||
# script so they can be re-used by other scripts.
|
||||
require "build-seamonkey-util.pl";
|
||||
|
||||
use strict;
|
||||
|
||||
# "use strict" complains if we do not define these.
|
||||
# They are not initialized here. The default values are after "__END__".
|
||||
$TreeSpecific::name = $TreeSpecific::checkout_target = $TreeSpecific::checkout_clobber_target = $::Version = undef;
|
||||
|
||||
$::Version = '$Revision: 1.100 $ ';
|
||||
|
||||
{
|
||||
TinderUtils::Setup();
|
||||
tree_specific_overides();
|
||||
TinderUtils::Build();
|
||||
}
|
||||
|
||||
# End of main
|
||||
#======================================================================
|
||||
|
||||
|
||||
|
||||
sub tree_specific_overides {
|
||||
|
||||
$TreeSpecific::name = 'mozilla';
|
||||
$TreeSpecific::checkout_target = '';
|
||||
$TreeSpecific::checkout_clobber_target = "checkout realclean build";
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
# Turning on security
|
||||
#
|
||||
ac_add_options --enable-crypto
|
||||
#
|
||||
# Add all extensions
|
||||
#
|
||||
ac_add_options --enable-extensions=all
|
||||
#
|
||||
# Optimized
|
||||
#
|
||||
ac_add_options --enable-optimize
|
||||
ac_add_options --disable-debug
|
||||
#
|
||||
# Bloat stats/optimized needs these:
|
||||
#
|
||||
#ac_add_options --enable-logrefcnt
|
||||
#ac_add_options --enable-perf-metrics
|
||||
#
|
||||
@@ -1,38 +0,0 @@
|
||||
#- tinder-config.pl - Tinderbox configuration file.
|
||||
#- Uncomment the variables you need to set.
|
||||
#- The default values are the same as the commented variables
|
||||
|
||||
#- PLEASE FILL THIS IN WITH YOUR PROPER EMAIL ADDRESS
|
||||
$BuildAdministrator = 'mcafee@mocha.com';
|
||||
|
||||
#- You'll need to change these to suit your machine's needs
|
||||
$DisplayServer = ':0.0'; # costarica:0.0
|
||||
|
||||
#- Until you get the script working. When it works,
|
||||
#- change to the tree you're actually building
|
||||
$BuildTree = 'MozillaTest';
|
||||
#$BuildTree = 'SeaMonkey';
|
||||
|
||||
$AliveTest = 1;
|
||||
$ViewerTest = 0;
|
||||
$BloatTest = 0;
|
||||
$BloatTest2 = 0;
|
||||
$DomToTextConversionTest = 0;
|
||||
$EmbedTest = 0;
|
||||
$MailNewsTest = 0;
|
||||
$LayoutPerformanceTest = 0;
|
||||
$StartupPerformanceTest = 0;
|
||||
|
||||
$MozProfileName = "default";
|
||||
$BloatTestTimeout = 240; # seconds
|
||||
$LayoutPerformanceTestTimeout = 1400; # seconds
|
||||
$StartupPerformanceTestTimeout = 60; # seconds
|
||||
|
||||
# Testing...
|
||||
# $TestOnly = 1;
|
||||
# $ObjDir = 'obj-i686-unknown-linux-gnu';
|
||||
|
||||
$UserComment = "Sample tinder-config.pl, changeme!";
|
||||
|
||||
# Need to end with a true value
|
||||
1;
|
||||
@@ -1,63 +0,0 @@
|
||||
#- tinder-config.pl - Tinderbox configuration file.
|
||||
#- Uncomment the variables you need to set.
|
||||
#- The default values are the same as the commented variables.
|
||||
|
||||
#- PLEASE FILL THIS IN WITH YOUR PROPER EMAIL ADDRESS
|
||||
$BuildAdministrator = "mcafee\@netscape.com";
|
||||
|
||||
#- You'll need to change these to suit your machine's needs
|
||||
$DisplayServer = 'costarica.mcom.com:0.0';
|
||||
|
||||
#- Default values of command-line opts
|
||||
#-
|
||||
$BuildDepend = 1; # Depend or Clobber
|
||||
$ReportStatus = 1; # Send results to server, or not
|
||||
$ReportFinalStatus = 1; # Finer control over $ReportStatus.
|
||||
$UseTimeStamp = 0; # Use the CVS 'pull-by-timestamp' option, or not
|
||||
#$BuildOnce = 0; # Build once, don't send results to server
|
||||
#$RunTest = 1; # Run the smoke tests on successful build, or not
|
||||
#$TestOnly = 0; # Only run tests, don't pull/build
|
||||
|
||||
# Tests
|
||||
$AliveTest = 1;
|
||||
$ViewerTest = 1;
|
||||
$BloatTest = 1;
|
||||
$DomToTextConversionTest = 1;
|
||||
$MailNewsTest = 0;
|
||||
#$MozConfigFileName = 'mozconfig';
|
||||
#$MozProfileName = 'default';
|
||||
$BloatTestTimeout = 240;
|
||||
$DomTestTimeout = 45;
|
||||
|
||||
#- Set these to what makes sense for your system
|
||||
$Make = 'gmake'; # Must be GNU make
|
||||
#$MakeOverrides = '';
|
||||
$mail = '/bin/mail';
|
||||
$CVS = 'cvs -q';
|
||||
$CVSCO = 'checkout -P';
|
||||
|
||||
#- Set these proper values for your tinderbox server
|
||||
$Tinderbox_server = 'tinderbox-daemon@tinderbox.mozilla.org';
|
||||
|
||||
#-
|
||||
#- The rest should not need to be changed
|
||||
#-
|
||||
|
||||
#- Minimum wait period from start of build to start of next build in minutes.
|
||||
#$BuildSleep = 10;
|
||||
|
||||
#- Until you get the script working. When it works,
|
||||
#- change to the tree you're actually building
|
||||
$BuildTree = 'SeaMonkey-Branch';
|
||||
|
||||
#$BuildName = '';
|
||||
$BuildTag = 'MOZILLA_0_9_1_BRANCH';
|
||||
#$BuildConfigDir = 'mozilla/config';
|
||||
#$Topsrcdir = 'mozilla';
|
||||
#$BinaryName = 'mozilla-bin';
|
||||
#$ShellOverride = ''; # Only used if the default shell is too stupid
|
||||
#$ConfigureArgs = '';
|
||||
#$ConfigureEnvArgs = '';
|
||||
#$Compiler = 'gcc';
|
||||
#$NSPRArgs = '';
|
||||
#$ShellOverride = '';
|
||||
@@ -1,73 +0,0 @@
|
||||
#!/usr/bin/perl
|
||||
#
|
||||
# Use high resolution routines if installed (on win32 or linux), using
|
||||
# eval as try/catch block around import of modules. Otherwise, just use 'time()'.
|
||||
#
|
||||
# 'Win32::API' <http://www.activestate.com/PPMPackages/zips/5xx-builds-only/Win32-API.zip>
|
||||
# 'Time::HiRes' <http://search.cpan.org/search?dist=Time-HiRes>
|
||||
# (also: http://rpmfind.net/linux/rpm2html/search.php?query=perl-Time-HiRes)
|
||||
#
|
||||
package Time::PossiblyHiRes;
|
||||
|
||||
use strict;
|
||||
|
||||
#use Time::HiRes qw(gettimeofday);
|
||||
|
||||
my $getLocalTime; # for win32
|
||||
my $lpSystemTime = pack("SSSSSSSS"); # for win32
|
||||
my $timesub; # code ref
|
||||
|
||||
# returns 12 char string "'s'x9.'m'x3" which is milliseconds since epoch,
|
||||
# although resolution may vary depending on OS and installed packages
|
||||
|
||||
sub getTime () {
|
||||
|
||||
return &$timesub
|
||||
if $timesub;
|
||||
|
||||
$timesub = sub { time() . "000"; }; # default
|
||||
|
||||
return &$timesub
|
||||
if $^O eq "MacOS"; # don't know a better way on Mac
|
||||
|
||||
if ($^O eq "MSWin32") {
|
||||
eval "use Win32::API;";
|
||||
$timesub = sub {
|
||||
# pass pointer to struct, void return
|
||||
$getLocalTime =
|
||||
eval "new Win32::API('kernel32', 'GetLocalTime', [qw{P}], qw{V});"
|
||||
unless $getLocalTime;
|
||||
$getLocalTime->Call($lpSystemTime);
|
||||
my @t = unpack("SSSSSSSS", $lpSystemTime);
|
||||
sprintf("%9s%03s", time(), pop @t);
|
||||
} if !$@;
|
||||
}
|
||||
|
||||
# ass-u-me if not mac/win32, then we're on a unix flavour
|
||||
else {
|
||||
eval "use Time::HiRes qw(gettimeofday);";
|
||||
$timesub = sub {
|
||||
my @t = gettimeofday();
|
||||
$t[0]*1000 + int($t[1]/1000);
|
||||
} if !$@;
|
||||
}
|
||||
|
||||
return &$timesub;
|
||||
|
||||
}
|
||||
|
||||
#
|
||||
#
|
||||
# Test script to compare with low-res time:
|
||||
#
|
||||
# require "gettime.pl";
|
||||
#
|
||||
# use POSIX qw(strftime);
|
||||
#
|
||||
# print "hires time = " . Time::PossiblyHiRes::getTime() . "\n";
|
||||
# print "lowres time = " . time() . "\n";
|
||||
#
|
||||
|
||||
|
||||
# end package
|
||||
1;
|
||||
@@ -1,14 +0,0 @@
|
||||
#! /bin/csh -f
|
||||
|
||||
#
|
||||
# Create links to install tinderbox stuff.
|
||||
#
|
||||
|
||||
ln -s ../mozilla/tools/tinderbox/tinderbox
|
||||
ln -s ../mozilla/tools/tinderbox/build-seamonkey.pl
|
||||
ln -s ../mozilla/tools/tinderbox/build-seamonkey-util.pl
|
||||
ln -s ../mozilla/tools/tinderbox/gettime.pl
|
||||
ln -s ../mozilla/tools/tinderbox/bloatdiff.pl
|
||||
ln -s ../mozilla/tools/tinderbox/tinder-defaults.pl
|
||||
ln -s ../mozilla/tools/tinderbox/reportdata.pl
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
#!/usr/bin/perl
|
||||
# vim:sw=4:et:ts=4:ai:
|
||||
|
||||
use strict;
|
||||
|
||||
sub PrintUsage() {
|
||||
die <<END_USAGE
|
||||
usage: $0 [options]
|
||||
Options:
|
||||
--example-config Instead of running, print an example
|
||||
'multi-config.pl' to help get started.
|
||||
END_USAGE
|
||||
}
|
||||
|
||||
sub PrintExample() {
|
||||
print <<END_EXAMPLE
|
||||
# multi-config.pl
|
||||
\$BuildSleep = 10; # minutes
|
||||
\$Tinderboxes = [ { tree => "SeaMonkey", args => "--depend --mozconfig mozconfig" }, { tree => "SeaMonkey-Branch", args => "--depend --mozconfig mozconfig" } ];
|
||||
END_EXAMPLE
|
||||
;
|
||||
exit;
|
||||
}
|
||||
|
||||
sub HandleArgs() {
|
||||
return if ($#ARGV == -1);
|
||||
PrintUsage() if ($#ARGV != 0 || $ARGV[0] ne "--example-config");
|
||||
PrintExample();
|
||||
}
|
||||
|
||||
sub LoadConfig() {
|
||||
if (-r 'multi-config.pl') {
|
||||
no strict 'vars';
|
||||
|
||||
open CONFIG, 'multi-config.pl' or
|
||||
print "can't open multi-config.pl, $?\n";
|
||||
|
||||
while (<CONFIG>) {
|
||||
package Settings;
|
||||
eval;
|
||||
}
|
||||
|
||||
close CONFIG;
|
||||
} else {
|
||||
warn "Error: Need tinderbox config file, multi-config.pl\n";
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sub Run() {
|
||||
my $start_time = 0;
|
||||
while (1) {
|
||||
# $BuildSleep is the minimum amount of time a build is allowed to take.
|
||||
# It prevents sending too many messages to the tinderbox server when
|
||||
# something is broken.
|
||||
my $sleep_time = ($Settings::BuildSleep * 60) - (time() - $start_time);
|
||||
if ($sleep_time > 0) {
|
||||
print "\n\nSleeping $sleep_time seconds ...\n";
|
||||
sleep $sleep_time;
|
||||
}
|
||||
$start_time = time();
|
||||
|
||||
foreach my $treeentry (@{$Settings::Tinderboxes}) {
|
||||
chdir($treeentry->{tree}) or
|
||||
die "Tree $treeentry->{tree} does not exist";
|
||||
system("./build-seamonkey.pl --once $treeentry->{args}");
|
||||
chdir("..");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HandleArgs();
|
||||
LoadConfig();
|
||||
Run();
|
||||
@@ -1,179 +0,0 @@
|
||||
#!/usr/bin/perl
|
||||
#
|
||||
|
||||
#
|
||||
# This script gets called after a full mozilla build & test.
|
||||
# Use this to build and test an embedded or commercial branding of Mozilla.
|
||||
#
|
||||
# Edit, and rename this file to post-mozilla.pl to activate.
|
||||
# ./build-seamonkey-utils.pl will call PostMozilla::main() after
|
||||
# a successful build and testing of mozilla. This package can report
|
||||
# status via the $TinderUtils::build_status variable. Yeah this is a hack,
|
||||
# but it works for now. Feel free to improve this mechanism to properly
|
||||
# return values & stuff. -mcafee
|
||||
#
|
||||
# Contributors:
|
||||
# leaf@mozilla.org - release processing/packaging/uploading
|
||||
|
||||
# Assumptions:
|
||||
# no objdir
|
||||
# ssh-agent running or empty passphrase RSA key
|
||||
#
|
||||
|
||||
use strict;
|
||||
|
||||
package PostMozilla;
|
||||
|
||||
sub print_log {
|
||||
my ($text) = @_;
|
||||
print LOG $text;
|
||||
print $text;
|
||||
}
|
||||
|
||||
# Cache builds in a dated directory if:
|
||||
# * The hour of the day is $Settings::build_hour or higher
|
||||
# (set in tinder-config.pl)
|
||||
# -and-
|
||||
# * the "last-built" file indicates a day before today's date
|
||||
#
|
||||
sub cacheit {
|
||||
my ($c_hour, $c_yday, $target_hour, $last_build_day) = @_;
|
||||
TinderUtils::print_log "current hour = $c_hour\n";
|
||||
TinderUtils::print_log "target hour = $target_hour\n";
|
||||
TinderUtils::print_log "current julian day = $c_yday\n";
|
||||
TinderUtils::print_log "last build julian day = $last_build_day\n";
|
||||
if (($c_hour > $target_hour) &&
|
||||
(($last_build_day < $c_yday) || ($c_yday == 0))) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
sub returnStatus{
|
||||
# build-anvil-util.pl expects an array, if no package is uploaded,
|
||||
# a single-element array with 'busted', 'testfailed', or 'success' works.
|
||||
my ($logtext, @status) = @_;
|
||||
TinderUtils::print_log "$logtext\n";
|
||||
return @status;
|
||||
}
|
||||
|
||||
sub pushit {
|
||||
my ($ssh_server,$upload_path,$upload_target) = @_;
|
||||
# need to convert the path in case we're using activestate perl
|
||||
# check for platform
|
||||
#my $upload_target_dos = `cygpath -w $upload_target`;
|
||||
#chop($upload_target_dos);
|
||||
|
||||
unless ( -e $upload_target) {
|
||||
TinderUtils::print_log "No $upload_target to upload\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
#for leaf
|
||||
TinderUtils::run_shell_command "ssh -1 -i /home/leaf/.ssh/cltbld/.ssh/identity -l cltbld $ssh_server mkdir -p $upload_path";
|
||||
TinderUtils::run_shell_command "scp -i /home/leaf/.ssh/cltbld/.ssh/identity -oProtocol=1 -r $upload_target cltbld\@$ssh_server:$upload_path";
|
||||
TinderUtils::run_shell_command "ssh -1 -i /home/leaf/.ssh/cltbld/.ssh/identity -l cltbld $ssh_server chmod -R 755 $upload_path/$upload_target";
|
||||
|
||||
# for cltbld
|
||||
#TinderUtils::run_shell_command "ssh -1 -l cltbld $ssh_server mkdir -p $upload_path";
|
||||
#TinderUtils::run_shell_command "scp -oProtocol=1 $upload_target cltbld\@$ssh_server:$upload_path";
|
||||
#TinderUtils::run_shell_command "ssh -1 -l cltbld $ssh_server chmod -R 755 $upload_path";
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub process_talkback {
|
||||
# this is where we
|
||||
# * generate a master.ini
|
||||
# * upload symbol-files
|
||||
# * shove talkback files into dist for packaging.
|
||||
#
|
||||
|
||||
}
|
||||
|
||||
sub make_packages {
|
||||
my ($build_dir, $build_date) = @_;
|
||||
my $save_dir = `pwd`;
|
||||
|
||||
#DEBUG_LEAF
|
||||
print_log "current directory is $save_dir\n";
|
||||
print_log "cd to $build_dir/$Settings::Topsrcdir/xpinstall\n";
|
||||
#end DEBUG_LEAF
|
||||
|
||||
chdir "$build_dir/$Settings::Topsrcdir/xpinstall";
|
||||
$ENV{"INSTALLER_URL"} = "http://ftp.mozilla.org/pub/mozilla.org/pub/mozilla/tinderbox-builds/$build_date";
|
||||
system "make installer";
|
||||
# if ($DEBUG_LEAF) {
|
||||
print_log "post |make installer|\n";
|
||||
# DEBUG_LEAF
|
||||
chdir $save_dir;
|
||||
|
||||
}
|
||||
|
||||
sub push_to_stage {
|
||||
my ($build_dir, $build_date) = @_;
|
||||
my $save_dir = `pwd`;
|
||||
chdir "$build_dir/$Settings::Topsrcdir/installer";
|
||||
mkdir $build_date;
|
||||
system "cp sea/* $build_date";
|
||||
system "cp stub/* $build_date";
|
||||
system "cp -r raw/xpi $build_date/linux-xpi";
|
||||
pushit ("stage.mozilla.org", "/home/ftp/pub/mozilla/tinderbox-builds", $build_date);
|
||||
chdir $save_dir;
|
||||
|
||||
}
|
||||
|
||||
sub pad_digit {
|
||||
my ($digit) = @_;
|
||||
if ($digit < 10) { return "0" . $digit };
|
||||
return $digit;
|
||||
}
|
||||
|
||||
sub main {
|
||||
# Get build directory from caller.
|
||||
my ($mozilla_build_dir) = @_;
|
||||
|
||||
#
|
||||
# (0: $sec, 1: $min, 2: $hour, 3: $mday, 4: $mon, 5: $year,
|
||||
# 6: $wday, 7: $yday, 8: $isdst)
|
||||
my ($hour, $mday, $mon, $year, $yday) = (localtime (time)) [2,3,4,5,7];
|
||||
$year = $year + 1900;
|
||||
$mon = $mon + 1;
|
||||
$hour = pad_digit ($hour);
|
||||
$mday = pad_digit ($mday);
|
||||
$mon = pad_digit ($mon);
|
||||
my $build_date = "$year-$mon-$mday-$hour";
|
||||
#
|
||||
my $last_build_day = -1;
|
||||
if ( -e "$mozilla_build_dir/last-built"){
|
||||
($last_build_day) = (localtime((stat "$mozilla_build_dir/last-built")[9]))[7];
|
||||
}
|
||||
|
||||
print_log "build dir is $mozilla_build_dir \n";
|
||||
TinderUtils::print_log "Post-Mozilla build goes here.\n";
|
||||
|
||||
# someday, we'll have talkback
|
||||
#process_talkback;
|
||||
|
||||
make_packages ($mozilla_build_dir, $build_date);
|
||||
if (cacheit($hour, $yday, "8", $last_build_day)) {
|
||||
push_to_stage ($mozilla_build_dir, $build_date);
|
||||
unlink "$mozilla_build_dir/last-built";
|
||||
open BLAH, ">$mozilla_build_dir/last-built";
|
||||
close BLAH;
|
||||
}
|
||||
|
||||
# Report some kind of status to parent script.
|
||||
#
|
||||
# {'busted', 'testfailed', 'success'}
|
||||
#
|
||||
|
||||
# Report a fake success, for example's sake.
|
||||
# Eventually return an array
|
||||
&returnStatus (('success'));
|
||||
}
|
||||
|
||||
# Need to end with a true value, (since we're using "require").
|
||||
1;
|
||||
@@ -1,46 +0,0 @@
|
||||
#!/usr/bin/perl
|
||||
#
|
||||
|
||||
#
|
||||
# This script gets called after a full mozilla build & test.
|
||||
# Use this to build and test an embedded or commercial branding of Mozilla.
|
||||
#
|
||||
# Edit, and rename this file to post-mozilla.pl to activate.
|
||||
# ./build-seamonkey-utils.pl will call PostMozilla::main() after
|
||||
# a successful build and testing of mozilla. This package can report
|
||||
# status via the $TinderUtils::build_status variable. Yeah this is a hack,
|
||||
# but it works for now. Feel free to improve this mechanism to properly
|
||||
# return values & stuff. -mcafee
|
||||
#
|
||||
|
||||
use strict;
|
||||
|
||||
package PostMozilla;
|
||||
|
||||
|
||||
sub main {
|
||||
# Get build directory from caller.
|
||||
my ($mozilla_build_dir) = @_;
|
||||
|
||||
|
||||
TinderUtils::print_log "Post-Mozilla build goes here.\n";
|
||||
|
||||
#
|
||||
# Build script goes here.
|
||||
#
|
||||
|
||||
# Report some kind of status to parent script.
|
||||
#
|
||||
# {'busted', 'testfailed', 'success'}
|
||||
#
|
||||
|
||||
# Report a fake success, for example's sake.
|
||||
# we return a list because sometimes we pass back a status *and*
|
||||
# a url to a binary location, e.g.:
|
||||
# return ('success', 'http://upload.host.org/path/to/binary');
|
||||
# tinderbox processes the binary url and links to it in the log.
|
||||
return ('success');
|
||||
}
|
||||
|
||||
# Need to end with a true value, (since we're using "require").
|
||||
1;
|
||||
@@ -1,362 +0,0 @@
|
||||
#!/usr/bin/perl -w
|
||||
# -*- Mode: perl; indent-tabs-mode: nil -*-
|
||||
#
|
||||
###################################################################
|
||||
# Report Summary Generator for ARMS v2.0 by Vladimir Ermakov
|
||||
###################################################################
|
||||
# This file parses through a results file and generates a
|
||||
# test summary giving the following info:
|
||||
# # of tcs passed
|
||||
# # of tcs failed
|
||||
# # of tcs died
|
||||
# % of pass and fail
|
||||
# List of testcases that failed.
|
||||
# Separates the results into suites with a convinient quick link
|
||||
# at the top of the page
|
||||
###################################################################
|
||||
# Questions Coments go to vladimire@netscape.com
|
||||
###################################################################
|
||||
|
||||
sub PrintUsage {
|
||||
die <<END_USAGE
|
||||
usage: $0 <filename> ["express"]
|
||||
END_USAGE
|
||||
}
|
||||
|
||||
if ($#ARGV < 0) {
|
||||
PrintUsage();
|
||||
}
|
||||
|
||||
my $DATAFILE = $ARGV[0];
|
||||
my $MODE;
|
||||
|
||||
if($#ARGV > 0) {
|
||||
$MODE = $ARGV[1];
|
||||
} else {
|
||||
$MODE = "";
|
||||
}
|
||||
|
||||
my $express = 0;
|
||||
|
||||
if($MODE eq "express") {
|
||||
$express = 1;
|
||||
}
|
||||
|
||||
my $ngdir = "http://geckoqa.mcom.com/ngdriver/"; #$input->url(-base=>1) . "/ngdriver/";
|
||||
my $ngsuites = $ngdir . "suites/";
|
||||
my $conffile = "ngdriver.conf";
|
||||
my $HTMLreport = "";
|
||||
|
||||
unless ($express) {
|
||||
print "Content-type: text/html\n\n";
|
||||
}
|
||||
|
||||
&generateResults;
|
||||
|
||||
$File{'SuiteList'} = \@suiteArray;
|
||||
|
||||
&generateHTML;
|
||||
|
||||
$File{'Project'} = "Buffy";
|
||||
|
||||
print $HTMLreport;
|
||||
|
||||
sub generateResults
|
||||
{
|
||||
if (!open(INFILE,$DATAFILE)) {
|
||||
print "DATAFILE = $DATAFILE\n";
|
||||
print "<H3> Cannot open $?, $!</H3>\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
$File{'tcsPass'} = 0;
|
||||
$File{'tcsFail'} = 0;
|
||||
$File{'tcsDied'} = 0;
|
||||
$File{'tcsTotal'} = 0;
|
||||
|
||||
$line = <INFILE>;
|
||||
while ($line) {
|
||||
my %Suite = ();
|
||||
|
||||
my @diedArray = ();
|
||||
$Suite{'DiedList'} = \@diedArray;
|
||||
my @testArray = ();
|
||||
$Suite{'FailedList'} = \@testArray;
|
||||
|
||||
# Skip to first anchor.
|
||||
while (!($line =~ /<A NAME=".*?">/i) && $line) {
|
||||
$line = <INFILE>; # Go to next line.
|
||||
}
|
||||
|
||||
# First anchor.
|
||||
$line =~ /<A NAME="(.*?)"><H1>(.*?)<\/H1>/i;
|
||||
|
||||
|
||||
my $name = $1;
|
||||
my $title =$2;
|
||||
|
||||
$Suite{'Name'} = $name;
|
||||
$Suite{'Title'} = $title;
|
||||
|
||||
$Suite{'tcsPass'} = 0;
|
||||
$Suite{'tcsFail'} = 0;
|
||||
$Suite{'tcsDied'} = 0;
|
||||
$Suite{'tcsTotal'} = 0;
|
||||
|
||||
do
|
||||
{
|
||||
while ($line && !($line =~ /<TC>/i) && !($line =~ /<A name=".*?">/i)) {
|
||||
$line = <INFILE>;
|
||||
}
|
||||
|
||||
if ($line && ($line =~ /<A name=\"(.*?)\">/i) && ($1 eq $Suite{'Name'})) {
|
||||
$line = <INFILE>;
|
||||
}
|
||||
|
||||
# TC = test case.
|
||||
if ($line && ($line =~ /<TC>/i)) {
|
||||
while ($line && !($line =~ /<ENDTC>/i)) {
|
||||
$line1 = <INFILE>;
|
||||
if ($line1 =~ /<TC>/i) {
|
||||
print "<H1>SOMETHING WRONG!</H1><BR>"; next; next;
|
||||
}
|
||||
$line .= $line1;
|
||||
}
|
||||
|
||||
my ($tfName, $tcStat);
|
||||
my @lines = split /<->/, $line;
|
||||
$tfName = $lines[1];
|
||||
$tcStat = $lines[3];
|
||||
|
||||
# D=died, P=pass, F=failure
|
||||
if ($tcStat eq 'D') {
|
||||
$Suite{'tcsDied'} += 1;
|
||||
push(@diedArray,$line);
|
||||
}
|
||||
if ($tcStat eq 'P') {
|
||||
$Suite{'tcsPass'} += 1;
|
||||
$Suite{'tcsTotal'} += 1;
|
||||
}
|
||||
if ($tcStat eq 'F') {
|
||||
push(@testArray,$line);
|
||||
$Suite{'tcsFail'} += 1;
|
||||
$Suite{'tcsTotal'} += 1;
|
||||
}
|
||||
$line = <INFILE>;
|
||||
}
|
||||
} while ($line && !($line =~ /<A NAME=".*?">/i) && $line);
|
||||
|
||||
$File{'tcsPass'} += $Suite{'tcsPass'};
|
||||
$File{'tcsFail'} += $Suite{'tcsFail'};
|
||||
$File{'tcsTotal'} += $Suite{'tcsTotal'};
|
||||
$File{'tcsDied'} += $Suite{'tcsDied'};
|
||||
push(@suiteArray,\%Suite);
|
||||
}
|
||||
close INFILE;
|
||||
1;
|
||||
}
|
||||
|
||||
sub generateHTML
|
||||
{
|
||||
my $prjExtension;
|
||||
my %extList;
|
||||
|
||||
my $os = `uname -s`; # Cheap OS id for now
|
||||
|
||||
my %Matrices;
|
||||
|
||||
# Hard-coded from ngdriver.conf, I didn't want extra files in tree.
|
||||
|
||||
$extList{"mb"} = "http://cemicrobrowser.web.aol.com/bugReportDetail.php?RID=%";
|
||||
$extList{"bs"} = "http://bugscape.nscp.aoltw.net/show_bug.cgi?id=%";
|
||||
$extList{"bz"} = "http://bugzilla.mozilla.org/show_bug.cgi?id=%";
|
||||
$extList{"bzx"} = "http://bugzilla.mozilla.org/show_bug.cgi?id=%";
|
||||
|
||||
$prjExtension = "bz"; # Buffy hard-coded here.
|
||||
|
||||
$Matricies{"dom-core"} = "http://geckoqa.mcom.com/browser/standards/dom1/tcmatrix/index.html";
|
||||
$Matricies{"dom-html"} = "http://geckoqa.mcom.com/browser/standards/dom1/tcmatrix/index.html";
|
||||
$Matricies{"domevents"} = "http://geckoqa.mcom.com/browser/standards/dom1/tcmatrix/index.html";
|
||||
$Matricies{"javascript"} = "http://geckoqa.mcom.com/browser/standards/javascript/tcmatrix/index.html";
|
||||
$Matricies{"forms"} = "http://geckoqa.mcom.com/browser/standards/form_submission/tcmatrix/index.html";
|
||||
$Matricies{"formsec"} = "http://geckoqa.mcom.com/browser/standards/form_submission/tcmatrix/index.html";
|
||||
|
||||
unless ($express) {
|
||||
$HTMLreport .= <<END_PRINT;
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>Test Result Summary on $File{'Platform'}</title>
|
||||
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<center><u><font color="#990000"><h3>AUTOMATED TEST RESULTS</h3></font></u></center><br>
|
||||
<center>
|
||||
<table border="0" cols="3" width="90%">
|
||||
<tbody>
|
||||
<tr align="Left" valign="CENTER">
|
||||
<td width="250" valign="Middle"><b>OS: </b><font color="#990000">$os</script></font></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</center>
|
||||
<hr>
|
||||
<h3><u>The Following Test Suites Were Run:</u></h3>
|
||||
<UL>
|
||||
END_PRINT
|
||||
|
||||
for (my $var = 0;$File{'SuiteList'}->[$var]->{'Name'};$var++) {
|
||||
if (my $href = $Matrices{$File{'SuiteList'}->[$var]->{'Name'}}) {
|
||||
$HTMLreport .= "<li><a href=\"$href\">$File{'SuiteList'}->[$var]->{'Title'}</a></li>\n";
|
||||
} else {
|
||||
$HTMLreport .= "<li><a href=\"$ngsuites$File{'SuiteList'}->[$var]->{'Name'}\">$File{'SuiteList'}->[$var]->{'Title'}</a></li>\n";
|
||||
}
|
||||
}
|
||||
|
||||
$HTMLreport .= <<END_PRINT;
|
||||
</UL>
|
||||
|
||||
<h3><u>Test Result Summary:</u></h3>
|
||||
END_PRINT
|
||||
} # !express
|
||||
|
||||
|
||||
$HTMLreport .= <<END_PRINT;
|
||||
<table border=2 cellspacing=0>
|
||||
<tr valign=top bgcolor=#CCCCCC>
|
||||
<td bgcolor=#999999> </td>
|
||||
<td>Passed</td>
|
||||
<td>Failed</td>
|
||||
<td>Total</td>
|
||||
<td>Died</td>
|
||||
<td>% Passed</td>
|
||||
<td>% Failed</td>
|
||||
</tr>
|
||||
END_PRINT
|
||||
|
||||
for (my $var = 0;$File{'SuiteList'}->[$var]->{'Name'};$var++) {
|
||||
$curSuite = $File{'SuiteList'}->[$var];
|
||||
|
||||
$HTMLreport .= "<tr valign=top>\n";
|
||||
if($express) {
|
||||
$HTMLreport .= "<td>$curSuite->{'Title'}</td>\n";
|
||||
} else {
|
||||
$HTMLreport .= "<td bgcolor=#cccccc><a href=\"#$curSuite->{'Name'}\">$curSuite->{'Title'}</a></td>\n";
|
||||
}
|
||||
$HTMLreport .= "<td>$File{'SuiteList'}->[$var]->{'tcsPass'}</td>\n";
|
||||
$HTMLreport .= "<td>$File{'SuiteList'}->[$var]->{'tcsFail'}</td>\n";
|
||||
$HTMLreport .= "<td>$File{'SuiteList'}->[$var]->{'tcsTotal'}</td>\n";
|
||||
$HTMLreport .= "<td>${@{$File{'SuiteList'}}[$var]}{'tcsDied'}</td>\n";
|
||||
|
||||
my $pctPass = $File{'SuiteList'}->[$var]->{'tcsPass'} / $File{'SuiteList'}->[$var]->{'tcsTotal'};
|
||||
$pctPass = int($pctPass*10000)/100;
|
||||
|
||||
$HTMLreport .= "<td>$pctPass</td>\n";
|
||||
|
||||
my $pctFail = $File{'SuiteList'}->[$var]->{'tcsFail'} / $File{'SuiteList'}->[$var]->{'tcsTotal'};
|
||||
$pctFail = int($pctFail*10000)/100;
|
||||
|
||||
$HTMLreport .= "<td>$pctFail</td>\n";
|
||||
$HTMLreport .= "</tr>\n";
|
||||
}
|
||||
|
||||
$HTMLreport .= <<END_PRINT;
|
||||
<tr valign=top bgcolor=#FFFFCC>
|
||||
<td>Total:</td>
|
||||
<td>$File{'tcsPass'}</td>
|
||||
<td>$File{'tcsFail'}</td>
|
||||
<td>$File{'tcsTotal'}</td>
|
||||
<td>$File{'tcsDied'}</td>
|
||||
END_PRINT
|
||||
my $pctPass = $File{'tcsPass'} / $File{'tcsTotal'};
|
||||
$pctPass = int($pctPass*10000)/100;
|
||||
my $pctFail = $File{'tcsFail'} / $File{'tcsTotal'};
|
||||
$pctFail = int($pctFail*10000)/100;
|
||||
|
||||
$HTMLreport .= <<END_PRINT;
|
||||
<td>$pctPass</td>
|
||||
<td>$pctFail</td>
|
||||
</tr>
|
||||
</table>
|
||||
END_PRINT
|
||||
|
||||
unless ($express) {
|
||||
$HTMLreport .= <<END_PRINT;
|
||||
<h3>Failed Testcases:</h3>
|
||||
END_PRINT
|
||||
|
||||
my $curSuite;
|
||||
for (my $var=0;$File{'SuiteList'}->[$var]->{'Name'};$var++) {
|
||||
$curSuite = $File{'SuiteList'}->[$var];
|
||||
|
||||
$HTMLreport .= <<END_PRINT;
|
||||
<hr>
|
||||
<h2>
|
||||
<a NAME="$curSuite->{'Name'}"></a><u><font color="#666600">$curSuite->{'Title'}</font></u></h2>
|
||||
<b><u>Died:</u></b>
|
||||
<table>
|
||||
END_PRINT
|
||||
|
||||
for (my $dcnt = 0;$curFile = $File{'SuiteList'}->[$var]->{'DiedList'}->[$dcnt];$dcnt++) {
|
||||
($none,$fName) = split(/<->/,$curFile);
|
||||
$HTMLreport .= "<tr><td style=\"color: red;\"><A href='$ngsuites$curSuite->{'Name'}/$fName' target=\"new\">$fName</A></td></tr>\n";
|
||||
}
|
||||
|
||||
$HTMLreport .= "</table><BR>\n";
|
||||
$HTMLreport .= "<b><u>Failures:</u></b><br>";
|
||||
$HTMLreport .= "<table BORDER CELLSPACING=0><TR>\n";
|
||||
|
||||
for ($fcnt = 0;$curFile = $File{'SuiteList'}->[$var]->{'FailedList'}->[$fcnt];$fcnt++) {
|
||||
($none,$fName,$fDesc,$fStat,$fBug,$fExpected,$fActual) = split(/<->/,$curFile);
|
||||
$HTMLreport.= "<TR><TD><A href=\"$ngsuites$curSuite->{'Name'}/$fName\" target=\"_new\">$fName</A></TD><TD>";
|
||||
|
||||
# Quiet perl warnings about unused variables.
|
||||
my $tmp; $tmp = $fStat; $tmp = $fActual; $tmp = $fExpected;
|
||||
|
||||
#
|
||||
# TEMPRORAY DISABLED.
|
||||
#
|
||||
my @bugList = split(/[\s+]|,/,$fBug);
|
||||
my $bug = "";
|
||||
my $index = 0;
|
||||
|
||||
while ($bugList[$index]) {
|
||||
if ($bugList[$index] =~ /(\d+)$prjExtension/i) {
|
||||
$bugList[$index] =~ s/(\d+)($prjExtension)/makelink($1,$extList{$2})/ige;
|
||||
$bug .= $bugList[$index];
|
||||
}
|
||||
|
||||
$index++;
|
||||
}
|
||||
$HTMLreport.= "$bug</TD><TD>$fDesc</TD></TR>\n";
|
||||
|
||||
# $fBug =~ s/(\d+)($prjExtension)/makelink($1,$extList{$2})/ige;
|
||||
# $HTMLreport.= "$fBug</TD><TD>$fDesc</TD></TR>\n";
|
||||
|
||||
}
|
||||
$HTMLreport .= "</table>\n";
|
||||
}
|
||||
|
||||
$HTMLreport .= <<END_PRINT;
|
||||
</BODY>
|
||||
</HTML>
|
||||
END_PRINT
|
||||
} # !express
|
||||
|
||||
1;
|
||||
}
|
||||
|
||||
sub makelink
|
||||
{
|
||||
$bugNum = $_[0];
|
||||
$bugLnk = $_[1];
|
||||
|
||||
|
||||
$bugLnk =~ s/%/$bugNum/ig;
|
||||
$bugLnk = "<A href=\"$bugLnk\">$bugNum</A>";
|
||||
|
||||
return $bugLnk;
|
||||
}
|
||||
|
||||
1;
|
||||
@@ -1,165 +0,0 @@
|
||||
#!/usr/bin/perl
|
||||
# -*- Mode: perl; indent-tabs-mode: nil -*-
|
||||
|
||||
#
|
||||
# Graph tree-open status, via tbox graph server.
|
||||
#
|
||||
|
||||
|
||||
# Location of this file. Make sure that hand-runs and crontab-runs
|
||||
# of this script read/write the same data.
|
||||
my $script_dir = "/builds/tinderbox/mozilla/tools/tinderbox";
|
||||
|
||||
my $graph_server = "coffee";
|
||||
|
||||
# Send data to graph server via HTTP.
|
||||
require "$script_dir/reportdata.pl";
|
||||
|
||||
use Sys::Hostname; # for ::hostname()
|
||||
|
||||
sub PrintUsage {
|
||||
die <<END_USAGE
|
||||
Usage:
|
||||
|
||||
$0 <ip or hostname>
|
||||
|
||||
END_USAGE
|
||||
}
|
||||
|
||||
|
||||
# Return true if httpd server is up.
|
||||
sub is_http_alive() {
|
||||
my $url = "http://$ARGV[0]";
|
||||
|
||||
my $rv = 0; # Assume false.
|
||||
|
||||
my $res =
|
||||
eval q{
|
||||
use LWP::UserAgent;
|
||||
use HTTP::Request;
|
||||
my $ua = LWP::UserAgent->new;
|
||||
$ua->timeout(10); # seconds
|
||||
|
||||
my $req = HTTP::Request->new(GET => $url);
|
||||
my $res = $ua->request($req);
|
||||
return $res;
|
||||
};
|
||||
if ($@) {
|
||||
warn "GET Failed: $@";
|
||||
#print "GET Failed.\n";
|
||||
} else {
|
||||
# Debug.
|
||||
#print "GET Succeeded: \n";
|
||||
#print "status:\n", $res->status_line, "\n";
|
||||
#print "content:\n", $res->content, "\n";
|
||||
#print "GET Succeeded.\n";
|
||||
|
||||
# This will be non-zero if http get went through ok.
|
||||
if($res->content) {
|
||||
$rv = 1;
|
||||
} else {
|
||||
$rv = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return $rv;
|
||||
}
|
||||
|
||||
|
||||
|
||||
# main
|
||||
{
|
||||
my $alive_time = 0; # Hours http has been up.
|
||||
my $alive = 0;
|
||||
my $timefile = "$script_dir/http_alive_timefiles/$ARGV[0]";
|
||||
|
||||
|
||||
# make sure directory exists
|
||||
unless (-d $timefile) {
|
||||
mkdir "$script_dir/http_alive_timefiles";
|
||||
}
|
||||
|
||||
PrintUsage() if $#ARGV == -1;
|
||||
|
||||
$alive = is_http_alive();
|
||||
|
||||
if ($alive) {
|
||||
print "$ARGV[0] is alive\n";
|
||||
|
||||
#
|
||||
# Record alive time.
|
||||
#
|
||||
|
||||
# Was zero before, report zero here, write out the
|
||||
# time for next cycle.
|
||||
if (not (-e "$timefile")) {
|
||||
print "no timefile found.\n";
|
||||
open TIMEFILE, ">$timefile";
|
||||
print TIMEFILE time();
|
||||
close TIMEFILE;
|
||||
} else {
|
||||
# Timefile found, compute difference and report that number.
|
||||
print "found timefile: $timefile!\n";
|
||||
|
||||
my $time_http_started = 0;
|
||||
my $now = 0;
|
||||
|
||||
open TIMEFILE, "$timefile";
|
||||
while (<TIMEFILE>) {
|
||||
chomp;
|
||||
$time_http_started = $_;
|
||||
}
|
||||
close TIMEFILE;
|
||||
print "time_http_started = $time_http_started\n";
|
||||
|
||||
$now = time();
|
||||
print "now = $now\n";
|
||||
|
||||
# Report time in hours.
|
||||
$alive_time = ($now - $time_http_started)/3600;
|
||||
print "alive_time (hours) = $alive_time\n";
|
||||
|
||||
# Clamp time to 20 hours so we don't get huge spikes for
|
||||
# extended open times (weekends)
|
||||
if ($alive_time > 20.0) {
|
||||
$alive_time = 20.0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
print "$ARGV[0] is not responding.\n";
|
||||
|
||||
# Delete timefile if there is one.
|
||||
if (-e "$timefile") {
|
||||
unlink("$timefile");
|
||||
}
|
||||
}
|
||||
|
||||
# Shorten some machine names.
|
||||
my $short_name = "$ARGV[0]";
|
||||
$short_name =~ s/.websys.aol.com//g;
|
||||
|
||||
ReportData::send_results_to_server($graph_server,
|
||||
"$alive_time",
|
||||
::hostname(),
|
||||
"http_alive",
|
||||
"$ARGV[0]");
|
||||
|
||||
my $status = "";
|
||||
if($alive) {
|
||||
$status = "success";
|
||||
} else {
|
||||
$status = "busted";
|
||||
}
|
||||
|
||||
# Hard-coded for now.
|
||||
my $graph_url = "http://$graph_server/graph/query.cgi?tbox=$ARGV[0]&testname=http_alive&autoscale=&size=&days=7&units=hours<ype=&points=&avg=&showpoint=";
|
||||
|
||||
ReportData::send_tbox_packet("tinderbox-daemon\@warp.mcom.com",
|
||||
"Talkback",
|
||||
$status,
|
||||
"TinderboxPrint:<a title=\"Hours httpd:80 has been alive.\" href=\"$graph_url\">Ta</a>",
|
||||
"$ARGV[0]",
|
||||
"$short_name HTTP Alive Test");
|
||||
}
|
||||
@@ -1,160 +0,0 @@
|
||||
#!/usr/bin/perl
|
||||
# -*- Mode: perl; indent-tabs-mode: nil -*-
|
||||
|
||||
#
|
||||
# Graph tree-open status, via tbox graph server.
|
||||
#
|
||||
|
||||
# Location of this file. Make sure that hand-runs and crontab-runs
|
||||
# of this script read/write the same data.
|
||||
my $script_dir = "/builds/tinderbox/mozilla/tools/tinderbox";
|
||||
|
||||
# Send data to graph server via HTTP.
|
||||
require "$script_dir/reportdata.pl";
|
||||
|
||||
use Sys::Hostname; # for ::hostname()
|
||||
|
||||
my $sheriff_string;
|
||||
|
||||
sub is_tree_open {
|
||||
my $tbox_url = "http://tinderbox.mozilla.org/showbuilds.cgi?tree=SeaMonkey";
|
||||
|
||||
# Dump tbox page source into a file.
|
||||
print "HTTP...";
|
||||
system ("wget", "-q", "-O", "$script_dir/tbox.source", $tbox_url);
|
||||
print "done\n";
|
||||
|
||||
my $rv = 0;
|
||||
|
||||
$sheriff_string = "";
|
||||
|
||||
# Scan file, looking for line that starts with <a NAME="open">
|
||||
open TBOX_FILE, "$script_dir/tbox.source";
|
||||
while (<TBOX_FILE>) {
|
||||
# Scan for open string
|
||||
if(/^<a NAME="open">/) {
|
||||
# look for "open" string
|
||||
if (/open<\/font>$/) {
|
||||
print "open\n";
|
||||
$rv = 1;
|
||||
} else {
|
||||
print "closed\n";
|
||||
$rv = 0;
|
||||
}
|
||||
}
|
||||
|
||||
# Scan for sheriff string & save it off for HTTP submit later.
|
||||
if(/^<br><a NAME="sheriff"><\/a>/) {
|
||||
chomp;
|
||||
$sheriff_string = $_;
|
||||
|
||||
# Strip out content to save space.
|
||||
|
||||
# Strip out permanent content.
|
||||
$sheriff_string =~ s/^<br><a NAME="sheriff"><\/a>//;
|
||||
|
||||
# Crude attempt at reducing the random html that shows up here.
|
||||
# Order is important, pick off easy tags, then make it legal cgi,
|
||||
# then shorten it up.
|
||||
$sheriff_string =~ s/<[pP]>//g;
|
||||
$sheriff_string =~ s/\015//g; # ^M
|
||||
$sheriff_string =~ s/<br>//g;
|
||||
$sheriff_string =~ s/<\/a>//g;
|
||||
$sheriff_string =~ s/<//g;
|
||||
$sheriff_string =~ s/>//g;
|
||||
$sheriff_string =~ s/"/ /g;
|
||||
$sheriff_string =~ s/\///g;
|
||||
$sheriff_string =~ s/\\//g;
|
||||
$sheriff_string =~ s/#/[lb]/g;
|
||||
$sheriff_string =~ s/mailto://g;
|
||||
$sheriff_string =~ s/[aA][iI][mM]://g;
|
||||
$sheriff_string =~ s/[iI][rR][cC]://g;
|
||||
$sheriff_string =~ s/a href//g;
|
||||
$sheriff_string =~ s/[sS]heriff//g;
|
||||
$sheriff_string =~ s/[mM]onday//g;
|
||||
$sheriff_string =~ s/[tT]uesday//g;
|
||||
$sheriff_string =~ s/[wW]ednesday//g;
|
||||
$sheriff_string =~ s/[tT]hursday//g;
|
||||
$sheriff_string =~ s/[fF]riday//g;
|
||||
$sheriff_string =~ s/[wW]eekend//g;
|
||||
$sheriff_string =~ s/^[tT]he //g;
|
||||
$sheriff_string =~ s/\/a//g;
|
||||
$sheriff_string =~ s/netscape.com/nscp/g;
|
||||
$sheriff_string =~ s/mozilla.org/moz/g;
|
||||
$sheriff_string =~ s/ is / /g;
|
||||
$sheriff_string =~ s/ for / /g;
|
||||
$sheriff_string =~ s/ on / /g;
|
||||
$sheriff_string =~ s/ in / /g;
|
||||
$sheriff_string =~ s/ = / /g;
|
||||
$sheriff_string =~ s/ - / /g;
|
||||
|
||||
$sheriff_string = substr($sheriff_string,0,60);
|
||||
print "sheriff string = $sheriff_string\n";
|
||||
}
|
||||
}
|
||||
close TBOX_FILE;
|
||||
|
||||
# Clean up.
|
||||
unlink("$script_dir/tbox.source");
|
||||
|
||||
return $rv;
|
||||
}
|
||||
|
||||
|
||||
# main
|
||||
{
|
||||
my $time_since_open = 0;
|
||||
my $timefile = "$script_dir/treeopen_timefile";
|
||||
|
||||
# Get tree status.
|
||||
if(is_tree_open()) {
|
||||
|
||||
# Record tree open time if not set.
|
||||
if (not (-e "$timefile")) {
|
||||
open TIMEFILE, ">$timefile";
|
||||
print TIMEFILE time();
|
||||
close TIMEFILE;
|
||||
} else {
|
||||
# Timefile found, compute difference and report that number.
|
||||
print "found timefile: $timefile!\n";
|
||||
|
||||
my $time_tree_opened = 0;
|
||||
my $now = 0;
|
||||
|
||||
open TIMEFILE, "$timefile";
|
||||
while (<TIMEFILE>) {
|
||||
chomp;
|
||||
$time_tree_opened = $_;
|
||||
}
|
||||
close TIMEFILE;
|
||||
print "time_tree_opened = $time_tree_opened\n";
|
||||
|
||||
$now = time();
|
||||
print "now = $now\n";
|
||||
|
||||
# Report time in hours.
|
||||
$time_since_open = ($now - $time_tree_opened)/3600;
|
||||
print "time_since_open (hours) = $time_since_open\n";
|
||||
|
||||
# Clamp time to 20 hours so we don't get huge spikes for
|
||||
# extended open times (weekends)
|
||||
if($time_since_open > 20.0) {
|
||||
$time_since_open = 20.0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
# tree is closed, leave tree_open_time at zero.
|
||||
|
||||
# Delete timefile if there is one.
|
||||
if (-e "$timefile") {
|
||||
unlink("$timefile");
|
||||
}
|
||||
}
|
||||
|
||||
ReportData::send_results_to_server("tegu.mozilla.org",
|
||||
"$time_since_open",
|
||||
"$sheriff_string",
|
||||
"treeopen", ::hostname());
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
#!/usr/bin/perl
|
||||
# -*- Mode: perl; indent-tabs-mode: nil -*-
|
||||
|
||||
|
||||
#
|
||||
# Utils used by tests to send data to graph server, or tinderbox.
|
||||
#
|
||||
|
||||
require 5.003;
|
||||
|
||||
use strict;
|
||||
|
||||
$::Version = '$Revision: 1.3 $ ';
|
||||
|
||||
package ReportData;
|
||||
|
||||
# Send data to graph cgi via HTTP.
|
||||
sub send_results_to_server {
|
||||
my ($server, $value, $data, $testname, $tbox) = @_;
|
||||
|
||||
my $tmpurl = "http://$server/graph/collect.cgi";
|
||||
$tmpurl .= "?value=$value&data=$data&testname=$testname&tbox=$tbox";
|
||||
|
||||
print "send_results_to_server(): \n";
|
||||
print "tmpurl = $tmpurl\n";
|
||||
|
||||
# libwww-perl has process control problems on windows,
|
||||
# spawn wget instead.
|
||||
if ($Settings::OS =~ /^WIN/) {
|
||||
system ("wget", "-o", "/dev/null", $tmpurl);
|
||||
print "send_results_to_server() succeeded.\n";
|
||||
} else {
|
||||
my $res = eval q{
|
||||
use LWP::UserAgent;
|
||||
use HTTP::Request;
|
||||
my $ua = LWP::UserAgent->new;
|
||||
$ua->timeout(10); # seconds
|
||||
my $req = HTTP::Request->new(GET => $tmpurl);
|
||||
my $res = $ua->request($req);
|
||||
return $res;
|
||||
};
|
||||
if ($@) {
|
||||
warn "Failed to submit startup results: $@";
|
||||
print "send_results_to_server() failed.\n";
|
||||
} else {
|
||||
print "Results submitted to server: \n",
|
||||
$res->status_line, "\n", $res->content, "\n";
|
||||
print "send_results_to_server() succeeded.\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Fake a tinderbox message.
|
||||
sub send_tbox_packet {
|
||||
my ($server_email, $tree, $status,
|
||||
$log, $machine, $build_name) = @_;
|
||||
|
||||
my $foo;
|
||||
|
||||
my $now = time();
|
||||
|
||||
$foo .= <<END_PRINT;
|
||||
tinderbox: tree: $tree
|
||||
tinderbox: builddate: $now
|
||||
tinderbox: status: $status
|
||||
tinderbox: build: $build_name
|
||||
tinderbox: errorparser: unix
|
||||
tinderbox: buildfamily: unix
|
||||
tinderbox: END
|
||||
END_PRINT
|
||||
|
||||
$foo .= $log;
|
||||
|
||||
print "foo = \n$foo\n";
|
||||
|
||||
open MSG, ">msg.$machine";
|
||||
print MSG $foo;
|
||||
close MSG;
|
||||
|
||||
system "/bin/mail $server_email " . "< msg.$machine";
|
||||
|
||||
|
||||
unlink "msg.$machine";
|
||||
}
|
||||
@@ -1,170 +0,0 @@
|
||||
#- PLEASE FILL THIS IN WITH YOUR PROPER EMAIL ADDRESS
|
||||
#$BuildAdministrator = "$ENV{USER}\@$ENV{HOST}";
|
||||
$BuildAdministrator = ($ENV{USER} || "cltbld") . "\@" . ($ENV{HOST} || "dhcp");
|
||||
|
||||
#- You'll need to change these to suit your machine's needs
|
||||
$DisplayServer = ':0.0';
|
||||
|
||||
#- Default values of command-line opts
|
||||
#-
|
||||
$BuildDepend = 1; # Depend or Clobber
|
||||
$BuildDebug = 0; # Debug or Opt (Darwin)
|
||||
$ReportStatus = 1; # Send results to server, or not
|
||||
$ReportFinalStatus = 1; # Finer control over $ReportStatus.
|
||||
$UseTimeStamp = 1; # Use the CVS 'pull-by-timestamp' option, or not
|
||||
$BuildOnce = 0; # Build once, don't send results to server
|
||||
$TestOnly = 0; # Only run tests, don't pull/build
|
||||
$BuildEmbed = 0; # After building seamonkey, go build embed app.
|
||||
$SkipMozilla = 0; # Use to debug post-mozilla.pl scripts.
|
||||
|
||||
# Tests
|
||||
$CleanProfile = 0;
|
||||
$ResetHomeDirForTests = 1;
|
||||
$ProductName = "Mozilla";
|
||||
|
||||
$RunMozillaTests = 1; # Allow turning off of all tests if needed.
|
||||
$RegxpcomTest = 1;
|
||||
$AliveTest = 1;
|
||||
$JavaTest = 0;
|
||||
$ViewerTest = 0;
|
||||
$BloatTest = 0; # warren memory bloat test
|
||||
$BloatTest2 = 0; # dbaron memory bloat test, require tracemalloc
|
||||
$DomToTextConversionTest = 0;
|
||||
$XpcomGlueTest = 0;
|
||||
$CodesizeTest = 0; # Z, require mozilla/tools/codesighs
|
||||
$EmbedCodesizeTest = 0; # mZ, require mozilla/tools/codesigns
|
||||
$MailBloatTest = 0;
|
||||
$EmbedTest = 0; # Assumes you wanted $BuildEmbed=1
|
||||
$LayoutPerformanceTest = 0; # Tp
|
||||
$QATest = 0;
|
||||
$XULWindowOpenTest = 0; # Txul
|
||||
$StartupPerformanceTest = 0; # Ts
|
||||
|
||||
# Release Build options
|
||||
# requires an appropriate post-mozilla.pl
|
||||
$ReleaseBuild = 0; # Make a release build?
|
||||
$package_creation_path = "mozilla/xpinstall/packager";
|
||||
$package_location = "mozilla/dist/install";
|
||||
$ftp_path = "/home/ftp/pub/mozilla/tinderbox-builds";
|
||||
$url_path = "http://ftp.mozilla.org/pub/mozilla.org/mozilla/tinderbox-builds";
|
||||
$build_hour = "8";
|
||||
$ssh_server = "stage.mozilla.org";
|
||||
$ssh_user = "cltbld";
|
||||
|
||||
# end Release Build options
|
||||
|
||||
$TestsPhoneHome = 0; # Should test report back to server?
|
||||
$results_server = "axolotl.mozilla.org"; # was tegu
|
||||
$pageload_server = "spider"; # localhost
|
||||
|
||||
#
|
||||
# Timeouts, values are in seconds.
|
||||
#
|
||||
|
||||
$CreateProfileTimeout = 45;
|
||||
$RegxpcomTestTimeout = 15;
|
||||
|
||||
$AliveTestTimeout = 45;
|
||||
$ViewerTestTimeout = 45;
|
||||
$EmbedTestTimeout = 45;
|
||||
$BloatTestTimeout = 120; # seconds
|
||||
$MailBloatTestTimeout = 120; # seconds
|
||||
$JavaTestTimeout = 45;
|
||||
$DomTestTimeout = 45; # seconds
|
||||
$XpcomGlueTestTimeout = 15;
|
||||
$CodesizeTestTimeout = 900; # seconds
|
||||
$CodesizeTestType = "auto"; # {"auto"|"base"}
|
||||
$LayoutPerformanceTestTimeout = 1200; # entire test, seconds
|
||||
$QATestTimeout = 1200; # entire test, seconds
|
||||
$LayoutPerformanceTestPageTimeout = 30000; # each page, ms
|
||||
$StartupPerformanceTestTimeout = 60; # seconds
|
||||
$XULWindowOpenTestTimeout = 150; # seconds
|
||||
|
||||
|
||||
$MozConfigFileName = 'mozconfig';
|
||||
|
||||
$UseMozillaProfile = 1;
|
||||
$MozProfileName = 'default';
|
||||
|
||||
#- Set these to what makes sense for your system
|
||||
$Make = 'gmake'; # Must be GNU make
|
||||
$MakeOverrides = '';
|
||||
$mail = '/bin/mail';
|
||||
$CVS = 'cvs -q';
|
||||
$CVSCO = 'checkout -P';
|
||||
|
||||
# win32 usually doesn't have /bin/mail
|
||||
$blat = 'c:/nstools/bin/blat';
|
||||
$use_blat = 0;
|
||||
|
||||
# Set moz_cvsroot to something like:
|
||||
# :pserver:$ENV{USER}%netscape.com\@cvs.mozilla.org:/cvsroot
|
||||
# :pserver:anonymous\@cvs-mirror.mozilla.org:/cvsroot
|
||||
#
|
||||
# Note that win32 may not need \@, depends on ' or ".
|
||||
# :pserver:$ENV{USER}%netscape.com@cvs.mozilla.org:/cvsroot
|
||||
|
||||
$moz_cvsroot = $ENV{CVSROOT};
|
||||
|
||||
#- Set these proper values for your tinderbox server
|
||||
$Tinderbox_server = 'tinderbox-daemon@tinderbox.mozilla.org';
|
||||
|
||||
# Allow for non-client builds, e.g. camino.
|
||||
$moz_client_mk = 'client.mk';
|
||||
|
||||
# Allow for non-client builds, e.g. camino.
|
||||
$moz_client_mk = 'client.mk';
|
||||
|
||||
#- Set if you want to build in a separate object tree
|
||||
$ObjDir = '';
|
||||
|
||||
# Extra build name, if needed.
|
||||
$BuildNameExtra = '';
|
||||
|
||||
# User comment, eg. ip address for dhcp builds.
|
||||
# ex: $UserComment = "ip = 208.12.36.108";
|
||||
$UserComment = 0;
|
||||
|
||||
#-
|
||||
#- The rest should not need to be changed
|
||||
#-
|
||||
|
||||
#- Minimum wait period from start of build to start of next build in minutes.
|
||||
$BuildSleep = 10;
|
||||
|
||||
#- Until you get the script working. When it works,
|
||||
#- change to the tree you're actually building
|
||||
$BuildTree = 'MozillaTest';
|
||||
|
||||
$BuildName = '';
|
||||
$BuildTag = '';
|
||||
$BuildConfigDir = 'mozilla/config';
|
||||
$Topsrcdir = 'mozilla';
|
||||
|
||||
$BinaryName = 'mozilla-bin';
|
||||
|
||||
#
|
||||
# For embedding app, use:
|
||||
$EmbedBinaryName = 'TestGtkEmbed';
|
||||
$EmbedDistDir = 'dist/bin'
|
||||
|
||||
|
||||
$ShellOverride = ''; # Only used if the default shell is too stupid
|
||||
$ConfigureArgs = '';
|
||||
$ConfigureEnvArgs = '';
|
||||
$Compiler = 'gcc';
|
||||
$NSPRArgs = '';
|
||||
$ShellOverride = '';
|
||||
|
||||
# allow override of timezone value (for win32 POSIX::strftime)
|
||||
$Timezone = '';
|
||||
|
||||
# Reboot the OS at the end of build-and-test cycle. This is primarily
|
||||
# intended for Win9x, which can't last more than a few cycles before
|
||||
# locking up (and testing would be suspect even after a couple of cycles).
|
||||
# Right now, there is only code to force the reboot for Win9x, so even
|
||||
# setting this to 1, will not have an effect on other platforms. Setting
|
||||
# up win9x to automatically logon and begin running tinderbox is left
|
||||
# as an exercise to the reader.
|
||||
$RebootSystem = 0;
|
||||
|
||||
@@ -1,118 +0,0 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# 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 Communicator.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Chris McAfee.
|
||||
# Portions created by Chris McAfee are
|
||||
# Copyright (C) The Mozilla Organization.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Contributor(s): Chris McAfee <mcafee@netscape.com>
|
||||
#
|
||||
|
||||
#
|
||||
# Tinderbox control script.
|
||||
#
|
||||
# Assumes that at most two tinderboxes are running
|
||||
# simultaneously, depend and clobber.
|
||||
#
|
||||
# Assumes that if mozconfig exists, use it. Format:
|
||||
# mk_add_options MOZ_MAKE_FLAGS=j8
|
||||
# ac_add_options --disable-debug
|
||||
# ac_add_options --enable-optimize
|
||||
#
|
||||
|
||||
|
||||
tinderbox_usage() {
|
||||
echo "Usage: tinderbox [depend|clobber|multi] {start|stop|status|restart}"
|
||||
exit 1
|
||||
}
|
||||
|
||||
if [ $# != 2 ]; then
|
||||
echo "Wrong number of arguments."
|
||||
tinderbox_usage
|
||||
fi
|
||||
|
||||
build_type="$1"
|
||||
build_action="$2"
|
||||
|
||||
# Depend or clobber build?
|
||||
if [ "$build_type" != "depend" -a \
|
||||
"$build_type" != "clobber" -a \
|
||||
"$build_type" != "multi" ]; then
|
||||
echo "Unknown option: $1"
|
||||
tinderbox_usage
|
||||
fi
|
||||
|
||||
# See how we were called.
|
||||
case "$build_action" in
|
||||
start)
|
||||
if test -f $build_type.pid; then
|
||||
echo "$build_type build already running with PID "`cat $build_type.pid`
|
||||
else
|
||||
echo "Starting $build_type tinderbox..."
|
||||
|
||||
# Say if we found post-mozilla.pl
|
||||
if test -f post-mozilla.pl; then
|
||||
echo "Found post-mozilla.pl"
|
||||
fi
|
||||
|
||||
# Grab and use mozconfig if it exists.
|
||||
if test "$build_type" = "multi"; then
|
||||
nohup ./multi-tinderbox.pl &
|
||||
elif test -f mozconfig; then
|
||||
echo "Found mozconfig..."
|
||||
nohup ./build-seamonkey.pl --$build_type --mozconfig mozconfig &
|
||||
elif test -f .mozconfig; then
|
||||
echo "Found .mozconfig..."
|
||||
nohup ./build-seamonkey.pl --$build_type --mozconfig .mozconfig &
|
||||
else
|
||||
nohup ./build-seamonkey.pl --$build_type &
|
||||
fi
|
||||
# Write out PID so we can shut things down later.
|
||||
# This needs to be right after the ./build-seamonkey.pl call to
|
||||
# get the right PID.
|
||||
echo "PID $!"
|
||||
echo $! > $build_type.pid
|
||||
\rm -f nohup.out
|
||||
fi
|
||||
;;
|
||||
stop)
|
||||
if test -f $build_type.pid; then
|
||||
pid=`cat $build_type.pid`
|
||||
echo "Shutting down $build_type tinderbox, PID = $pid"
|
||||
kill $pid
|
||||
\rm $build_type.pid
|
||||
else
|
||||
echo "$build_type is not running."
|
||||
fi
|
||||
echo
|
||||
;;
|
||||
status)
|
||||
if test -f $build_type.pid; then
|
||||
echo "$build_type build is running with PID of "`cat $build_type.pid`
|
||||
else
|
||||
echo "$build_type build is not running."
|
||||
fi
|
||||
;;
|
||||
restart)
|
||||
echo "Restarting $build_type tinderbox:"
|
||||
$0 $build_type stop
|
||||
$0 $build_type start
|
||||
;;
|
||||
*)
|
||||
tinderbox_usage
|
||||
exit 1
|
||||
esac
|
||||
|
||||
exit 0
|
||||
Reference in New Issue
Block a user