WindowsXP-SP1/windows/advcore/gdiplus/engine/imaging/gif/gifcodec.hpp
2020-09-30 16:53:49 +02:00

268 lines
10 KiB
C++

#pragma once
/**************************************************************************\
*
* Copyright (c) 1998 Microsoft Corporation
*
* Module Name:
*
* gifcodec.hpp
*
* Abstract:
*
* Header file for the gif encoder/decoder
*
* Revision History:
*
* 5/13/1999 t-aaronl
* Created it from OriG's template.
*
\**************************************************************************/
#include "giffile.h"
#include "liblzw/lzwread.h"
#include "liblzw/lzwwrite.h"
#include "gifoverflow.hpp"
#include "gifbuffer.hpp"
#include "gifframecache.hpp"
//TODO: The encoder and decoder should be split into separate classes
//because they really don't share anything between themselves anyway.
class GpGifCodec : public IImageDecoder,
public IImageEncoder,
public IImageSink
{
private:
/*-----------------\
For en/decoding
\-----------------*/
ImageInfo CachedImageInfo; // Image info for input image
BOOL IsImageInfoCached; // TRUE if we have already cached it
BOOL HasCodecInitialized;//TRUE if Init(En|De)coder has been called
// before the corresponding Terminate.
BOOL HasCalledBeginDecode;// State for BeginDecode/EndDecode
IStream *istream;
BYTE colorpalettebuffer[offsetof(ColorPalette, Entries) + sizeof(ARGB) * 256];
ColorPalette *colorpalette;
/*-----------------\
For decoding
\-----------------*/
IImageSink* decodeSink;
GifFileHeader gifinfo;
BOOL bGifinfoFirstFrameDim;
WORD gifinfoFirstFrameWidth;
WORD gifinfoFirstFrameHeight;
BOOL bGifinfoMaxDim;
WORD gifinfoMaxWidth;
WORD gifinfoMaxHeight;
GifColorTable GlobalColorTable; // GIF global color table
GifGraphicControlExtension lastgce; // The scope of a GCE is limited to
// The following image chunk.
GifFrameCache* GifFrameCachePtr; // Pointer to the Gif Frame Cache
DecoderInitFlag decoderflags;
BOOL blocking;
BOOL lastgcevalid; // TRUE if the variable lastgce has been
// set.
BOOL headerread;
BOOL firstdecode;
BOOL HasCalledBeginSink;
BOOL IsAnimatedGif; // True if the image is animated GIF
BOOL IsMultiImageGif; // True if the image is a multiimage GIF
WORD FrameDelay; // Frame delay, in hundreths of a second
BOOL HasLoopExtension;
UINT16 LoopCount; // Loop count for an animated gif
BOOL moreframes;
UINT GlobalColorTableSize; // GIF global color table size
INT TotalNumOfFrame;
INT currentframe;
LONGLONG frame0pos;
// Property related variables
UINT PropertyNumOfItems; // Number of property items in the image
UINT PropertyListSize; // Total bytes for storing values
BOOL HasProcessedPropertyItem; // TRUE if we have processed once
UINT* FrameDelayArrayPtr; // A pointer to an array of frame delay
// value. Each frame has a frame delay
UINT FrameDelayBufferSize; // Current size of the buffer for
// storingframe delay info
BYTE* CommentsBufferPtr; // A pointer to the comments buffer
UINT CommentsBufferLength; // Length of comments chunk
int TranslateInterlacedLine(IN int line, IN int height, IN int pass);
int WhichPass(IN int line, IN int height);
int NumRowsInPass(IN int pass);
BYTE GetBackgroundColor (void);
void CopyConvertPalette(IN GifColorTable *gct,
OUT ColorPalette *cp,
IN UINT count);
STDMETHOD(SetFrameColorTable)(IN BOOL local,
IN OUT ColorPalette *colorpalette);
STDMETHOD(GetOutputSpace)(IN int line,
IN GifBuffer &gifbuffer,
IN LZWDecompressor &lzwdecompressor,
IN GifOverflow &gifoverflow,
IN GifImageDescriptor currentImageInfo,
IN GifImageDescriptor clippedCurrentImageInfo,
IN BOOL padborder);
STDMETHOD(GetCompressedData)(IN LZWDecompressor &lzwdecompressor,
IN BYTE compresseddata[256],
OUT BOOL &stillmoredata);
STDMETHOD(ReadGifHeaders)();
STDMETHOD(ProcessImageChunk)(IN BOOL processdata,
IN BOOL sinkdata,
ImageInfo dstImageInfo);
STDMETHOD(ProcessGraphicControlChunk)(IN BOOL processdata);
STDMETHOD(ProcessCommentChunk)(IN BOOL processdata);
STDMETHOD(ProcessPlainTextChunk)(IN BOOL processdata);
STDMETHOD(ProcessApplicationChunk)(IN BOOL processdata);
STDMETHOD(SeekThroughDataChunk)(IN IStream *istream, IN BYTE headersize);
STDMETHOD(MarkStream)(IN IStream *istream, OUT LONGLONG &markpos);
STDMETHOD(ResetStream)(IN IStream *istream, IN LONGLONG &markpos);
STDMETHOD(SkipToNextFrame)();
STDMETHOD(ReadFrameProperties)();
STDMETHOD(MoveToNextFrame)();
STDMETHOD(DoDecode)(BOOL processdata, BOOL sinkdata, BOOL decodeframe);
/*-----------------\
For encoding
\-----------------*/
RECT encoderrect; //Contains the bounds that the encoder is handling.
RECT scanrect; //Contains the bounds of the area that is currently being
//pushed into the encoder
unsigned __int8* compressionbuffer;
BOOL headerwritten;
BOOL bTransparentColorIndex;
UINT transparentColorIndex;
BOOL from32bpp;
BOOL gif89;
BOOL interlaced;
int currentline;
STDMETHOD(WritePalette)();
STDMETHOD(WriteGifHeader)(IN ImageInfo &imageinfo, IN BOOL from32bpp);
STDMETHOD(WriteGifGraphicControlExtension) (IN BYTE packedFields,
IN WORD delayTime,
IN UINT transparentColorIndex);
STDMETHOD(WriteGifImageDescriptor)(IN ImageInfo &imageinfo, IN BOOL
from32bpp);
STDMETHOD(AllocateCompressionBuffer)(const BitmapData *bitmapdata);
STDMETHOD(CompressAndWriteImage)();
STDMETHOD(WriteImage)();
int TranslateInterlacedLineBackwards(IN int line, IN int height);
protected:
LONG comRefCount; //COM object reference count
public:
// Constructor and Destructor
GpGifCodec::GpGifCodec(void);
GpGifCodec::~GpGifCodec(void);
// IImageDecoder methods
STDMETHOD(InitDecoder)(IN IStream* stream, IN DecoderInitFlag flags);
STDMETHOD(TerminateDecoder)();
STDMETHOD(BeginDecode)(IN IImageSink* imageSink, IN OPTIONAL
IPropertySetStorage* newPropSet);
STDMETHOD(Decode)();
STDMETHOD(EndDecode)(IN HRESULT statusCode);
STDMETHOD(GetFrameDimensionsCount)(OUT UINT* count);
STDMETHOD(GetFrameDimensionsList)(OUT GUID* dimensionIDs,IN OUT UINT count);
STDMETHOD(GetFrameCount)(IN const GUID* dimensionID, OUT UINT* count);
STDMETHOD(SelectActiveFrame)(IN const GUID* dimensionID,
IN UINT frameIndex);
STDMETHOD(GetImageInfo)(OUT ImageInfo* imageInfo);
STDMETHOD(GetThumbnail)(IN OPTIONAL UINT thumbWidth, IN OPTIONAL UINT thumbHeight,
OUT IImage** thumbImage);
STDMETHOD(QueryDecoderParam)(IN GUID Guid);
STDMETHOD(SetDecoderParam)(IN GUID Guid, IN UINT Length, IN PVOID Value);
STDMETHOD(GetPropertyCount)(OUT UINT* numOfProperty);
STDMETHOD(GetPropertyIdList)(IN UINT numOfProperty,IN OUT PROPID* list);
STDMETHOD(GetPropertyItemSize)(IN PROPID propId, OUT UINT* size);
STDMETHOD(GetPropertyItem)(IN PROPID propId, IN UINT propSize,
IN OUT PropertyItem* buffer);
STDMETHOD(GetPropertySize)(OUT UINT* totalBufferSize,
OUT UINT* numProperties);
STDMETHOD(GetAllPropertyItems)(IN UINT totalBufferSize,
IN UINT numProperties,
IN OUT PropertyItem* allItems);
STDMETHOD(RemovePropertyItem)(IN PROPID propId);
STDMETHOD(SetPropertyItem)(IN PropertyItem item);
STDMETHOD(GetRawInfo)(IN OUT void** info)
{
return E_NOTIMPL;
}
// IImageEncoder methods
STDMETHOD(InitEncoder)(IN IStream* stream);
STDMETHOD(TerminateEncoder)();
STDMETHOD(GetEncodeSink)(OUT IImageSink** sink);
STDMETHOD(SetFrameDimension)(IN const GUID* dimensionID);
STDMETHOD(GetEncoderParameterListSize)(OUT UINT* size);
STDMETHOD(GetEncoderParameterList)(IN UINT size,
OUT EncoderParameters* Params);
STDMETHOD(SetEncoderParameters)(IN const EncoderParameters* Param);
STDMETHOD(NeedTransform(OUT UINT* rotation))
{
return E_NOTIMPL;
}
STDMETHOD(NeedRawProperty)(void *pSRc)
{
// GIF can't handle raw property when saving for now
return E_FAIL;
}
STDMETHOD(PushRawInfo)(IN OUT void* info)
{
return E_NOTIMPL;
}
STDMETHOD(GetPropertyBuffer)(
IN UINT uiTotalBufferSize,
IN OUT PropertyItem** ppBuffer
)
{
return E_NOTIMPL;
}
STDMETHOD(PushPropertyItems)(
IN UINT numOfItems,
IN UINT uiTotalBufferSize,
IN PropertyItem* item,
IN BOOL fICCProfileChanged
)
{
return E_NOTIMPL;
}
// IImageSink methods (sink for encoder)
STDMETHOD(BeginSink)(IN OUT ImageInfo* imageInfo,
OUT OPTIONAL RECT* subarea);
STDMETHOD(EndSink)(IN HRESULT statusCode);
STDMETHOD(SetPalette)(IN const ColorPalette* palette);
STDMETHOD(GetPixelDataBuffer)(IN const RECT* rect,
IN PixelFormatID pixelFormat, IN BOOL lastPass,
OUT BitmapData* bitmapData);
STDMETHOD(ReleasePixelDataBuffer)(IN const BitmapData* bitmapData);
STDMETHOD(PushRawData)(IN const VOID* buffer, IN UINT bufsize);
STDMETHOD(PushPixelData)(IN const RECT* rect,
IN const BitmapData* bitmapData, IN BOOL lastPass);
// IUnknown methods
STDMETHOD(QueryInterface)(REFIID riid, VOID** ppv);
STDMETHOD_(ULONG, AddRef)(VOID);
STDMETHOD_(ULONG, Release)(VOID);
};