Compare commits

..

1 Commits

Author SHA1 Message Date
(no author)
428ec0ae9d This commit was manufactured by cvs2svn to create tag 'Pre-XPCOM'.
git-svn-id: svn://10.0.0.236/tags/Pre-XPCOM@29612 18797224-902f-48f8-a5cc-f745e15eee43
1999-04-28 00:34:31 +00:00
19 changed files with 1282 additions and 2970 deletions

View File

@@ -0,0 +1,5 @@
#
# This is a list of local files which get copied to the mozilla:dist directory
#
zipfile.h

View File

@@ -0,0 +1,36 @@
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
#
DEPTH = ../..
topsrcdir = @top_srcdir@
VPATH = @srcdir@
srcdir = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = jar
LIBRARY_NAME = jar$(VERSION_NUMBER)
CPPSRCS = \
nsZipArchive.cpp \
$(NULL)
EXPORTS = zipfile.h
EXPORTS := $(addprefix $(srcdir)/, $(EXPORTS))
include $(topsrcdir)/config/rules.mk

Binary file not shown.

View File

@@ -0,0 +1,2 @@
# target: libjarDebug.shlb
mozilla/modules/libjar/nsZipArchive.cpp

View File

@@ -0,0 +1,67 @@
#!gmake
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (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,
# released March 31, 1998.
#
# 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.
#
# Contributors:
# Daniel Veditz <dveditz@netscape.com>
IGNORE_MANIFEST=1
DIRS=standalone
MODULE=jar
DEPTH=..\..
MAKE_OBJ_TYPE=DLL
DLLNAME=jar$(VERSION_NUMBER)
DLL=.\$(OBJDIR)\$(DLLNAME).dll
MAPFILE=$(DLLNAME).map
EXPORTS=zipfile.h
OBJS=.\$(OBJDIR)\nsZipArchive.obj
LINCS= \
-I$(XPDIST)\public\nspr \
-I$(XPDIST)\public\raptor \
-I$(XPDIST)\public\xpcom \
-I$(XPDIST)\public\zlib \
-I$(XPDIST)\public\network \
$(NULL)
LLIBS= \
$(LIBNSPR) \
$(DIST)\lib\plc3.lib \
$(DIST)\lib\zlib.lib \
$(DIST)\lib\xplib.lib \
$(NULL)
include <$(DEPTH)/config/rules.mak>
install:: $(DLL)
$(MAKE_INSTALL) .\$(OBJDIR)\$(DLLNAME).dll $(DIST)\bin
$(MAKE_INSTALL) .\$(OBJDIR)\$(DLLNAME).lib $(DIST)\lib
clobber::
$(RM) $(OBJS)
$(RM) $(DIST)\bin\$(DLLNAME).dll
$(RM) $(DIST)\lib\$(DLLNAME).lib

View File

@@ -0,0 +1,795 @@
/* -*- 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.0 (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,
* released March 31, 1998.
*
* 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.
*
* Contributors:
* Daniel Veditz <dveditz@netscape.com>
*/
/*
* This module implements a simple archive extractor for the PKZIP format.
*/
#include <string.h>
#include "nscore.h"
#include "prmem.h"
#include "prio.h"
#include "plstr.h"
#include "prlog.h"
#include "xp_regexp.h"
#include "zlib.h"
#include "zipfile.h"
#include "zipstruct.h"
#include "nsZipArchive.h"
static PRUint16 xtoint(unsigned char *ii);
static PRUint32 xtolong(unsigned char *ll);
/*---------------------------------------------
* C API wrapper for nsZipArchive
*--------------------------------------------*/
/**
* ZIP_OpenArchive
*
* opens the named zip/jar archive and returns a handle that
* represents the archive in other ZIP_ calls.
*
* @param zipname archive filename
* @param hZip receives handle if archive opened OK
* @return status code
*/
PR_PUBLIC_API(PRInt32) ZIP_OpenArchive( const char * zipname, void** hZip )
{
PRInt32 status;
/*--- error check args ---*/
if ( hZip == NULL )
return ZIP_ERR_PARAM;
/*--- NULL output to prevent use by bozos who don't check errors ---*/
*hZip = NULL;
/*--- create and open the archive ---*/
nsZipArchive* zip = new nsZipArchive();
if ( zip == NULL )
return ZIP_ERR_MEMORY;
status = zip->OpenArchive(zipname);
if ( status == ZIP_OK )
*hZip = NS_STATIC_CAST(void*,zip);
else
delete zip;
return status;
}
/**
* ZIP_CloseArchive
*
* closes zip archive and frees memory
* @param hZip handle obtained from ZIP_OpenArchive
* @return status code
*/
PR_PUBLIC_API(PRInt32) ZIP_CloseArchive( void** hZip )
{
/*--- error check args ---*/
if ( hZip == NULL || *hZip == NULL )
return ZIP_ERR_PARAM;
nsZipArchive* zip = NS_STATIC_CAST(nsZipArchive*,*hZip);
if ( zip->kMagic != ZIP_MAGIC )
return ZIP_ERR_PARAM; /* whatever it is isn't one of ours! */
/*--- close the archive ---*/
*hZip = NULL;
delete zip;
return ZIP_OK;
}
/**
* ZIP_ExtractFile
*
* extracts named file from an opened archive
*
* @param hZip handle obtained from ZIP_OpenArchive
* @param filename name of file in archive
* @param outname filename to extract to
*/
PR_PUBLIC_API(PRInt32) ZIP_ExtractFile( void* hZip, const char * filename, const char * outname )
{
/*--- error check args ---*/
if ( hZip == NULL )
return ZIP_ERR_PARAM;
nsZipArchive* zip = NS_STATIC_CAST(nsZipArchive*,hZip);
if ( zip->kMagic != ZIP_MAGIC )
return ZIP_ERR_PARAM; /* whatever it is isn't one of ours! */
/*--- extract the file ---*/
return zip->ExtractFile( filename, outname );
}
/**
* ZIP_FindInit
*
* Initializes an enumeration of files in the archive
*
* @param hZip handle obtained from ZIP_OpenArchive
* @param pattern regexp to match files in archive, the usual shell expressions.
* NULL pattern also matches all files, faster than "*"
*/
PR_EXTERN(PRInt32) ZIP_FindInit( void* hZip, const char * pattern )
{
/*--- error check args ---*/
if ( hZip == NULL )
return ZIP_ERR_PARAM;
nsZipArchive* zip = NS_STATIC_CAST(nsZipArchive*,hZip);
if ( zip->kMagic != ZIP_MAGIC )
return ZIP_ERR_PARAM; /* whatever it is isn't one of ours! */
/*--- initialize the pattern search ---*/
return zip->FindInit( pattern );
}
/**
* ZIP_FindInit
*
* Puts the next name in the passed buffer. Returns ZIP_ERR_SMALLBUF when
* the name is too large for the buffer, and ZIP_ERR_FNF when there are no
* more files that match the pattern
*
* @param hZip handle obtained from ZIP_OpenArchive
* @param outbuf buffer to receive next filename
* @param bufsize size of allocated buffer
*/
PR_EXTERN(PRInt32) ZIP_FindNext( void* hZip, char * outbuf, PRUint16 bufsize )
{
/*--- error check args ---*/
if ( hZip == NULL )
return ZIP_ERR_PARAM;
nsZipArchive* zip = NS_STATIC_CAST(nsZipArchive*,hZip);
if ( zip->kMagic != ZIP_MAGIC )
return ZIP_ERR_PARAM; /* whatever it is isn't one of ours! */
/*--- return next filename file ---*/
return zip->FindNext( outbuf, bufsize );
}
//***********************************************************
// nsZipArchive -- public methods
//***********************************************************
//---------------------------------------------
// nsZipArchive::OpenArchive
//---------------------------------------------
PRInt32 nsZipArchive::OpenArchive( const char * aArchiveName )
{
//-- validate arguments
if ( aArchiveName == NULL || *aArchiveName == '\0')
return ZIP_ERR_PARAM;
//-- not allowed to do two opens on the same object!
if ( mFd != NULL )
return ZIP_ERR_GENERAL;
//-- open the physical file
mFd = PR_Open( aArchiveName, PR_RDONLY, 0 );
if ( mFd == NULL )
return ZIP_ERR_DISK;
//-- get table of contents for archive
return BuildFileList();
}
//---------------------------------------------
// nsZipArchive::ExtractFile
//---------------------------------------------
PRInt32 nsZipArchive::ExtractFile(const char* aFilename, const char* aOutname)
{
//-- sanity check arguments
if ( aFilename == NULL || aOutname == NULL )
return ZIP_ERR_PARAM;
//-- find file information
const nsZipItem* item = GetFileItem( aFilename );
if ( item == NULL )
return ZIP_ERR_FNF;
//-- extract the file using appropriate method
switch( item->compression )
{
case STORED:
return CopyItemToDisk( item, aOutname );
case DEFLATED:
return InflateItemToDisk( item, aOutname );
default:
//-- unsupported compression type
return ZIP_ERR_UNSUPPORTED;
}
}
//---------------------------------------------
// nsZipArchive::FindInit
//---------------------------------------------
PRInt32 nsZipArchive::FindInit( const char * aPattern )
{
// validate the pattern
if ( aPattern != NULL )
switch (XP_RegExpValid( (char*)aPattern ))
{
case INVALID_SXP:
return ZIP_ERR_PARAM;
case NON_SXP:
mPatternIsRegExp = PR_FALSE;
break;
case VALID_SXP:
mPatternIsRegExp = PR_TRUE;
break;
default:
// unexpected/undoc'ed return value
PR_ASSERT( PR_FALSE );
return ZIP_ERR_GENERAL;
}
// clear the old pattern
if ( mPattern != NULL )
{
PL_strfree( mPattern );
mPattern = NULL;
}
// re-initialize pattern state
mPatternSlot = 0;
mPatternItem = NULL;
if ( aPattern != NULL )
mPattern = PL_strdup( aPattern );
return ZIP_OK;
}
//---------------------------------------------
// nsZipArchive::FindNext
//---------------------------------------------
PRInt32 nsZipArchive::FindNext( char * aBuf, PRUint16 aSize )
{
PRInt32 status;
PRBool found = PR_FALSE;
PRUint32 slot = mPatternSlot;
nsZipItem* item = mPatternItem;
// we start from last match, look for next
while ( slot < ZIP_TABSIZE && !found )
{
if ( item != NULL )
item = item->next; // move to next in current chain
else
item = mFiles[slot]; // starting a new slot
if ( item == NULL )
{ // no more in this chain, move to next slot
++slot;
continue;
}
else if ( mPattern == NULL )
found = PR_TRUE; // always match
else if ( mPatternIsRegExp )
found = XP_RegExpMatch( item->name, mPattern, PR_FALSE );
else
found = ( PL_strcmp( item->name, mPattern ) == 0 );
}
if ( found )
{
if ( aSize > item->namelen )
{
PL_strcpy( aBuf, item->name );
status = ZIP_OK;
}
else
status = ZIP_ERR_SMALLBUF;
}
else
status = ZIP_ERR_FNF;
// save state for next Find. For 'smallbuf' we give user another chance
if ( status != ZIP_ERR_SMALLBUF )
{
mPatternSlot = slot;
mPatternItem = item;
}
return status;
}
//***********************************************************
// nsZipArchive -- private implementation
//***********************************************************
//---------------------------------------------
// nsZipArchive::BuildFileList
//---------------------------------------------
PRInt32 nsZipArchive::BuildFileList()
{
PRInt32 status = ZIP_OK;
PRUint32 sig = 0L;
PRUint32 namelen, extralen;
PRUint16 hash;
ZipLocal Local;
nsZipItem* item;
//-----------------------------------------------------------------------
// read the local file headers.
//
// What we *should* be doing is reading the central directory at the end,
// all in one place. We'll have to change this eventually since the local
// headers don't have the mode information we need for Unix files.
//-----------------------------------------------------------------------
PRInt32 pos = 0L;
while ( status == ZIP_OK )
{
if ( PR_Seek( mFd, pos, PR_SEEK_SET ) != (PRInt32)pos )
{
//-- couldn't seek to next position
status = ZIP_ERR_CORRUPT;
break;
}
if ( PR_Read( mFd, (char*)&Local, sizeof(ZipLocal) ) != sizeof(ZipLocal) )
{
//-- file ends prematurely
status = ZIP_ERR_CORRUPT;
break;
}
//-- make sure we're processing a local header
sig = xtolong( Local.signature );
if ( sig == CENTRALSIG )
{
// we're onto the next section
break;
}
else if ( sig != LOCALSIG )
{
//-- otherwise expected to find a local header
status = ZIP_ERR_CORRUPT;
break;
}
namelen = xtoint( Local.filename_len );
extralen = xtoint( Local.extrafield_len );
item = new nsZipItem();
if ( item != NULL )
{
item->name = new char[namelen+1];
if ( item->name != NULL )
{
if ( PR_Read( mFd, item->name, namelen ) == (PRInt32)namelen )
{
item->name[namelen] = 0;
item->namelen = namelen;
item->headerloc = pos;
item->offset = pos + sizeof(ZipLocal) + namelen + extralen;
item->compression = xtoint( Local.method );
item->size = xtolong( Local.size );
item->realsize = xtolong( Local.orglen );
item->crc32 = xtolong( Local.crc32 );
//-- add item to file table
hash = HashName( item->name );
item->next = mFiles[hash];
mFiles[hash] = item;
pos = item->offset + item->size;
}
else
{
//-- file is truncated
status = ZIP_ERR_CORRUPT;
delete item;
}
}
else
{
//-- couldn't allocate for the filename
status = ZIP_ERR_MEMORY;
delete item;
}
}
else
{
//-- couldn't create a nsZipItem
status = ZIP_ERR_MEMORY;
}
} /* while reading local headers */
//-------------------------------------------------------
// we don't care about the rest of the file (until we
// fix this to read the central directory instead)
//-------------------------------------------------------
return status;
}
//---------------------------------------------
// nsZipArchive::CopyItemToDisk
//---------------------------------------------
PRInt32 nsZipArchive::CopyItemToDisk( const nsZipItem* aItem, const char* aOutname )
{
PRInt32 status = ZIP_OK;
PRUint32 chunk, pos, size;
PRFileDesc* fOut = NULL;
PR_ASSERT( aItem != NULL && aOutname != NULL );
char* buf = (char*)PR_Malloc(ZIP_BUFLEN);
if ( buf == NULL )
return ZIP_ERR_MEMORY;
//-- find start of file in archive
if ( PR_Seek( mFd, aItem->offset, PR_SEEK_SET ) != (PRInt32)aItem->offset )
{
status = ZIP_ERR_CORRUPT;
goto cleanup;
}
//-- open output file
fOut = PR_Open( aOutname, PR_WRONLY | PR_CREATE_FILE, 0644);
if ( fOut == NULL )
{
status = ZIP_ERR_DISK;
goto cleanup;
}
//-- copy chunks until file is done
size = aItem->size;
for ( pos=0; pos < size; pos += chunk )
{
chunk = (pos+ZIP_BUFLEN <= size) ? ZIP_BUFLEN : size - pos;
if ( PR_Read( mFd, buf, chunk ) != (PRInt32)chunk )
{
//-- unexpected end of data in archive
status = ZIP_ERR_CORRUPT;
break;
}
if ( PR_Write( fOut, buf, chunk ) < (PRInt32)chunk )
{
//-- Couldn't write all the data (disk full?)
status = ZIP_ERR_DISK;
break;
}
}
cleanup:
if ( fOut != NULL )
PR_Close( fOut );
PR_FREEIF( buf );
return status;
}
//---------------------------------------------
// nsZipArchive::GetFileItem
//---------------------------------------------
const nsZipItem* nsZipArchive::GetFileItem( const char * aFilename )
{
PR_ASSERT( aFilename != NULL );
nsZipItem* item = mFiles[ HashName(aFilename) ];
for ( ; item != NULL; item = item->next )
{
if ( 0 == PL_strcmp( aFilename, item->name ) )
break; //-- found it
}
return item;
}
//---------------------------------------------
// nsZipArchive::HashName
//---------------------------------------------
PRUint16 nsZipArchive::HashName( const char* aName )
{
PRUint16 val = 0;
PRUint8* c;
PR_ASSERT( aName != NULL );
for ( c = (PRUint8*)aName; *c != 0; c++ ) {
val = val*37 + *c;
}
return (val % ZIP_TABSIZE);
}
//---------------------------------------------
// nsZipArchive::InflateItemToDisk
//---------------------------------------------
PRInt32 nsZipArchive::InflateItemToDisk( const nsZipItem* aItem, const char* aOutname )
{
PRInt32 status = ZIP_OK;
PRUint32 chunk, inpos, outpos, size;
PRFileDesc* fOut = NULL;
z_stream zs;
int zerr;
PRBool bInflating = PR_FALSE;
PR_ASSERT( aItem != NULL && aOutname != NULL );
//-- allocate deflation buffers
Bytef *inbuf = (Bytef*)PR_Malloc(ZIP_BUFLEN);
Bytef *outbuf = (Bytef*)PR_Malloc(ZIP_BUFLEN);
if ( inbuf == NULL || outbuf == NULL )
{
status = ZIP_ERR_MEMORY;
goto cleanup;
}
//-- find start of file in archive
if ( PR_Seek( mFd, aItem->offset, PR_SEEK_SET ) != (PRInt32)aItem->offset )
{
status = ZIP_ERR_CORRUPT;
goto cleanup;
}
//-- open output file
fOut = PR_Open( aOutname, PR_WRONLY | PR_CREATE_FILE, 0644);
if ( fOut == NULL )
{
status = ZIP_ERR_DISK;
goto cleanup;
}
//-- set up the inflate
memset( &zs, 0, sizeof(zs) );
zerr = inflateInit2( &zs, -MAX_WBITS );
if ( zerr != Z_OK )
{
status = ZIP_ERR_GENERAL;
goto cleanup;
}
bInflating = PR_TRUE;
//-- inflate loop
size = aItem->size;
outpos = inpos = 0;
zs.next_out = outbuf;
zs.avail_out = ZIP_BUFLEN;
while ( zerr == Z_OK )
{
if ( zs.avail_in == 0 && zs.total_in < size )
{
//-- no data to inflate yet still more in file:
//-- read another chunk of compressed data
inpos = zs.total_in; // input position
chunk = ( inpos + ZIP_BUFLEN <= size ) ? ZIP_BUFLEN : size - inpos;
if ( PR_Read( mFd, inbuf, chunk ) != (PRInt32)chunk )
{
//-- unexpected end of data
status = ZIP_ERR_CORRUPT;
break;
}
zs.next_in = inbuf;
zs.avail_in = ZIP_BUFLEN;
}
if ( zs.avail_out == 0 )
{
//-- write inflated buffer to disk and make space
if ( PR_Write( fOut, outbuf, ZIP_BUFLEN ) < ZIP_BUFLEN )
{
//-- Couldn't write all the data (disk full?)
status = ZIP_ERR_DISK;
break;
}
outpos = zs.total_out;
zs.next_out = outbuf;
zs.avail_out = chunk;
}
zerr = inflate( &zs, Z_PARTIAL_FLUSH );
} // while
//-- write last inflated bit to disk
if ( zerr == Z_STREAM_END && outpos < zs.total_out )
{
chunk = zs.total_out - outpos;
if ( PR_Write( fOut, outbuf, chunk ) < (PRInt32)chunk )
{
status = ZIP_ERR_DISK;
}
}
//-- convert zlib error to return value
if ( status == ZIP_OK && zerr != Z_OK && zerr != Z_STREAM_END )
{
status = (zerr == Z_MEM_ERROR) ? ZIP_ERR_MEMORY : ZIP_ERR_CORRUPT;
}
//-- if found no errors make sure we've converted the whole thing
PR_ASSERT( status != ZIP_OK || zs.total_in == aItem->size );
PR_ASSERT( status != ZIP_OK || zs.total_out == aItem->realsize );
cleanup:
if ( bInflating )
{
//-- free zlib internal state
inflateEnd( &zs );
}
if ( fOut != NULL )
PR_Close( fOut );
PR_FREEIF( inbuf );
PR_FREEIF( outbuf );
return status;
}
//------------------------------------------
// nsZipArchive constructor and destructor
//------------------------------------------
nsZipArchive::nsZipArchive()
: kMagic(ZIP_MAGIC), mFd(NULL), mPattern(NULL),
mPatternSlot(ZIP_TABSIZE), mPatternItem(NULL)
{
// initialize the table to NULL
for ( int i = 0; i < ZIP_TABSIZE; ++i) {
mFiles[i] = NULL;
}
}
nsZipArchive::~nsZipArchive()
{
// close the file if open
if ( mFd != NULL ) {
PR_Close(mFd);
}
// delete nsZipItems in table
nsZipItem* pItem;
for ( int i = 0; i < ZIP_TABSIZE; ++i)
{
pItem = mFiles[i];
while ( pItem != NULL )
{
mFiles[i] = pItem->next;
delete pItem;
pItem = mFiles[i];
}
}
if ( mPattern != NULL ) {
PL_strfree(mPattern);
}
}
//------------------------------------------
// nsZipItem constructor and destructor
//------------------------------------------
nsZipItem::nsZipItem() : name(NULL),next(NULL) {}
nsZipItem::~nsZipItem()
{
if (name != NULL )
delete [] name;
}
//------------------------------------------
// helper functions
//------------------------------------------
/*
* x t o i n t
*
* Converts a two byte ugly endianed integer
* to our platform's integer.
*/
static PRUint16 xtoint (unsigned char *ii)
{
return (PRUint16) (ii [0]) | ((PRUint16) ii [1] << 8);
}
/*
* x t o l o n g
*
* Converts a four byte ugly endianed integer
* to our platform's integer.
*/
static PRUint32 xtolong (unsigned char *ll)
{
PRUint32 ret;
ret = (
(((PRUint32) ll [0]) << 0) |
(((PRUint32) ll [1]) << 8) |
(((PRUint32) ll [2]) << 16) |
(((PRUint32) ll [3]) << 24)
);
return ret;
}

View File

@@ -0,0 +1,126 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (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,
* released March 31, 1998.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 1998-1999 Netscape Communications Corporation. All Rights
* Reserved.
*
* Contributors:
* Daniel Veditz <dveditz@netscape.com>
*/
#include "prtypes.h"
#define ZIP_MAGIC 0x5F5A4950L /* "_ZIP" */
#define ZIP_TABSIZE 256
#define ZIP_BUFLEN 32767
/**
* nsZipItem -- a helper class for nsZipArchive
*
* each nsZipItem represents one file in the archive and all the
* information needed to manipulate it.
*/
class nsZipItem
{
public:
char* name;
PRUint32 namelen;
PRUint32 offset;
PRUint32 headerloc;
PRUint16 compression;
PRUint32 size;
PRUint32 realsize;
PRUint32 crc32;
nsZipItem* next;
nsZipItem();
~nsZipItem();
private:
//-- prevent copies and assignments
nsZipItem& operator=(const nsZipItem& rhs);
nsZipItem(const nsZipItem& rhs);
};
/**
* nsZipArchive -- a class for reading the PKZIP file format.
*
*/
class nsZipArchive
{
public:
/** cookie used to validate supposed objects passed from C code */
const PRInt32 kMagic;
/** constructing does not open the archive. See OpenArchive() */
nsZipArchive();
/** destructing the object closes the archive */
~nsZipArchive();
/**
* OpenArchive
*
* It's an error to call this more than once on the same nsZipArchive
* object. If we were allowed to use exceptions this would have been
* part of the constructor
*
* @param aArchiveName full pathname of archive
* @return status code
*/
PRInt32 OpenArchive( const char * aArchiveName );
/**
* ExtractFile
*
* @param aFilename name of file in archive to extract
* @param aOutname where to extract on disk
* @return status code
*/
PRInt32 ExtractFile( const char * aFilename, const char * aOutname );
PRInt32 FindInit( const char * aPattern );
PRInt32 FindNext( char * aBuf, PRUint16 aSize );
private:
//--- private members ---
PRFileDesc *mFd;
nsZipItem* mFiles[ZIP_TABSIZE];
char* mPattern;
PRUint16 mPatternSlot;
nsZipItem* mPatternItem;
PRBool mPatternIsRegExp;
//--- private methods ---
nsZipArchive& operator=(const nsZipArchive& rhs); // prevent assignments
nsZipArchive(const nsZipArchive& rhs); // prevent copies
PRInt32 BuildFileList();
PRInt32 CopyItemToDisk( const nsZipItem* aItem, const char* aOutname );
const nsZipItem* GetFileItem( const char * aFilename );
PRUint16 HashName( const char* aName );
PRInt32 InflateItemToDisk( const nsZipItem* aItem, const char* aOutname );
};

View File

@@ -0,0 +1,66 @@
#!gmake
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (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,
# released March 31, 1998.
#
# 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.
#
# Contributors:
# Daniel Veditz <dveditz@netscape.com>
IGNORE_MANIFEST=1
MODULE=jar
DEPTH=..\..\..
MAKE_OBJ_TYPE=DLL
LIBRARY=$(OBJDIR)\jar_s.lib
OBJS=.\$(OBJDIR)\nsZipArchive.obj
LCFLAGS=-DSTANDALONE
LINCS= \
-I$(XPDIST)\public\nspr \
-I$(XPDIST)\public\raptor \
-I$(XPDIST)\public\xpcom \
-I$(XPDIST)\public\zlib \
$(NULL)
LLIBS= \
$(LIBNSPR) \
$(DIST)\lib\plc3.lib \
$(DIST)\lib\zlib.lib \
$(DIST)\lib\xplib.lib \
$(NULL)
include <$(DEPTH)/config/rules.mak>
docopy:
$(MAKE_INSTALL) ..\nsZip*.* .
$(MAKE_INSTALL) ..\zip*.* .
export:: docopy
install:: $(LIBRARY)
$(MAKE_INSTALL) .\$(OBJDIR)\jar_s.lib $(DIST)\lib
$(RM) *.h *.cpp
clobber::
$(RM) $(OBJS)
$(RM) $(DIST)\lib\jar_s.lib

View File

@@ -0,0 +1,85 @@
/* -*- 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.0 (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,
* released March 31, 1998.
*
* 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.
*
* Contributors:
* Daniel Veditz <dveditz@netscape.com>
*/
#ifndef _zipfile_h
#define _zipfile_h
/*
* This module implements a simple archive extractor for the PKZIP format.
*
* All functions return a status/error code, and have an opaque hZip argument
* that represents an open archive.
*
* Currently only compression mode 8 (or none) is supported.
*/
#include "prtypes.h"
#define ZIP_OK 0
#define ZIP_ERR_GENERAL -1
#define ZIP_ERR_MEMORY -2
#define ZIP_ERR_DISK -3
#define ZIP_ERR_CORRUPT -4
#define ZIP_ERR_PARAM -5
#define ZIP_ERR_FNF -6
#define ZIP_ERR_UNSUPPORTED -7
#define ZIP_ERR_SMALLBUF -8
PR_BEGIN_EXTERN_C
/* Open and close the archive
*
* If successful OpenArchive returns a handle in the hZip parameter
* that must be passed to all subsequent operations on the archive
*/
PR_EXTERN(PRInt32) ZIP_OpenArchive( const char * zipname, void** hZip );
PR_EXTERN(PRInt32) ZIP_CloseArchive( void** hZip );
/* Extract the named file in the archive to disk.
* This function will happily overwrite an existing Outfile if it can.
* It's up to the caller to detect or move it out of the way if it's important.
*/
PR_EXTERN(PRInt32) ZIP_ExtractFile( void* hZip, const char * filename, const char * outname );
/* Functions to list the files contained in the archive
*
* FindInit() initializes the search with the pattern, then FindNext() is
* called to get the matching filenames if any.
*
* a NULL pattern will find all the files in the archive, otherwise the
* pattern must be a shell regexp type pattern.
*
* if a matching filename is too small for the passed buffer FindNext()
* will return ZIP_ERR_SMALLBUF. When no more matches can be found in
* the archive it will return ZIP_ERR_FNF
*/
PR_EXTERN(PRInt32) ZIP_FindInit( void* hZip, const char * pattern );
PR_EXTERN(PRInt32) ZIP_FindNext( void* hZip, char * outbuf, PRUint16 bufsize );
PR_END_EXTERN_C
#endif /* _zipfile_h */

View File

@@ -0,0 +1,100 @@
/* -*- 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.0 (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,
* released March 31, 1998.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 1998-1999 Netscape Communications Corporation. All Rights
* Reserved.
*
* Contributors:
* Daniel Veditz <dveditz@netscape.com>
*/
#ifndef _zipstruct_h
#define _zipstruct_h
/*
* Certain constants and structures for
* the Phil Katz ZIP archive format.
*
*/
typedef struct ZipLocal_
{
unsigned char signature [4];
unsigned char word [2];
unsigned char bitflag [2];
unsigned char method [2];
unsigned char time [2];
unsigned char date [2];
unsigned char crc32 [4];
unsigned char size [4];
unsigned char orglen [4];
unsigned char filename_len [2];
unsigned char extrafield_len [2];
} ZipLocal;
typedef struct ZipCentral_
{
char signature [4];
char version_made_by [2];
char version [2];
char bitflag [2];
char method [2];
char time [2];
char date [2];
char crc32 [4];
char size [4];
char orglen [4];
char filename_len [2];
char extrafield_len [2];
char commentfield_len [2];
char diskstart_number [2];
char internal_attributes [2];
char external_attributes [4];
char localhdr_offset [4];
} ZipCentral;
typedef struct ZipEnd_
{
char signature [4];
char disk_nr [2];
char start_central_dir [2];
char total_entries_disk [2];
char total_entries_archive [2];
char central_dir_size [4];
char offset_central_dir [4];
char commentfield_len [2];
} ZipEnd;
/* signatures */
#define LOCALSIG 0x04034B50l
#define CENTRALSIG 0x02014B50l
#define ENDSIG 0x06054B50l
/* compression methods */
#define STORED 0
#define SHRUNK 1
#define REDUCED1 2
#define REDUCED2 3
#define REDUCED3 4
#define REDUCED4 5
#define IMPLODED 6
#define TOKENIZED 7
#define DEFLATED 8
#endif /* _zipstruct_h */

File diff suppressed because it is too large Load Diff

View File

@@ -1,338 +0,0 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* 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 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 NPL, 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 NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#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,
PRUint32 aDisposal);
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 */
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 *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,
PRUint32 aDisposal),
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 */
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);
PRStatus gif_write(gif_struct* aGIFStruct, const PRUint8 * buf, PRUint32 numbytes);
PRBool gif_write_ready(const 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,
PRUint32 aDisposal); /* 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

View File

@@ -1,53 +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 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
EXPORT_LIBRARY = 1
IS_COMPONENT = 1
MODULE_NAME = nsGIFModule2
ifeq ($(OS_ARCH),WINNT)
EXTRA_DSO_LIBS = gkgfx
endif
REQUIRES = xpcom \
gfx \
gfx2 \
imglib2 \
$(NULL)
CPPSRCS = GIF2.cpp nsGIFDecoder2.cpp nsGIFModule.cpp
EXTRA_DSO_LDOPTS = $(GIF_LIBS) \
$(EXTRA_DSO_LIBS) \
$(MOZ_COMPONENT_LIBS) \
$(NULL)
include $(topsrcdir)/config/rules.mk

View File

@@ -1,48 +0,0 @@
#!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=..\..\..\..
MODULE = imggif
REQUIRES = xpcom \
gfx \
gfx2 \
imglib2 \
$(NULL)
include <$(DEPTH)/config/config.mak>
LIBRARY_NAME = imggif
MODULE_NAME = nsGIFModule2
OBJS = \
.\$(OBJDIR)\nsGIFDecoder2.obj \
.\$(OBJDIR)\GIF2.obj \
.\$(OBJDIR)\nsGIFModule.obj \
$(NULL)
LLIBS=\
$(LIBNSPR) \
$(DIST)\lib\xpcom.lib \
$(DIST)\lib\gkgfx.lib \
$(NULL)
include <$(DEPTH)\config\rules.mak>

View File

@@ -1,555 +0,0 @@
/* -*- 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 "imgILoad.h"
#include "nsRect.h"
//////////////////////////////////////////////////////////////////////
// GIF Decoder Implementation
// This is an adaptor between GIF2 and imgIDecoder
NS_IMPL_ISUPPORTS1(nsGIFDecoder2, imgIDecoder);
nsGIFDecoder2::nsGIFDecoder2()
{
NS_INIT_ISUPPORTS();
mImageFrame = nsnull;
mGIFStruct = nsnull;
mAlphaLine = nsnull;
mRGBLine = nsnull;
mBackgroundRGBIndex = 0;
mCurrentRow = -1;
mLastFlushedRow = -1;
mCurrentPass = 0;
mLastFlushedPass = 0;
}
nsGIFDecoder2::~nsGIFDecoder2(void)
{
if (mAlphaLine)
nsMemory::Free(mAlphaLine);
if (mRGBLine)
nsMemory::Free(mRGBLine);
if (mGIFStruct) {
gif_destroy(mGIFStruct);
mGIFStruct = nsnull;
}
}
//******************************************************************************
/** imgIDecoder methods **/
//******************************************************************************
//******************************************************************************
/* void init (in imgILoad aLoad); */
NS_IMETHODIMP nsGIFDecoder2::Init(imgILoad *aLoad)
{
mObserver = do_QueryInterface(aLoad);
mImageContainer = do_CreateInstance("@mozilla.org/image/container;1");
aLoad->SetImage(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;
}
//******************************************************************************
/** 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;
}
//******************************************************************************
/* 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);
nsresult rv = decoder->ProcessData((unsigned char*)fromRawSegment, count, writeCount);
if (NS_FAILED(rv)) {
*writeCount = 0;
return rv;
}
return NS_OK;
}
// Push any new rows according to mCurrentPass/mLastFlushedPass and
// mCurrentRow/mLastFlushedRow. Note: caller is responsible for
// updating mlastFlushed{Row,Pass}.
NS_METHOD
nsGIFDecoder2::FlushImageData()
{
PRInt32 width;
PRInt32 height;
mImageFrame->GetWidth(&width);
mImageFrame->GetHeight(&height);
switch (mCurrentPass - mLastFlushedPass) {
case 0: { // same pass
PRInt32 remainingRows = mCurrentRow - mLastFlushedRow;
if (remainingRows) {
nsRect r(0, mLastFlushedRow+1, width, remainingRows);
mObserver->OnDataAvailable(nsnull, nsnull, mImageFrame, &r);
}
}
break;
case 1: { // one pass on - need to handle bottom & top rects
nsRect r(0, 0, width, mCurrentRow+1);
mObserver->OnDataAvailable(nsnull, nsnull, mImageFrame, &r);
nsRect r2(0, mLastFlushedRow+1, width, height-mLastFlushedRow-1);
mObserver->OnDataAvailable(nsnull, nsnull, mImageFrame, &r2);
}
break;
default: { // more than one pass on - push the whole frame
nsRect r(0, 0, width, height);
mObserver->OnDataAvailable(nsnull, nsnull, mImageFrame, &r);
}
}
return NS_OK;
}
//******************************************************************************
nsresult nsGIFDecoder2::ProcessData(unsigned char *data, PRUint32 count, PRUint32 *_retval)
{
// 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)) {
PRStatus result = gif_write(mGIFStruct, data, count);
if (result != PR_SUCCESS)
return NS_ERROR_FAILURE;
}
if (mImageFrame && mObserver) {
FlushImageData();
mLastFlushedRow = mCurrentRow;
mLastFlushedPass = mCurrentPass;
}
*_retval = count;
return NS_OK;
}
//******************************************************************************
/* unsigned long writeFrom (in nsIInputStream inStr, in unsigned long count); */
NS_IMETHODIMP nsGIFDecoder2::WriteFrom(nsIInputStream *inStr, PRUint32 count, PRUint32 *_retval)
{
return inStr->ReadSegments(ReadDataOut, this, count, _retval);
}
//******************************************************************************
// GIF decoder callback methods. Part of pulic API for GIF2
//******************************************************************************
//******************************************************************************
int BeginGIF(
void* aClientData,
PRUint32 aLogicalScreenWidth,
PRUint32 aLogicalScreenHeight,
PRUint8 aBackgroundRGBIndex)
{
// If we have passed an illogical screen size, bail and hope that we'll get
// set later by the first frame's local image header.
if(aLogicalScreenWidth == 0 || aLogicalScreenHeight == 0)
return 0;
// copy GIF info into imagelib structs
nsGIFDecoder2 *decoder = NS_STATIC_CAST(nsGIFDecoder2*, aClientData);
decoder->mBackgroundRGBIndex = aBackgroundRGBIndex;
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,
PRUint32 aDisposal) /* 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.
decoder->mImageContainer->EndFrameDecode(aFrameNumber, aDelayTimeout);
if (decoder->mObserver && decoder->mImageFrame) {
decoder->mImageFrame->SetFrameDisposalMethod(aDisposal);
decoder->FlushImageData();
decoder->mCurrentRow = decoder->mLastFlushedRow = -1;
decoder->mCurrentPass = decoder->mLastFlushedPass = 0;
decoder->mObserver->OnStopFrame(nsnull, nsnull, decoder->mImageFrame);
}
decoder->mImageFrame = nsnull;
decoder->mGIFStruct->local_colormap = nsnull;
decoder->mGIFStruct->is_transparent = PR_FALSE;
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
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;
}
#if defined(XP_PC) || defined(XP_BEOS) || defined(MOZ_WIDGET_PHOTON)
// 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);
decoder->mRGBLine = (PRUint8 *)nsMemory::Realloc(decoder->mRGBLine, bpr);
if (format == gfxIFormats::RGB_A1 || format == gfxIFormats::BGR_A1) {
decoder->mAlphaLine = (PRUint8 *)nsMemory::Realloc(decoder->mAlphaLine, 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;
cmapsize = decoder->mGIFStruct->global_colormap_size;
cmap = decoder->mGIFStruct->global_colormap;
if(decoder->mGIFStruct->global_colormap &&
decoder->mGIFStruct->screen_bgcolor < cmapsize) {
gfx_color bgColor = 0;
bgColor |= cmap[decoder->mGIFStruct->screen_bgcolor].red;
bgColor |= cmap[decoder->mGIFStruct->screen_bgcolor].green << 8;
bgColor |= cmap[decoder->mGIFStruct->screen_bgcolor].blue << 16;
decoder->mImageFrame->SetBackgroundColor(bgColor);
}
if(decoder->mGIFStruct->local_colormap) {
cmapsize = decoder->mGIFStruct->local_colormap_size;
cmap = decoder->mGIFStruct->local_colormap;
}
PRUint8* rgbRowIndex = decoder->mRGBLine;
PRUint8* rowBufIndex = aRowBufPtr;
switch (format) {
case gfxIFormats::RGB:
{
while(rowBufIndex != decoder->mGIFStruct->rowend) {
#if defined(XP_MAC) || defined(XP_MACOSX)
*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;
}
for (int i=0; i<aDuplicateCount; i++)
decoder->mImageFrame->SetImageData(decoder->mRGBLine,
bpr, (aRowNumber+i)*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;
}
for (int i=0; i<aDuplicateCount; i++)
decoder->mImageFrame->SetImageData(decoder->mRGBLine,
bpr, (aRowNumber+i)*bpr);
}
break;
case gfxIFormats::RGB_A1:
case gfxIFormats::BGR_A1:
{
if (decoder->mGIFStruct->is_transparent &&
(decoder->mGIFStruct->tpixel < cmapsize)) {
gfx_color transColor = 0;
transColor |= cmap[decoder->mGIFStruct->tpixel].red;
transColor |= cmap[decoder->mGIFStruct->tpixel].green << 8;
transColor |= cmap[decoder->mGIFStruct->tpixel].blue << 16;
decoder->mImageFrame->SetTransparentColor(transColor);
}
memset(decoder->mRGBLine, 0, bpr);
memset(decoder->mAlphaLine, 0, abpr);
PRUint32 iwidth = (PRUint32)width;
for (PRUint32 x=0; x<iwidth; x++) {
if (*rowBufIndex != decoder->mGIFStruct->tpixel) {
#if defined(XP_PC) || defined(XP_BEOS) || defined(MOZ_WIDGET_PHOTON)
*rgbRowIndex++ = cmap[PRUint8(*rowBufIndex)].blue;
*rgbRowIndex++ = cmap[PRUint8(*rowBufIndex)].green;
*rgbRowIndex++ = cmap[PRUint8(*rowBufIndex)].red;
#else
#if defined(XP_MAC) || defined(XP_MACOSX)
*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 {
#if defined(XP_MAC) || defined(XP_MACOSX)
rgbRowIndex+=4;
#else
rgbRowIndex+=3;
#endif
}
++rowBufIndex;
}
for (int i=0; i<aDuplicateCount; i++) {
decoder->mImageFrame->SetAlphaData(decoder->mAlphaLine,
abpr, (aRowNumber+i)*abpr);
decoder->mImageFrame->SetImageData(decoder->mRGBLine,
bpr, (aRowNumber+i)*bpr);
}
}
break;
default:
break;
}
decoder->mCurrentRow = aRowNumber+aDuplicateCount-1;
decoder->mCurrentPass = aInterlacePass;
if (aInterlacePass == 1)
decoder->mLastFlushedPass = aInterlacePass; // interlaced starts at 1
}
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;
}

View File

@@ -1,117 +0,0 @@
/* -*- 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 "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
nsGIFDecoder2();
virtual ~nsGIFDecoder2();
nsresult ProcessData(unsigned char *data, PRUint32 count, PRUint32 *_retval);
NS_METHOD FlushImageData();
nsCOMPtr<imgIContainer> mImageContainer;
nsCOMPtr<gfxIImageFrame> mImageFrame;
nsCOMPtr<imgIDecoderObserver> mObserver; // this is just qi'd from mRequest for speed
PRInt32 mCurrentRow;
PRInt32 mLastFlushedRow;
gif_struct *mGIFStruct;
PRUint8 *mAlphaLine;
PRUint8 *mRGBLine;
PRUint8 mBackgroundRGBIndex;
PRUint8 mCurrentPass;
PRUint8 mLastFlushedPass;
};
// 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
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,
PRUint32 aDisposal);
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

View File

@@ -1,64 +0,0 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* 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 the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Chris Saari <saari@netscape.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, 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 NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsGIFDecoder2.h"
#include "nsIComponentManager.h"
#include "nsIGenericFactory.h"
#include "nsISupports.h"
#include "nsCOMPtr.h"
#include "nsGifAllocator.h"
NS_GENERIC_FACTORY_CONSTRUCTOR(nsGIFDecoder2)
static nsModuleComponentInfo components[] =
{
{ "GIF Decoder",
NS_GIFDECODER2_CID,
"@mozilla.org/image/decoder;2?type=image/gif",
nsGIFDecoder2Constructor, },
};
// GIF module shutdown hook
static void PR_CALLBACK nsGifShutdown(nsIModule *module)
{
// Release cached buffers from zlib allocator
delete gGifAllocator;
}
NS_IMPL_NSGETMODULE_WITH_DTOR(nsGIFModule2, components, nsGifShutdown);

View File

@@ -1,104 +0,0 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* 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 ***** */
/*
* Allocator optimized for use with gif decoder
*
* For every image that gets loaded, we allocate
* 4097 x 2 : gs->prefix
* 4097 x 1 : gs->suffix
* 4097 x 1 : gs->stack
* for lzw to operate on the data. These are held for a very short interval
* and freed. This allocator tries to keep one set of these around
* and reuses them; automatically fails over to use calloc/free when all
* buckets are full.
*/
#include "prlock.h"
#include "prlog.h"
class nsGifAllocator;
extern nsGifAllocator *gGifAllocator;
const PRInt32 kNumBuckets = 3;
class nsGifAllocator {
protected:
void *mMemBucket[kNumBuckets];
PRUint32 mSize[kNumBuckets];
PRLock *mLock;
PRUint32 mFlag;
public:
nsGifAllocator() : mFlag(0), mLock(nsnull)
{
memset(mMemBucket, 0, sizeof mMemBucket);
memset(mSize, 0, sizeof mSize);
mLock = PR_NewLock();
PR_ASSERT(mLock != NULL);
}
~nsGifAllocator()
{
ClearBuckets();
if (mLock)
PR_DestroyLock(mLock);
}
// Gif allocators
void* Calloc(PRUint32 items, PRUint32 size);
void Free(void *ptr);
// Clear all buckets of memory
void ClearBuckets();
// in-use flag getters/setters
inline PRBool IsUsed(PRUint32 i)
{
PR_ASSERT(i <= 31);
return mFlag & (1 << i);
}
inline void MarkUsed(PRUint32 i)
{
PR_ASSERT(i <= 31);
mFlag |= (1 << i);
}
inline void ClearUsed(PRUint32 i)
{
PR_ASSERT(i <= 31);
mFlag &= ~(1 << i);
}
};

View File

@@ -1,18 +0,0 @@
?Release@nsGIFDecoder2@@UAGKXZ ; 9300
?AddRef@nsGIFDecoder2@@UAGKXZ ; 9300
?ProcessData@nsGIFDecoder2@@QAGIPAEI@Z ; 6722
?gif_write_ready@@YAEPAUgif_struct@@@Z ; 6722
?gif_write@@YAHPAUgif_struct@@PBEI@Z ; 6722
?WriteFrom@nsGIFDecoder2@@UAGIPAVnsIInputStream@@IPAI@Z ; 4869
?gif_destroy@@YAXPAUgif_struct@@@Z ; 4650
?QueryInterface@nsGIFDecoder2@@UAGIABUnsID@@PAPAX@Z ; 4650
?Init@nsGIFDecoder2@@UAGIPAVimgIRequest@@@Z ; 4650
??_EnsGIFDecoder2@@UAEPAXI@Z ; 4650
?Close@nsGIFDecoder2@@UAGIXZ ; 4650
??0nsGIFDecoder2@@QAE@XZ ; 4650
??1nsGIFDecoder2@@UAE@XZ ; 4650
?GIFInit@@YAHPAUgif_struct@@PAXP6AHXZP6AH1IIE@ZP6AH1H@ZP6AH1IIIIIPAU_GIF_RGB@@@ZP6AH1III@Z2222P6AH1PAE8HHHHEH@ZP6AH1@Z@Z ; 4650
?gif_create@@YAHPAPAUgif_struct@@@Z ; 4650
?Flush@nsGIFDecoder2@@UAGIXZ ; 4650
?il_BACat@@YAPADPAPADIPBDI@Z ; 4124
NSGetModule ; 1