/************************************************************************** * * Copyright (c) 2000 Microsoft Corporation * * Module Name & Abstract * * Stretch. This module contains the code to do various stretching * by applying a kernel filter. The code correctly handles minification. * * Notes: * * This code does not handle rotation or shear. * * Created: * * 04/17/2000 asecchia * Created it. * **************************************************************************/ #ifndef _STRETCH_HPP #define _STRETCH_HPP // All the filter modes supported by DpOutputSpanStretch. enum FilterModeType { HighQualityBilinear = 0, HighQualityBicubic = 1, FilterModeMax }; // Filter width is 1 for Bilinear and 2 for Bicubic. const INT FilterWidth[FilterModeMax] = {1, 2}; template class DpOutputSpanStretch : public DpOutputSpan { public: const DpBitmap *dBitmap; BitmapData BmpData; DpScanBuffer *Scan; GpRectF SrcRect; GpRectF DstRect; // Wrap mode state WrapMode QWrapMode; ARGB ClampColor; BYTE ClampColorA; BYTE ClampColorR; BYTE ClampColorG; BYTE ClampColorB; BOOL WrapZeroClamp; // Destination rectangle for valid bits. // The valid bits are the translation of the source valid bits to // the destination space. FIX16 fixDLeft; FIX16 fixDTop; FIX16 fixDRight; FIX16 fixDBottom; // x scale state. FIX16 xkci; // Initial x- kernel position FIX16 xw; // Width of x- kernel from center to edge FIX16 xa; // 1/xw FIX16 xscale; // x- scale factor (magnification or minification) FIX16 xscaleinv; // 1/xscale INT ixleft; // y scale state. FIX16 ykci; // Initial y- kernel position FIX16 yw; // Width of y- kernel from center to edge FIX16 ya; // 1/yw FIX16 yscale; // y- scale factor (magnification or minification) FIX16 yscaleinv; // 1/yscale // This is the last y scanline that contributed to the previous run. INT last_k; // This is the destination y scanline corresponding to the top of the // destination rectangle. INT iytop; // Buffer to store the temporary results for the 1D x-scale. // The xbuffer is implemented as a rotational buffer of scanlines. // Each scanline is the width required to hold one destination width // scanline and there are enough scanlines to fill a y-dimension kernel. ARGB *xbuffer; // This represents the first scanline in the rotational xbuffer. INT xbuffer_start_scanline; // These represent the dimensions of the xbuffer - height is the number // of scanlines and width is the x-size in pixels. INT xbuffer_height; INT xbuffer_width; // This is an array of y-coefficient values. // The kernel weights are computed for each contributing scanline and // stored in this array (1-1 correspondence with the xbuffer) so that // they don't have to be recomputed for every x coordinate. FIX16 *ycoeff; bool isValid; public: DpOutputSpanStretch( DpBitmap* bitmap, DpScanBuffer * scan, DpContext* context, DpImageAttributes imgAttributes, const GpRectF *dstRect, const GpRectF *srcRect ) { InitializeClass(bitmap, scan, context, imgAttributes, dstRect, srcRect); } void InitializeClass( DpBitmap* bitmap, DpScanBuffer * scan, DpContext* context, DpImageAttributes imgAttributes, const GpRectF *dstRect, const GpRectF *srcRect ); virtual GpStatus OutputSpan( INT y, INT xMin, INT xMax ); void StretchScanline( ARGB *dst, // destination pointer ARGB *src, // source pointer INT dw, // destination width (pixels) INT sw, // source width (pixels) FIX16 kci, // initial position of the kernel center FIX16 scale, // scale factor FIX16 w, // width from center of the kernel to the edge FIX16 a // 1/w ); void StretchMiddleScanline2_MMX( ARGB *dst, ARGB *src, INT dw, FIX16 kci ); virtual BOOL IsValid() const { return (isValid && (dBitmap!=NULL)); } DpScanBuffer* GetScanBuffer(){ return Scan; } virtual ~DpOutputSpanStretch() { // throw away our working buffer. GpFree(xbuffer); GpFree(ycoeff); } }; #endif