Compare commits
2 Commits
BOBS_MPI_E
...
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,152 +0,0 @@
|
||||
#
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is the Netscape security libraries.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Netscape Communications Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 1994-2000
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Dr Vipul Gupta <vipul.gupta@sun.com> and
|
||||
# Douglas Stebila <douglas@stebila.ca>, Sun Microsystems
|
||||
# Laboratories
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
CORE_DEPTH = ../../..
|
||||
|
||||
MODULE = nss
|
||||
|
||||
ifndef FREEBL_RECURSIVE_BUILD
|
||||
LIBRARY_NAME = freebl
|
||||
else
|
||||
ifdef USE_PURE_32
|
||||
CORE_DEPTH = ../../../..
|
||||
LIBRARY_NAME = freebl_pure32
|
||||
else
|
||||
LIBRARY_NAME = freebl_hybrid
|
||||
endif
|
||||
endif
|
||||
|
||||
# same version as rest of freebl
|
||||
LIBRARY_VERSION = _3
|
||||
|
||||
DEFINES += -DSHLIB_SUFFIX=\"$(DLL_SUFFIX)\" -DSHLIB_PREFIX=\"$(DLL_PREFIX)\"
|
||||
|
||||
REQUIRES =
|
||||
|
||||
EXPORTS = \
|
||||
blapit.h \
|
||||
shsign.h \
|
||||
ecl-exp.h \
|
||||
$(NULL)
|
||||
|
||||
PRIVATE_EXPORTS = \
|
||||
blapi.h \
|
||||
secmpi.h \
|
||||
secrng.h \
|
||||
ec.h \
|
||||
ecl.h \
|
||||
ecl-curve.h \
|
||||
$(NULL)
|
||||
|
||||
MPI_HDRS = mpi-config.h mpi.h mpi-priv.h mplogic.h mpprime.h logtab.h mp_gf2m.h
|
||||
MPI_SRCS = mpprime.c mpmontg.c mplogic.c mpi.c mp_gf2m.c mpcpucache.c
|
||||
ECL_HDRS = ecl-exp.h ecl.h ec2.h ecp.h ecl-priv.h
|
||||
ifdef NSS_ENABLE_ECC
|
||||
ECL_SRCS = ecl.c ecl_curve.c ecl_mult.c ecl_gf.c \
|
||||
ec2_aff.c ec2_mont.c ec2_proj.c \
|
||||
ec2_163.c ec2_193.c ec2_233.c \
|
||||
ecp_aff.c ecp_jac.c ecp_mont.c \
|
||||
ecp_192.c ecp_224.c \
|
||||
ec_naf.c ecp_jm.c
|
||||
else
|
||||
ECL_SRCS = $(NULL)
|
||||
endif
|
||||
|
||||
CSRCS = \
|
||||
ldvector.c \
|
||||
prng_fips1861.c \
|
||||
sysrand.c \
|
||||
sha_fast.c \
|
||||
md2.c \
|
||||
md5.c \
|
||||
sha512.c \
|
||||
alg2268.c \
|
||||
arcfour.c \
|
||||
arcfive.c \
|
||||
desblapi.c \
|
||||
des.c \
|
||||
rijndael.c \
|
||||
aeskeywrap.c \
|
||||
dh.c \
|
||||
ec.c \
|
||||
pqg.c \
|
||||
dsa.c \
|
||||
rsa.c \
|
||||
shvfy.c \
|
||||
$(MPI_SRCS) \
|
||||
$(ECL_SRCS) \
|
||||
$(NULL)
|
||||
|
||||
ALL_CSRCS := $(CSRCS)
|
||||
|
||||
ALL_HDRS = \
|
||||
blapi.h \
|
||||
blapit.h \
|
||||
des.h \
|
||||
ec.h \
|
||||
loader.h \
|
||||
rijndael.h \
|
||||
secmpi.h \
|
||||
sha.h \
|
||||
sha_fast.h \
|
||||
shsign.h \
|
||||
vis_proto.h \
|
||||
$(NULL)
|
||||
|
||||
ifdef NSS_ENABLE_ECC
|
||||
DEFINES += -DNSS_ENABLE_ECC
|
||||
endif
|
||||
|
||||
ifdef AES_GEN_TBL
|
||||
DEFINES += -DRIJNDAEL_GENERATE_TABLES
|
||||
else
|
||||
ifdef AES_GEN_TBL_M
|
||||
DEFINES += -DRIJNDAEL_GENERATE_TABLES_MACRO
|
||||
else
|
||||
ifdef AES_GEN_VAL
|
||||
DEFINES += -DRIJNDAEL_GENERATE_VALUES
|
||||
else
|
||||
ifdef AES_GEN_VAL_M
|
||||
DEFINES += -DRIJNDAEL_GENERATE_VALUES_MACRO
|
||||
else
|
||||
DEFINES += -DRIJNDAEL_INCLUDE_TABLES
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
@@ -1,278 +0,0 @@
|
||||
#
|
||||
# Makefile for MPI library
|
||||
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is the MPI Arbitrary Precision Integer Arithmetic library.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Michael J. Fromberger <sting@linguist.dartmouth.edu>.
|
||||
# Portions created by the Initial Developer are Copyright (C) 1998
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Netscape Communications Corporation
|
||||
# Richard C. Swift (swift@netscape.com)
|
||||
# Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
#
|
||||
# $Id: Makefile,v 1.21 2005-02-02 22:28:22 gerv%gerv.net Exp $
|
||||
#
|
||||
|
||||
## Define CC to be the C compiler you wish to use. The GNU cc
|
||||
## compiler (gcc) should work, at the very least
|
||||
#CC=cc
|
||||
#CC=gcc
|
||||
|
||||
##
|
||||
## Define PERL to point to your local Perl interpreter. It
|
||||
## should be Perl 5.x, although it's conceivable that Perl 4
|
||||
## might work ... I haven't tested it.
|
||||
##
|
||||
#PERL=/usr/bin/perl
|
||||
PERL=perl
|
||||
|
||||
include target.mk
|
||||
|
||||
CFLAGS+= $(XCFLAGS)
|
||||
|
||||
##
|
||||
## Define LIBS to include any libraries you need to link against.
|
||||
## If NO_TABLE is define, LIBS should include '-lm' or whatever is
|
||||
## necessary to bring in the math library. Otherwise, it can be
|
||||
## left alone, unless your system has other peculiar requirements.
|
||||
##
|
||||
LIBS=#-lmalloc#-lefence#-lm
|
||||
|
||||
##
|
||||
## Define RANLIB to be the library header randomizer; you might not
|
||||
## need this on some systems (just set it to 'echo' on these systems,
|
||||
## such as IRIX)
|
||||
##
|
||||
RANLIB=echo
|
||||
|
||||
##
|
||||
## This is the version string used for the documentation and
|
||||
## building the distribution tarball. Don't mess with it unless
|
||||
## you are releasing a new version
|
||||
VERS=1.7p6
|
||||
|
||||
## ----------------------------------------------------------------------
|
||||
## You probably don't need to change anything below this line...
|
||||
##
|
||||
|
||||
##
|
||||
## This is the list of source files that need to be packed into
|
||||
## the distribution file
|
||||
SRCS= mpi.c mpprime.c mplogic.c mp_gf2m.c mpmontg.c mpi-test.c primes.c tests/ \
|
||||
utils/gcd.c utils/invmod.c utils/lap.c \
|
||||
utils/ptab.pl utils/sieve.c utils/isprime.c\
|
||||
utils/dec2hex.c utils/hex2dec.c utils/bbs_rand.c \
|
||||
utils/bbsrand.c utils/prng.c utils/primegen.c \
|
||||
utils/basecvt.c utils/makeprime.c\
|
||||
utils/fact.c utils/exptmod.c utils/pi.c utils/metime.c \
|
||||
utils/mpi.h utils/mpprime.h mulsqr.c \
|
||||
make-test-arrays test-arrays.txt all-tests make-logtab \
|
||||
types.pl stats timetest multest
|
||||
|
||||
## These are the header files that go into the distribution file
|
||||
HDRS=mpi.h mpi-config.h utils/mpi.h utils/mpi-config.h mpprime.h mplogic.h mp_gf2m.h \
|
||||
mp_gf2m-priv.h utils/bbs_rand.h tests/mpi.h tests/mpprime.h
|
||||
|
||||
## These are the documentation files that go into the distribution file
|
||||
DOCS=README doc utils/README utils/PRIMES
|
||||
|
||||
## This is the list of tools built by 'make tools'
|
||||
TOOLS=gcd invmod isprime lap dec2hex hex2dec primegen prng \
|
||||
basecvt fact exptmod pi makeprime identest
|
||||
|
||||
LIBOBJS = mpprime.o mpmontg.o mplogic.o mp_gf2m.o mpi.o $(AS_OBJS)
|
||||
LIBHDRS = mpi-config.h mpi-priv.h mpi.h
|
||||
APPHDRS = mpi-config.h mpi.h mplogic.h mp_gf2m.h mpprime.h
|
||||
|
||||
help:
|
||||
@ echo ""
|
||||
@ echo "The following targets can be built with this Makefile:"
|
||||
@ echo ""
|
||||
@ echo "libmpi.a - arithmetic and prime testing library"
|
||||
@ echo "mpi-test - test driver (requires MP_IOFUNC)"
|
||||
@ echo "tools - command line tools"
|
||||
@ echo "doc - manual pages for tools"
|
||||
@ echo "clean - clean up objects and such"
|
||||
@ echo "distclean - get ready for distribution"
|
||||
@ echo "dist - distribution tarball"
|
||||
@ echo ""
|
||||
|
||||
.SUFFIXES: .c .o .i
|
||||
|
||||
.c.i:
|
||||
$(CC) $(CFLAGS) -E $< > $@
|
||||
|
||||
#.c.o: $*.h $*.c
|
||||
# $(CC) $(CFLAGS) -c $<
|
||||
|
||||
#---------------------------------------
|
||||
|
||||
$(LIBOBJS): $(LIBHDRS)
|
||||
|
||||
logtab.h: make-logtab
|
||||
$(PERL) make-logtab > logtab.h
|
||||
|
||||
mpi.o: mpi.c logtab.h $(LIBHDRS)
|
||||
|
||||
mplogic.o: mplogic.c mpi-priv.h mplogic.h $(LIBHDRS)
|
||||
|
||||
mp_gf2m.o: mp_gf2m.c mpi-priv.h mp_gf2m.h mp_gf2m-priv.h $(LIBHDRS)
|
||||
|
||||
mpmontg.o: mpmontg.c mpi-priv.h mplogic.h mpprime.h $(LIBHDRS)
|
||||
|
||||
mpprime.o: mpprime.c mpi-priv.h mpprime.h mplogic.h primes.c $(LIBHDRS)
|
||||
|
||||
mpi_mips.o: mpi_mips.s
|
||||
$(CC) -o $@ $(ASFLAGS) -c mpi_mips.s
|
||||
|
||||
mpi_sparc.o : montmulf.h
|
||||
|
||||
mpv_sparcv9.s: vis_64.il mpv_sparc.c
|
||||
$(CC) -o $@ $(SOLARIS_FPU_FLAGS) -S vis_64.il mpv_sparc.c
|
||||
|
||||
mpv_sparcv8.s: vis_64.il mpv_sparc.c
|
||||
$(CC) -o $@ $(SOLARIS_FPU_FLAGS) -S vis_32.il mpv_sparc.c
|
||||
|
||||
montmulfv8.o montmulfv9.o mpv_sparcv8.o mpv_sparcv9.o : %.o : %.s
|
||||
$(CC) -o $@ $(SOLARIS_ASM_FLAGS) -c $<
|
||||
|
||||
# This rule is used to build the .s sources, which are then hand optimized.
|
||||
#montmulfv8.s montmulfv9.s : montmulf%.s : montmulf%.il montmulf.c montmulf.h
|
||||
# $(CC) -o $@ $(SOLARIS_ASM_FLAGS) -S montmulf$*.il montmulf.c
|
||||
|
||||
|
||||
libmpi.a: $(LIBOBJS)
|
||||
ar -cvr libmpi.a $(LIBOBJS)
|
||||
$(RANLIB) libmpi.a
|
||||
|
||||
lib libs: libmpi.a
|
||||
|
||||
mpi.i: mpi.h
|
||||
|
||||
#---------------------------------------
|
||||
|
||||
MPTESTOBJS = mptest1.o mptest2.o mptest3.o mptest3a.o mptest4.o mptest4a.o \
|
||||
mptest4b.o mptest6.o mptest7.o mptest8.o mptest9.o mptestb.o
|
||||
MPTESTS = $(MPTESTOBJS:.o=)
|
||||
|
||||
$(MPTESTOBJS): mptest%.o: tests/mptest-%.c $(LIBHDRS)
|
||||
$(CC) $(CFLAGS) -o $@ -c $<
|
||||
|
||||
$(MPTESTS): mptest%: mptest%.o libmpi.a
|
||||
$(CC) $(CFLAGS) -o $@ $^ $(LIBS)
|
||||
|
||||
tests: mptest1 mptest2 mptest3 mptest3a mptest4 mptest4a mptest4b mptest6 \
|
||||
mptestb bbsrand
|
||||
|
||||
utests: mptest7 mptest8 mptest9
|
||||
|
||||
#---------------------------------------
|
||||
|
||||
EXTRAOBJS = bbsrand.o bbs_rand.o prng.o
|
||||
UTILOBJS = primegen.o metime.o identest.o basecvt.o fact.o exptmod.o pi.o \
|
||||
makeprime.o gcd.o invmod.o lap.o isprime.o \
|
||||
dec2hex.o hex2dec.o
|
||||
UTILS = $(UTILOBJS:.o=)
|
||||
|
||||
$(UTILS): % : %.o libmpi.a
|
||||
$(CC) $(CFLAGS) -o $@ $^ $(LIBS)
|
||||
|
||||
$(UTILOBJS) $(EXTRAOBJS): %.o : utils/%.c $(LIBHDRS)
|
||||
$(CC) $(CFLAGS) -o $@ -c $<
|
||||
|
||||
prng: prng.o bbs_rand.o libmpi.a
|
||||
$(CC) $(CFLAGS) -o $@ $^ $(LIBS)
|
||||
|
||||
bbsrand: bbsrand.o bbs_rand.o libmpi.a
|
||||
$(CC) $(CFLAGS) -o $@ $^ $(LIBS)
|
||||
|
||||
utils: $(UTILS) prng bbsrand
|
||||
|
||||
#---------------------------------------
|
||||
|
||||
test-info.c: test-arrays.txt
|
||||
$(PERL) make-test-arrays test-arrays.txt > test-info.c
|
||||
|
||||
mpi-test.o: mpi-test.c test-info.c $(LIBHDRS)
|
||||
$(CC) $(CFLAGS) -o $@ -c $<
|
||||
|
||||
mpi-test: mpi-test.o libmpi.a
|
||||
$(CC) $(CFLAGS) -o $@ $^ $(LIBS)
|
||||
|
||||
mdxptest.o: mdxptest.c $(LIBHDRS) mpi-priv.h
|
||||
|
||||
mdxptest: mdxptest.o libmpi.a
|
||||
$(CC) $(CFLAGS) -o $@ $^ $(LIBS)
|
||||
|
||||
mulsqr.o: mulsqr.c logtab.h mpi.h mpi-config.h mpprime.h
|
||||
$(CC) $(CFLAGS) -DMP_SQUARE=1 -o $@ -c mulsqr.c
|
||||
|
||||
mulsqr: mulsqr.o libmpi.a
|
||||
$(CC) $(CFLAGS) -o $@ $^ $(LIBS)
|
||||
|
||||
#---------------------------------------
|
||||
|
||||
alltests: tests utests mpi-test
|
||||
|
||||
tools: $(TOOLS)
|
||||
|
||||
doc:
|
||||
(cd doc; ./build)
|
||||
|
||||
clean:
|
||||
rm -f *.o *.a *.i
|
||||
rm -f core
|
||||
rm -f *~ .*~
|
||||
rm -f utils/*.o
|
||||
rm -f utils/core
|
||||
rm -f utils/*~ utils/.*~
|
||||
|
||||
clobber: clean
|
||||
rm -f $(TOOLS) $(UTILS)
|
||||
|
||||
distclean: clean
|
||||
rm -f mptest? mpi-test metime mulsqr karatsuba
|
||||
rm -f mptest?a mptest?b
|
||||
rm -f utils/mptest?
|
||||
rm -f test-info.c logtab.h
|
||||
rm -f libmpi.a
|
||||
rm -f $(TOOLS)
|
||||
|
||||
dist: Makefile $(HDRS) $(SRCS) $(DOCS)
|
||||
tar -cvf mpi-$(VERS).tar Makefile $(HDRS) $(SRCS) $(DOCS)
|
||||
pgps -ab mpi-$(VERS).tar
|
||||
chmod +r mpi-$(VERS).tar.asc
|
||||
gzip -9 mpi-$(VERS).tar
|
||||
|
||||
# END
|
||||
@@ -1,280 +0,0 @@
|
||||
#
|
||||
# Makefile.win - gmake Makefile for building MPI with VACPP on OS/2
|
||||
#
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is the MPI Arbitrary Precision Integer Arithmetic library.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Michael J. Fromberger <sting@linguist.dartmouth.edu>.
|
||||
# Portions created by the Initial Developer are Copyright (C) 1998
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Netscape Communications Corporation
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
#
|
||||
# $Id: Makefile.os2,v 1.3 2005-02-02 22:28:22 gerv%gerv.net Exp $
|
||||
#
|
||||
|
||||
## Define CC to be the C compiler you wish to use. The GNU cc
|
||||
## compiler (gcc) should work, at the very least
|
||||
#CC=cc
|
||||
#CC=gcc
|
||||
CC=icc.exe
|
||||
AS=alp.exe
|
||||
|
||||
##
|
||||
## Define PERL to point to your local Perl interpreter. It
|
||||
## should be Perl 5.x, although it's conceivable that Perl 4
|
||||
## might work ... I haven't tested it.
|
||||
##
|
||||
#PERL=/usr/bin/perl
|
||||
PERL=perl
|
||||
|
||||
##
|
||||
## Define CFLAGS to contain any local options your compiler
|
||||
## setup requires.
|
||||
##
|
||||
## Conditional compilation options are no longer here; see
|
||||
## the file 'mpi-config.h' instead.
|
||||
##
|
||||
MPICMN = -I. -DMP_API_COMPATIBLE -DMP_IOFUNC -DMP_USE_UINT_DIGIT -DMP_NO_MP_WORD
|
||||
|
||||
#OS/2
|
||||
AS_SRCS = mpi_x86.asm
|
||||
MPICMN += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE -DMP_ASSEMBLY_DIV_2DX1D
|
||||
#CFLAGS= -Od -Z7 -MD -W3 -nologo -D_X86_ -DXP_PC \
|
||||
-DDEBUG -D_DEBUG -UNDEBUG -DWIN32 -D_WINDOWS -DWIN95 $(MPICMN)
|
||||
#CFLAGS = -O2 -MD -W3 -nologo -D_X86_ -DXP_PC -UDEBUG -U_DEBUG -DNDEBUG \
|
||||
-DWIN32 -D_WINDOWS -DWIN95 $(MPICMN)
|
||||
#CFLAGS = -Od -Z7 -MD -W3 -nologo -D_X86_ -DXP_PC -UDEBUG -U_DEBUG -DNDEBUG \
|
||||
-DWIN32 -D_WINDOWS -DWIN95 $(MPICMN)
|
||||
CFLAGS = /Ti+ -D_X86_ -DXP_PC -UDEBUG -U_DEBUG -DNDEBUG \
|
||||
$(MPICMN)
|
||||
ASFLAGS =
|
||||
|
||||
##
|
||||
## Define LIBS to include any libraries you need to link against.
|
||||
## If NO_TABLE is define, LIBS should include '-lm' or whatever is
|
||||
## necessary to bring in the math library. Otherwise, it can be
|
||||
## left alone, unless your system has other peculiar requirements.
|
||||
##
|
||||
LIBS=#-lmalloc#-lefence#-lm
|
||||
|
||||
##
|
||||
## Define RANLIB to be the library header randomizer; you might not
|
||||
## need this on some systems (just set it to 'echo' on these systems,
|
||||
## such as IRIX)
|
||||
##
|
||||
RANLIB=echo
|
||||
|
||||
##
|
||||
## This is the version string used for the documentation and
|
||||
## building the distribution tarball. Don't mess with it unless
|
||||
## you are releasing a new version
|
||||
VERS=1.7p6
|
||||
|
||||
## ----------------------------------------------------------------------
|
||||
## You probably don't need to change anything below this line...
|
||||
##
|
||||
|
||||
##
|
||||
## This is the list of source files that need to be packed into
|
||||
## the distribution file
|
||||
SRCS= mpi.c mpprime.c mplogic.c mpmontg.c mpi-test.c primes.c tests/ \
|
||||
utils/gcd.c utils/invmod.c utils/lap.c \
|
||||
utils/ptab.pl utils/sieve.c utils/isprime.c\
|
||||
utils/dec2hex.c utils/hex2dec.c utils/bbs_rand.c \
|
||||
utils/bbsrand.c utils/prng.c utils/primegen.c \
|
||||
utils/basecvt.c utils/makeprime.c\
|
||||
utils/fact.c utils/exptmod.c utils/pi.c utils/metime.c \
|
||||
utils/mpi.h utils/mpprime.h mulsqr.c \
|
||||
make-test-arrays test-arrays.txt all-tests make-logtab \
|
||||
types.pl stats timetest multest
|
||||
|
||||
## These are the header files that go into the distribution file
|
||||
HDRS=mpi.h mpi-config.h utils/mpi.h utils/mpi-config.h mpprime.h mplogic.h \
|
||||
utils/bbs_rand.h tests/mpi.h tests/mpprime.h
|
||||
|
||||
## These are the documentation files that go into the distribution file
|
||||
DOCS=README doc utils/README utils/PRIMES
|
||||
|
||||
## This is the list of tools built by 'make tools'
|
||||
TOOLS=gcd.exe invmod.exe isprime.exe lap.exe dec2hex.exe hex2dec.exe \
|
||||
primegen.exe prng.exe basecvt.exe fact.exe exptmod.exe pi.exe makeprime.exe
|
||||
|
||||
AS_OBJS = $(AS_SRCS:.asm=.obj)
|
||||
LIBOBJS = mpprime.obj mpmontg.obj mplogic.obj mpi.obj $(AS_OBJS)
|
||||
LIBHDRS = mpi-config.h mpi-priv.h mpi.h
|
||||
APPHDRS = mpi-config.h mpi.h mplogic.h mpprime.h
|
||||
|
||||
|
||||
help:
|
||||
@ echo ""
|
||||
@ echo "The following targets can be built with this Makefile:"
|
||||
@ echo ""
|
||||
@ echo "mpi.lib - arithmetic and prime testing library"
|
||||
@ echo "mpi-test.exe - test driver (requires MP_IOFUNC)"
|
||||
@ echo "tools - command line tools"
|
||||
@ echo "doc - manual pages for tools"
|
||||
@ echo "clean - clean up objects and such"
|
||||
@ echo "distclean - get ready for distribution"
|
||||
@ echo "dist - distribution tarball"
|
||||
@ echo ""
|
||||
|
||||
.SUFFIXES: .c .obj .i .lib .exe .asm
|
||||
|
||||
.c.i:
|
||||
$(CC) $(CFLAGS) -E $< > $@
|
||||
|
||||
.c.obj:
|
||||
$(CC) $(CFLAGS) -c $<
|
||||
|
||||
.asm.obj:
|
||||
$(AS) $(ASFLAGS) $<
|
||||
|
||||
.obj.exe:
|
||||
$(CC) $(CFLAGS) -Fo$@ $<
|
||||
|
||||
#---------------------------------------
|
||||
|
||||
$(LIBOBJS): $(LIBHDRS)
|
||||
|
||||
logtab.h: make-logtab
|
||||
$(PERL) make-logtab > logtab.h
|
||||
|
||||
mpi.obj: mpi.c logtab.h $(LIBHDRS)
|
||||
|
||||
mplogic.obj: mplogic.c mpi-priv.h mplogic.h $(LIBHDRS)
|
||||
|
||||
mpmontg.obj: mpmontg.c mpi-priv.h mplogic.h mpprime.h $(LIBHDRS)
|
||||
|
||||
mpprime.obj: mpprime.c mpi-priv.h mpprime.h mplogic.h primes.c $(LIBHDRS)
|
||||
|
||||
mpi_mips.obj: mpi_mips.s
|
||||
$(CC) -Fo$@ $(ASFLAGS) -c mpi_mips.s
|
||||
|
||||
mpi.lib: $(LIBOBJS)
|
||||
ilib /out:mpi.lib $(LIBOBJS)
|
||||
$(RANLIB) mpi.lib
|
||||
|
||||
lib libs: mpi.lib
|
||||
|
||||
#---------------------------------------
|
||||
|
||||
MPTESTOBJS = mptest1.obj mptest2.obj mptest3.obj mptest3a.obj mptest4.obj \
|
||||
mptest4a.obj mptest4b.obj mptest6.obj mptest7.obj mptest8.obj mptest9.obj
|
||||
MPTESTS = $(MPTESTOBJS:.obj=.exe)
|
||||
|
||||
$(MPTESTOBJS): mptest%.obj: tests/mptest-%.c $(LIBHDRS)
|
||||
$(CC) $(CFLAGS) -Fo$@ -c $<
|
||||
|
||||
$(MPTESTS): mptest%.exe: mptest%.obj mpi.lib $(LIBS)
|
||||
$(CC) $(CFLAGS) -Fo$@ $^
|
||||
|
||||
tests: mptest1.exe mptest2.exe mptest3.exe mptest3a.exe mptest4.exe \
|
||||
mptest4a.exe mptest4b.exe mptest6.exe bbsrand.exe
|
||||
|
||||
utests: mptest7.exe mptest8.exe mptest9.exe
|
||||
|
||||
#---------------------------------------
|
||||
|
||||
EXTRAOBJS = bbsrand.obj bbs_rand.obj prng.obj
|
||||
UTILOBJS = primegen.obj metime.obj identest.obj basecvt.obj fact.obj \
|
||||
exptmod.obj pi.obj makeprime.obj karatsuba.obj gcd.obj invmod.obj lap.obj \
|
||||
isprime.obj dec2hex.obj hex2dec.obj
|
||||
UTILS = $(UTILOBJS:.obj=.exe)
|
||||
|
||||
$(UTILS): %.exe : %.obj mpi.lib $(LIBS)
|
||||
$(CC) $(CFLAGS) -Fo$@ $^
|
||||
|
||||
$(UTILOBJS) $(EXTRAOBJS): %.obj : utils/%.c $(LIBHDRS)
|
||||
$(CC) $(CFLAGS) -Fo$@ -c $<
|
||||
|
||||
prng.exe: prng.obj bbs_rand.obj mpi.lib $(LIBS)
|
||||
$(CC) $(CFLAGS) -Fo$@ $^
|
||||
|
||||
bbsrand.exe: bbsrand.obj bbs_rand.obj mpi.lib $(LIBS)
|
||||
$(CC) $(CFLAGS) -Fo$@ $^
|
||||
|
||||
utils: $(UTILS) prng.exe bbsrand.exe
|
||||
|
||||
#---------------------------------------
|
||||
|
||||
test-info.c: test-arrays.txt
|
||||
$(PERL) make-test-arrays test-arrays.txt > test-info.c
|
||||
|
||||
mpi-test.obj: mpi-test.c test-info.c $(LIBHDRS)
|
||||
$(CC) $(CFLAGS) -Fo$@ -c $<
|
||||
|
||||
mpi-test.exe: mpi-test.obj mpi.lib $(LIBS)
|
||||
$(CC) $(CFLAGS) -Fo$@ $^
|
||||
|
||||
mdxptest.obj: mdxptest.c $(LIBHDRS) mpi-priv.h
|
||||
|
||||
mdxptest.exe: mdxptest.obj mpi.lib $(LIBS)
|
||||
$(CC) $(CFLAGS) -Fo$@ $^
|
||||
|
||||
mulsqr.obj: mulsqr.c logtab.h mpi.h mpi-config.h mpprime.h
|
||||
$(CC) $(CFLAGS) -DMP_SQUARE=1 -Fo$@ -c mulsqr.c
|
||||
|
||||
mulsqr.exe: mulsqr.obj mpi.lib $(LIBS)
|
||||
$(CC) $(CFLAGS) -Fo$@ $^
|
||||
|
||||
#---------------------------------------
|
||||
|
||||
alltests: tests utests mpi-test.exe
|
||||
|
||||
tools: $(TOOLS)
|
||||
|
||||
doc:
|
||||
(cd doc; ./build)
|
||||
|
||||
clean:
|
||||
rm -f *.obj *.lib *.pdb *.ilk
|
||||
cd utils; rm -f *.obj *.lib *.pdb *.ilk
|
||||
|
||||
distclean: clean
|
||||
rm -f mptest? mpi-test metime mulsqr karatsuba
|
||||
rm -f mptest?a mptest?b
|
||||
rm -f utils/mptest?
|
||||
rm -f test-info.c logtab.h
|
||||
rm -f mpi.lib
|
||||
rm -f $(TOOLS)
|
||||
|
||||
dist: Makefile $(HDRS) $(SRCS) $(DOCS)
|
||||
tar -cvf mpi-$(VERS).tar Makefile $(HDRS) $(SRCS) $(DOCS)
|
||||
pgps -ab mpi-$(VERS).tar
|
||||
chmod +r mpi-$(VERS).tar.asc
|
||||
gzip -9 mpi-$(VERS).tar
|
||||
|
||||
|
||||
print:
|
||||
@echo LIBOBJS = $(LIBOBJS)
|
||||
# END
|
||||
@@ -1,280 +0,0 @@
|
||||
#
|
||||
# Makefile.win - gmake Makefile for building MPI with MSVC on NT
|
||||
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is the MPI Arbitrary Precision Integer Arithmetic library.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Michael J. Fromberger <sting@linguist.dartmouth.edu>.
|
||||
# Portions created by the Initial Developer are Copyright (C) 1998
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Netscape Communications Corporation
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
#
|
||||
# $Id: Makefile.win,v 1.3 2005-02-02 22:28:22 gerv%gerv.net Exp $
|
||||
#
|
||||
|
||||
## Define CC to be the C compiler you wish to use. The GNU cc
|
||||
## compiler (gcc) should work, at the very least
|
||||
#CC=cc
|
||||
#CC=gcc
|
||||
CC=cl.exe
|
||||
AS=ml.exe
|
||||
|
||||
##
|
||||
## Define PERL to point to your local Perl interpreter. It
|
||||
## should be Perl 5.x, although it's conceivable that Perl 4
|
||||
## might work ... I haven't tested it.
|
||||
##
|
||||
#PERL=/usr/bin/perl
|
||||
PERL=perl
|
||||
|
||||
##
|
||||
## Define CFLAGS to contain any local options your compiler
|
||||
## setup requires.
|
||||
##
|
||||
## Conditional compilation options are no longer here; see
|
||||
## the file 'mpi-config.h' instead.
|
||||
##
|
||||
MPICMN = -I. -DMP_API_COMPATIBLE -DMP_IOFUNC
|
||||
|
||||
#NT
|
||||
AS_SRCS = mpi_x86.asm
|
||||
MPICMN += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE -DMP_ASSEMBLY_DIV_2DX1D
|
||||
#CFLAGS= -Od -Z7 -MD -W3 -nologo -D_X86_ -DXP_PC \
|
||||
-DDEBUG -D_DEBUG -UNDEBUG -DWIN32 -D_WINDOWS -DWIN95 $(MPICMN)
|
||||
#CFLAGS = -O2 -MD -W3 -nologo -D_X86_ -DXP_PC -UDEBUG -U_DEBUG -DNDEBUG \
|
||||
-DWIN32 -D_WINDOWS -DWIN95 $(MPICMN)
|
||||
#CFLAGS = -Od -Z7 -MD -W3 -nologo -D_X86_ -DXP_PC -UDEBUG -U_DEBUG -DNDEBUG \
|
||||
-DWIN32 -D_WINDOWS -DWIN95 $(MPICMN)
|
||||
CFLAGS = -O2 -Z7 -MD -W3 -nologo -D_X86_ -DXP_PC -UDEBUG -U_DEBUG -DNDEBUG \
|
||||
-DWIN32 -D_WINDOWS -DWIN95 $(MPICMN)
|
||||
ASFLAGS = -Cp -Sn -Zi -coff -I.
|
||||
|
||||
##
|
||||
## Define LIBS to include any libraries you need to link against.
|
||||
## If NO_TABLE is define, LIBS should include '-lm' or whatever is
|
||||
## necessary to bring in the math library. Otherwise, it can be
|
||||
## left alone, unless your system has other peculiar requirements.
|
||||
##
|
||||
LIBS=#-lmalloc#-lefence#-lm
|
||||
|
||||
##
|
||||
## Define RANLIB to be the library header randomizer; you might not
|
||||
## need this on some systems (just set it to 'echo' on these systems,
|
||||
## such as IRIX)
|
||||
##
|
||||
RANLIB=echo
|
||||
|
||||
##
|
||||
## This is the version string used for the documentation and
|
||||
## building the distribution tarball. Don't mess with it unless
|
||||
## you are releasing a new version
|
||||
VERS=1.7p6
|
||||
|
||||
## ----------------------------------------------------------------------
|
||||
## You probably don't need to change anything below this line...
|
||||
##
|
||||
|
||||
##
|
||||
## This is the list of source files that need to be packed into
|
||||
## the distribution file
|
||||
SRCS= mpi.c mpprime.c mplogic.c mpmontg.c mpi-test.c primes.c tests/ \
|
||||
utils/gcd.c utils/invmod.c utils/lap.c \
|
||||
utils/ptab.pl utils/sieve.c utils/isprime.c\
|
||||
utils/dec2hex.c utils/hex2dec.c utils/bbs_rand.c \
|
||||
utils/bbsrand.c utils/prng.c utils/primegen.c \
|
||||
utils/basecvt.c utils/makeprime.c\
|
||||
utils/fact.c utils/exptmod.c utils/pi.c utils/metime.c \
|
||||
utils/mpi.h utils/mpprime.h mulsqr.c \
|
||||
make-test-arrays test-arrays.txt all-tests make-logtab \
|
||||
types.pl stats timetest multest
|
||||
|
||||
## These are the header files that go into the distribution file
|
||||
HDRS=mpi.h mpi-config.h utils/mpi.h utils/mpi-config.h mpprime.h mplogic.h \
|
||||
utils/bbs_rand.h tests/mpi.h tests/mpprime.h
|
||||
|
||||
## These are the documentation files that go into the distribution file
|
||||
DOCS=README doc utils/README utils/PRIMES
|
||||
|
||||
## This is the list of tools built by 'make tools'
|
||||
TOOLS=gcd.exe invmod.exe isprime.exe lap.exe dec2hex.exe hex2dec.exe \
|
||||
primegen.exe prng.exe basecvt.exe fact.exe exptmod.exe pi.exe makeprime.exe
|
||||
|
||||
AS_OBJS = $(AS_SRCS:.asm=.obj)
|
||||
LIBOBJS = mpprime.obj mpmontg.obj mplogic.obj mpi.obj $(AS_OBJS)
|
||||
LIBHDRS = mpi-config.h mpi-priv.h mpi.h
|
||||
APPHDRS = mpi-config.h mpi.h mplogic.h mpprime.h
|
||||
|
||||
|
||||
help:
|
||||
@ echo ""
|
||||
@ echo "The following targets can be built with this Makefile:"
|
||||
@ echo ""
|
||||
@ echo "mpi.lib - arithmetic and prime testing library"
|
||||
@ echo "mpi-test - test driver (requires MP_IOFUNC)"
|
||||
@ echo "tools - command line tools"
|
||||
@ echo "doc - manual pages for tools"
|
||||
@ echo "clean - clean up objects and such"
|
||||
@ echo "distclean - get ready for distribution"
|
||||
@ echo "dist - distribution tarball"
|
||||
@ echo ""
|
||||
|
||||
.SUFFIXES: .c .obj .i .lib .exe .asm
|
||||
|
||||
.c.i:
|
||||
$(CC) $(CFLAGS) -E $< > $@
|
||||
|
||||
.c.obj:
|
||||
$(CC) $(CFLAGS) -c $<
|
||||
|
||||
.asm.obj:
|
||||
$(AS) $(ASFLAGS) -c $<
|
||||
|
||||
.obj.exe:
|
||||
$(CC) $(CFLAGS) -Fo$@ $<
|
||||
|
||||
#---------------------------------------
|
||||
|
||||
$(LIBOBJS): $(LIBHDRS)
|
||||
|
||||
logtab.h: make-logtab
|
||||
$(PERL) make-logtab > logtab.h
|
||||
|
||||
mpi.obj: mpi.c logtab.h $(LIBHDRS)
|
||||
|
||||
mplogic.obj: mplogic.c mpi-priv.h mplogic.h $(LIBHDRS)
|
||||
|
||||
mpmontg.obj: mpmontg.c mpi-priv.h mplogic.h mpprime.h $(LIBHDRS)
|
||||
|
||||
mpprime.obj: mpprime.c mpi-priv.h mpprime.h mplogic.h primes.c $(LIBHDRS)
|
||||
|
||||
mpi_mips.obj: mpi_mips.s
|
||||
$(CC) -Fo$@ $(ASFLAGS) -c mpi_mips.s
|
||||
|
||||
mpi.lib: $(LIBOBJS)
|
||||
ar -cvr mpi.lib $(LIBOBJS)
|
||||
$(RANLIB) mpi.lib
|
||||
|
||||
lib libs: mpi.lib
|
||||
|
||||
#---------------------------------------
|
||||
|
||||
MPTESTOBJS = mptest1.obj mptest2.obj mptest3.obj mptest3a.obj mptest4.obj \
|
||||
mptest4a.obj mptest4b.obj mptest6.obj mptest7.obj mptest8.obj mptest9.obj
|
||||
MPTESTS = $(MPTESTOBJS:.obj=.exe)
|
||||
|
||||
$(MPTESTOBJS): mptest%.obj: tests/mptest-%.c $(LIBHDRS)
|
||||
$(CC) $(CFLAGS) -Fo$@ -c $<
|
||||
|
||||
$(MPTESTS): mptest%.exe: mptest%.obj mpi.lib $(LIBS)
|
||||
$(CC) $(CFLAGS) -Fo$@ $^
|
||||
|
||||
tests: mptest1.exe mptest2.exe mptest3.exe mptest3a.exe mptest4.exe \
|
||||
mptest4a.exe mptest4b.exe mptest6.exe bbsrand.exe
|
||||
|
||||
utests: mptest7.exe mptest8.exe mptest9.exe
|
||||
|
||||
#---------------------------------------
|
||||
|
||||
EXTRAOBJS = bbsrand.obj bbs_rand.obj prng.obj
|
||||
UTILOBJS = primegen.obj metime.obj identest.obj basecvt.obj fact.obj \
|
||||
exptmod.obj pi.obj makeprime.obj karatsuba.obj gcd.obj invmod.obj lap.obj \
|
||||
isprime.obj dec2hex.obj hex2dec.obj
|
||||
UTILS = $(UTILOBJS:.obj=.exe)
|
||||
|
||||
$(UTILS): %.exe : %.obj mpi.lib $(LIBS)
|
||||
$(CC) $(CFLAGS) -Fo$@ $^
|
||||
|
||||
$(UTILOBJS) $(EXTRAOBJS): %.obj : utils/%.c $(LIBHDRS)
|
||||
$(CC) $(CFLAGS) -Fo$@ -c $<
|
||||
|
||||
prng.exe: prng.obj bbs_rand.obj mpi.lib $(LIBS)
|
||||
$(CC) $(CFLAGS) -Fo$@ $^
|
||||
|
||||
bbsrand.exe: bbsrand.obj bbs_rand.obj mpi.lib $(LIBS)
|
||||
$(CC) $(CFLAGS) -Fo$@ $^
|
||||
|
||||
utils: $(UTILS) prng.exe bbsrand.exe
|
||||
|
||||
#---------------------------------------
|
||||
|
||||
test-info.c: test-arrays.txt
|
||||
$(PERL) make-test-arrays test-arrays.txt > test-info.c
|
||||
|
||||
mpi-test.obj: mpi-test.c test-info.c $(LIBHDRS)
|
||||
$(CC) $(CFLAGS) -Fo$@ -c $<
|
||||
|
||||
mpi-test.exe: mpi-test.obj mpi.lib $(LIBS)
|
||||
$(CC) $(CFLAGS) -Fo$@ $^
|
||||
|
||||
mdxptest.obj: mdxptest.c $(LIBHDRS) mpi-priv.h
|
||||
|
||||
mdxptest.exe: mdxptest.obj mpi.lib $(LIBS)
|
||||
$(CC) $(CFLAGS) -Fo$@ $^
|
||||
|
||||
mulsqr.obj: mulsqr.c logtab.h mpi.h mpi-config.h mpprime.h
|
||||
$(CC) $(CFLAGS) -DMP_SQUARE=1 -Fo$@ -c mulsqr.c
|
||||
|
||||
mulsqr.exe: mulsqr.obj mpi.lib $(LIBS)
|
||||
$(CC) $(CFLAGS) -Fo$@ $^
|
||||
|
||||
#---------------------------------------
|
||||
|
||||
alltests: tests utests mpi-test.exe
|
||||
|
||||
tools: $(TOOLS)
|
||||
|
||||
doc:
|
||||
(cd doc; ./build)
|
||||
|
||||
clean:
|
||||
rm -f *.obj *.lib *.pdb *.ilk
|
||||
cd utils; rm -f *.obj *.lib *.pdb *.ilk
|
||||
|
||||
distclean: clean
|
||||
rm -f mptest? mpi-test metime mulsqr karatsuba
|
||||
rm -f mptest?a mptest?b
|
||||
rm -f utils/mptest?
|
||||
rm -f test-info.c logtab.h
|
||||
rm -f mpi.lib
|
||||
rm -f $(TOOLS)
|
||||
|
||||
dist: Makefile $(HDRS) $(SRCS) $(DOCS)
|
||||
tar -cvf mpi-$(VERS).tar Makefile $(HDRS) $(SRCS) $(DOCS)
|
||||
pgps -ab mpi-$(VERS).tar
|
||||
chmod +r mpi-$(VERS).tar.asc
|
||||
gzip -9 mpi-$(VERS).tar
|
||||
|
||||
|
||||
print:
|
||||
@echo LIBOBJS = $(LIBOBJS)
|
||||
# END
|
||||
@@ -1,799 +0,0 @@
|
||||
***** BEGIN LICENSE BLOCK *****
|
||||
Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
|
||||
The contents of this file are subject to the Mozilla Public License Version
|
||||
1.1 (the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
http://www.mozilla.org/MPL/
|
||||
|
||||
Software distributed under the License is distributed on an "AS IS" basis,
|
||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
for the specific language governing rights and limitations under the
|
||||
License.
|
||||
|
||||
The Original Code is the MPI Arbitrary Precision Integer Arithmetic
|
||||
library.
|
||||
|
||||
The Initial Developer of the Original Code is
|
||||
Michael J. Fromberger <sting@linguist.dartmouth.edu>
|
||||
Portions created by the Initial Developer are Copyright (C) 1997-2000
|
||||
the Initial Developer. All Rights Reserved.
|
||||
|
||||
Contributor(s):
|
||||
|
||||
Alternatively, the contents of this file may be used under the terms of
|
||||
either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
of those above. If you wish to allow use of your version of this file only
|
||||
under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
use your version of this file under the terms of the MPL, indicate your
|
||||
decision by deleting the provisions above and replace them with the notice
|
||||
and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
the provisions above, a recipient may use your version of this file under
|
||||
the terms of any one of the MPL, the GPL or the LGPL.
|
||||
|
||||
***** END LICENSE BLOCK *****
|
||||
|
||||
About the MPI Library
|
||||
---------------------
|
||||
|
||||
The files 'mpi.h' and 'mpi.c' define a simple, arbitrary precision
|
||||
signed integer arithmetic package. The implementation is not the most
|
||||
efficient possible, but the code is small and should be fairly easily
|
||||
portable to just about any machine that supports an ANSI C compiler,
|
||||
as long as it is capable of at least 16-bit arithmetic (but also see
|
||||
below for more on this).
|
||||
|
||||
This library was written with an eye to cryptographic applications;
|
||||
thus, some care is taken to make sure that temporary values are not
|
||||
left lying around in memory when they are no longer in use. This adds
|
||||
some overhead for zeroing buffers before they are released back into
|
||||
the free pool; however, it gives you the assurance that there is only
|
||||
one copy of your important values residing in your process's address
|
||||
space at a time. Obviously, it is difficult to guarantee anything, in
|
||||
a pre-emptive multitasking environment, but this at least helps you
|
||||
keep a lid on the more obvious ways your data can get spread around in
|
||||
memory.
|
||||
|
||||
|
||||
Using the Library
|
||||
-----------------
|
||||
|
||||
To use the MPI library in your program, you must include the header:
|
||||
|
||||
#include "mpi.h"
|
||||
|
||||
This header provides all the type and function declarations you'll
|
||||
need to use the library. Almost all the names defined by the library
|
||||
begin with the prefix 'mp_', so it should be easy to keep them from
|
||||
clashing with your program's namespace (he says, glibly, knowing full
|
||||
well there are always pathological cases).
|
||||
|
||||
There are a few things you may want to configure about the library.
|
||||
By default, the MPI library uses an unsigned short for its digit type,
|
||||
and an unsigned int for its word type. The word type must be big
|
||||
enough to contain at least two digits, for the primitive arithmetic to
|
||||
work out. On my machine, a short is 2 bytes and an int is 4 bytes --
|
||||
but if you have 64-bit ints, you might want to use a 4-byte digit and
|
||||
an 8-byte word. I have tested the library using 1-byte digits and
|
||||
2-byte words, as well. Whatever you choose to do, the things you need
|
||||
to change are:
|
||||
|
||||
(1) The type definitions for mp_digit and mp_word.
|
||||
|
||||
(2) The macro DIGIT_FMT which tells mp_print() how to display a
|
||||
single digit. This is just a printf() format string, so you
|
||||
can adjust it appropriately.
|
||||
|
||||
(3) The macros DIGIT_MAX and MP_WORD_MAX, which specify the
|
||||
largest value expressible in an mp_digit and an mp_word,
|
||||
respectively.
|
||||
|
||||
Both the mp_digit and mp_word should be UNSIGNED integer types. The
|
||||
code relies on having the full positive precision of the type used for
|
||||
digits and words.
|
||||
|
||||
The remaining type definitions should be left alone, for the most
|
||||
part. The code in the library does not make any significant
|
||||
assumptions about the sizes of things, but there is little if any
|
||||
reason to change the other parameters, so I would recommend you leave
|
||||
them as you found them.
|
||||
|
||||
The library comes with a Perl script, 'types.pl', which will scan your
|
||||
current Makefile settings, and attempt to find good definitions for
|
||||
these types. It relies on a Unix sort of build environment, so it
|
||||
probably won't work under MacOS or Windows, but it can be convenient
|
||||
if you're porting to a new flavour of Unix. Just run 'types.pl' at
|
||||
the command line, and it will spit out its results to the standard
|
||||
output.
|
||||
|
||||
|
||||
Conventions
|
||||
-----------
|
||||
|
||||
Most functions in the library return a value of type mp_err. This
|
||||
permits the library to communicate success or various kinds of failure
|
||||
to the calling program. The return values currently defined are:
|
||||
|
||||
MP_OKAY - okay, operation succeeded, all's well
|
||||
MP_YES - okay, the answer is yes (same as MP_OKAY)
|
||||
MP_NO - okay, but answer is no (not MP_OKAY)
|
||||
MP_MEM - operation ran out of memory
|
||||
MP_RANGE - input parameter was out of range
|
||||
MP_BADARG - an invalid input parameter was provided
|
||||
MP_UNDEF - no output value is defined for this input
|
||||
|
||||
The only function which currently uses MP_UNDEF is mp_invmod().
|
||||
Division by zero is undefined, but the division functions will return
|
||||
MP_RANGE for a zero divisor. MP_BADARG usually means you passed a
|
||||
bogus mp_int structure to the function. MP_YES and MP_NO are not used
|
||||
by the library itself; they're defined so you can use them in your own
|
||||
extensions.
|
||||
|
||||
If you need a readable interpretation of these error codes in your
|
||||
program, you may also use the mp_strerror() function. This function
|
||||
takes an mp_err as input, and returns a pointer to a human-readable
|
||||
string describing the meaning of the error. These strings are stored
|
||||
as constants within the library, so the caller should not attempt to
|
||||
modify or free the memory associated with these strings.
|
||||
|
||||
The library represents values in signed-magnitude format. Values
|
||||
strictly less than zero are negative, all others are considered
|
||||
positive (zero is positive by fiat). You can access the 'sign' member
|
||||
of the mp_int structure directly, but better is to use the mp_cmp_z()
|
||||
function, to find out which side of zero the value lies on.
|
||||
|
||||
Most arithmetic functions have a single-digit variant, as well as the
|
||||
full arbitrary-precision. An mp_digit is an unsigned value between 0
|
||||
and DIGIT_MAX inclusive. The radix is available as RADIX. The number
|
||||
of bits in a given digit is given as DIGIT_BIT.
|
||||
|
||||
Generally, input parameters are given before output parameters.
|
||||
Unless otherwise specified, any input parameter can be re-used as an
|
||||
output parameter, without confusing anything.
|
||||
|
||||
The basic numeric type defined by the library is an mp_int. Virtually
|
||||
all the functions in the library take a pointer to an mp_int as one of
|
||||
their parameters. An explanation of how to create and use these
|
||||
<HR>
|
||||
<A NAME="p23">
|
||||
<H3>Problem 23:</H3>
|
||||
|
||||
structures follows. And so, without further ado...
|
||||
|
||||
|
||||
Initialization and Cleanup
|
||||
--------------------------
|
||||
|
||||
The basic numeric type defined by the library is an 'mp_int'.
|
||||
However, it is not sufficient to simply declare a variable of type
|
||||
mp_int in your program. These variables also need to be initialized
|
||||
before they can be used, to allocate the internal storage they require
|
||||
for computation.
|
||||
|
||||
This is done using one of the following functions:
|
||||
|
||||
mp_init(mp_int *mp);
|
||||
mp_init_copy(mp_int *mp, mp_int *from);
|
||||
mp_init_size(mp_int *mp, mp_size p);
|
||||
|
||||
Each of these requires a pointer to a structure of type mp_int. The
|
||||
basic mp_init() simply initializes the mp_int to a default size, and
|
||||
sets its value to zero. If you would like to initialize a copy of an
|
||||
existing mp_int, use mp_init_copy(), where the 'from' parameter is the
|
||||
mp_int you'd like to make a copy of. The third function,
|
||||
mp_init_size(), permits you to specify how many digits of precision
|
||||
should be preallocated for your mp_int. This can help the library
|
||||
avoid unnecessary re-allocations later on.
|
||||
|
||||
The default precision used by mp_init() can be retrieved using:
|
||||
|
||||
precision = mp_get_prec();
|
||||
|
||||
This returns the number of digits that will be allocated. You can
|
||||
change this value by using:
|
||||
|
||||
mp_set_prec(unsigned int prec);
|
||||
|
||||
Any positive value is acceptable -- if you pass zero, the default
|
||||
precision will be re-set to the compiled-in library default (this is
|
||||
specified in the header file 'mpi-config.h', and typically defaults to
|
||||
8 or 16).
|
||||
|
||||
Just as you must allocate an mp_int before you can use it, you must
|
||||
clean up the structure when you are done with it. This is performed
|
||||
using the mp_clear() function. Remember that any mp_int that you
|
||||
create as a local variable in a function must be mp_clear()'d before
|
||||
that function exits, or else the memory allocated to that mp_int will
|
||||
be orphaned and unrecoverable.
|
||||
|
||||
To set an mp_int to a given value, the following functions are given:
|
||||
|
||||
mp_set(mp_int *mp, mp_digit d);
|
||||
mp_set_int(mp_int *mp, long z);
|
||||
|
||||
The mp_set() function sets the mp_int to a single digit value, while
|
||||
mp_set_int() sets the mp_int to a signed long integer value.
|
||||
|
||||
To set an mp_int to zero, use:
|
||||
|
||||
mp_zero(mp_int *mp);
|
||||
|
||||
|
||||
Copying and Moving
|
||||
------------------
|
||||
|
||||
If you have two initialized mp_int's, and you want to copy the value
|
||||
of one into the other, use:
|
||||
|
||||
mp_copy(from, to)
|
||||
|
||||
This takes care of clearing the old value of 'to', and copies the new
|
||||
value into it. If 'to' is not yet initialized, use mp_init_copy()
|
||||
instead (see above).
|
||||
|
||||
Note: The library tries, whenever possible, to avoid allocating
|
||||
---- new memory. Thus, mp_copy() tries first to satisfy the needs
|
||||
of the copy by re-using the memory already allocated to 'to'.
|
||||
Only if this proves insufficient will mp_copy() actually
|
||||
allocate new memory.
|
||||
|
||||
For this reason, if you know a priori that 'to' has enough
|
||||
available space to hold 'from', you don't need to check the
|
||||
return value of mp_copy() for memory failure. The USED()
|
||||
macro tells you how many digits are used by an mp_int, and
|
||||
the ALLOC() macro tells you how many are allocated.
|
||||
|
||||
If you have two initialized mp_int's, and you want to exchange their
|
||||
values, use:
|
||||
|
||||
mp_exch(a, b)
|
||||
|
||||
This is better than using mp_copy() with a temporary, since it will
|
||||
not (ever) touch the memory allocator -- it just swaps the exact
|
||||
contents of the two structures. The mp_exch() function cannot fail;
|
||||
if you pass it an invalid structure, it just ignores it, and does
|
||||
nothing.
|
||||
|
||||
|
||||
Basic Arithmetic
|
||||
----------------
|
||||
|
||||
Once you have initialized your integers, you can operate on them. The
|
||||
basic arithmetic functions on full mp_int values are:
|
||||
|
||||
mp_add(a, b, c) - computes c = a + b
|
||||
mp_sub(a, b, c) - computes c = a - b
|
||||
mp_mul(a, b, c) - computes c = a * b
|
||||
mp_sqr(a, b) - computes b = a * a
|
||||
mp_div(a, b, q, r) - computes q, r such that a = bq + r
|
||||
mp_div_2d(a, d, q, r) - computes q = a / 2^d, r = a % 2^d
|
||||
mp_expt(a, b, c) - computes c = a ** b
|
||||
mp_2expt(a, k) - computes a = 2^k
|
||||
mp_sqrt(a, c) - computes c = floor(sqrt(a))
|
||||
|
||||
The mp_div_2d() function efficiently computes division by powers of
|
||||
two. Either the q or r parameter may be NULL, in which case that
|
||||
portion of the computation will be discarded.
|
||||
|
||||
The algorithms used for some of the computations here are described in
|
||||
the following files which are included with this distribution:
|
||||
|
||||
mul.txt Describes the multiplication algorithm
|
||||
div.txt Describes the division algorithm
|
||||
expt.txt Describes the exponentiation algorithm
|
||||
sqrt.txt Describes the square-root algorithm
|
||||
square.txt Describes the squaring algorithm
|
||||
|
||||
There are single-digit versions of most of these routines, as well.
|
||||
In the following prototypes, 'd' is a single mp_digit:
|
||||
|
||||
mp_add_d(a, d, c) - computes c = a + d
|
||||
mp_sub_d(a, d, c) - computes c = a - d
|
||||
mp_mul_d(a, d, c) - computes c = a * d
|
||||
mp_mul_2(a, c) - computes c = a * 2
|
||||
mp_div_d(a, d, q, r) - computes q, r such that a = bq + r
|
||||
mp_div_2(a, c) - computes c = a / 2
|
||||
mp_expt_d(a, d, c) - computes c = a ** d
|
||||
|
||||
The mp_mul_2() and mp_div_2() functions take advantage of the internal
|
||||
representation of an mp_int to do multiplication by two more quickly
|
||||
than mp_mul_d() would. Other basic functions of an arithmetic variety
|
||||
include:
|
||||
|
||||
mp_zero(a) - assign 0 to a
|
||||
mp_neg(a, c) - negate a: c = -a
|
||||
mp_abs(a, c) - absolute value: c = |a|
|
||||
|
||||
|
||||
Comparisons
|
||||
-----------
|
||||
|
||||
Several comparison functions are provided. Each of these, unless
|
||||
otherwise specified, returns zero if the comparands are equal, < 0 if
|
||||
the first is less than the second, and > 0 if the first is greater
|
||||
than the second:
|
||||
|
||||
mp_cmp_z(a) - compare a <=> 0
|
||||
mp_cmp_d(a, d) - compare a <=> d, d is a single digit
|
||||
mp_cmp(a, b) - compare a <=> b
|
||||
mp_cmp_mag(a, b) - compare |a| <=> |b|
|
||||
mp_cmp_int(a, z) - compare a <=> z, z is a signed long integer
|
||||
mp_isodd(a) - return nonzero if odd, zero otherwise
|
||||
mp_iseven(a) - return nonzero if even, zero otherwise
|
||||
|
||||
|
||||
Modular Arithmetic
|
||||
------------------
|
||||
|
||||
Modular variations of the basic arithmetic functions are also
|
||||
supported. These are available if the MP_MODARITH parameter in
|
||||
mpi-config.h is turned on (it is by default). The modular arithmetic
|
||||
functions are:
|
||||
|
||||
mp_mod(a, m, c) - compute c = a (mod m), 0 <= c < m
|
||||
mp_mod_d(a, d, c) - compute c = a (mod d), 0 <= c < d (see below)
|
||||
mp_addmod(a, b, m, c) - compute c = (a + b) mod m
|
||||
mp_submod(a, b, m, c) - compute c = (a - b) mod m
|
||||
mp_mulmod(a, b, m, c) - compute c = (a * b) mod m
|
||||
mp_sqrmod(a, m, c) - compute c = (a * a) mod m
|
||||
mp_exptmod(a, b, m, c) - compute c = (a ** b) mod m
|
||||
mp_exptmod_d(a, d, m, c)- compute c = (a ** d) mod m
|
||||
|
||||
The mp_sqr() function squares its input argument. A call to mp_sqr(a,
|
||||
c) is identical in meaning to mp_mul(a, a, c); however, if the
|
||||
MP_SQUARE variable is set true in mpi-config.h (see below), then it
|
||||
will be implemented with a different algorithm, that is supposed to
|
||||
take advantage of the redundant computation that takes place during
|
||||
squaring. Unfortunately, some compilers result in worse performance
|
||||
on this code, so you can change the behaviour at will. There is a
|
||||
utility program "mulsqr.c" that lets you test which does better on
|
||||
your system.
|
||||
|
||||
The mp_sqrmod() function is analogous to the mp_sqr() function; it
|
||||
uses the mp_sqr() function rather than mp_mul(), and then performs the
|
||||
modular reduction. This probably won't help much unless you are doing
|
||||
a lot of them.
|
||||
|
||||
See the file 'square.txt' for a synopsis of the algorithm used.
|
||||
|
||||
Note: The mp_mod_d() function computes a modular reduction around
|
||||
---- a single digit d. The result is a single digit c.
|
||||
|
||||
Because an inverse is defined for a (mod m) if and only if (a, m) = 1
|
||||
(that is, if a and m are relatively prime), mp_invmod() may not be
|
||||
able to compute an inverse for the arguments. In this case, it
|
||||
returns the value MP_UNDEF, and does not modify c. If an inverse is
|
||||
defined, however, it returns MP_OKAY, and sets c to the value of the
|
||||
inverse (mod m).
|
||||
|
||||
See the file 'redux.txt' for a description of the modular reduction
|
||||
algorithm used by mp_exptmod().
|
||||
|
||||
|
||||
Greatest Common Divisor
|
||||
-----------------------
|
||||
|
||||
If The greates common divisor of two values can be found using one of the
|
||||
following functions:
|
||||
|
||||
mp_gcd(a, b, c) - compute c = (a, b) using binary algorithm
|
||||
mp_lcm(a, b, c) - compute c = [a, b] = ab / (a, b)
|
||||
mp_xgcd(a, b, g, x, y) - compute g, x, y so that ax + by = g = (a, b)
|
||||
|
||||
Also provided is a function to compute modular inverses, if they
|
||||
exist:
|
||||
|
||||
mp_invmod(a, m, c) - compute c = a^-1 (mod m), if it exists
|
||||
|
||||
The function mp_xgcd() computes the greatest common divisor, and also
|
||||
returns values of x and y satisfying Bezout's identity. This is used
|
||||
by mp_invmod() to find modular inverses. However, if you do not need
|
||||
these values, you will find that mp_gcd() is MUCH more efficient,
|
||||
since it doesn't need all the intermediate values that mp_xgcd()
|
||||
requires in order to compute x and y.
|
||||
|
||||
The mp_gcd() (and mp_xgcd()) functions use the binary (extended) GCD
|
||||
algorithm due to Josef Stein.
|
||||
|
||||
|
||||
Input & Output Functions
|
||||
------------------------
|
||||
|
||||
The following basic I/O routines are provided. These are present at
|
||||
all times:
|
||||
|
||||
mp_read_radix(mp, str, r) - convert a string in radix r to an mp_int
|
||||
mp_read_raw(mp, s, len) - convert a string of bytes to an mp_int
|
||||
mp_radix_size(mp, r) - return length of buffer needed by mp_toradix()
|
||||
mp_raw_size(mp) - return length of buffer needed by mp_toraw()
|
||||
mp_toradix(mp, str, r) - convert an mp_int to a string of radix r
|
||||
digits
|
||||
mp_toraw(mp, str) - convert an mp_int to a string of bytes
|
||||
mp_tovalue(ch, r) - convert ch to its value when taken as
|
||||
a radix r digit, or -1 if invalid
|
||||
mp_strerror(err) - get a string describing mp_err value 'err'
|
||||
|
||||
If you compile the MPI library with MP_IOFUNC defined, you will also
|
||||
have access to the following additional I/O function:
|
||||
|
||||
mp_print(mp, ofp) - print an mp_int as text to output stream ofp
|
||||
|
||||
Note that mp_radix_size() returns a size in bytes guaranteed to be AT
|
||||
LEAST big enough for the digits output by mp_toradix(). Because it
|
||||
uses an approximation technique to figure out how many digits will be
|
||||
needed, it may return a figure which is larger than necessary. Thus,
|
||||
the caller should not rely on the value to determine how many bytes
|
||||
will actually be written by mp_toradix(). The string mp_toradix()
|
||||
creates will be NUL terminated, so the standard C library function
|
||||
strlen() should be able to ascertain this for you, if you need it.
|
||||
|
||||
The mp_read_radix() and mp_toradix() functions support bases from 2 to
|
||||
64 inclusive. If you require more general radix conversion facilities
|
||||
than this, you will need to write them yourself (that's why mp_div_d()
|
||||
is provided, after all).
|
||||
|
||||
Note: mp_read_radix() will accept as digits either capital or
|
||||
---- lower-case letters. However, the current implementation of
|
||||
mp_toradix() only outputs upper-case letters, when writing
|
||||
bases betwee 10 and 36. The underlying code supports using
|
||||
lower-case letters, but the interface stub does not have a
|
||||
selector for it. You can add one yourself if you think it
|
||||
is worthwhile -- I do not. Bases from 36 to 64 use lower-
|
||||
case letters as distinct from upper-case. Bases 63 and
|
||||
64 use the characters '+' and '/' as digits.
|
||||
|
||||
Note also that compiling with MP_IOFUNC defined will cause
|
||||
inclusion of <stdio.h>, so if you are trying to write code
|
||||
which does not depend on the standard C library, you will
|
||||
probably want to avoid this option. This is needed because
|
||||
the mp_print() function takes a standard library FILE * as
|
||||
one of its parameters, and uses the fprintf() function.
|
||||
|
||||
The mp_toraw() function converts the integer to a sequence of bytes,
|
||||
in big-endian ordering (most-significant byte first). Assuming your
|
||||
bytes are 8 bits wide, this corresponds to base 256. The sign is
|
||||
encoded as a single leading byte, whose value is 0 for zero or
|
||||
positive values, or 1 for negative values. The mp_read_raw() function
|
||||
reverses this process -- it takes a buffer of bytes, interprets the
|
||||
first as a sign indicator (0 = zero/positive, nonzero = negative), and
|
||||
the rest as a sequence of 1-byte digits in big-endian ordering.
|
||||
|
||||
The mp_raw_size() function returns the exact number of bytes required
|
||||
to store the given integer in "raw" format (as described in the
|
||||
previous paragraph). Zero is returned in case of error; a valid
|
||||
integer will require at least three bytes of storage.
|
||||
|
||||
In previous versions of the MPI library, an "external representation
|
||||
format" was supported. This was removed, however, because I found I
|
||||
was never using it, it was not as portable as I would have liked, and
|
||||
I decided it was a waste of space.
|
||||
|
||||
|
||||
Other Functions
|
||||
---------------
|
||||
|
||||
The files 'mpprime.h' and 'mpprime.c' define some routines which are
|
||||
useful for divisibility testing and probabilistic primality testing.
|
||||
The routines defined are:
|
||||
|
||||
mpp_divis(a, b) - is a divisible by b?
|
||||
mpp_divis_d(a, d) - is a divisible by digit d?
|
||||
mpp_random(a) - set a to random value at current precision
|
||||
mpp_random_size(a, prec) - set a to random value at given precision
|
||||
|
||||
Note: The mpp_random() and mpp_random_size() functions use the C
|
||||
---- library's rand() function to generate random values. It is
|
||||
up to the caller to seed this generator before it is called.
|
||||
These functions are not suitable for generating quantities
|
||||
requiring cryptographic-quality randomness; they are intended
|
||||
primarily for use in primality testing.
|
||||
|
||||
Note too that the MPI library does not call srand(), so your
|
||||
application should do this, if you ever want the sequence
|
||||
to change.
|
||||
|
||||
mpp_divis_vector(a, v, s, w) - is a divisible by any of the s digits
|
||||
in v? If so, let w be the index of
|
||||
that digit
|
||||
|
||||
mpp_divis_primes(a, np) - is a divisible by any of the first np
|
||||
primes? If so, set np to the prime
|
||||
which divided a.
|
||||
|
||||
mpp_fermat(a, d) - test if w^a = w (mod a). If so,
|
||||
returns MP_YES, otherwise MP_NO.
|
||||
|
||||
mpp_pprime(a, nt) - perform nt iterations of the Rabin-
|
||||
Miller probabilistic primality test
|
||||
on a. Returns MP_YES if all tests
|
||||
passed, or MP_NO if any test fails.
|
||||
|
||||
The mpp_fermat() function works based on Fermat's little theorem, a
|
||||
consequence of which is that if p is a prime, and (w, p) = 1, then:
|
||||
|
||||
w^p = w (mod p)
|
||||
|
||||
Put another way, if w^p != w (mod p), then p is not prime. The test
|
||||
is expensive to compute, but it helps to quickly eliminate an enormous
|
||||
class of composite numbers prior to Rabin-Miller testing.
|
||||
|
||||
Building the Library
|
||||
--------------------
|
||||
|
||||
The MPI library is designed to be as self-contained as possible. You
|
||||
should be able to compile it with your favourite ANSI C compiler, and
|
||||
link it into your program directly. If you are on a Unix system using
|
||||
the GNU C compiler (gcc), the following should work:
|
||||
|
||||
% gcc -ansi -pedantic -Wall -O2 -c mpi.c
|
||||
|
||||
The file 'mpi-config.h' defines several configurable parameters for
|
||||
the library, which you can adjust to suit your application. At the
|
||||
time of this writing, the available options are:
|
||||
|
||||
MP_IOFUNC - Define true to include the mp_print() function,
|
||||
which is moderately useful for debugging. This
|
||||
implicitly includes <stdio.h>.
|
||||
|
||||
MP_MODARITH - Define true to include the modular arithmetic
|
||||
functions. If you don't need modular arithmetic
|
||||
in your application, you can set this to zero to
|
||||
leave out all the modular routines.
|
||||
|
||||
MP_NUMTH - Define true to include number theoretic functions
|
||||
such as mp_gcd(), mp_lcm(), and mp_invmod().
|
||||
|
||||
MP_LOGTAB - If true, the file "logtab.h" is included, which
|
||||
is basically a static table of base 2 logarithms.
|
||||
These are used to compute how big the buffers for
|
||||
radix conversion need to be. If you set this false,
|
||||
the library includes <math.h> and uses log(). This
|
||||
typically forces you to link against math libraries.
|
||||
|
||||
MP_MEMSET - If true, use memset() to zero buffers. If you run
|
||||
into weird alignment related bugs, set this to zero
|
||||
and an explicit loop will be used.
|
||||
|
||||
MP_MEMCPY - If true, use memcpy() to copy buffers. If you run
|
||||
into weird alignment bugs, set this to zero and an
|
||||
explicit loop will be used.
|
||||
|
||||
MP_CRYPTO - If true, whenever arrays of digits are free'd, they
|
||||
are zeroed first. This is useful if you're using
|
||||
the library in a cryptographic environment; however,
|
||||
it does add overhead to each free operation. For
|
||||
performance, if you don't care about zeroing your
|
||||
buffers, set this to false.
|
||||
|
||||
MP_ARGCHK - Set to 0, 1, or 2. This defines how the argument
|
||||
checking macro, ARGCHK(), gets expanded. If this
|
||||
is set to zero, ARGCHK() expands to nothing; no
|
||||
argument checks are performed. If this is 1, the
|
||||
ARGCHK() macro expands to code that returns MP_BADARG
|
||||
or similar at runtime. If it is 2, ARGCHK() expands
|
||||
to an assert() call that aborts the program on a
|
||||
bad input.
|
||||
|
||||
MP_DEBUG - Turns on debugging output. This is probably not at
|
||||
all useful unless you are debugging the library. It
|
||||
tends to spit out a LOT of output.
|
||||
|
||||
MP_DEFPREC - The default precision of a newly-created mp_int, in
|
||||
digits. The precision can be changed at runtime by
|
||||
the mp_set_prec() function, but this is its initial
|
||||
value.
|
||||
|
||||
MP_SQUARE - If this is set to a nonzero value, the mp_sqr()
|
||||
function will use an alternate algorithm that takes
|
||||
advantage of the redundant inner product computation
|
||||
when both multiplicands are identical. Unfortunately,
|
||||
with some compilers this is actually SLOWER than just
|
||||
calling mp_mul() with the same argument twice. So
|
||||
if you set MP_SQUARE to zero, mp_sqr() will be expan-
|
||||
ded into a call to mp_mul(). This applies to all
|
||||
the uses of mp_sqr(), including mp_sqrmod() and the
|
||||
internal calls to s_mp_sqr() inside mpi.c
|
||||
|
||||
The program 'mulsqr' (mulsqr.c) can be used to test
|
||||
which works best for your configuration. Set up the
|
||||
CC and CFLAGS variables in the Makefile, then type:
|
||||
|
||||
make mulsqr
|
||||
|
||||
Invoke it with arguments similar to the following:
|
||||
|
||||
mulsqr 25000 1024
|
||||
|
||||
That is, 25000 products computed on 1024-bit values.
|
||||
The output will compare the two timings, and recommend
|
||||
a setting for MP_SQUARE. It is off by default.
|
||||
|
||||
If you would like to use the mp_print() function (see above), be sure
|
||||
to define MP_IOFUNC in mpi-config.h. Many of the test drivers in the
|
||||
'tests' subdirectory expect this to be defined (although the test
|
||||
driver 'mpi-test' doesn't need it)
|
||||
|
||||
The Makefile which comes with the library should take care of building
|
||||
the library for you, if you have set the CC and CFLAGS variables at
|
||||
the top of the file appropriately. By default, they are set up to
|
||||
use the GNU C compiler:
|
||||
|
||||
CC=gcc
|
||||
CFLAGS=-ansi -pedantic -Wall -O2
|
||||
|
||||
If all goes well, the library should compile without warnings using
|
||||
this combination. You should, of course, make whatever adjustments
|
||||
you find necessary.
|
||||
|
||||
The MPI library distribution comes with several additional programs
|
||||
which are intended to demonstrate the use of the library, and provide
|
||||
a framework for testing it. There are a handful of test driver
|
||||
programs, in the files named 'mptest-X.c', where X is a digit. Also,
|
||||
there are some simple command-line utilities (in the 'utils'
|
||||
directory) for manipulating large numbers. These include:
|
||||
|
||||
basecvt.c A radix-conversion program, supporting bases from
|
||||
2 to 64 inclusive.
|
||||
|
||||
bbsrand.c A BBS (quadratic residue) pseudo-random number
|
||||
generator. The file 'bbsrand.c' is just the driver
|
||||
for the program; the real code lives in the files
|
||||
'bbs_rand.h' and 'bbs_rand.c'
|
||||
|
||||
dec2hex.c Converts decimal to hexadecimal
|
||||
|
||||
gcd.c Computes the greatest common divisor of two values.
|
||||
If invoked as 'xgcd', also computes constants x and
|
||||
y such that (a, b) = ax + by, in accordance with
|
||||
Bezout's identity.
|
||||
|
||||
hex2dec.c Converts hexadecimal to decimal
|
||||
|
||||
invmod.c Computes modular inverses
|
||||
|
||||
isprime.c Performs the Rabin-Miller probabilistic primality
|
||||
test on a number. Values which fail this test are
|
||||
definitely composite, and those which pass are very
|
||||
likely to be prime (although there are no guarantees)
|
||||
|
||||
lap.c Computes the order (least annihilating power) of
|
||||
a value v modulo m. Very dumb algorithm.
|
||||
|
||||
primegen.c Generates large (probable) primes.
|
||||
|
||||
prng.c A pseudo-random number generator based on the
|
||||
BBS generator code in 'bbs_rand.c'
|
||||
|
||||
sieve.c Implements the Sieve of Eratosthenes, using a big
|
||||
bitmap, to generate a list of prime numbers.
|
||||
|
||||
fact.c Computes the factorial of an arbitrary precision
|
||||
integer (iterative).
|
||||
|
||||
exptmod.c Computes arbitrary precision modular exponentiation
|
||||
from the command line (exptmod a b m -> a^b (mod m))
|
||||
|
||||
Most of these can be built from the Makefile that comes with the
|
||||
library. Try 'make tools', if your environment supports it. (If you
|
||||
are compiling on a Macintosh, I'm afraid you'll have to build them by
|
||||
hand -- fortunately, this is not difficult -- the library itself
|
||||
should compile just fine under Metrowerks CodeWarrior).
|
||||
|
||||
|
||||
Testing the Library
|
||||
-------------------
|
||||
|
||||
Automatic test vectors are included, in the form of a program called
|
||||
'mpi-test'. To build this program and run all the tests, simply
|
||||
invoke the shell script 'all-tests'. If all the tests pass, you
|
||||
should see a message:
|
||||
|
||||
All tests passed
|
||||
|
||||
If something went wrong, you'll get:
|
||||
|
||||
One or more tests failed.
|
||||
|
||||
If this happens, scan back through the preceding lines, to see which
|
||||
test failed. Any failure indicates a bug in the library, which needs
|
||||
to be fixed before it will give accurate results. If you get any such
|
||||
thing, please let me know, and I'll try to fix it. Please let me know
|
||||
what platform and compiler you were using, as well as which test
|
||||
failed. If a reason for failure was given, please send me that text
|
||||
as well.
|
||||
|
||||
If you're on a system such as the Macintosh, where the standard Unix
|
||||
build tools don't work, you can build the 'mpi-test' program manually,
|
||||
and run it by hand. This is tedious and obnoxious, sorry.
|
||||
|
||||
Further manual testing can be performed by building the manual testing
|
||||
programs, whose source is found in the 'tests' subdirectory. Each
|
||||
test is in a source file called 'mptest-X.c'. The Makefile contains a
|
||||
target to build all of them at once:
|
||||
|
||||
make tests
|
||||
|
||||
Read the comments at the top of each source file to see what the
|
||||
driver is supposed to test. You probably don't need to do this; these
|
||||
programs were only written to help me as I was developing the library.
|
||||
|
||||
The relevant files are:
|
||||
|
||||
mpi-test.c The source for the test driver
|
||||
|
||||
make-test-arrays A Perl script to generate some of the internal
|
||||
data structures used by mpi-test.c
|
||||
|
||||
test-arrays.txt The source file for make-test-arrays
|
||||
|
||||
all-tests A Bourne shell script which runs all the
|
||||
tests in the mpi-test suite
|
||||
|
||||
Running 'make mpi-test' should build the mpi-test program. If you
|
||||
cannot use make, here is what needs to be done:
|
||||
|
||||
(1) Use 'make-test-arrays' to generate the file 'test-info.c' from
|
||||
the 'test-arrays.txt' file. Since Perl can be found everywhere,
|
||||
even on the Macintosh, this should be no trouble. Under Unix,
|
||||
this looks like:
|
||||
|
||||
make-test-arrays test-arrays.txt > test-info.c
|
||||
|
||||
(2) Build the MPI library:
|
||||
|
||||
gcc -ansi -pedantic -Wall -c mpi.c
|
||||
|
||||
(3) Build the mpi-test program:
|
||||
|
||||
gcc -ansi -pedantic -Wall -o mpi-test mpi.o mpi-test.c
|
||||
|
||||
When you've got mpi-test, you can use 'all-tests' to run all the tests
|
||||
made available by mpi-test. If any of them fail, there should be a
|
||||
diagnostic indicating what went wrong. These are fairly high-level
|
||||
diagnostics, and won't really help you debug the problem; they're
|
||||
simply intended to help you isolate which function caused the problem.
|
||||
If you encounter a problem of this sort, feel free to e-mail me, and I
|
||||
will certainly attempt to help you debug it.
|
||||
|
||||
Note: Several of the tests hard-wired into 'mpi-test' operate under
|
||||
---- the assumption that you are using at least a 16-bit mp_digit
|
||||
type. If that is not true, several tests might fail, because
|
||||
of range problems with the maximum digit value.
|
||||
|
||||
If you are using an 8-bit digit, you will also need to
|
||||
modify the code for mp_read_raw(), which assumes that
|
||||
multiplication by 256 can be done with mp_mul_d(), a
|
||||
fact that fails when DIGIT_MAX is 255. You can replace
|
||||
the call with s_mp_lshd(), which will give you the same
|
||||
effect, and without doing as much work. :)
|
||||
|
||||
Acknowledgements:
|
||||
----------------
|
||||
|
||||
The algorithms used in this library were drawn primarily from Volume
|
||||
2 of Donald Knuth's magnum opus, _The Art of Computer Programming_,
|
||||
"Semi-Numerical Methods". Barrett's algorithm for modular reduction
|
||||
came from Menezes, Oorschot, and Vanstone's _Handbook of Applied
|
||||
Cryptography_, Chapter 14.
|
||||
|
||||
Thanks are due to Tom St. Denis, for finding an obnoxious sign-related
|
||||
bug in mp_read_raw() that made things break on platforms which use
|
||||
signed chars.
|
||||
|
||||
About the Author
|
||||
----------------
|
||||
|
||||
This software was written by Michael J. Fromberger. You can contact
|
||||
the author as follows:
|
||||
|
||||
E-mail: <sting@linguist.dartmouth.edu>
|
||||
|
||||
Postal: 8000 Cummings Hall, Thayer School of Engineering
|
||||
Dartmouth College, Hanover, New Hampshire, USA
|
||||
|
||||
PGP key: http://linguist.dartmouth.edu/~sting/keys/mjf.html
|
||||
9736 188B 5AFA 23D6 D6AA BE0D 5856 4525 289D 9907
|
||||
|
||||
Last updated: 16-Jan-2000
|
||||
@@ -1,115 +0,0 @@
|
||||
#!/bin/sh
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is the MPI Arbitrary Precision Integer Arithmetic library.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Michael J. Fromberger <sting@linguist.dartmouth.edu>.
|
||||
# Portions created by the Initial Developer are Copyright (C) 1997
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
ECHO=/bin/echo
|
||||
MAKE=gmake
|
||||
|
||||
$ECHO "\n** Running unit tests for MPI library\n"
|
||||
|
||||
# Build the mpi-test program, which comprises all the unit tests for
|
||||
# the MPI library...
|
||||
|
||||
$ECHO "Bringing mpi-test up to date ... "
|
||||
if $MAKE mpi-test ; then
|
||||
:
|
||||
else
|
||||
$ECHO " "
|
||||
$ECHO "Make failed to build mpi-test."
|
||||
$ECHO " "
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -x mpi-test ] ; then
|
||||
$ECHO " "
|
||||
$ECHO "Cannot find 'mpi-test' program, testing cannot continue."
|
||||
$ECHO " "
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Get the list of available test suites...
|
||||
tests=`mpi-test list | awk '{print $1}'`
|
||||
errs=0
|
||||
|
||||
# Run each test suite and check the result code of mpi-test
|
||||
for test in $tests ; do
|
||||
$ECHO "$test ... \c"
|
||||
if mpi-test $test ; then
|
||||
$ECHO "passed"
|
||||
else
|
||||
$ECHO "FAILED"
|
||||
errs=1
|
||||
fi
|
||||
done
|
||||
|
||||
# If any tests failed, we'll stop at this point
|
||||
if [ "$errs" = "0" ] ; then
|
||||
$ECHO "All unit tests passed"
|
||||
else
|
||||
$ECHO "One or more tests failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Now try to build the 'pi' program, and see if it can compute the
|
||||
# first thousand digits of pi correctly
|
||||
$ECHO "\n** Running other tests\n"
|
||||
|
||||
$ECHO "Bringing 'pi' up to date ... "
|
||||
if $MAKE pi ; then
|
||||
:
|
||||
else
|
||||
$ECHO "\nMake failed to build pi.\n"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -x pi ] ; then
|
||||
$ECHO "\nCannot find 'pi' program; testing cannot continue.\n"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
./pi 2000 > /tmp/pi.tmp.$$
|
||||
if cmp tests/pi2k.txt /tmp/pi.tmp.$$ ; then
|
||||
$ECHO "Okay! The pi test passes."
|
||||
else
|
||||
$ECHO "Oops! The pi test failed. :("
|
||||
exit 1
|
||||
fi
|
||||
|
||||
rm -f /tmp/pi.tmp.$$
|
||||
|
||||
exit 0
|
||||
|
||||
# Here there be dragons
|
||||
@@ -1,11 +0,0 @@
|
||||
Within this directory, each of the file listed below is licensed under
|
||||
the terms given in the file LICENSE-MPL, also in this directory.
|
||||
|
||||
basecvt.pod
|
||||
gcd.pod
|
||||
invmod.pod
|
||||
isprime.pod
|
||||
lap.pod
|
||||
mpi-test.pod
|
||||
prime.txt
|
||||
prng.pod
|
||||
@@ -1,32 +0,0 @@
|
||||
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 the Netscape security libraries.
|
||||
|
||||
The Initial Developer of the Original Code is Netscape
|
||||
Communications Corporation. Portions created by Netscape are
|
||||
Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
Rights Reserved.
|
||||
|
||||
Contributor(s):
|
||||
|
||||
Alternatively, the contents of this file may be used under the
|
||||
terms of the GNU General Public License Version 2 or later (the
|
||||
"GPL"), in which case the provisions of the GPL are applicable
|
||||
instead of those above. If you wish to allow use of your
|
||||
version of this file only under the terms of the GPL and not to
|
||||
allow others to use your version of this file under the MPL,
|
||||
indicate your decision by deleting the provisions above and
|
||||
replace them with the notice and other provisions required by
|
||||
the GPL. If you do not delete the provisions above, a recipient
|
||||
may use your version of this file under either the MPL or the
|
||||
GPL.
|
||||
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
=head1 NAME
|
||||
|
||||
basecvt - radix conversion for arbitrary precision integers
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
basecvt <ibase> <obase> [values]
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
The B<basecvt> program is a command-line tool for converting integers
|
||||
of arbitrary precision from one radix to another. The current version
|
||||
supports radix values from 2 (binary) to 64, inclusive. The first two
|
||||
command line arguments specify the input and output radix, in base 10.
|
||||
Any further arguments are taken to be integers notated in the input
|
||||
radix, and these are converted to the output radix. The output is
|
||||
written, one integer per line, to standard output.
|
||||
|
||||
When reading integers, only digits considered "valid" for the input
|
||||
radix are considered. Processing of an integer terminates when an
|
||||
invalid input digit is encountered. So, for example, if you set the
|
||||
input radix to 10 and enter '10ACF', B<basecvt> would assume that you
|
||||
had entered '10' and ignore the rest of the string.
|
||||
|
||||
If no values are provided, no output is written, but the program
|
||||
simply terminates with a zero exit status. Error diagnostics are
|
||||
written to standard error in the event of out-of-range radix
|
||||
specifications. Regardless of the actual values of the input and
|
||||
output radix, the radix arguments are taken to be in base 10 (decimal)
|
||||
notation.
|
||||
|
||||
=head1 DIGITS
|
||||
|
||||
For radices from 2-10, standard ASCII decimal digits 0-9 are used for
|
||||
both input and output. For radices from 11-36, the ASCII letters A-Z
|
||||
are also included, following the convention used in hexadecimal. In
|
||||
this range, input is accepted in either upper or lower case, although
|
||||
on output only lower-case letters are used.
|
||||
|
||||
For radices from 37-62, the output includes both upper- and lower-case
|
||||
ASCII letters, and case matters. In this range, case is distinguished
|
||||
both for input and for output values.
|
||||
|
||||
For radices 63 and 64, the characters '+' (plus) and '/' (forward
|
||||
solidus) are also used. These are derived from the MIME base64
|
||||
encoding scheme. The overall encoding is not the same as base64,
|
||||
because the ASCII digits are used for the bottom of the range, and the
|
||||
letters are shifted upward; however, the output will consist of the
|
||||
same character set.
|
||||
|
||||
This input and output behaviour is inherited from the MPI library used
|
||||
by B<basecvt>, and so is not configurable at runtime.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
dec2hex(1), hex2dec(1)
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Michael J. Fromberger <sting@linguist.dartmouth.edu>
|
||||
Thayer School of Engineering, Hanover, New Hampshire, USA
|
||||
|
||||
$Date: 2000-07-14 00:44:31 $
|
||||
@@ -1,66 +0,0 @@
|
||||
#!/bin/sh
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is the MPI Arbitrary Precision Integer Arithmetic library.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Michael J. Fromberger <sting@linguist.dartmouth.edu>.
|
||||
# Portions created by the Initial Developer are Copyright (C) 1998
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Netscape Communications Corporation
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
# $Id: build,v 1.3 2005-02-02 22:28:22 gerv%gerv.net Exp $
|
||||
#
|
||||
|
||||
VERS="1.7p6"
|
||||
SECT="1"
|
||||
NAME="MPI Tools"
|
||||
|
||||
echo "Building manual pages ..."
|
||||
case $# in
|
||||
0)
|
||||
files=`ls *.pod`
|
||||
;;
|
||||
*)
|
||||
files=$*
|
||||
;;
|
||||
esac
|
||||
|
||||
for name in $files
|
||||
do
|
||||
echo -n "$name ... "
|
||||
# sname=`noext $name`
|
||||
sname=`basename $name .pod`
|
||||
pod2man --section="$SECT" --center="$NAME" --release="$VERS" $name > $sname.$SECT
|
||||
echo "(done)"
|
||||
done
|
||||
|
||||
echo "Finished building."
|
||||
|
||||
@@ -1,101 +0,0 @@
|
||||
Division
|
||||
|
||||
This describes the division algorithm used by the MPI library.
|
||||
|
||||
Input: a, b; a > b
|
||||
Compute: Q, R; a = Qb + R
|
||||
|
||||
The input numbers are normalized so that the high-order digit of b is
|
||||
at least half the radix. This guarantees that we have a reasonable
|
||||
way to guess at the digits of the quotient (this method was taken from
|
||||
Knuth, vol. 2, with adaptations).
|
||||
|
||||
To normalize, test the high-order digit of b. If it is less than half
|
||||
the radix, multiply both a and b by d, where:
|
||||
|
||||
radix - 1
|
||||
d = -----------
|
||||
bmax + 1
|
||||
|
||||
...where bmax is the high-order digit of b. Otherwise, set d = 1.
|
||||
|
||||
Given normalize values for a and b, let the notation a[n] denote the
|
||||
nth digit of a. Let #a be the number of significant figures of a (not
|
||||
including any leading zeroes).
|
||||
|
||||
Let R = 0
|
||||
Let p = #a - 1
|
||||
|
||||
while(p >= 0)
|
||||
do
|
||||
R = (R * radix) + a[p]
|
||||
p = p - 1
|
||||
while(R < b and p >= 0)
|
||||
|
||||
if(R < b)
|
||||
break
|
||||
|
||||
q = (R[#R - 1] * radix) + R[#R - 2]
|
||||
q = q / b[#b - 1]
|
||||
|
||||
T = b * q
|
||||
|
||||
while(T > L)
|
||||
q = q - 1
|
||||
T = T - b
|
||||
endwhile
|
||||
|
||||
L = L - T
|
||||
|
||||
Q = (Q * radix) + q
|
||||
|
||||
endwhile
|
||||
|
||||
At this point, Q is the quotient, and R is the normalized remainder.
|
||||
To denormalize R, compute:
|
||||
|
||||
R = (R / d)
|
||||
|
||||
At this point, you are finished.
|
||||
|
||||
------------------------------------------------------------------
|
||||
***** BEGIN LICENSE BLOCK *****
|
||||
Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
|
||||
The contents of this file are subject to the Mozilla Public License Version
|
||||
1.1 (the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
http://www.mozilla.org/MPL/
|
||||
|
||||
Software distributed under the License is distributed on an "AS IS" basis,
|
||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
for the specific language governing rights and limitations under the
|
||||
License.
|
||||
|
||||
The Original Code is the MPI Arbitrary Precision Integer Arithmetic
|
||||
library.
|
||||
|
||||
The Initial Developer of the Original Code is
|
||||
Michael J. Fromberger <sting@linguist.dartmouth.edu>
|
||||
Portions created by the Initial Developer are Copyright (C) 1998, 2000
|
||||
the Initial Developer. All Rights Reserved.
|
||||
|
||||
Contributor(s):
|
||||
|
||||
Alternatively, the contents of this file may be used under the terms of
|
||||
either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
of those above. If you wish to allow use of your version of this file only
|
||||
under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
use your version of this file under the terms of the MPL, indicate your
|
||||
decision by deleting the provisions above and replace them with the notice
|
||||
and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
the provisions above, a recipient may use your version of this file under
|
||||
the terms of any one of the MPL, the GPL or the LGPL.
|
||||
|
||||
***** END LICENSE BLOCK *****
|
||||
|
||||
$Id: div.txt,v 1.2 2005-02-02 22:28:22 gerv%gerv.net Exp $
|
||||
|
||||
|
||||
@@ -1,132 +0,0 @@
|
||||
Exponentiation
|
||||
|
||||
For exponentiation, the MPI library uses a simple and fairly standard
|
||||
square-and-multiply method. The algorithm is this:
|
||||
|
||||
Input: a, b
|
||||
Output: a ** b
|
||||
|
||||
s = 1
|
||||
|
||||
while(b != 0)
|
||||
if(b is odd)
|
||||
s = s * a
|
||||
endif
|
||||
|
||||
b = b / 2
|
||||
|
||||
x = x * x
|
||||
endwhile
|
||||
|
||||
return s
|
||||
|
||||
The modular exponentiation is done the same way, except replacing:
|
||||
|
||||
s = s * a
|
||||
|
||||
with
|
||||
s = (s * a) mod m
|
||||
|
||||
and replacing
|
||||
|
||||
x = x * x
|
||||
|
||||
with
|
||||
|
||||
x = (x * x) mod m
|
||||
|
||||
Here is a sample exponentiation using the MPI library, as compared to
|
||||
the same problem solved by the Unix 'bc' program on my system:
|
||||
|
||||
Computation of 2,381,283 ** 235
|
||||
|
||||
'bc' says:
|
||||
|
||||
4385CA4A804D199FBEAD95FAD0796FAD0D0B51FC9C16743C45568C789666985DB719\
|
||||
4D90E393522F74C9601262C0514145A49F3B53D00983F95FDFCEA3D0043ECEF6227E\
|
||||
6FB59C924C3EE74447B359B5BF12A555D46CB819809EF423F004B55C587D6F0E8A55\
|
||||
4988036A42ACEF9F71459F97CEF6E574BD7373657111648626B1FF8EE15F663B2C0E\
|
||||
6BBE5082D4CDE8E14F263635AE8F35DB2C280819517BE388B5573B84C5A19C871685\
|
||||
FD408A6471F9D6AFAF5129A7548EAE926B40874B340285F44765BF5468CE20A13267\
|
||||
CD88CE6BC786ACED36EC7EA50F67FF27622575319068A332C3C0CB23E26FB55E26F4\
|
||||
5F732753A52B8E2FB4D4F42D894242613CA912A25486C3DEC9C66E5DB6182F6C1761\
|
||||
CF8CD0D255BE64B93836B27D452AE38F950EB98B517D4CF50D48F0165EF0CCCE1F5C\
|
||||
49BF18219FDBA0EEDD1A7E8B187B70C2BAED5EC5C6821EF27FAFB1CFF70111C52235\
|
||||
5E948B93A015AA1AE152B110BB5658CB14D3E45A48BFE7F082C1182672A455A695CD\
|
||||
A1855E8781E625F25B41B516E77F589FA420C3B058861EA138CF7A2C58DB3C7504FD\
|
||||
D29554D78237834CC5AE710D403CC4F6973D5012B7E117A8976B14A0B5AFA889BD47\
|
||||
92C461F0F96116F00A97AE9E83DC5203680CAF9A18A062566C145650AB86BE4F907F\
|
||||
A9F7AB4A700B29E1E5BACCD6DCBFA513E10832815F710807EED2E279081FEC61D619\
|
||||
AB270BEB3D3A1787B35A9DD41A8766CF21F3B5C693B3BAB1C2FA14A4ED202BC35743\
|
||||
E5CBE2391624D4F8C9BFBBC78D69764E7C6C5B11BF005677BFAD17D9278FFC1F158F\
|
||||
1B3683FF7960FA0608103792C4163DC0AF3E06287BB8624F8FE3A0FFBDF82ACECA2F\
|
||||
CFFF2E1AC93F3CA264A1B
|
||||
|
||||
MPI says:
|
||||
|
||||
4385CA4A804D199FBEAD95FAD0796FAD0D0B51FC9C16743C45568C789666985DB719\
|
||||
4D90E393522F74C9601262C0514145A49F3B53D00983F95FDFCEA3D0043ECEF6227E\
|
||||
6FB59C924C3EE74447B359B5BF12A555D46CB819809EF423F004B55C587D6F0E8A55\
|
||||
4988036A42ACEF9F71459F97CEF6E574BD7373657111648626B1FF8EE15F663B2C0E\
|
||||
6BBE5082D4CDE8E14F263635AE8F35DB2C280819517BE388B5573B84C5A19C871685\
|
||||
FD408A6471F9D6AFAF5129A7548EAE926B40874B340285F44765BF5468CE20A13267\
|
||||
CD88CE6BC786ACED36EC7EA50F67FF27622575319068A332C3C0CB23E26FB55E26F4\
|
||||
5F732753A52B8E2FB4D4F42D894242613CA912A25486C3DEC9C66E5DB6182F6C1761\
|
||||
CF8CD0D255BE64B93836B27D452AE38F950EB98B517D4CF50D48F0165EF0CCCE1F5C\
|
||||
49BF18219FDBA0EEDD1A7E8B187B70C2BAED5EC5C6821EF27FAFB1CFF70111C52235\
|
||||
5E948B93A015AA1AE152B110BB5658CB14D3E45A48BFE7F082C1182672A455A695CD\
|
||||
A1855E8781E625F25B41B516E77F589FA420C3B058861EA138CF7A2C58DB3C7504FD\
|
||||
D29554D78237834CC5AE710D403CC4F6973D5012B7E117A8976B14A0B5AFA889BD47\
|
||||
92C461F0F96116F00A97AE9E83DC5203680CAF9A18A062566C145650AB86BE4F907F\
|
||||
A9F7AB4A700B29E1E5BACCD6DCBFA513E10832815F710807EED2E279081FEC61D619\
|
||||
AB270BEB3D3A1787B35A9DD41A8766CF21F3B5C693B3BAB1C2FA14A4ED202BC35743\
|
||||
E5CBE2391624D4F8C9BFBBC78D69764E7C6C5B11BF005677BFAD17D9278FFC1F158F\
|
||||
1B3683FF7960FA0608103792C4163DC0AF3E06287BB8624F8FE3A0FFBDF82ACECA2F\
|
||||
CFFF2E1AC93F3CA264A1B
|
||||
|
||||
Diff says:
|
||||
% diff bc.txt mp.txt
|
||||
%
|
||||
|
||||
------------------------------------------------------------------
|
||||
***** BEGIN LICENSE BLOCK *****
|
||||
Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
|
||||
The contents of this file are subject to the Mozilla Public License Version
|
||||
1.1 (the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
http://www.mozilla.org/MPL/
|
||||
|
||||
Software distributed under the License is distributed on an "AS IS" basis,
|
||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
for the specific language governing rights and limitations under the
|
||||
License.
|
||||
|
||||
The Original Code is the MPI Arbitrary Precision Integer Arithmetic
|
||||
library.
|
||||
|
||||
The Initial Developer of the Original Code is
|
||||
Michael J. Fromberger <sting@linguist.dartmouth.edu>
|
||||
Portions created by the Initial Developer are Copyright (C) 1998, 2000
|
||||
the Initial Developer. All Rights Reserved.
|
||||
|
||||
Contributor(s):
|
||||
|
||||
Alternatively, the contents of this file may be used under the terms of
|
||||
either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
of those above. If you wish to allow use of your version of this file only
|
||||
under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
use your version of this file under the terms of the MPL, indicate your
|
||||
decision by deleting the provisions above and replace them with the notice
|
||||
and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
the provisions above, a recipient may use your version of this file under
|
||||
the terms of any one of the MPL, the GPL or the LGPL.
|
||||
|
||||
***** END LICENSE BLOCK *****
|
||||
|
||||
$Id: expt.txt,v 1.2 2005-02-02 22:28:22 gerv%gerv.net Exp $
|
||||
|
||||
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
=head1 NAME
|
||||
|
||||
gcd - compute greatest common divisor of two integers
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
gcd <a> <b>
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
The B<gcd> program computes the greatest common divisor of two
|
||||
arbitrary-precision integers I<a> and I<b>. The result is written in
|
||||
standard decimal notation to the standard output.
|
||||
|
||||
If I<b> is zero, B<gcd> will print an error message and exit.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
invmod(1), isprime(1), lap(1)
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Michael J. Fromberger <sting@linguist.dartmouth.edu>
|
||||
Thayer School of Engineering, Hanover, New Hampshire, USA
|
||||
|
||||
$Date: 2000-07-14 00:44:32 $
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
=head1 NAME
|
||||
|
||||
invmod - compute modular inverse of an integer
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
invmod <a> <m>
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
The B<invmod> program computes the inverse of I<a>, modulo I<m>, if
|
||||
that inverse exists. Both I<a> and I<m> are arbitrary-precision
|
||||
integers in decimal notation. The result is written in standard
|
||||
decimal notation to the standard output.
|
||||
|
||||
If there is no inverse, the message:
|
||||
|
||||
No inverse
|
||||
|
||||
...will be printed to the standard output (an inverse exists if and
|
||||
only if the greatest common divisor of I<a> and I<m> is 1).
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
gcd(1), isprime(1), lap(1)
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Michael J. Fromberger <sting@linguist.dartmouth.edu>
|
||||
Thayer School of Engineering, Hanover, New Hampshire, USA
|
||||
|
||||
$Date: 2000-07-14 00:44:33 $
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
=head1 NAME
|
||||
|
||||
isprime - probabilistic primality testing
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
isprime <a>
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
The B<isprime> program attempts to determine whether the arbitrary
|
||||
precision integer I<a> is prime. It first tests I<a> for divisibility
|
||||
by the first 170 or so small primes, and assuming I<a> is not
|
||||
divisible by any of these, applies 15 iterations of the Rabin-Miller
|
||||
probabilistic primality test.
|
||||
|
||||
If the program discovers that the number is composite, it will print:
|
||||
|
||||
Not prime (reason)
|
||||
|
||||
Where I<reason> is either:
|
||||
|
||||
divisible by small prime x
|
||||
|
||||
Or:
|
||||
|
||||
failed nth pseudoprime test
|
||||
|
||||
In the first case, I<x> indicates the first small prime factor that
|
||||
was found. In the second case, I<n> indicates which of the
|
||||
pseudoprime tests failed (numbered from 1)
|
||||
|
||||
If this happens, the number is definitely not prime. However, if the
|
||||
number succeeds, this message results:
|
||||
|
||||
Probably prime, 1 in 4^15 chance of false positive
|
||||
|
||||
If this happens, the number is prime with very high probability, but
|
||||
its primality has not been absolutely proven, only demonstrated to a
|
||||
very convincing degree.
|
||||
|
||||
The value I<a> can be input in standard decimal notation, or, if it is
|
||||
prefixed with I<Ox>, it will be read as hexadecimal.
|
||||
|
||||
=head1 ENVIRONMENT
|
||||
|
||||
You can control how many iterations of Rabin-Miller are performed on
|
||||
the candidate number by setting the I<RM_TESTS> environment variable
|
||||
to an integer value before starting up B<isprime>. This will change
|
||||
the output slightly if the number passes all the tests.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
gcd(1), invmod(1), lap(1)
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Michael J. Fromberger <sting@linguist.dartmouth.edu>
|
||||
Thayer School of Engineering, Hanover, New Hampshire, USA
|
||||
|
||||
$Date: 2000-07-14 00:44:33 $
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
=head1 NAME
|
||||
|
||||
lap - compute least annihilating power of a number
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
lap <a> <m>
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
The B<lap> program computes the order of I<a> modulo I<m>, for
|
||||
arbitrary precision integers I<a> and I<m>. The B<order> of I<a>
|
||||
modulo I<m> is defined as the smallest positive value I<n> for which
|
||||
I<a> raised to the I<n>th power, modulo I<m>, is equal to 1. The
|
||||
order may not exist, if I<m> is composite.
|
||||
|
||||
=head1 RESTRICTIONS
|
||||
|
||||
This program is very slow, especially for large moduli. It is
|
||||
intended as a way to help find primitive elements in a modular field,
|
||||
but it does not do so in a particularly inefficient manner. It was
|
||||
written simply to help verify that a particular candidate does not
|
||||
have an obviously short cycle mod I<m>.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
gcd(1), invmod(1), isprime(1)
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Michael J. Fromberger <sting@linguist.dartmouth.edu>
|
||||
Thayer School of Engineering, Hanover, New Hampshire, USA
|
||||
|
||||
$Date: 2000-07-14 00:44:34 $
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
=head1 NAME
|
||||
|
||||
mpi-test - automated test program for MPI library
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
mpi-test <suite-name> [quiet]
|
||||
mpi-test list
|
||||
mpi-test help
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
The B<mpi-test> program is a general unit test driver for the MPI
|
||||
library. It is used to verify that the library works as it is
|
||||
supposed to on your architecture. As with most such things, passing
|
||||
all the tests in B<mpi-test> does not guarantee the code is correct,
|
||||
but if any of them fail, there are certainly problems.
|
||||
|
||||
Each major function of the library can be tested individually. For a
|
||||
list of the test suites understood by B<mpi-test>, run it with the
|
||||
I<list> command line option:
|
||||
|
||||
mpi-test list
|
||||
|
||||
This will display a list of the available test suites and a brief
|
||||
synopsis of what each one does. For a brief overview of this
|
||||
document, run B<mpi-test> I<help>.
|
||||
|
||||
B<mpi-test> exits with a zero status if the selected test succeeds, or
|
||||
a nonzero status if it fails. If a I<suite-name> which is not
|
||||
understood by B<mpi-test> is given, a diagnostic is printed to the
|
||||
standard error, and the program exits with a result code of 2. If a
|
||||
test fails, the result code will be 1, and a diagnostic is ordinarily
|
||||
printed to the standard error. However, if the I<quiet> option is
|
||||
provided, these diagnostics will be suppressed.
|
||||
|
||||
=head1 RESTRICTIONS
|
||||
|
||||
Only a few canned test cases are provided. The solutions have been
|
||||
verified using the GNU bc(1) program, so bugs there may cause problems
|
||||
here; however, this is very unlikely, so if a test fails, it is almost
|
||||
certainly my fault, not bc(1)'s.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Michael J. Fromberger <sting@linguist.dartmouth.edu>
|
||||
Thayer School of Engineering, Hanover, New Hampshire, USA
|
||||
|
||||
$Date: 2000-07-14 00:44:34 $
|
||||
@@ -1,114 +0,0 @@
|
||||
Multiplication
|
||||
|
||||
This describes the multiplication algorithm used by the MPI library.
|
||||
|
||||
This is basically a standard "schoolbook" algorithm. It is slow --
|
||||
O(mn) for m = #a, n = #b -- but easy to implement and verify.
|
||||
Basically, we run two nested loops, as illustrated here (R is the
|
||||
radix):
|
||||
|
||||
k = 0
|
||||
for j <- 0 to (#b - 1)
|
||||
for i <- 0 to (#a - 1)
|
||||
w = (a[j] * b[i]) + k + c[i+j]
|
||||
c[i+j] = w mod R
|
||||
k = w div R
|
||||
endfor
|
||||
c[i+j] = k;
|
||||
k = 0;
|
||||
endfor
|
||||
|
||||
It is necessary that 'w' have room for at least two radix R digits.
|
||||
The product of any two digits in radix R is at most:
|
||||
|
||||
(R - 1)(R - 1) = R^2 - 2R + 1
|
||||
|
||||
Since a two-digit radix-R number can hold R^2 - 1 distinct values,
|
||||
this insures that the product will fit into the two-digit register.
|
||||
|
||||
To insure that two digits is enough for w, we must also show that
|
||||
there is room for the carry-in from the previous multiplication, and
|
||||
the current value of the product digit that is being recomputed.
|
||||
Assuming each of these may be as big as R - 1 (and no larger,
|
||||
certainly), two digits will be enough if and only if:
|
||||
|
||||
(R^2 - 2R + 1) + 2(R - 1) <= R^2 - 1
|
||||
|
||||
Solving this equation shows that, indeed, this is the case:
|
||||
|
||||
R^2 - 2R + 1 + 2R - 2 <= R^2 - 1
|
||||
|
||||
R^2 - 1 <= R^2 - 1
|
||||
|
||||
This suggests that a good radix would be one more than the largest
|
||||
value that can be held in half a machine word -- so, for example, as
|
||||
in this implementation, where we used a radix of 65536 on a machine
|
||||
with 4-byte words. Another advantage of a radix of this sort is that
|
||||
binary-level operations are easy on numbers in this representation.
|
||||
|
||||
Here's an example multiplication worked out longhand in radix-10,
|
||||
using the above algorithm:
|
||||
|
||||
a = 999
|
||||
b = x 999
|
||||
-------------
|
||||
p = 98001
|
||||
|
||||
w = (a[jx] * b[ix]) + kin + c[ix + jx]
|
||||
c[ix+jx] = w % RADIX
|
||||
k = w / RADIX
|
||||
product
|
||||
ix jx a[jx] b[ix] kin w c[i+j] kout 000000
|
||||
0 0 9 9 0 81+0+0 1 8 000001
|
||||
0 1 9 9 8 81+8+0 9 8 000091
|
||||
0 2 9 9 8 81+8+0 9 8 000991
|
||||
8 0 008991
|
||||
1 0 9 9 0 81+0+9 0 9 008901
|
||||
1 1 9 9 9 81+9+9 9 9 008901
|
||||
1 2 9 9 9 81+9+8 8 9 008901
|
||||
9 0 098901
|
||||
2 0 9 9 0 81+0+9 0 9 098001
|
||||
2 1 9 9 9 81+9+8 8 9 098001
|
||||
2 2 9 9 9 81+9+9 9 9 098001
|
||||
|
||||
------------------------------------------------------------------
|
||||
***** BEGIN LICENSE BLOCK *****
|
||||
Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
|
||||
The contents of this file are subject to the Mozilla Public License Version
|
||||
1.1 (the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
http://www.mozilla.org/MPL/
|
||||
|
||||
Software distributed under the License is distributed on an "AS IS" basis,
|
||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
for the specific language governing rights and limitations under the
|
||||
License.
|
||||
|
||||
The Original Code is the MPI Arbitrary Precision Integer Arithmetic
|
||||
library.
|
||||
|
||||
The Initial Developer of the Original Code is
|
||||
Michael J. Fromberger <sting@linguist.dartmouth.edu>
|
||||
Portions created by the Initial Developer are Copyright (C) 1998, 2000
|
||||
the Initial Developer. All Rights Reserved.
|
||||
|
||||
Contributor(s):
|
||||
|
||||
Alternatively, the contents of this file may be used under the terms of
|
||||
either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
of those above. If you wish to allow use of your version of this file only
|
||||
under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
use your version of this file under the terms of the MPL, indicate your
|
||||
decision by deleting the provisions above and replace them with the notice
|
||||
and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
the provisions above, a recipient may use your version of this file under
|
||||
the terms of any one of the MPL, the GPL or the LGPL.
|
||||
|
||||
***** END LICENSE BLOCK *****
|
||||
|
||||
$Id: mul.txt,v 1.2 2005-02-02 22:28:22 gerv%gerv.net Exp $
|
||||
|
||||
|
||||
@@ -1,90 +0,0 @@
|
||||
This file describes how pi is computed by the program in 'pi.c' (see
|
||||
the utils subdirectory).
|
||||
|
||||
Basically, we use Machin's formula, which is what everyone in the
|
||||
world uses as a simple method for computing approximations to pi.
|
||||
This works for up to a few thousand digits without too much effort.
|
||||
Beyond that, though, it gets too slow.
|
||||
|
||||
Machin's formula states:
|
||||
|
||||
pi := 16 * arctan(1/5) - 4 * arctan(1/239)
|
||||
|
||||
We compute this in integer arithmetic by first multiplying everything
|
||||
through by 10^d, where 'd' is the number of digits of pi we wanted to
|
||||
compute. It turns out, the last few digits will be wrong, but the
|
||||
number that are wrong is usually very small (ordinarly only 2-3).
|
||||
Having done this, we compute the arctan() function using the formula:
|
||||
|
||||
1 1 1 1 1
|
||||
arctan(1/x) := --- - ----- + ----- - ----- + ----- - ...
|
||||
x 3 x^3 5 x^5 7 x^7 9 x^9
|
||||
|
||||
This is done iteratively by computing the first term manually, and
|
||||
then iteratively dividing x^2 and k, where k = 3, 5, 7, ... out of the
|
||||
current figure. This is then added to (or subtracted from) a running
|
||||
sum, as appropriate. The iteration continues until we overflow our
|
||||
available precision and the current figure goes to zero under integer
|
||||
division. At that point, we're finished.
|
||||
|
||||
Actually, we get a couple extra bits of precision out of the fact that
|
||||
we know we're computing y * arctan(1/x), by setting up the multiplier
|
||||
as:
|
||||
|
||||
y * 10^d
|
||||
|
||||
... instead of just 10^d. There is also a bit of cleverness in how
|
||||
the loop is constructed, to avoid special-casing the first term.
|
||||
Check out the code for arctan() in 'pi.c', if you are interested in
|
||||
seeing how it is set up.
|
||||
|
||||
Thanks to Jason P. for this algorithm, which I assembled from notes
|
||||
and programs found on his cool "Pile of Pi Programs" page, at:
|
||||
|
||||
http://www.isr.umd.edu/~jasonp/pipage.html
|
||||
|
||||
Thanks also to Henrik Johansson <Henrik.Johansson@Nexus.Comm.SE>, from
|
||||
whose pi program I borrowed the clever idea of pre-multiplying by x in
|
||||
order to avoid a special case on the loop iteration.
|
||||
|
||||
------------------------------------------------------------------
|
||||
***** BEGIN LICENSE BLOCK *****
|
||||
Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
|
||||
The contents of this file are subject to the Mozilla Public License Version
|
||||
1.1 (the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
http://www.mozilla.org/MPL/
|
||||
|
||||
Software distributed under the License is distributed on an "AS IS" basis,
|
||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
for the specific language governing rights and limitations under the
|
||||
License.
|
||||
|
||||
The Original Code is the MPI Arbitrary Precision Integer Arithmetic
|
||||
library.
|
||||
|
||||
The Initial Developer of the Original Code is
|
||||
Michael J. Fromberger <sting@linguist.dartmouth.edu>
|
||||
Portions created by the Initial Developer are Copyright (C) 1998, 2000
|
||||
the Initial Developer. All Rights Reserved.
|
||||
|
||||
Contributor(s):
|
||||
|
||||
Alternatively, the contents of this file may be used under the terms of
|
||||
either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
of those above. If you wish to allow use of your version of this file only
|
||||
under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
use your version of this file under the terms of the MPL, indicate your
|
||||
decision by deleting the provisions above and replace them with the notice
|
||||
and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
the provisions above, a recipient may use your version of this file under
|
||||
the terms of any one of the MPL, the GPL or the LGPL.
|
||||
|
||||
***** END LICENSE BLOCK *****
|
||||
|
||||
$Id: pi.txt,v 1.2 2005-02-02 22:28:22 gerv%gerv.net Exp $
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,41 +0,0 @@
|
||||
=head1 NAME
|
||||
|
||||
prng - pseudo-random number generator
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
prng [count]
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
B<Prng> generates 32-bit pseudo-random integers using the
|
||||
Blum-Blum-Shub (BBS) quadratic residue generator. It is seeded using
|
||||
the standard C library's rand() function, which itself seeded from the
|
||||
system clock and the process ID number. Thus, the values generated
|
||||
are not particularly useful for cryptographic applications, but they
|
||||
are in general much better than the typical output of the usual
|
||||
multiplicative congruency generator used by most runtime libraries.
|
||||
|
||||
You may optionally specify how many random values should be generated
|
||||
by giving a I<count> argument on the command line. If you do not
|
||||
specify a count, only one random value will be generated. The results
|
||||
are output to the standard output in decimal notation, one value per
|
||||
line.
|
||||
|
||||
=head1 RESTRICTIONS
|
||||
|
||||
As stated above, B<prng> uses the C library's rand() function to seed
|
||||
the generator, so it is not terribly suitable for cryptographic
|
||||
applications. Also note that each time you run the program, a new
|
||||
seed is generated, so it is better to run it once with a I<count>
|
||||
parameter than it is to run it multiple times to generate several
|
||||
values.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Michael J. Fromberger <sting@linguist.dartmouth.edu>
|
||||
Copyright (C) 1998 Michael J. Fromberger, All Rights Reserved
|
||||
Thayer School of Engineering, Dartmouth College, Hanover, NH USA
|
||||
|
||||
$Date: 2000-07-14 00:44:36 $
|
||||
|
||||
@@ -1,121 +0,0 @@
|
||||
Modular Reduction
|
||||
|
||||
Usually, modular reduction is accomplished by long division, using the
|
||||
mp_div() or mp_mod() functions. However, when performing modular
|
||||
exponentiation, you spend a lot of time reducing by the same modulus
|
||||
again and again. For this purpose, doing a full division for each
|
||||
multiplication is quite inefficient.
|
||||
|
||||
For this reason, the mp_exptmod() function does not perform modular
|
||||
reductions in the usual way, but instead takes advantage of an
|
||||
algorithm due to Barrett, as described by Menezes, Oorschot and
|
||||
VanStone in their book _Handbook of Applied Cryptography_, published
|
||||
by the CRC Press (see Chapter 14 for details). This method reduces
|
||||
most of the computation of reduction to efficient shifting and masking
|
||||
operations, and avoids the multiple-precision division entirely.
|
||||
|
||||
Here is a brief synopsis of Barrett reduction, as it is implemented in
|
||||
this library.
|
||||
|
||||
Let b denote the radix of the computation (one more than the maximum
|
||||
value that can be denoted by an mp_digit). Let m be the modulus, and
|
||||
let k be the number of significant digits of m. Let x be the value to
|
||||
be reduced modulo m. By the Division Theorem, there exist unique
|
||||
integers Q and R such that:
|
||||
|
||||
x = Qm + R, 0 <= R < m
|
||||
|
||||
Barrett reduction takes advantage of the fact that you can easily
|
||||
approximate Q to within two, given a value M such that:
|
||||
|
||||
2k
|
||||
b
|
||||
M = floor( ----- )
|
||||
m
|
||||
|
||||
Computation of M requires a full-precision division step, so if you
|
||||
are only doing a single reduction by m, you gain no advantage.
|
||||
However, when multiple reductions by the same m are required, this
|
||||
division need only be done once, beforehand. Using this, we can use
|
||||
the following equation to compute Q', an approximation of Q:
|
||||
|
||||
x
|
||||
floor( ------ ) M
|
||||
k-1
|
||||
b
|
||||
Q' = floor( ----------------- )
|
||||
k+1
|
||||
b
|
||||
|
||||
The divisions by b^(k-1) and b^(k+1) and the floor() functions can be
|
||||
efficiently implemented with shifts and masks, leaving only a single
|
||||
multiplication to be performed to get this approximation. It can be
|
||||
shown that Q - 2 <= Q' <= Q, so in the worst case, we can get out with
|
||||
two additional subtractions to bring the value into line with the
|
||||
actual value of Q.
|
||||
|
||||
Once we've got Q', we basically multiply that by m and subtract from
|
||||
x, yielding:
|
||||
|
||||
x - Q'm = Qm + R - Q'm
|
||||
|
||||
Since we know the constraint on Q', this is one of:
|
||||
|
||||
R
|
||||
m + R
|
||||
2m + R
|
||||
|
||||
Since R < m by the Division Theorem, we can simply subtract off m
|
||||
until we get a value in the correct range, which will happen with no
|
||||
more than 2 subtractions:
|
||||
|
||||
v = x - Q'm
|
||||
|
||||
while(v >= m)
|
||||
v = v - m
|
||||
endwhile
|
||||
|
||||
|
||||
In random performance trials, modular exponentiation using this method
|
||||
of reduction gave around a 40% speedup over using the division for
|
||||
reduction.
|
||||
|
||||
------------------------------------------------------------------
|
||||
***** BEGIN LICENSE BLOCK *****
|
||||
Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
|
||||
The contents of this file are subject to the Mozilla Public License Version
|
||||
1.1 (the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
http://www.mozilla.org/MPL/
|
||||
|
||||
Software distributed under the License is distributed on an "AS IS" basis,
|
||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
for the specific language governing rights and limitations under the
|
||||
License.
|
||||
|
||||
The Original Code is the MPI Arbitrary Precision Integer Arithmetic
|
||||
library.
|
||||
|
||||
The Initial Developer of the Original Code is
|
||||
Michael J. Fromberger <sting@linguist.dartmouth.edu>
|
||||
Portions created by the Initial Developer are Copyright (C) 1998, 2000
|
||||
the Initial Developer. All Rights Reserved.
|
||||
|
||||
Contributor(s):
|
||||
|
||||
Alternatively, the contents of this file may be used under the terms of
|
||||
either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
of those above. If you wish to allow use of your version of this file only
|
||||
under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
use your version of this file under the terms of the MPL, indicate your
|
||||
decision by deleting the provisions above and replace them with the notice
|
||||
and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
the provisions above, a recipient may use your version of this file under
|
||||
the terms of any one of the MPL, the GPL or the LGPL.
|
||||
|
||||
***** END LICENSE BLOCK *****
|
||||
|
||||
$Id: redux.txt,v 1.2 2005-02-02 22:28:22 gerv%gerv.net Exp $
|
||||
@@ -1,87 +0,0 @@
|
||||
Square Root
|
||||
|
||||
A simple iterative algorithm is used to compute the greatest integer
|
||||
less than or equal to the square root. Essentially, this is Newton's
|
||||
linear approximation, computed by finding successive values of the
|
||||
equation:
|
||||
|
||||
x[k]^2 - V
|
||||
x[k+1] = x[k] - ------------
|
||||
2 x[k]
|
||||
|
||||
...where V is the value for which the square root is being sought. In
|
||||
essence, what is happening here is that we guess a value for the
|
||||
square root, then figure out how far off we were by squaring our guess
|
||||
and subtracting the target. Using this value, we compute a linear
|
||||
approximation for the error, and adjust the "guess". We keep doing
|
||||
this until the precision gets low enough that the above equation
|
||||
yields a quotient of zero. At this point, our last guess is one
|
||||
greater than the square root we're seeking.
|
||||
|
||||
The initial guess is computed by dividing V by 4, which is a heuristic
|
||||
I have found to be fairly good on average. This also has the
|
||||
advantage of being very easy to compute efficiently, even for large
|
||||
values.
|
||||
|
||||
So, the resulting algorithm works as follows:
|
||||
|
||||
x = V / 4 /* compute initial guess */
|
||||
|
||||
loop
|
||||
t = (x * x) - V /* Compute absolute error */
|
||||
u = 2 * x /* Adjust by tangent slope */
|
||||
t = t / u
|
||||
|
||||
/* Loop is done if error is zero */
|
||||
if(t == 0)
|
||||
break
|
||||
|
||||
/* Adjust guess by error term */
|
||||
x = x - t
|
||||
end
|
||||
|
||||
x = x - 1
|
||||
|
||||
The result of the computation is the value of x.
|
||||
|
||||
------------------------------------------------------------------
|
||||
***** BEGIN LICENSE BLOCK *****
|
||||
Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
|
||||
The contents of this file are subject to the Mozilla Public License Version
|
||||
1.1 (the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
http://www.mozilla.org/MPL/
|
||||
|
||||
Software distributed under the License is distributed on an "AS IS" basis,
|
||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
for the specific language governing rights and limitations under the
|
||||
License.
|
||||
|
||||
The Original Code is the MPI Arbitrary Precision Integer Arithmetic
|
||||
library.
|
||||
|
||||
The Initial Developer of the Original Code is
|
||||
Michael J. Fromberger <sting@linguist.dartmouth.edu>
|
||||
Portions created by the Initial Developer are Copyright (C) 1998, 2000
|
||||
the Initial Developer. All Rights Reserved.
|
||||
|
||||
Contributor(s):
|
||||
|
||||
Alternatively, the contents of this file may be used under the terms of
|
||||
either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
of those above. If you wish to allow use of your version of this file only
|
||||
under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
use your version of this file under the terms of the MPL, indicate your
|
||||
decision by deleting the provisions above and replace them with the notice
|
||||
and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
the provisions above, a recipient may use your version of this file under
|
||||
the terms of any one of the MPL, the GPL or the LGPL.
|
||||
|
||||
***** END LICENSE BLOCK *****
|
||||
|
||||
$Id: sqrt.txt,v 1.2 2005-02-02 22:28:22 gerv%gerv.net Exp $
|
||||
|
||||
|
||||
@@ -1,109 +0,0 @@
|
||||
Squaring Algorithm
|
||||
|
||||
When you are squaring a value, you can take advantage of the fact that
|
||||
half the multiplications performed by the more general multiplication
|
||||
algorithm (see 'mul.txt' for a description) are redundant when the
|
||||
multiplicand equals the multiplier.
|
||||
|
||||
In particular, the modified algorithm is:
|
||||
|
||||
k = 0
|
||||
for j <- 0 to (#a - 1)
|
||||
w = c[2*j] + (a[j] ^ 2);
|
||||
k = w div R
|
||||
|
||||
for i <- j+1 to (#a - 1)
|
||||
w = (2 * a[j] * a[i]) + k + c[i+j]
|
||||
c[i+j] = w mod R
|
||||
k = w div R
|
||||
endfor
|
||||
c[i+j] = k;
|
||||
k = 0;
|
||||
endfor
|
||||
|
||||
On the surface, this looks identical to the multiplication algorithm;
|
||||
however, note the following differences:
|
||||
|
||||
- precomputation of the leading term in the outer loop
|
||||
|
||||
- i runs from j+1 instead of from zero
|
||||
|
||||
- doubling of a[i] * a[j] in the inner product
|
||||
|
||||
Unfortunately, the construction of the inner product is such that we
|
||||
need more than two digits to represent the inner product, in some
|
||||
cases. In a C implementation, this means that some gymnastics must be
|
||||
performed in order to handle overflow, for which C has no direct
|
||||
abstraction. We do this by observing the following:
|
||||
|
||||
If we have multiplied a[i] and a[j], and the product is more than half
|
||||
the maximum value expressible in two digits, then doubling this result
|
||||
will overflow into a third digit. If this occurs, we take note of the
|
||||
overflow, and double it anyway -- C integer arithmetic ignores
|
||||
overflow, so the two digits we get back should still be valid, modulo
|
||||
the overflow.
|
||||
|
||||
Having doubled this value, we now have to add in the remainders and
|
||||
the digits already computed by earlier steps. If we did not overflow
|
||||
in the previous step, we might still cause an overflow here. That
|
||||
will happen whenever the maximum value expressible in two digits, less
|
||||
the amount we have to add, is greater than the result of the previous
|
||||
step. Thus, the overflow computation is:
|
||||
|
||||
|
||||
u = 0
|
||||
w = a[i] * a[j]
|
||||
|
||||
if(w > (R - 1)/ 2)
|
||||
u = 1;
|
||||
|
||||
w = w * 2
|
||||
v = c[i + j] + k
|
||||
|
||||
if(u == 0 && (R - 1 - v) < w)
|
||||
u = 1
|
||||
|
||||
If there is an overflow, u will be 1, otherwise u will be 0. The rest
|
||||
of the parameters are the same as they are in the above description.
|
||||
|
||||
------------------------------------------------------------------
|
||||
***** BEGIN LICENSE BLOCK *****
|
||||
Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
|
||||
The contents of this file are subject to the Mozilla Public License Version
|
||||
1.1 (the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
http://www.mozilla.org/MPL/
|
||||
|
||||
Software distributed under the License is distributed on an "AS IS" basis,
|
||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
for the specific language governing rights and limitations under the
|
||||
License.
|
||||
|
||||
The Original Code is the MPI Arbitrary Precision Integer Arithmetic
|
||||
library.
|
||||
|
||||
The Initial Developer of the Original Code is
|
||||
Michael J. Fromberger <sting@linguist.dartmouth.edu>
|
||||
Portions created by the Initial Developer are Copyright (C) 1998, 2000
|
||||
the Initial Developer. All Rights Reserved.
|
||||
|
||||
Contributor(s):
|
||||
|
||||
Alternatively, the contents of this file may be used under the terms of
|
||||
either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
of those above. If you wish to allow use of your version of this file only
|
||||
under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
use your version of this file under the terms of the MPL, indicate your
|
||||
decision by deleting the provisions above and replace them with the notice
|
||||
and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
the provisions above, a recipient may use your version of this file under
|
||||
the terms of any one of the MPL, the GPL or the LGPL.
|
||||
|
||||
***** END LICENSE BLOCK *****
|
||||
|
||||
$Id: square.txt,v 1.2 2005-02-02 22:28:22 gerv%gerv.net Exp $
|
||||
|
||||
|
||||
@@ -1,250 +0,0 @@
|
||||
MPI Library Timing Tests
|
||||
|
||||
Hardware/OS
|
||||
(A) SGI O2 1 x MIPS R10000 250MHz IRIX 6.5.3
|
||||
(B) IBM RS/6000 43P-240 1 x PowerPC 603e 223MHz AIX 4.3
|
||||
(C) Dell GX1/L+ 1 x Pentium III 550MHz Linux 2.2.12-20
|
||||
(D) PowerBook G3 1 x PowerPC 750 266MHz LinuxPPC 2.2.6-15apmac
|
||||
(E) PowerBook G3 1 x PowerPC 750 266MHz MacOS 8.5.1
|
||||
(F) PowerBook G3 1 x PowerPC 750 400MHz MacOS 9.0.2
|
||||
|
||||
Compiler
|
||||
(1) MIPSpro C 7.2.1 -O3 optimizations
|
||||
(2) GCC 2.95.1 -O3 optimizations
|
||||
(3) IBM AIX xlc -O3 optimizations (version unknown)
|
||||
(4) EGCS 2.91.66 -O3 optimizations
|
||||
(5) Metrowerks CodeWarrior 5.0 C, all optimizations
|
||||
(6) MIPSpro C 7.30 -O3 optimizations
|
||||
(7) same as (6), with optimized libmalloc.so
|
||||
|
||||
Timings are given in seconds, computed using the C library's clock()
|
||||
function. The first column gives the hardware and compiler
|
||||
configuration used for the test. The second column indicates the
|
||||
number of tests that were aggregated to get the statistics for that
|
||||
size. These were compiled using 16 bit digits.
|
||||
|
||||
Source data were generated randomly using a fixed seed, so they should
|
||||
be internally consistent, but may vary on different systems depending
|
||||
on the C library. Also, since the resolution of the timer accessed by
|
||||
clock() varies, there may be some variance in the precision of these
|
||||
measurements.
|
||||
|
||||
Prime Generation (primegen)
|
||||
|
||||
128 bits:
|
||||
A1 200 min=0.03, avg=0.19, max=0.72, sum=38.46
|
||||
A2 200 min=0.02, avg=0.16, max=0.62, sum=32.55
|
||||
B3 200 min=0.01, avg=0.07, max=0.22, sum=13.29
|
||||
C4 200 min=0.00, avg=0.03, max=0.20, sum=6.14
|
||||
D4 200 min=0.00, avg=0.05, max=0.33, sum=9.70
|
||||
A6 200 min=0.01, avg=0.09, max=0.36, sum=17.48
|
||||
A7 200 min=0.00, avg=0.05, max=0.24, sum=10.07
|
||||
|
||||
192 bits:
|
||||
A1 200 min=0.05, avg=0.45, max=3.13, sum=89.96
|
||||
A2 200 min=0.04, avg=0.39, max=2.61, sum=77.55
|
||||
B3 200 min=0.02, avg=0.18, max=1.25, sum=36.97
|
||||
C4 200 min=0.01, avg=0.09, max=0.33, sum=18.24
|
||||
D4 200 min=0.02, avg=0.15, max=0.54, sum=29.63
|
||||
A6 200 min=0.02, avg=0.24, max=1.70, sum=47.84
|
||||
A7 200 min=0.01, avg=0.15, max=1.05, sum=30.88
|
||||
|
||||
256 bits:
|
||||
A1 200 min=0.08, avg=0.92, max=6.13, sum=184.79
|
||||
A2 200 min=0.06, avg=0.76, max=5.03, sum=151.11
|
||||
B3 200 min=0.04, avg=0.41, max=2.68, sum=82.35
|
||||
C4 200 min=0.02, avg=0.19, max=0.69, sum=37.91
|
||||
D4 200 min=0.03, avg=0.31, max=1.15, sum=63.00
|
||||
A6 200 min=0.04, avg=0.48, max=3.13, sum=95.46
|
||||
A7 200 min=0.03, avg=0.37, max=2.36, sum=73.60
|
||||
|
||||
320 bits:
|
||||
A1 200 min=0.11, avg=1.59, max=6.14, sum=318.81
|
||||
A2 200 min=0.09, avg=1.27, max=4.93, sum=254.03
|
||||
B3 200 min=0.07, avg=0.82, max=3.13, sum=163.80
|
||||
C4 200 min=0.04, avg=0.44, max=1.91, sum=87.59
|
||||
D4 200 min=0.06, avg=0.73, max=3.22, sum=146.73
|
||||
A6 200 min=0.07, avg=0.93, max=3.50, sum=185.01
|
||||
A7 200 min=0.05, avg=0.76, max=2.94, sum=151.78
|
||||
|
||||
384 bits:
|
||||
A1 200 min=0.16, avg=2.69, max=11.41, sum=537.89
|
||||
A2 200 min=0.13, avg=2.15, max=9.03, sum=429.14
|
||||
B3 200 min=0.11, avg=1.54, max=6.49, sum=307.78
|
||||
C4 200 min=0.06, avg=0.81, max=4.84, sum=161.13
|
||||
D4 200 min=0.10, avg=1.38, max=8.31, sum=276.81
|
||||
A6 200 min=0.11, avg=1.73, max=7.36, sum=345.55
|
||||
A7 200 min=0.09, avg=1.46, max=6.12, sum=292.02
|
||||
|
||||
448 bits:
|
||||
A1 200 min=0.23, avg=3.36, max=15.92, sum=672.63
|
||||
A2 200 min=0.17, avg=2.61, max=12.25, sum=522.86
|
||||
B3 200 min=0.16, avg=2.10, max=9.83, sum=420.86
|
||||
C4 200 min=0.09, avg=1.44, max=7.64, sum=288.36
|
||||
D4 200 min=0.16, avg=2.50, max=13.29, sum=500.17
|
||||
A6 200 min=0.15, avg=2.31, max=10.81, sum=461.58
|
||||
A7 200 min=0.14, avg=2.03, max=9.53, sum=405.16
|
||||
|
||||
512 bits:
|
||||
A1 200 min=0.30, avg=6.12, max=22.18, sum=1223.35
|
||||
A2 200 min=0.25, avg=4.67, max=16.90, sum=933.18
|
||||
B3 200 min=0.23, avg=4.13, max=14.94, sum=825.45
|
||||
C4 200 min=0.13, avg=2.08, max=9.75, sum=415.22
|
||||
D4 200 min=0.24, avg=4.04, max=20.18, sum=808.11
|
||||
A6 200 min=0.22, avg=4.47, max=16.19, sum=893.83
|
||||
A7 200 min=0.20, avg=4.03, max=14.65, sum=806.02
|
||||
|
||||
Modular Exponentation (metime)
|
||||
|
||||
The following results are aggregated from 200 pseudo-randomly
|
||||
generated tests, based on a fixed seed.
|
||||
|
||||
base, exponent, and modulus size (bits)
|
||||
P/C 128 192 256 320 384 448 512 640 768 896 1024
|
||||
------- -----------------------------------------------------------------
|
||||
A1 0.015 0.027 0.047 0.069 0.098 0.133 0.176 0.294 0.458 0.680 1.040
|
||||
A2 0.013 0.024 0.037 0.053 0.077 0.102 0.133 0.214 0.326 0.476 0.668
|
||||
B3 0.005 0.011 0.021 0.036 0.056 0.084 0.121 0.222 0.370 0.573 0.840
|
||||
C4 0.002 0.006 0.011 0.020 0.032 0.048 0.069 0.129 0.223 0.344 0.507
|
||||
D4 0.004 0.010 0.019 0.034 0.056 0.085 0.123 0.232 0.390 0.609 0.899
|
||||
E5 0.007 0.015 0.031 0.055 0.088 0.133 0.183 0.342 0.574 0.893 1.317
|
||||
A6 0.008 0.016 0.038 0.042 0.064 0.093 0.133 0.239 0.393 0.604 0.880
|
||||
A7 0.005 0.011 0.020 0.036 0.056 0.083 0.121 0.223 0.374 0.583 0.855
|
||||
|
||||
Multiplication and Squaring tests, (mulsqr)
|
||||
|
||||
The following results are aggregated from 500000 pseudo-randomly
|
||||
generated tests, based on a per-run wall-clock seed. Times are given
|
||||
in seconds, except where indicated in microseconds (us).
|
||||
|
||||
(A1)
|
||||
|
||||
bits multiply square ad percent time/mult time/square
|
||||
64 9.33 9.15 > 1.9 18.7us 18.3us
|
||||
128 10.88 10.44 > 4.0 21.8us 20.9us
|
||||
192 13.30 11.89 > 10.6 26.7us 23.8us
|
||||
256 14.88 12.64 > 15.1 29.8us 25.3us
|
||||
320 18.64 15.01 > 19.5 37.3us 30.0us
|
||||
384 23.11 17.70 > 23.4 46.2us 35.4us
|
||||
448 28.28 20.88 > 26.2 56.6us 41.8us
|
||||
512 34.09 24.51 > 28.1 68.2us 49.0us
|
||||
640 47.86 33.25 > 30.5 95.7us 66.5us
|
||||
768 64.91 43.54 > 32.9 129.8us 87.1us
|
||||
896 84.49 55.48 > 34.3 169.0us 111.0us
|
||||
1024 107.25 69.21 > 35.5 214.5us 138.4us
|
||||
1536 227.97 141.91 > 37.8 456.0us 283.8us
|
||||
2048 394.05 242.15 > 38.5 788.1us 484.3us
|
||||
|
||||
(A2)
|
||||
|
||||
bits multiply square ad percent time/mult time/square
|
||||
64 7.87 7.95 < 1.0 15.7us 15.9us
|
||||
128 9.40 9.19 > 2.2 18.8us 18.4us
|
||||
192 11.15 10.59 > 5.0 22.3us 21.2us
|
||||
256 12.02 11.16 > 7.2 24.0us 22.3us
|
||||
320 14.62 13.43 > 8.1 29.2us 26.9us
|
||||
384 17.72 15.80 > 10.8 35.4us 31.6us
|
||||
448 21.24 18.51 > 12.9 42.5us 37.0us
|
||||
512 25.36 21.78 > 14.1 50.7us 43.6us
|
||||
640 34.57 29.00 > 16.1 69.1us 58.0us
|
||||
768 46.10 37.60 > 18.4 92.2us 75.2us
|
||||
896 58.94 47.72 > 19.0 117.9us 95.4us
|
||||
1024 73.76 59.12 > 19.8 147.5us 118.2us
|
||||
1536 152.00 118.80 > 21.8 304.0us 237.6us
|
||||
2048 259.41 199.57 > 23.1 518.8us 399.1us
|
||||
|
||||
(B3)
|
||||
|
||||
bits multiply square ad percent time/mult time/square
|
||||
64 2.60 2.47 > 5.0 5.20us 4.94us
|
||||
128 4.43 4.06 > 8.4 8.86us 8.12us
|
||||
192 7.03 6.10 > 13.2 14.1us 12.2us
|
||||
256 10.44 8.59 > 17.7 20.9us 17.2us
|
||||
320 14.44 11.64 > 19.4 28.9us 23.3us
|
||||
384 19.12 15.08 > 21.1 38.2us 30.2us
|
||||
448 24.55 19.09 > 22.2 49.1us 38.2us
|
||||
512 31.03 23.53 > 24.2 62.1us 47.1us
|
||||
640 45.05 33.80 > 25.0 90.1us 67.6us
|
||||
768 63.02 46.05 > 26.9 126.0us 92.1us
|
||||
896 83.74 60.29 > 28.0 167.5us 120.6us
|
||||
1024 106.73 76.65 > 28.2 213.5us 153.3us
|
||||
1536 228.94 160.98 > 29.7 457.9us 322.0us
|
||||
2048 398.08 275.93 > 30.7 796.2us 551.9us
|
||||
|
||||
(C4)
|
||||
|
||||
bits multiply square ad percent time/mult time/square
|
||||
64 1.34 1.28 > 4.5 2.68us 2.56us
|
||||
128 2.76 2.59 > 6.2 5.52us 5.18us
|
||||
192 4.52 4.16 > 8.0 9.04us 8.32us
|
||||
256 6.64 5.99 > 9.8 13.3us 12.0us
|
||||
320 9.20 8.13 > 11.6 18.4us 16.3us
|
||||
384 12.01 10.58 > 11.9 24.0us 21.2us
|
||||
448 15.24 13.33 > 12.5 30.5us 26.7us
|
||||
512 19.02 16.46 > 13.5 38.0us 32.9us
|
||||
640 27.56 23.54 > 14.6 55.1us 47.1us
|
||||
768 37.89 31.78 > 16.1 75.8us 63.6us
|
||||
896 49.24 41.42 > 15.9 98.5us 82.8us
|
||||
1024 62.59 52.18 > 16.6 125.2us 104.3us
|
||||
1536 131.66 107.72 > 18.2 263.3us 215.4us
|
||||
2048 226.45 182.95 > 19.2 453.0us 365.9us
|
||||
|
||||
(A7)
|
||||
|
||||
bits multiply square ad percent time/mult time/square
|
||||
64 1.74 1.71 > 1.7 3.48us 3.42us
|
||||
128 3.48 2.96 > 14.9 6.96us 5.92us
|
||||
192 5.74 4.60 > 19.9 11.5us 9.20us
|
||||
256 8.75 6.61 > 24.5 17.5us 13.2us
|
||||
320 12.5 8.99 > 28.1 25.0us 18.0us
|
||||
384 16.9 11.9 > 29.6 33.8us 23.8us
|
||||
448 22.2 15.2 > 31.7 44.4us 30.4us
|
||||
512 28.3 19.0 > 32.7 56.6us 38.0us
|
||||
640 42.4 28.0 > 34.0 84.8us 56.0us
|
||||
768 59.4 38.5 > 35.2 118.8us 77.0us
|
||||
896 79.5 51.2 > 35.6 159.0us 102.4us
|
||||
1024 102.6 65.5 > 36.2 205.2us 131.0us
|
||||
1536 224.3 140.6 > 37.3 448.6us 281.2us
|
||||
2048 393.4 244.3 > 37.9 786.8us 488.6us
|
||||
|
||||
------------------------------------------------------------------
|
||||
***** BEGIN LICENSE BLOCK *****
|
||||
Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
|
||||
The contents of this file are subject to the Mozilla Public License Version
|
||||
1.1 (the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
http://www.mozilla.org/MPL/
|
||||
|
||||
Software distributed under the License is distributed on an "AS IS" basis,
|
||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
for the specific language governing rights and limitations under the
|
||||
License.
|
||||
|
||||
The Original Code is the MPI Arbitrary Precision Integer Arithmetic
|
||||
library.
|
||||
|
||||
The Initial Developer of the Original Code is
|
||||
Michael J. Fromberger <sting@linguist.dartmouth.edu>
|
||||
Portions created by the Initial Developer are Copyright (C) 1998, 2000
|
||||
the Initial Developer. All Rights Reserved.
|
||||
|
||||
Contributor(s):
|
||||
|
||||
Alternatively, the contents of this file may be used under the terms of
|
||||
either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
of those above. If you wish to allow use of your version of this file only
|
||||
under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
use your version of this file under the terms of the MPL, indicate your
|
||||
decision by deleting the provisions above and replace them with the notice
|
||||
and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
the provisions above, a recipient may use your version of this file under
|
||||
the terms of any one of the MPL, the GPL or the LGPL.
|
||||
|
||||
***** END LICENSE BLOCK *****
|
||||
|
||||
$Id: timing.txt,v 1.2 2005-02-02 22:28:22 gerv%gerv.net Exp $
|
||||
|
||||
|
||||
@@ -1,640 +0,0 @@
|
||||
/*
|
||||
* 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 multacc512 multiple-precision integer arithmetic.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Hewlett-Packard Company.
|
||||
* Portions created by Hewlett-Packard Company are
|
||||
* Copyright (C) March 1999, Hewlett-Packard Company. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* coded by: Bill Worley, Hewlett-Packard labs
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*
|
||||
* This PA-RISC 2.0 function computes the product of two unsigned integers,
|
||||
* and adds the result to a previously computed integer. The multiplicand
|
||||
* is a 512-bit (64-byte, eight doubleword) unsigned integer, stored in
|
||||
* memory in little-double-wordian order. The multiplier is an unsigned
|
||||
* 64-bit integer. The previously computed integer to which the product is
|
||||
* added is located in the result ("res") area, and is assumed to be a
|
||||
* 576-bit (72-byte, nine doubleword) unsigned integer, stored in memory
|
||||
* in little-double-wordian order. This value normally will be the result
|
||||
* of a previously computed nine doubleword result. It is not necessary
|
||||
* to pad the multiplicand with an additional 64-bit zero doubleword.
|
||||
*
|
||||
* Multiplicand, multiplier, and addend ideally should be aligned at
|
||||
* 16-byte boundaries for best performance. The code will function
|
||||
* correctly for alignment at eight-byte boundaries which are not 16-byte
|
||||
* boundaries, but the execution may be slightly slower due to even/odd
|
||||
* bank conflicts on PA-RISC 8000 processors.
|
||||
*
|
||||
* This function is designed to accept the same calling sequence as Bill
|
||||
* Ackerman's "maxpy_little" function. The carry from the ninth doubleword
|
||||
* of the result is written to the tenth word of the result, as is done by
|
||||
* Bill Ackerman's function. The final carry also is returned as an
|
||||
* integer, which may be ignored. The function prototype may be either
|
||||
* of the following:
|
||||
*
|
||||
* void multacc512( int l, chunk* m, const chunk* a, chunk* res );
|
||||
* or
|
||||
* int multacc512( int l, chunk* m, const chunk* a, chunk* res );
|
||||
*
|
||||
* where: "l" originally denoted vector lengths. This parameter is
|
||||
* ignored. This function always assumes a multiplicand length of
|
||||
* 512 bits (eight doublewords), and addend and result lengths of
|
||||
* 576 bits (nine doublewords).
|
||||
*
|
||||
* "m" is a pointer to the doubleword multiplier, ideally aligned
|
||||
* on a 16-byte boundary.
|
||||
*
|
||||
* "a" is a pointer to the eight-doubleword multiplicand, stored
|
||||
* in little-double-wordian order, and ideally aligned on a 16-byte
|
||||
* boundary.
|
||||
*
|
||||
* "res" is a pointer to the nine doubleword addend, and to the
|
||||
* nine-doubleword product computed by this function. The result
|
||||
* also is stored in little-double-wordian order, and ideally is
|
||||
* aligned on a 16-byte boundary. It is expected that the alignment
|
||||
* of the "res" area may alternate between even/odd doubleword
|
||||
* boundaries for successive calls for 512-bit x 512-bit
|
||||
* multiplications.
|
||||
*
|
||||
* The code for this function has been scheduled to use the parallelism
|
||||
* of the PA-RISC 8000 series microprocessors as well as the author was
|
||||
* able. Comments and/or suggestions for improvement are welcomed.
|
||||
*
|
||||
* The code is "64-bit safe". This means it may be called in either
|
||||
* the 32ILP context or the 64LP context. All 64-bits of registers are
|
||||
* saved and restored.
|
||||
*
|
||||
* This code is self-contained. It requires no other header files in order
|
||||
* to compile and to be linkable on a PA-RISC 2.0 machine. Symbolic
|
||||
* definitions for registers and stack offsets are included within this
|
||||
* one source file.
|
||||
*
|
||||
* This is a leaf routine. As such, minimal use is made of the stack area.
|
||||
* Of the 192 bytes allocated, 64 bytes are used for saving/restoring eight
|
||||
* general registers, and 128 bytes are used to move intermediate products
|
||||
* from the floating-point registers to the general registers. Stack
|
||||
* protocols assure proper alignment of these areas.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/* ====================================================================*/
|
||||
/* symbolic definitions for PA-RISC registers */
|
||||
/* in the MIPS style, avoids lots of case shifts */
|
||||
/* assigments (except t4) preserve register number parity */
|
||||
/* ====================================================================*/
|
||||
|
||||
#define zero %r0 /* permanent zero */
|
||||
#define t5 %r1 /* temp register, altered by addil */
|
||||
|
||||
#define rp %r2 /* return pointer */
|
||||
|
||||
#define s1 %r3 /* callee saves register*/
|
||||
#define s0 %r4 /* callee saves register*/
|
||||
#define s3 %r5 /* callee saves register*/
|
||||
#define s2 %r6 /* callee saves register*/
|
||||
#define s5 %r7 /* callee saves register*/
|
||||
#define s4 %r8 /* callee saves register*/
|
||||
#define s7 %r9 /* callee saves register*/
|
||||
#define s6 %r10 /* callee saves register*/
|
||||
|
||||
#define t1 %r19 /* caller saves register*/
|
||||
#define t0 %r20 /* caller saves register*/
|
||||
#define t3 %r21 /* caller saves register*/
|
||||
#define t2 %r22 /* caller saves register*/
|
||||
|
||||
#define a3 %r23 /* fourth argument register, high word */
|
||||
#define a2 %r24 /* third argument register, low word*/
|
||||
#define a1 %r25 /* second argument register, high word*/
|
||||
#define a0 %r26 /* first argument register, low word*/
|
||||
|
||||
#define v0 %r28 /* high order return value*/
|
||||
#define v1 %r29 /* low order return value*/
|
||||
|
||||
#define sp %r30 /* stack pointer*/
|
||||
#define t4 %r31 /* temporary register */
|
||||
|
||||
#define fa0 %fr4 /* first argument register*/
|
||||
#define fa1 %fr5 /* second argument register*/
|
||||
#define fa2 %fr6 /* third argument register*/
|
||||
#define fa3 %fr7 /* fourth argument register*/
|
||||
|
||||
#define fa0r %fr4R /* first argument register*/
|
||||
#define fa1r %fr5R /* second argument register*/
|
||||
#define fa2r %fr6R /* third argument register*/
|
||||
#define fa3r %fr7R /* fourth argument register*/
|
||||
|
||||
#define ft0 %fr8 /* caller saves register*/
|
||||
#define ft1 %fr9 /* caller saves register*/
|
||||
#define ft2 %fr10 /* caller saves register*/
|
||||
#define ft3 %fr11 /* caller saves register*/
|
||||
|
||||
#define ft0r %fr8R /* caller saves register*/
|
||||
#define ft1r %fr9R /* caller saves register*/
|
||||
#define ft2r %fr10R /* caller saves register*/
|
||||
#define ft3r %fr11R /* caller saves register*/
|
||||
|
||||
#define ft4 %fr22 /* caller saves register*/
|
||||
#define ft5 %fr23 /* caller saves register*/
|
||||
#define ft6 %fr24 /* caller saves register*/
|
||||
#define ft7 %fr25 /* caller saves register*/
|
||||
#define ft8 %fr26 /* caller saves register*/
|
||||
#define ft9 %fr27 /* caller saves register*/
|
||||
#define ft10 %fr28 /* caller saves register*/
|
||||
#define ft11 %fr29 /* caller saves register*/
|
||||
#define ft12 %fr30 /* caller saves register*/
|
||||
#define ft13 %fr31 /* caller saves register*/
|
||||
|
||||
#define ft4r %fr22R /* caller saves register*/
|
||||
#define ft5r %fr23R /* caller saves register*/
|
||||
#define ft6r %fr24R /* caller saves register*/
|
||||
#define ft7r %fr25R /* caller saves register*/
|
||||
#define ft8r %fr26R /* caller saves register*/
|
||||
#define ft9r %fr27R /* caller saves register*/
|
||||
#define ft10r %fr28R /* caller saves register*/
|
||||
#define ft11r %fr29R /* caller saves register*/
|
||||
#define ft12r %fr30R /* caller saves register*/
|
||||
#define ft13r %fr31R /* caller saves register*/
|
||||
|
||||
|
||||
|
||||
/* ================================================================== */
|
||||
/* functional definitions for PA-RISC registers */
|
||||
/* ================================================================== */
|
||||
|
||||
/* general registers */
|
||||
|
||||
#define T1 a0 /* temp, (length parameter ignored) */
|
||||
|
||||
#define pM a1 /* -> 64-bit multiplier */
|
||||
#define T2 a1 /* temp, (after fetching multiplier) */
|
||||
|
||||
#define pA a2 /* -> multiplicand vector (8 64-bit words) */
|
||||
#define T3 a2 /* temp, (after fetching multiplicand) */
|
||||
|
||||
#define pR a3 /* -> addend vector (8 64-bit doublewords,
|
||||
result vector (9 64-bit words) */
|
||||
|
||||
#define S0 s0 /* callee saves summand registers */
|
||||
#define S1 s1
|
||||
#define S2 s2
|
||||
#define S3 s3
|
||||
#define S4 s4
|
||||
#define S5 s5
|
||||
#define S6 s6
|
||||
#define S7 s7
|
||||
|
||||
#define S8 v0 /* caller saves summand registers */
|
||||
#define S9 v1
|
||||
#define S10 t0
|
||||
#define S11 t1
|
||||
#define S12 t2
|
||||
#define S13 t3
|
||||
#define S14 t4
|
||||
#define S15 t5
|
||||
|
||||
|
||||
|
||||
/* floating-point registers */
|
||||
|
||||
#define M fa0 /* multiplier double word */
|
||||
#define MR fa0r /* low order half of multiplier double word */
|
||||
#define ML fa0 /* high order half of multiplier double word */
|
||||
|
||||
#define A0 fa2 /* multiplicand double word 0 */
|
||||
#define A0R fa2r /* low order half of multiplicand double word */
|
||||
#define A0L fa2 /* high order half of multiplicand double word */
|
||||
|
||||
#define A1 fa3 /* multiplicand double word 1 */
|
||||
#define A1R fa3r /* low order half of multiplicand double word */
|
||||
#define A1L fa3 /* high order half of multiplicand double word */
|
||||
|
||||
#define A2 ft0 /* multiplicand double word 2 */
|
||||
#define A2R ft0r /* low order half of multiplicand double word */
|
||||
#define A2L ft0 /* high order half of multiplicand double word */
|
||||
|
||||
#define A3 ft1 /* multiplicand double word 3 */
|
||||
#define A3R ft1r /* low order half of multiplicand double word */
|
||||
#define A3L ft1 /* high order half of multiplicand double word */
|
||||
|
||||
#define A4 ft2 /* multiplicand double word 4 */
|
||||
#define A4R ft2r /* low order half of multiplicand double word */
|
||||
#define A4L ft2 /* high order half of multiplicand double word */
|
||||
|
||||
#define A5 ft3 /* multiplicand double word 5 */
|
||||
#define A5R ft3r /* low order half of multiplicand double word */
|
||||
#define A5L ft3 /* high order half of multiplicand double word */
|
||||
|
||||
#define A6 ft4 /* multiplicand double word 6 */
|
||||
#define A6R ft4r /* low order half of multiplicand double word */
|
||||
#define A6L ft4 /* high order half of multiplicand double word */
|
||||
|
||||
#define A7 ft5 /* multiplicand double word 7 */
|
||||
#define A7R ft5r /* low order half of multiplicand double word */
|
||||
#define A7L ft5 /* high order half of multiplicand double word */
|
||||
|
||||
#define P0 ft6 /* product word 0 */
|
||||
#define P1 ft7 /* product word 0 */
|
||||
#define P2 ft8 /* product word 0 */
|
||||
#define P3 ft9 /* product word 0 */
|
||||
#define P4 ft10 /* product word 0 */
|
||||
#define P5 ft11 /* product word 0 */
|
||||
#define P6 ft12 /* product word 0 */
|
||||
#define P7 ft13 /* product word 0 */
|
||||
|
||||
|
||||
|
||||
|
||||
/* ====================================================================== */
|
||||
/* symbolic definitions for HP-UX stack offsets */
|
||||
/* symbolic definitions for memory NOPs */
|
||||
/* ====================================================================== */
|
||||
|
||||
#define ST_SZ 192 /* stack area total size */
|
||||
|
||||
#define SV0 -192(sp) /* general register save area */
|
||||
#define SV1 -184(sp)
|
||||
#define SV2 -176(sp)
|
||||
#define SV3 -168(sp)
|
||||
#define SV4 -160(sp)
|
||||
#define SV5 -152(sp)
|
||||
#define SV6 -144(sp)
|
||||
#define SV7 -136(sp)
|
||||
|
||||
#define XF0 -128(sp) /* data transfer area */
|
||||
#define XF1 -120(sp) /* for floating-pt to integer regs */
|
||||
#define XF2 -112(sp)
|
||||
#define XF3 -104(sp)
|
||||
#define XF4 -96(sp)
|
||||
#define XF5 -88(sp)
|
||||
#define XF6 -80(sp)
|
||||
#define XF7 -72(sp)
|
||||
#define XF8 -64(sp)
|
||||
#define XF9 -56(sp)
|
||||
#define XF10 -48(sp)
|
||||
#define XF11 -40(sp)
|
||||
#define XF12 -32(sp)
|
||||
#define XF13 -24(sp)
|
||||
#define XF14 -16(sp)
|
||||
#define XF15 -8(sp)
|
||||
|
||||
#define mnop proberi (sp),3,zero /* memory NOP */
|
||||
|
||||
|
||||
|
||||
|
||||
/* ====================================================================== */
|
||||
/* assembler formalities */
|
||||
/* ====================================================================== */
|
||||
|
||||
#ifdef __LP64__
|
||||
.level 2.0W
|
||||
#else
|
||||
.level 2.0
|
||||
#endif
|
||||
.space $TEXT$
|
||||
.subspa $CODE$
|
||||
.align 16
|
||||
|
||||
/* ====================================================================== */
|
||||
/* here to compute 64-bit x 512-bit product + 512-bit addend */
|
||||
/* ====================================================================== */
|
||||
|
||||
multacc512
|
||||
.PROC
|
||||
.CALLINFO
|
||||
.ENTER
|
||||
fldd 0(pM),M ; multiplier double word
|
||||
ldo ST_SZ(sp),sp ; push stack
|
||||
|
||||
fldd 0(pA),A0 ; multiplicand double word 0
|
||||
std S1,SV1 ; save s1
|
||||
|
||||
fldd 16(pA),A2 ; multiplicand double word 2
|
||||
std S3,SV3 ; save s3
|
||||
|
||||
fldd 32(pA),A4 ; multiplicand double word 4
|
||||
std S5,SV5 ; save s5
|
||||
|
||||
fldd 48(pA),A6 ; multiplicand double word 6
|
||||
std S7,SV7 ; save s7
|
||||
|
||||
|
||||
std S0,SV0 ; save s0
|
||||
fldd 8(pA),A1 ; multiplicand double word 1
|
||||
xmpyu MR,A0L,P0 ; A0 cross 32-bit word products
|
||||
xmpyu ML,A0R,P2
|
||||
|
||||
std S2,SV2 ; save s2
|
||||
fldd 24(pA),A3 ; multiplicand double word 3
|
||||
xmpyu MR,A2L,P4 ; A2 cross 32-bit word products
|
||||
xmpyu ML,A2R,P6
|
||||
|
||||
std S4,SV4 ; save s4
|
||||
fldd 40(pA),A5 ; multiplicand double word 5
|
||||
|
||||
std S6,SV6 ; save s6
|
||||
fldd 56(pA),A7 ; multiplicand double word 7
|
||||
|
||||
|
||||
fstd P0,XF0 ; MR * A0L
|
||||
xmpyu MR,A0R,P0 ; A0 right 32-bit word product
|
||||
xmpyu MR,A1L,P1 ; A1 cross 32-bit word product
|
||||
|
||||
fstd P2,XF2 ; ML * A0R
|
||||
xmpyu ML,A0L,P2 ; A0 left 32-bit word product
|
||||
xmpyu ML,A1R,P3 ; A1 cross 32-bit word product
|
||||
|
||||
fstd P4,XF4 ; MR * A2L
|
||||
xmpyu MR,A2R,P4 ; A2 right 32-bit word product
|
||||
xmpyu MR,A3L,P5 ; A3 cross 32-bit word product
|
||||
|
||||
fstd P6,XF6 ; ML * A2R
|
||||
xmpyu ML,A2L,P6 ; A2 parallel 32-bit word product
|
||||
xmpyu ML,A3R,P7 ; A3 cross 32-bit word product
|
||||
|
||||
|
||||
ldd XF0,S0 ; MR * A0L
|
||||
fstd P1,XF1 ; MR * A1L
|
||||
|
||||
ldd XF2,S2 ; ML * A0R
|
||||
fstd P3,XF3 ; ML * A1R
|
||||
|
||||
ldd XF4,S4 ; MR * A2L
|
||||
fstd P5,XF5 ; MR * A3L
|
||||
xmpyu MR,A1R,P1 ; A1 parallel 32-bit word products
|
||||
xmpyu ML,A1L,P3
|
||||
|
||||
ldd XF6,S6 ; ML * A2R
|
||||
fstd P7,XF7 ; ML * A3R
|
||||
xmpyu MR,A3R,P5 ; A3 parallel 32-bit word products
|
||||
xmpyu ML,A3L,P7
|
||||
|
||||
|
||||
fstd P0,XF0 ; MR * A0R
|
||||
ldd XF1,S1 ; MR * A1L
|
||||
nop
|
||||
add S0,S2,T1 ; A0 cross product sum
|
||||
|
||||
fstd P2,XF2 ; ML * A0L
|
||||
ldd XF3,S3 ; ML * A1R
|
||||
add,dc zero,zero,S0 ; A0 cross product sum carry
|
||||
depd,z T1,31,32,S2 ; A0 cross product sum << 32
|
||||
|
||||
fstd P4,XF4 ; MR * A2R
|
||||
ldd XF5,S5 ; MR * A3L
|
||||
shrpd S0,T1,32,S0 ; A0 carry | cross product sum >> 32
|
||||
add S4,S6,T3 ; A2 cross product sum
|
||||
|
||||
fstd P6,XF6 ; ML * A2L
|
||||
ldd XF7,S7 ; ML * A3R
|
||||
add,dc zero,zero,S4 ; A2 cross product sum carry
|
||||
depd,z T3,31,32,S6 ; A2 cross product sum << 32
|
||||
|
||||
|
||||
ldd XF0,S8 ; MR * A0R
|
||||
fstd P1,XF1 ; MR * A1R
|
||||
xmpyu MR,A4L,P0 ; A4 cross 32-bit word product
|
||||
xmpyu MR,A5L,P1 ; A5 cross 32-bit word product
|
||||
|
||||
ldd XF2,S10 ; ML * A0L
|
||||
fstd P3,XF3 ; ML * A1L
|
||||
xmpyu ML,A4R,P2 ; A4 cross 32-bit word product
|
||||
xmpyu ML,A5R,P3 ; A5 cross 32-bit word product
|
||||
|
||||
ldd XF4,S12 ; MR * A2R
|
||||
fstd P5,XF5 ; MR * A3L
|
||||
xmpyu MR,A6L,P4 ; A6 cross 32-bit word product
|
||||
xmpyu MR,A7L,P5 ; A7 cross 32-bit word product
|
||||
|
||||
ldd XF6,S14 ; ML * A2L
|
||||
fstd P7,XF7 ; ML * A3L
|
||||
xmpyu ML,A6R,P6 ; A6 cross 32-bit word product
|
||||
xmpyu ML,A7R,P7 ; A7 cross 32-bit word product
|
||||
|
||||
|
||||
fstd P0,XF0 ; MR * A4L
|
||||
ldd XF1,S9 ; MR * A1R
|
||||
shrpd S4,T3,32,S4 ; A2 carry | cross product sum >> 32
|
||||
add S1,S3,T1 ; A1 cross product sum
|
||||
|
||||
fstd P2,XF2 ; ML * A4R
|
||||
ldd XF3,S11 ; ML * A1L
|
||||
add,dc zero,zero,S1 ; A1 cross product sum carry
|
||||
depd,z T1,31,32,S3 ; A1 cross product sum << 32
|
||||
|
||||
fstd P4,XF4 ; MR * A6L
|
||||
ldd XF5,S13 ; MR * A3R
|
||||
shrpd S1,T1,32,S1 ; A1 carry | cross product sum >> 32
|
||||
add S5,S7,T3 ; A3 cross product sum
|
||||
|
||||
fstd P6,XF6 ; ML * A6R
|
||||
ldd XF7,S15 ; ML * A3L
|
||||
add,dc zero,zero,S5 ; A3 cross product sum carry
|
||||
depd,z T3,31,32,S7 ; A3 cross product sum << 32
|
||||
|
||||
|
||||
shrpd S5,T3,32,S5 ; A3 carry | cross product sum >> 32
|
||||
add S2,S8,S8 ; M * A0 right doubleword, P0 doubleword
|
||||
|
||||
add,dc S0,S10,S10 ; M * A0 left doubleword
|
||||
add S3,S9,S9 ; M * A1 right doubleword
|
||||
|
||||
add,dc S1,S11,S11 ; M * A1 left doubleword
|
||||
add S6,S12,S12 ; M * A2 right doubleword
|
||||
|
||||
|
||||
ldd 24(pR),S3 ; Addend word 3
|
||||
fstd P1,XF1 ; MR * A5L
|
||||
add,dc S4,S14,S14 ; M * A2 left doubleword
|
||||
xmpyu MR,A5R,P1 ; A5 right 32-bit word product
|
||||
|
||||
ldd 8(pR),S1 ; Addend word 1
|
||||
fstd P3,XF3 ; ML * A5R
|
||||
add S7,S13,S13 ; M * A3 right doubleword
|
||||
xmpyu ML,A5L,P3 ; A5 left 32-bit word product
|
||||
|
||||
ldd 0(pR),S7 ; Addend word 0
|
||||
fstd P5,XF5 ; MR * A7L
|
||||
add,dc S5,S15,S15 ; M * A3 left doubleword
|
||||
xmpyu MR,A7R,P5 ; A7 right 32-bit word product
|
||||
|
||||
ldd 16(pR),S5 ; Addend word 2
|
||||
fstd P7,XF7 ; ML * A7R
|
||||
add S10,S9,S9 ; P1 doubleword
|
||||
xmpyu ML,A7L,P7 ; A7 left 32-bit word products
|
||||
|
||||
|
||||
ldd XF0,S0 ; MR * A4L
|
||||
fstd P1,XF9 ; MR * A5R
|
||||
add,dc S11,S12,S12 ; P2 doubleword
|
||||
xmpyu MR,A4R,P0 ; A4 right 32-bit word product
|
||||
|
||||
ldd XF2,S2 ; ML * A4R
|
||||
fstd P3,XF11 ; ML * A5L
|
||||
add,dc S14,S13,S13 ; P3 doubleword
|
||||
xmpyu ML,A4L,P2 ; A4 left 32-bit word product
|
||||
|
||||
ldd XF6,S6 ; ML * A6R
|
||||
fstd P5,XF13 ; MR * A7R
|
||||
add,dc zero,S15,T2 ; P4 partial doubleword
|
||||
xmpyu MR,A6R,P4 ; A6 right 32-bit word product
|
||||
|
||||
ldd XF4,S4 ; MR * A6L
|
||||
fstd P7,XF15 ; ML * A7L
|
||||
add S7,S8,S8 ; R0 + P0, new R0 doubleword
|
||||
xmpyu ML,A6L,P6 ; A6 left 32-bit word product
|
||||
|
||||
|
||||
fstd P0,XF0 ; MR * A4R
|
||||
ldd XF7,S7 ; ML * A7R
|
||||
add,dc S1,S9,S9 ; c + R1 + P1, new R1 doubleword
|
||||
|
||||
fstd P2,XF2 ; ML * A4L
|
||||
ldd XF1,S1 ; MR * A5L
|
||||
add,dc S5,S12,S12 ; c + R2 + P2, new R2 doubleword
|
||||
|
||||
fstd P4,XF4 ; MR * A6R
|
||||
ldd XF5,S5 ; MR * A7L
|
||||
add,dc S3,S13,S13 ; c + R3 + P3, new R3 doubleword
|
||||
|
||||
fstd P6,XF6 ; ML * A6L
|
||||
ldd XF3,S3 ; ML * A5R
|
||||
add,dc zero,T2,T2 ; c + partial P4
|
||||
add S0,S2,T1 ; A4 cross product sum
|
||||
|
||||
|
||||
std S8,0(pR) ; save R0
|
||||
add,dc zero,zero,S0 ; A4 cross product sum carry
|
||||
depd,z T1,31,32,S2 ; A4 cross product sum << 32
|
||||
|
||||
std S9,8(pR) ; save R1
|
||||
shrpd S0,T1,32,S0 ; A4 carry | cross product sum >> 32
|
||||
add S4,S6,T3 ; A6 cross product sum
|
||||
|
||||
std S12,16(pR) ; save R2
|
||||
add,dc zero,zero,S4 ; A6 cross product sum carry
|
||||
depd,z T3,31,32,S6 ; A6 cross product sum << 32
|
||||
|
||||
|
||||
std S13,24(pR) ; save R3
|
||||
shrpd S4,T3,32,S4 ; A6 carry | cross product sum >> 32
|
||||
add S1,S3,T1 ; A5 cross product sum
|
||||
|
||||
ldd XF0,S8 ; MR * A4R
|
||||
add,dc zero,zero,S1 ; A5 cross product sum carry
|
||||
depd,z T1,31,32,S3 ; A5 cross product sum << 32
|
||||
|
||||
ldd XF2,S10 ; ML * A4L
|
||||
ldd XF9,S9 ; MR * A5R
|
||||
shrpd S1,T1,32,S1 ; A5 carry | cross product sum >> 32
|
||||
add S5,S7,T3 ; A7 cross product sum
|
||||
|
||||
ldd XF4,S12 ; MR * A6R
|
||||
ldd XF11,S11 ; ML * A5L
|
||||
add,dc zero,zero,S5 ; A7 cross product sum carry
|
||||
depd,z T3,31,32,S7 ; A7 cross product sum << 32
|
||||
|
||||
ldd XF6,S14 ; ML * A6L
|
||||
ldd XF13,S13 ; MR * A7R
|
||||
shrpd S5,T3,32,S5 ; A7 carry | cross product sum >> 32
|
||||
add S2,S8,S8 ; M * A4 right doubleword
|
||||
|
||||
|
||||
ldd XF15,S15 ; ML * A7L
|
||||
add,dc S0,S10,S10 ; M * A4 left doubleword
|
||||
add S3,S9,S9 ; M * A5 right doubleword
|
||||
|
||||
add,dc S1,S11,S11 ; M * A5 left doubleword
|
||||
add S6,S12,S12 ; M * A6 right doubleword
|
||||
|
||||
ldd 32(pR),S0 ; Addend word 4
|
||||
ldd 40(pR),S1 ; Addend word 5
|
||||
add,dc S4,S14,S14 ; M * A6 left doubleword
|
||||
add S7,S13,S13 ; M * A7 right doubleword
|
||||
|
||||
ldd 48(pR),S2 ; Addend word 6
|
||||
ldd 56(pR),S3 ; Addend word 7
|
||||
add,dc S5,S15,S15 ; M * A7 left doubleword
|
||||
add S8,T2,S8 ; P4 doubleword
|
||||
|
||||
ldd 64(pR),S4 ; Addend word 8
|
||||
ldd SV5,s5 ; restore s5
|
||||
add,dc S10,S9,S9 ; P5 doubleword
|
||||
add,dc S11,S12,S12 ; P6 doubleword
|
||||
|
||||
|
||||
ldd SV6,s6 ; restore s6
|
||||
ldd SV7,s7 ; restore s7
|
||||
add,dc S14,S13,S13 ; P7 doubleword
|
||||
add,dc zero,S15,S15 ; P8 doubleword
|
||||
|
||||
add S0,S8,S8 ; new R4 doubleword
|
||||
|
||||
ldd SV0,s0 ; restore s0
|
||||
std S8,32(pR) ; save R4
|
||||
add,dc S1,S9,S9 ; new R5 doubleword
|
||||
|
||||
ldd SV1,s1 ; restore s1
|
||||
std S9,40(pR) ; save R5
|
||||
add,dc S2,S12,S12 ; new R6 doubleword
|
||||
|
||||
ldd SV2,s2 ; restore s2
|
||||
std S12,48(pR) ; save R6
|
||||
add,dc S3,S13,S13 ; new R7 doubleword
|
||||
|
||||
ldd SV3,s3 ; restore s3
|
||||
std S13,56(pR) ; save R7
|
||||
add,dc S4,S15,S15 ; new R8 doubleword
|
||||
|
||||
ldd SV4,s4 ; restore s4
|
||||
std S15,64(pR) ; save result[8]
|
||||
add,dc zero,zero,v0 ; return carry from R8
|
||||
|
||||
CMPIB,*= 0,v0,$L0 ; if no overflow, exit
|
||||
LDO 8(pR),pR
|
||||
|
||||
$FINAL1 ; Final carry propagation
|
||||
LDD 64(pR),v0
|
||||
LDO 8(pR),pR
|
||||
ADDI 1,v0,v0
|
||||
CMPIB,*= 0,v0,$FINAL1 ; Keep looping if there is a carry.
|
||||
STD v0,56(pR)
|
||||
$L0
|
||||
bv zero(rp) ; -> caller
|
||||
ldo -ST_SZ(sp),sp ; pop stack
|
||||
|
||||
/* ====================================================================== */
|
||||
/* end of module */
|
||||
/* ====================================================================== */
|
||||
|
||||
.LEAVE
|
||||
|
||||
.PROCEND
|
||||
.SPACE $TEXT$
|
||||
.SUBSPA $CODE$
|
||||
.EXPORT multacc512,ENTRY
|
||||
|
||||
.end
|
||||
@@ -1,929 +0,0 @@
|
||||
; 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 MAXPY multiple-precision integer arithmetic.
|
||||
;
|
||||
; The Initial Developer of the Original Code is the Hewlett-Packard Company.
|
||||
; Portions created by Hewlett-Packard Company are
|
||||
; Copyright (C) 1997 Hewlett-Packard Company. All Rights Reserved.
|
||||
;
|
||||
; Contributor(s):
|
||||
; coded by: William B. Ackerman
|
||||
;
|
||||
; Alternatively, the contents of this file may be used under the
|
||||
; terms of the GNU General Public License Version 2 or later (the
|
||||
; "GPL"), in which case the provisions of the GPL are applicable
|
||||
; instead of those above. If you wish to allow use of your
|
||||
; version of this file only under the terms of the GPL and not to
|
||||
; allow others to use your version of this file under the MPL,
|
||||
; indicate your decision by deleting the provisions above and
|
||||
; replace them with the notice and other provisions required by
|
||||
; the GPL. If you do not delete the provisions above, a recipient
|
||||
; may use your version of this file under either the MPL or the
|
||||
; GPL.
|
||||
|
||||
#ifdef __LP64__
|
||||
.LEVEL 2.0W
|
||||
#else
|
||||
; .LEVEL 1.1
|
||||
; .ALLOW 2.0N
|
||||
.LEVEL 2.0N
|
||||
#endif
|
||||
.SPACE $TEXT$,SORT=8
|
||||
.SUBSPA $CODE$,QUAD=0,ALIGN=4,ACCESS=0x2c,CODE_ONLY,SORT=24
|
||||
|
||||
; ***************************************************************
|
||||
;
|
||||
; maxpy_[little/big]
|
||||
;
|
||||
; ***************************************************************
|
||||
|
||||
; There is no default -- you must specify one or the other.
|
||||
#define LITTLE_WORDIAN 1
|
||||
|
||||
#ifdef LITTLE_WORDIAN
|
||||
#define EIGHT 8
|
||||
#define SIXTEEN 16
|
||||
#define THIRTY_TWO 32
|
||||
#define UN_EIGHT -8
|
||||
#define UN_SIXTEEN -16
|
||||
#define UN_TWENTY_FOUR -24
|
||||
#endif
|
||||
|
||||
#ifdef BIG_WORDIAN
|
||||
#define EIGHT -8
|
||||
#define SIXTEEN -16
|
||||
#define THIRTY_TWO -32
|
||||
#define UN_EIGHT 8
|
||||
#define UN_SIXTEEN 16
|
||||
#define UN_TWENTY_FOUR 24
|
||||
#endif
|
||||
|
||||
; This performs a multiple-precision integer version of "daxpy",
|
||||
; Using the selected addressing direction. "Little-wordian" means that
|
||||
; the least significant word of a number is stored at the lowest address.
|
||||
; "Big-wordian" means that the most significant word is at the lowest
|
||||
; address. Either way, the incoming address of the vector is that
|
||||
; of the least significant word. That means that, for little-wordian
|
||||
; addressing, we move the address upward as we propagate carries
|
||||
; from the least significant word to the most significant. For
|
||||
; big-wordian we move the address downward.
|
||||
|
||||
; We use the following registers:
|
||||
;
|
||||
; r2 return PC, of course
|
||||
; r26 = arg1 = length
|
||||
; r25 = arg2 = address of scalar
|
||||
; r24 = arg3 = multiplicand vector
|
||||
; r23 = arg4 = result vector
|
||||
;
|
||||
; fr9 = scalar loaded once only from r25
|
||||
|
||||
; The cycle counts shown in the bodies below are simply the result of a
|
||||
; scheduling by hand. The actual PCX-U hardware does it differently.
|
||||
; The intention is that the overall speed is the same.
|
||||
|
||||
; The pipeline startup and shutdown code is constructed in the usual way,
|
||||
; by taking the loop bodies and removing unnecessary instructions.
|
||||
; We have left the comments describing cycle numbers in the code.
|
||||
; These are intended for reference when comparing with the main loop,
|
||||
; and have no particular relationship to actual cycle numbers.
|
||||
|
||||
#ifdef LITTLE_WORDIAN
|
||||
maxpy_little
|
||||
#else
|
||||
maxpy_big
|
||||
#endif
|
||||
.PROC
|
||||
.CALLINFO FRAME=120,ENTRY_GR=%r4
|
||||
.ENTER
|
||||
|
||||
; Of course, real men don't use the sissy "enter" and "leave" commands.
|
||||
; They write their own stack manipulation stuff. Unfortunately,
|
||||
; that doesn't generate complete unwind info, whereas "enter" and
|
||||
; "leave" (if the documentation is to be believed) do so. Therefore,
|
||||
; we use the sissy commands. We have verified (by real-man methods)
|
||||
; that the above command generates what we want:
|
||||
; STW,MA %r3,128(%sp)
|
||||
; STW %r4,-124(%sp)
|
||||
|
||||
ADDIB,< -1,%r26,$L0 ; If N = 0, exit immediately.
|
||||
FLDD 0(%r25),%fr9 ; fr9 = scalar
|
||||
|
||||
; First startup
|
||||
|
||||
FLDD 0(%r24),%fr24 ; Cycle 1
|
||||
XMPYU %fr9R,%fr24R,%fr27 ; Cycle 3
|
||||
XMPYU %fr9R,%fr24L,%fr25 ; Cycle 4
|
||||
XMPYU %fr9L,%fr24L,%fr26 ; Cycle 5
|
||||
CMPIB,> 3,%r26,$N_IS_SMALL ; Pick out cases N = 1, 2, or 3
|
||||
XMPYU %fr9L,%fr24R,%fr24 ; Cycle 6
|
||||
FLDD EIGHT(%r24),%fr28 ; Cycle 8
|
||||
XMPYU %fr9L,%fr28R,%fr31 ; Cycle 10
|
||||
FSTD %fr24,-96(%sp)
|
||||
XMPYU %fr9R,%fr28L,%fr30 ; Cycle 11
|
||||
FSTD %fr25,-80(%sp)
|
||||
LDO SIXTEEN(%r24),%r24 ; Cycle 12
|
||||
FSTD %fr31,-64(%sp)
|
||||
XMPYU %fr9R,%fr28R,%fr29 ; Cycle 13
|
||||
FSTD %fr27,-48(%sp)
|
||||
|
||||
; Second startup
|
||||
|
||||
XMPYU %fr9L,%fr28L,%fr28 ; Cycle 1
|
||||
FSTD %fr30,-56(%sp)
|
||||
FLDD 0(%r24),%fr24
|
||||
|
||||
FSTD %fr26,-88(%sp) ; Cycle 2
|
||||
|
||||
XMPYU %fr9R,%fr24R,%fr27 ; Cycle 3
|
||||
FSTD %fr28,-104(%sp)
|
||||
|
||||
XMPYU %fr9R,%fr24L,%fr25 ; Cycle 4
|
||||
LDD -96(%sp),%r3
|
||||
FSTD %fr29,-72(%sp)
|
||||
|
||||
XMPYU %fr9L,%fr24L,%fr26 ; Cycle 5
|
||||
LDD -64(%sp),%r19
|
||||
LDD -80(%sp),%r21
|
||||
|
||||
XMPYU %fr9L,%fr24R,%fr24 ; Cycle 6
|
||||
LDD -56(%sp),%r20
|
||||
ADD %r21,%r3,%r3
|
||||
|
||||
ADD,DC %r20,%r19,%r19 ; Cycle 7
|
||||
LDD -88(%sp),%r4
|
||||
SHRPD %r3,%r0,32,%r21
|
||||
LDD -48(%sp),%r1
|
||||
|
||||
FLDD EIGHT(%r24),%fr28 ; Cycle 8
|
||||
LDD -104(%sp),%r31
|
||||
ADD,DC %r0,%r0,%r20
|
||||
SHRPD %r19,%r3,32,%r3
|
||||
|
||||
LDD -72(%sp),%r29 ; Cycle 9
|
||||
SHRPD %r20,%r19,32,%r20
|
||||
ADD %r21,%r1,%r1
|
||||
|
||||
XMPYU %fr9L,%fr28R,%fr31 ; Cycle 10
|
||||
ADD,DC %r3,%r4,%r4
|
||||
FSTD %fr24,-96(%sp)
|
||||
|
||||
XMPYU %fr9R,%fr28L,%fr30 ; Cycle 11
|
||||
ADD,DC %r0,%r20,%r20
|
||||
LDD 0(%r23),%r3
|
||||
FSTD %fr25,-80(%sp)
|
||||
|
||||
LDO SIXTEEN(%r24),%r24 ; Cycle 12
|
||||
FSTD %fr31,-64(%sp)
|
||||
|
||||
XMPYU %fr9R,%fr28R,%fr29 ; Cycle 13
|
||||
ADD %r0,%r0,%r0 ; clear the carry bit
|
||||
ADDIB,<= -4,%r26,$ENDLOOP ; actually happens in cycle 12
|
||||
FSTD %fr27,-48(%sp)
|
||||
; MFCTL %cr16,%r21 ; for timing
|
||||
; STD %r21,-112(%sp)
|
||||
|
||||
; Here is the loop.
|
||||
|
||||
$LOOP XMPYU %fr9L,%fr28L,%fr28 ; Cycle 1
|
||||
ADD,DC %r29,%r4,%r4
|
||||
FSTD %fr30,-56(%sp)
|
||||
FLDD 0(%r24),%fr24
|
||||
|
||||
LDO SIXTEEN(%r23),%r23 ; Cycle 2
|
||||
ADD,DC %r0,%r20,%r20
|
||||
FSTD %fr26,-88(%sp)
|
||||
|
||||
XMPYU %fr9R,%fr24R,%fr27 ; Cycle 3
|
||||
ADD %r3,%r1,%r1
|
||||
FSTD %fr28,-104(%sp)
|
||||
LDD UN_EIGHT(%r23),%r21
|
||||
|
||||
XMPYU %fr9R,%fr24L,%fr25 ; Cycle 4
|
||||
ADD,DC %r21,%r4,%r28
|
||||
FSTD %fr29,-72(%sp)
|
||||
LDD -96(%sp),%r3
|
||||
|
||||
XMPYU %fr9L,%fr24L,%fr26 ; Cycle 5
|
||||
ADD,DC %r20,%r31,%r22
|
||||
LDD -64(%sp),%r19
|
||||
LDD -80(%sp),%r21
|
||||
|
||||
XMPYU %fr9L,%fr24R,%fr24 ; Cycle 6
|
||||
ADD %r21,%r3,%r3
|
||||
LDD -56(%sp),%r20
|
||||
STD %r1,UN_SIXTEEN(%r23)
|
||||
|
||||
ADD,DC %r20,%r19,%r19 ; Cycle 7
|
||||
SHRPD %r3,%r0,32,%r21
|
||||
LDD -88(%sp),%r4
|
||||
LDD -48(%sp),%r1
|
||||
|
||||
ADD,DC %r0,%r0,%r20 ; Cycle 8
|
||||
SHRPD %r19,%r3,32,%r3
|
||||
FLDD EIGHT(%r24),%fr28
|
||||
LDD -104(%sp),%r31
|
||||
|
||||
SHRPD %r20,%r19,32,%r20 ; Cycle 9
|
||||
ADD %r21,%r1,%r1
|
||||
STD %r28,UN_EIGHT(%r23)
|
||||
LDD -72(%sp),%r29
|
||||
|
||||
XMPYU %fr9L,%fr28R,%fr31 ; Cycle 10
|
||||
ADD,DC %r3,%r4,%r4
|
||||
FSTD %fr24,-96(%sp)
|
||||
|
||||
XMPYU %fr9R,%fr28L,%fr30 ; Cycle 11
|
||||
ADD,DC %r0,%r20,%r20
|
||||
FSTD %fr25,-80(%sp)
|
||||
LDD 0(%r23),%r3
|
||||
|
||||
LDO SIXTEEN(%r24),%r24 ; Cycle 12
|
||||
FSTD %fr31,-64(%sp)
|
||||
|
||||
XMPYU %fr9R,%fr28R,%fr29 ; Cycle 13
|
||||
ADD %r22,%r1,%r1
|
||||
ADDIB,> -2,%r26,$LOOP ; actually happens in cycle 12
|
||||
FSTD %fr27,-48(%sp)
|
||||
|
||||
$ENDLOOP
|
||||
|
||||
; Shutdown code, first stage.
|
||||
|
||||
; MFCTL %cr16,%r21 ; for timing
|
||||
; STD %r21,UN_SIXTEEN(%r23)
|
||||
; LDD -112(%sp),%r21
|
||||
; STD %r21,UN_EIGHT(%r23)
|
||||
|
||||
XMPYU %fr9L,%fr28L,%fr28 ; Cycle 1
|
||||
ADD,DC %r29,%r4,%r4
|
||||
CMPIB,= 0,%r26,$ONEMORE
|
||||
FSTD %fr30,-56(%sp)
|
||||
|
||||
LDO SIXTEEN(%r23),%r23 ; Cycle 2
|
||||
ADD,DC %r0,%r20,%r20
|
||||
FSTD %fr26,-88(%sp)
|
||||
|
||||
ADD %r3,%r1,%r1 ; Cycle 3
|
||||
FSTD %fr28,-104(%sp)
|
||||
LDD UN_EIGHT(%r23),%r21
|
||||
|
||||
ADD,DC %r21,%r4,%r28 ; Cycle 4
|
||||
FSTD %fr29,-72(%sp)
|
||||
STD %r28,UN_EIGHT(%r23) ; moved up from cycle 9
|
||||
LDD -96(%sp),%r3
|
||||
|
||||
ADD,DC %r20,%r31,%r22 ; Cycle 5
|
||||
STD %r1,UN_SIXTEEN(%r23)
|
||||
$JOIN4
|
||||
LDD -64(%sp),%r19
|
||||
LDD -80(%sp),%r21
|
||||
|
||||
ADD %r21,%r3,%r3 ; Cycle 6
|
||||
LDD -56(%sp),%r20
|
||||
|
||||
ADD,DC %r20,%r19,%r19 ; Cycle 7
|
||||
SHRPD %r3,%r0,32,%r21
|
||||
LDD -88(%sp),%r4
|
||||
LDD -48(%sp),%r1
|
||||
|
||||
ADD,DC %r0,%r0,%r20 ; Cycle 8
|
||||
SHRPD %r19,%r3,32,%r3
|
||||
LDD -104(%sp),%r31
|
||||
|
||||
SHRPD %r20,%r19,32,%r20 ; Cycle 9
|
||||
ADD %r21,%r1,%r1
|
||||
LDD -72(%sp),%r29
|
||||
|
||||
ADD,DC %r3,%r4,%r4 ; Cycle 10
|
||||
|
||||
ADD,DC %r0,%r20,%r20 ; Cycle 11
|
||||
LDD 0(%r23),%r3
|
||||
|
||||
ADD %r22,%r1,%r1 ; Cycle 13
|
||||
|
||||
; Shutdown code, second stage.
|
||||
|
||||
ADD,DC %r29,%r4,%r4 ; Cycle 1
|
||||
|
||||
LDO SIXTEEN(%r23),%r23 ; Cycle 2
|
||||
ADD,DC %r0,%r20,%r20
|
||||
|
||||
LDD UN_EIGHT(%r23),%r21 ; Cycle 3
|
||||
ADD %r3,%r1,%r1
|
||||
|
||||
ADD,DC %r21,%r4,%r28 ; Cycle 4
|
||||
|
||||
ADD,DC %r20,%r31,%r22 ; Cycle 5
|
||||
|
||||
STD %r1,UN_SIXTEEN(%r23); Cycle 6
|
||||
|
||||
STD %r28,UN_EIGHT(%r23) ; Cycle 9
|
||||
|
||||
LDD 0(%r23),%r3 ; Cycle 11
|
||||
|
||||
; Shutdown code, third stage.
|
||||
|
||||
LDO SIXTEEN(%r23),%r23
|
||||
ADD %r3,%r22,%r1
|
||||
$JOIN1 ADD,DC %r0,%r0,%r21
|
||||
CMPIB,*= 0,%r21,$L0 ; if no overflow, exit
|
||||
STD %r1,UN_SIXTEEN(%r23)
|
||||
|
||||
; Final carry propagation
|
||||
|
||||
$FINAL1 LDO EIGHT(%r23),%r23
|
||||
LDD UN_SIXTEEN(%r23),%r21
|
||||
ADDI 1,%r21,%r21
|
||||
CMPIB,*= 0,%r21,$FINAL1 ; Keep looping if there is a carry.
|
||||
STD %r21,UN_SIXTEEN(%r23)
|
||||
B $L0
|
||||
NOP
|
||||
|
||||
; Here is the code that handles the difficult cases N=1, N=2, and N=3.
|
||||
; We do the usual trick -- branch out of the startup code at appropriate
|
||||
; points, and branch into the shutdown code.
|
||||
|
||||
$N_IS_SMALL
|
||||
CMPIB,= 0,%r26,$N_IS_ONE
|
||||
FSTD %fr24,-96(%sp) ; Cycle 10
|
||||
FLDD EIGHT(%r24),%fr28 ; Cycle 8
|
||||
XMPYU %fr9L,%fr28R,%fr31 ; Cycle 10
|
||||
XMPYU %fr9R,%fr28L,%fr30 ; Cycle 11
|
||||
FSTD %fr25,-80(%sp)
|
||||
FSTD %fr31,-64(%sp) ; Cycle 12
|
||||
XMPYU %fr9R,%fr28R,%fr29 ; Cycle 13
|
||||
FSTD %fr27,-48(%sp)
|
||||
XMPYU %fr9L,%fr28L,%fr28 ; Cycle 1
|
||||
CMPIB,= 2,%r26,$N_IS_THREE
|
||||
FSTD %fr30,-56(%sp)
|
||||
|
||||
; N = 2
|
||||
FSTD %fr26,-88(%sp) ; Cycle 2
|
||||
FSTD %fr28,-104(%sp) ; Cycle 3
|
||||
LDD -96(%sp),%r3 ; Cycle 4
|
||||
FSTD %fr29,-72(%sp)
|
||||
B $JOIN4
|
||||
ADD %r0,%r0,%r22
|
||||
|
||||
$N_IS_THREE
|
||||
FLDD SIXTEEN(%r24),%fr24
|
||||
FSTD %fr26,-88(%sp) ; Cycle 2
|
||||
XMPYU %fr9R,%fr24R,%fr27 ; Cycle 3
|
||||
FSTD %fr28,-104(%sp)
|
||||
XMPYU %fr9R,%fr24L,%fr25 ; Cycle 4
|
||||
LDD -96(%sp),%r3
|
||||
FSTD %fr29,-72(%sp)
|
||||
XMPYU %fr9L,%fr24L,%fr26 ; Cycle 5
|
||||
LDD -64(%sp),%r19
|
||||
LDD -80(%sp),%r21
|
||||
B $JOIN3
|
||||
ADD %r0,%r0,%r22
|
||||
|
||||
$N_IS_ONE
|
||||
FSTD %fr25,-80(%sp)
|
||||
FSTD %fr27,-48(%sp)
|
||||
FSTD %fr26,-88(%sp) ; Cycle 2
|
||||
B $JOIN5
|
||||
ADD %r0,%r0,%r22
|
||||
|
||||
; We came out of the unrolled loop with wrong parity. Do one more
|
||||
; single cycle. This is quite tricky, because of the way the
|
||||
; carry chains and SHRPD chains have been chopped up.
|
||||
|
||||
$ONEMORE
|
||||
|
||||
FLDD 0(%r24),%fr24
|
||||
|
||||
LDO SIXTEEN(%r23),%r23 ; Cycle 2
|
||||
ADD,DC %r0,%r20,%r20
|
||||
FSTD %fr26,-88(%sp)
|
||||
|
||||
XMPYU %fr9R,%fr24R,%fr27 ; Cycle 3
|
||||
FSTD %fr28,-104(%sp)
|
||||
LDD UN_EIGHT(%r23),%r21
|
||||
ADD %r3,%r1,%r1
|
||||
|
||||
XMPYU %fr9R,%fr24L,%fr25 ; Cycle 4
|
||||
ADD,DC %r21,%r4,%r28
|
||||
STD %r28,UN_EIGHT(%r23) ; moved from cycle 9
|
||||
LDD -96(%sp),%r3
|
||||
FSTD %fr29,-72(%sp)
|
||||
|
||||
XMPYU %fr9L,%fr24L,%fr26 ; Cycle 5
|
||||
ADD,DC %r20,%r31,%r22
|
||||
LDD -64(%sp),%r19
|
||||
LDD -80(%sp),%r21
|
||||
|
||||
STD %r1,UN_SIXTEEN(%r23); Cycle 6
|
||||
$JOIN3
|
||||
XMPYU %fr9L,%fr24R,%fr24
|
||||
LDD -56(%sp),%r20
|
||||
ADD %r21,%r3,%r3
|
||||
|
||||
ADD,DC %r20,%r19,%r19 ; Cycle 7
|
||||
LDD -88(%sp),%r4
|
||||
SHRPD %r3,%r0,32,%r21
|
||||
LDD -48(%sp),%r1
|
||||
|
||||
LDD -104(%sp),%r31 ; Cycle 8
|
||||
ADD,DC %r0,%r0,%r20
|
||||
SHRPD %r19,%r3,32,%r3
|
||||
|
||||
LDD -72(%sp),%r29 ; Cycle 9
|
||||
SHRPD %r20,%r19,32,%r20
|
||||
ADD %r21,%r1,%r1
|
||||
|
||||
ADD,DC %r3,%r4,%r4 ; Cycle 10
|
||||
FSTD %fr24,-96(%sp)
|
||||
|
||||
ADD,DC %r0,%r20,%r20 ; Cycle 11
|
||||
LDD 0(%r23),%r3
|
||||
FSTD %fr25,-80(%sp)
|
||||
|
||||
ADD %r22,%r1,%r1 ; Cycle 13
|
||||
FSTD %fr27,-48(%sp)
|
||||
|
||||
; Shutdown code, stage 1-1/2.
|
||||
|
||||
ADD,DC %r29,%r4,%r4 ; Cycle 1
|
||||
|
||||
LDO SIXTEEN(%r23),%r23 ; Cycle 2
|
||||
ADD,DC %r0,%r20,%r20
|
||||
FSTD %fr26,-88(%sp)
|
||||
|
||||
LDD UN_EIGHT(%r23),%r21 ; Cycle 3
|
||||
ADD %r3,%r1,%r1
|
||||
|
||||
ADD,DC %r21,%r4,%r28 ; Cycle 4
|
||||
STD %r28,UN_EIGHT(%r23) ; moved from cycle 9
|
||||
|
||||
ADD,DC %r20,%r31,%r22 ; Cycle 5
|
||||
STD %r1,UN_SIXTEEN(%r23)
|
||||
$JOIN5
|
||||
LDD -96(%sp),%r3 ; moved from cycle 4
|
||||
LDD -80(%sp),%r21
|
||||
ADD %r21,%r3,%r3 ; Cycle 6
|
||||
ADD,DC %r0,%r0,%r19 ; Cycle 7
|
||||
LDD -88(%sp),%r4
|
||||
SHRPD %r3,%r0,32,%r21
|
||||
LDD -48(%sp),%r1
|
||||
SHRPD %r19,%r3,32,%r3 ; Cycle 8
|
||||
ADD %r21,%r1,%r1 ; Cycle 9
|
||||
ADD,DC %r3,%r4,%r4 ; Cycle 10
|
||||
LDD 0(%r23),%r3 ; Cycle 11
|
||||
ADD %r22,%r1,%r1 ; Cycle 13
|
||||
|
||||
; Shutdown code, stage 2-1/2.
|
||||
|
||||
ADD,DC %r0,%r4,%r4 ; Cycle 1
|
||||
LDO SIXTEEN(%r23),%r23 ; Cycle 2
|
||||
LDD UN_EIGHT(%r23),%r21 ; Cycle 3
|
||||
ADD %r3,%r1,%r1
|
||||
STD %r1,UN_SIXTEEN(%r23)
|
||||
ADD,DC %r21,%r4,%r1
|
||||
B $JOIN1
|
||||
LDO EIGHT(%r23),%r23
|
||||
|
||||
; exit
|
||||
|
||||
$L0
|
||||
.LEAVE
|
||||
|
||||
; We have verified that the above command generates what we want:
|
||||
; LDW -124(%sp),%r4
|
||||
; BVE (%r2)
|
||||
; LDW,MB -128(%sp),%r3
|
||||
|
||||
.PROCEND
|
||||
|
||||
; ***************************************************************
|
||||
;
|
||||
; add_diag_[little/big]
|
||||
;
|
||||
; ***************************************************************
|
||||
|
||||
; The arguments are as follows:
|
||||
; r2 return PC, of course
|
||||
; r26 = arg1 = length
|
||||
; r25 = arg2 = vector to square
|
||||
; r24 = arg3 = result vector
|
||||
|
||||
#ifdef LITTLE_WORDIAN
|
||||
add_diag_little
|
||||
#else
|
||||
add_diag_big
|
||||
#endif
|
||||
.PROC
|
||||
.CALLINFO FRAME=120,ENTRY_GR=%r4
|
||||
.ENTER
|
||||
|
||||
ADDIB,< -1,%r26,$Z0 ; If N=0, exit immediately.
|
||||
NOP
|
||||
|
||||
; Startup code
|
||||
|
||||
FLDD 0(%r25),%fr7 ; Cycle 2 (alternate body)
|
||||
XMPYU %fr7R,%fr7R,%fr29 ; Cycle 4
|
||||
XMPYU %fr7L,%fr7R,%fr27 ; Cycle 5
|
||||
XMPYU %fr7L,%fr7L,%fr30
|
||||
LDO SIXTEEN(%r25),%r25 ; Cycle 6
|
||||
FSTD %fr29,-88(%sp)
|
||||
FSTD %fr27,-72(%sp) ; Cycle 7
|
||||
CMPIB,= 0,%r26,$DIAG_N_IS_ONE ; Cycle 1 (main body)
|
||||
FSTD %fr30,-96(%sp)
|
||||
FLDD UN_EIGHT(%r25),%fr7 ; Cycle 2
|
||||
LDD -88(%sp),%r22 ; Cycle 3
|
||||
LDD -72(%sp),%r31 ; Cycle 4
|
||||
XMPYU %fr7R,%fr7R,%fr28
|
||||
XMPYU %fr7L,%fr7R,%fr24 ; Cycle 5
|
||||
XMPYU %fr7L,%fr7L,%fr31
|
||||
LDD -96(%sp),%r20 ; Cycle 6
|
||||
FSTD %fr28,-80(%sp)
|
||||
ADD %r0,%r0,%r0 ; clear the carry bit
|
||||
ADDIB,<= -2,%r26,$ENDDIAGLOOP ; Cycle 7
|
||||
FSTD %fr24,-64(%sp)
|
||||
|
||||
; Here is the loop. It is unrolled twice, modelled after the "alternate body" and then the "main body".
|
||||
|
||||
$DIAGLOOP
|
||||
SHRPD %r31,%r0,31,%r3 ; Cycle 1 (alternate body)
|
||||
LDO SIXTEEN(%r25),%r25
|
||||
LDD 0(%r24),%r1
|
||||
FSTD %fr31,-104(%sp)
|
||||
SHRPD %r0,%r31,31,%r4 ; Cycle 2
|
||||
ADD,DC %r22,%r3,%r3
|
||||
FLDD UN_SIXTEEN(%r25),%fr7
|
||||
ADD,DC %r0,%r20,%r20 ; Cycle 3
|
||||
ADD %r1,%r3,%r3
|
||||
XMPYU %fr7R,%fr7R,%fr29 ; Cycle 4
|
||||
LDD -80(%sp),%r21
|
||||
STD %r3,0(%r24)
|
||||
XMPYU %fr7L,%fr7R,%fr27 ; Cycle 5
|
||||
XMPYU %fr7L,%fr7L,%fr30
|
||||
LDD -64(%sp),%r29
|
||||
LDD EIGHT(%r24),%r1
|
||||
ADD,DC %r4,%r20,%r20 ; Cycle 6
|
||||
LDD -104(%sp),%r19
|
||||
FSTD %fr29,-88(%sp)
|
||||
ADD %r20,%r1,%r1 ; Cycle 7
|
||||
FSTD %fr27,-72(%sp)
|
||||
SHRPD %r29,%r0,31,%r4 ; Cycle 1 (main body)
|
||||
LDO THIRTY_TWO(%r24),%r24
|
||||
LDD UN_SIXTEEN(%r24),%r28
|
||||
FSTD %fr30,-96(%sp)
|
||||
SHRPD %r0,%r29,31,%r3 ; Cycle 2
|
||||
ADD,DC %r21,%r4,%r4
|
||||
FLDD UN_EIGHT(%r25),%fr7
|
||||
STD %r1,UN_TWENTY_FOUR(%r24)
|
||||
ADD,DC %r0,%r19,%r19 ; Cycle 3
|
||||
ADD %r28,%r4,%r4
|
||||
XMPYU %fr7R,%fr7R,%fr28 ; Cycle 4
|
||||
LDD -88(%sp),%r22
|
||||
STD %r4,UN_SIXTEEN(%r24)
|
||||
XMPYU %fr7L,%fr7R,%fr24 ; Cycle 5
|
||||
XMPYU %fr7L,%fr7L,%fr31
|
||||
LDD -72(%sp),%r31
|
||||
LDD UN_EIGHT(%r24),%r28
|
||||
ADD,DC %r3,%r19,%r19 ; Cycle 6
|
||||
LDD -96(%sp),%r20
|
||||
FSTD %fr28,-80(%sp)
|
||||
ADD %r19,%r28,%r28 ; Cycle 7
|
||||
FSTD %fr24,-64(%sp)
|
||||
ADDIB,> -2,%r26,$DIAGLOOP ; Cycle 8
|
||||
STD %r28,UN_EIGHT(%r24)
|
||||
|
||||
$ENDDIAGLOOP
|
||||
|
||||
ADD,DC %r0,%r22,%r22
|
||||
CMPIB,= 0,%r26,$ONEMOREDIAG
|
||||
SHRPD %r31,%r0,31,%r3
|
||||
|
||||
; Shutdown code, first stage.
|
||||
|
||||
FSTD %fr31,-104(%sp) ; Cycle 1 (alternate body)
|
||||
LDD 0(%r24),%r28
|
||||
SHRPD %r0,%r31,31,%r4 ; Cycle 2
|
||||
ADD %r3,%r22,%r3
|
||||
ADD,DC %r0,%r20,%r20 ; Cycle 3
|
||||
LDD -80(%sp),%r21
|
||||
ADD %r3,%r28,%r3
|
||||
LDD -64(%sp),%r29 ; Cycle 4
|
||||
STD %r3,0(%r24)
|
||||
LDD EIGHT(%r24),%r1 ; Cycle 5
|
||||
LDO SIXTEEN(%r25),%r25 ; Cycle 6
|
||||
LDD -104(%sp),%r19
|
||||
ADD,DC %r4,%r20,%r20
|
||||
ADD %r20,%r1,%r1 ; Cycle 7
|
||||
ADD,DC %r0,%r21,%r21 ; Cycle 8
|
||||
STD %r1,EIGHT(%r24)
|
||||
|
||||
; Shutdown code, second stage.
|
||||
|
||||
SHRPD %r29,%r0,31,%r4 ; Cycle 1 (main body)
|
||||
LDO THIRTY_TWO(%r24),%r24
|
||||
LDD UN_SIXTEEN(%r24),%r1
|
||||
SHRPD %r0,%r29,31,%r3 ; Cycle 2
|
||||
ADD %r4,%r21,%r4
|
||||
ADD,DC %r0,%r19,%r19 ; Cycle 3
|
||||
ADD %r4,%r1,%r4
|
||||
STD %r4,UN_SIXTEEN(%r24); Cycle 4
|
||||
LDD UN_EIGHT(%r24),%r28 ; Cycle 5
|
||||
ADD,DC %r3,%r19,%r19 ; Cycle 6
|
||||
ADD %r19,%r28,%r28 ; Cycle 7
|
||||
ADD,DC %r0,%r0,%r22 ; Cycle 8
|
||||
CMPIB,*= 0,%r22,$Z0 ; if no overflow, exit
|
||||
STD %r28,UN_EIGHT(%r24)
|
||||
|
||||
; Final carry propagation
|
||||
|
||||
$FDIAG2
|
||||
LDO EIGHT(%r24),%r24
|
||||
LDD UN_EIGHT(%r24),%r26
|
||||
ADDI 1,%r26,%r26
|
||||
CMPIB,*= 0,%r26,$FDIAG2 ; Keep looping if there is a carry.
|
||||
STD %r26,UN_EIGHT(%r24)
|
||||
|
||||
B $Z0
|
||||
NOP
|
||||
|
||||
; Here is the code that handles the difficult case N=1.
|
||||
; We do the usual trick -- branch out of the startup code at appropriate
|
||||
; points, and branch into the shutdown code.
|
||||
|
||||
$DIAG_N_IS_ONE
|
||||
|
||||
LDD -88(%sp),%r22
|
||||
LDD -72(%sp),%r31
|
||||
B $JOINDIAG
|
||||
LDD -96(%sp),%r20
|
||||
|
||||
; We came out of the unrolled loop with wrong parity. Do one more
|
||||
; single cycle. This is the "alternate body". It will, of course,
|
||||
; give us opposite registers from the other case, so we need
|
||||
; completely different shutdown code.
|
||||
|
||||
$ONEMOREDIAG
|
||||
FSTD %fr31,-104(%sp) ; Cycle 1 (alternate body)
|
||||
LDD 0(%r24),%r28
|
||||
FLDD 0(%r25),%fr7 ; Cycle 2
|
||||
SHRPD %r0,%r31,31,%r4
|
||||
ADD %r3,%r22,%r3
|
||||
ADD,DC %r0,%r20,%r20 ; Cycle 3
|
||||
LDD -80(%sp),%r21
|
||||
ADD %r3,%r28,%r3
|
||||
LDD -64(%sp),%r29 ; Cycle 4
|
||||
STD %r3,0(%r24)
|
||||
XMPYU %fr7R,%fr7R,%fr29
|
||||
LDD EIGHT(%r24),%r1 ; Cycle 5
|
||||
XMPYU %fr7L,%fr7R,%fr27
|
||||
XMPYU %fr7L,%fr7L,%fr30
|
||||
LDD -104(%sp),%r19 ; Cycle 6
|
||||
FSTD %fr29,-88(%sp)
|
||||
ADD,DC %r4,%r20,%r20
|
||||
FSTD %fr27,-72(%sp) ; Cycle 7
|
||||
ADD %r20,%r1,%r1
|
||||
ADD,DC %r0,%r21,%r21 ; Cycle 8
|
||||
STD %r1,EIGHT(%r24)
|
||||
|
||||
; Shutdown code, first stage.
|
||||
|
||||
SHRPD %r29,%r0,31,%r4 ; Cycle 1 (main body)
|
||||
LDO THIRTY_TWO(%r24),%r24
|
||||
FSTD %fr30,-96(%sp)
|
||||
LDD UN_SIXTEEN(%r24),%r1
|
||||
SHRPD %r0,%r29,31,%r3 ; Cycle 2
|
||||
ADD %r4,%r21,%r4
|
||||
ADD,DC %r0,%r19,%r19 ; Cycle 3
|
||||
LDD -88(%sp),%r22
|
||||
ADD %r4,%r1,%r4
|
||||
LDD -72(%sp),%r31 ; Cycle 4
|
||||
STD %r4,UN_SIXTEEN(%r24)
|
||||
LDD UN_EIGHT(%r24),%r28 ; Cycle 5
|
||||
LDD -96(%sp),%r20 ; Cycle 6
|
||||
ADD,DC %r3,%r19,%r19
|
||||
ADD %r19,%r28,%r28 ; Cycle 7
|
||||
ADD,DC %r0,%r22,%r22 ; Cycle 8
|
||||
STD %r28,UN_EIGHT(%r24)
|
||||
|
||||
; Shutdown code, second stage.
|
||||
|
||||
$JOINDIAG
|
||||
SHRPD %r31,%r0,31,%r3 ; Cycle 1 (alternate body)
|
||||
LDD 0(%r24),%r28
|
||||
SHRPD %r0,%r31,31,%r4 ; Cycle 2
|
||||
ADD %r3,%r22,%r3
|
||||
ADD,DC %r0,%r20,%r20 ; Cycle 3
|
||||
ADD %r3,%r28,%r3
|
||||
STD %r3,0(%r24) ; Cycle 4
|
||||
LDD EIGHT(%r24),%r1 ; Cycle 5
|
||||
ADD,DC %r4,%r20,%r20
|
||||
ADD %r20,%r1,%r1 ; Cycle 7
|
||||
ADD,DC %r0,%r0,%r21 ; Cycle 8
|
||||
CMPIB,*= 0,%r21,$Z0 ; if no overflow, exit
|
||||
STD %r1,EIGHT(%r24)
|
||||
|
||||
; Final carry propagation
|
||||
|
||||
$FDIAG1
|
||||
LDO EIGHT(%r24),%r24
|
||||
LDD EIGHT(%r24),%r26
|
||||
ADDI 1,%r26,%r26
|
||||
CMPIB,*= 0,%r26,$FDIAG1 ; Keep looping if there is a carry.
|
||||
STD %r26,EIGHT(%r24)
|
||||
|
||||
$Z0
|
||||
.LEAVE
|
||||
.PROCEND
|
||||
; .ALLOW
|
||||
|
||||
.SPACE $TEXT$
|
||||
.SUBSPA $CODE$
|
||||
#ifdef LITTLE_WORDIAN
|
||||
.EXPORT maxpy_little,ENTRY,PRIV_LEV=3,ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR,LONG_RETURN
|
||||
.EXPORT add_diag_little,ENTRY,PRIV_LEV=3,ARGW0=GR,ARGW1=GR,ARGW2=GR,LONG_RETURN
|
||||
#else
|
||||
.EXPORT maxpy_big,ENTRY,PRIV_LEV=3,ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR,LONG_RETURN
|
||||
.EXPORT add_diag_big,ENTRY,PRIV_LEV=3,ARGW0=GR,ARGW1=GR,ARGW2=GR,LONG_RETURN
|
||||
#endif
|
||||
.END
|
||||
|
||||
|
||||
; How to use "maxpy_PA20_little" and "maxpy_PA20_big"
|
||||
;
|
||||
; The routine "maxpy_PA20_little" or "maxpy_PA20_big"
|
||||
; performs a 64-bit x any-size multiply, and adds the
|
||||
; result to an area of memory. That is, it performs
|
||||
; something like
|
||||
;
|
||||
; A B C D
|
||||
; * Z
|
||||
; __________
|
||||
; P Q R S T
|
||||
;
|
||||
; and then adds the "PQRST" vector into an area of memory,
|
||||
; handling all carries.
|
||||
;
|
||||
; Digression on nomenclature and endian-ness:
|
||||
;
|
||||
; Each of the capital letters in the above represents a 64-bit
|
||||
; quantity. That is, you could think of the discussion as
|
||||
; being in terms of radix-16-quintillion arithmetic. The data
|
||||
; type being manipulated is "unsigned long long int". This
|
||||
; requires the 64-bit extension of the HP-UX C compiler,
|
||||
; available at release 10. You need these compiler flags to
|
||||
; enable these extensions:
|
||||
;
|
||||
; -Aa +e +DA2.0 +DS2.0
|
||||
;
|
||||
; (The first specifies ANSI C, the second enables the
|
||||
; extensions, which are beyond ANSI C, and the third and
|
||||
; fourth tell the compiler to use whatever features of the
|
||||
; PA2.0 architecture it wishes, in order to made the code more
|
||||
; efficient. Since the presence of the assembly code will
|
||||
; make the program unable to run on anything less than PA2.0,
|
||||
; you might as well gain the performance enhancements in the C
|
||||
; code as well.)
|
||||
;
|
||||
; Questions of "endian-ness" often come up, usually in the
|
||||
; context of byte ordering in a word. These routines have a
|
||||
; similar issue, that could be called "wordian-ness".
|
||||
; Independent of byte ordering (PA is always big-endian), one
|
||||
; can make two choices when representing extremely large
|
||||
; numbers as arrays of 64-bit doublewords in memory.
|
||||
;
|
||||
; "Little-wordian" layout means that the least significant
|
||||
; word of a number is stored at the lowest address.
|
||||
;
|
||||
; MSW LSW
|
||||
; | |
|
||||
; V V
|
||||
;
|
||||
; A B C D E
|
||||
;
|
||||
; ^ ^ ^
|
||||
; | | |____ address 0
|
||||
; | |
|
||||
; | |_______address 8
|
||||
; |
|
||||
; address 32
|
||||
;
|
||||
; "Big-wordian" means that the most significant word is at the
|
||||
; lowest address.
|
||||
;
|
||||
; MSW LSW
|
||||
; | |
|
||||
; V V
|
||||
;
|
||||
; A B C D E
|
||||
;
|
||||
; ^ ^ ^
|
||||
; | | |____ address 32
|
||||
; | |
|
||||
; | |_______address 24
|
||||
; |
|
||||
; address 0
|
||||
;
|
||||
; When you compile the file, you must specify one or the other, with
|
||||
; a switch "-DLITTLE_WORDIAN" or "-DBIG_WORDIAN".
|
||||
;
|
||||
; Incidentally, you assemble this file as part of your
|
||||
; project with the same C compiler as the rest of the program.
|
||||
; My "makefile" for a superprecision arithmetic package has
|
||||
; the following stuff:
|
||||
;
|
||||
; # definitions:
|
||||
; CC = cc -Aa +e -z +DA2.0 +DS2.0 +w1
|
||||
; CFLAGS = +O3
|
||||
; LDFLAGS = -L /usr/lib -Wl,-aarchive
|
||||
;
|
||||
; # general build rule for ".s" files:
|
||||
; .s.o:
|
||||
; $(CC) $(CFLAGS) -c $< -DBIG_WORDIAN
|
||||
;
|
||||
; # Now any bind step that calls for pa20.o will assemble pa20.s
|
||||
;
|
||||
; End of digression, back to arithmetic:
|
||||
;
|
||||
; The way we multiply two huge numbers is, of course, to multiply
|
||||
; the "ABCD" vector by each of the "WXYZ" doublewords, adding
|
||||
; the result vectors with increasing offsets, the way we learned
|
||||
; in school, back before we all used calculators:
|
||||
;
|
||||
; A B C D
|
||||
; * W X Y Z
|
||||
; __________
|
||||
; P Q R S T
|
||||
; E F G H I
|
||||
; M N O P Q
|
||||
; + R S T U V
|
||||
; _______________
|
||||
; F I N A L S U M
|
||||
;
|
||||
; So we call maxpy_PA20_big (in my case; my package is
|
||||
; big-wordian) repeatedly, giving the W, X, Y, and Z arguments
|
||||
; in turn as the "scalar", and giving the "ABCD" vector each
|
||||
; time. We direct it to add its result into an area of memory
|
||||
; that we have cleared at the start. We skew the exact
|
||||
; location into that area with each call.
|
||||
;
|
||||
; The prototype for the function is
|
||||
;
|
||||
; extern void maxpy_PA20_big(
|
||||
; int length, /* Number of doublewords in the multiplicand vector. */
|
||||
; const long long int *scalaraddr, /* Address to fetch the scalar. */
|
||||
; const long long int *multiplicand, /* The multiplicand vector. */
|
||||
; long long int *result); /* Where to accumulate the result. */
|
||||
;
|
||||
; (You should place a copy of this prototype in an include file
|
||||
; or in your C file.)
|
||||
;
|
||||
; Now, IN ALL CASES, the given address for the multiplicand or
|
||||
; the result is that of the LEAST SIGNIFICANT DOUBLEWORD.
|
||||
; That word is, of course, the word at which the routine
|
||||
; starts processing. "maxpy_PA20_little" then increases the
|
||||
; addresses as it computes. "maxpy_PA20_big" decreases them.
|
||||
;
|
||||
; In our example above, "length" would be 4 in each case.
|
||||
; "multiplicand" would be the "ABCD" vector. Specifically,
|
||||
; the address of the element "D". "scalaraddr" would be the
|
||||
; address of "W", "X", "Y", or "Z" on the four calls that we
|
||||
; would make. (The order doesn't matter, of course.)
|
||||
; "result" would be the appropriate address in the result
|
||||
; area. When multiplying by "Z", that would be the least
|
||||
; significant word. When multiplying by "Y", it would be the
|
||||
; next higher word (8 bytes higher if little-wordian; 8 bytes
|
||||
; lower if big-wordian), and so on. The size of the result
|
||||
; area must be the the sum of the sizes of the multiplicand
|
||||
; and multiplier vectors, and must be initialized to zero
|
||||
; before we start.
|
||||
;
|
||||
; Whenever the routine adds its partial product into the result
|
||||
; vector, it follows carry chains as far as they need to go.
|
||||
;
|
||||
; Here is the super-precision multiply routine that I use for
|
||||
; my package. The package is big-wordian. I have taken out
|
||||
; handling of exponents (it's a floating point package):
|
||||
;
|
||||
; static void mul_PA20(
|
||||
; int size,
|
||||
; const long long int *arg1,
|
||||
; const long long int *arg2,
|
||||
; long long int *result)
|
||||
; {
|
||||
; int i;
|
||||
;
|
||||
; for (i=0 ; i<2*size ; i++) result[i] = 0ULL;
|
||||
;
|
||||
; for (i=0 ; i<size ; i++) {
|
||||
; maxpy_PA20_big(size, &arg2[i], &arg1[size-1], &result[size+i]);
|
||||
; }
|
||||
; }
|
||||
@@ -1,54 +0,0 @@
|
||||
#/bin/sh
|
||||
#
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is script to change the system id in an object file from PA-RISC 2.0 to 1.1.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Hewlett-Packard Company.
|
||||
# Portions created by the Initial Developer are Copyright (C) 1999
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# wrapped by Dennis Handly on Tue Mar 23 15:23:43 1999
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
# script to change the system id in an object file from PA-RISC 2.0 to 1.1
|
||||
|
||||
adb -w $1 << EOF
|
||||
?m 0 -1 0
|
||||
0x0?X
|
||||
0x0?W (@0x0&~0x40000)|(~@0x0&0x40000)
|
||||
|
||||
0?"change checksum"
|
||||
0x7c?X
|
||||
0x7c?W (@0x7c&~0x40000)|(~@0x7c&0x40000)
|
||||
$q
|
||||
EOF
|
||||
|
||||
exit 0
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
/*
|
||||
* logtab.h
|
||||
*
|
||||
* Arbitrary precision integer arithmetic library
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the MPI Arbitrary Precision Integer Arithmetic library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Michael J. Fromberger.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
/* $Id: logtab.h,v 1.5 2004-04-27 23:04:36 gerv%gerv.net Exp $ */
|
||||
|
||||
const float s_logv_2[] = {
|
||||
0.000000000f, 0.000000000f, 1.000000000f, 0.630929754f, /* 0 1 2 3 */
|
||||
0.500000000f, 0.430676558f, 0.386852807f, 0.356207187f, /* 4 5 6 7 */
|
||||
0.333333333f, 0.315464877f, 0.301029996f, 0.289064826f, /* 8 9 10 11 */
|
||||
0.278942946f, 0.270238154f, 0.262649535f, 0.255958025f, /* 12 13 14 15 */
|
||||
0.250000000f, 0.244650542f, 0.239812467f, 0.235408913f, /* 16 17 18 19 */
|
||||
0.231378213f, 0.227670249f, 0.224243824f, 0.221064729f, /* 20 21 22 23 */
|
||||
0.218104292f, 0.215338279f, 0.212746054f, 0.210309918f, /* 24 25 26 27 */
|
||||
0.208014598f, 0.205846832f, 0.203795047f, 0.201849087f, /* 28 29 30 31 */
|
||||
0.200000000f, 0.198239863f, 0.196561632f, 0.194959022f, /* 32 33 34 35 */
|
||||
0.193426404f, 0.191958720f, 0.190551412f, 0.189200360f, /* 36 37 38 39 */
|
||||
0.187901825f, 0.186652411f, 0.185449023f, 0.184288833f, /* 40 41 42 43 */
|
||||
0.183169251f, 0.182087900f, 0.181042597f, 0.180031327f, /* 44 45 46 47 */
|
||||
0.179052232f, 0.178103594f, 0.177183820f, 0.176291434f, /* 48 49 50 51 */
|
||||
0.175425064f, 0.174583430f, 0.173765343f, 0.172969690f, /* 52 53 54 55 */
|
||||
0.172195434f, 0.171441601f, 0.170707280f, 0.169991616f, /* 56 57 58 59 */
|
||||
0.169293808f, 0.168613099f, 0.167948779f, 0.167300179f, /* 60 61 62 63 */
|
||||
0.166666667f
|
||||
};
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user