Last active
August 29, 2015 14:24
-
-
Save jonny-novikov/e4779619298a856abfc1 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| static void inner_stretch_argb8888_bilinear(Blitter* blitter, const InnerInfo* info) | |
| { | |
| uint32 u = info->ustart; | |
| uint32 vfrac2 = info->vfrac >> 8; | |
| uint32 vfrac1 = 0x100 - vfrac2; | |
| uint32* src1 = reinterpret_cast<uint32*>(info->src); | |
| uint32* src2 = reinterpret_cast<uint32*>(info->src2); | |
| uint32* dest = reinterpret_cast<uint32*>(info->dest); | |
| int count = info->width; | |
| while ( count-- ) | |
| { | |
| uint32 uinte = (u >> 16); | |
| uint32 ufrac2 = (u & 0xff00) >> 8; | |
| uint32 ufrac1 = 0x100 - ufrac2; | |
| uint32 pix11a = src1[uinte]; | |
| uint32 pix12a = src1[uinte + 1]; | |
| uint32 pix21a = src2[uinte]; | |
| uint32 pix22a = src2[uinte + 1]; | |
| uint32 pix11b = pix11a & 0x00ff00ff; | |
| uint32 pix12b = pix12a & 0x00ff00ff; | |
| uint32 pix21b = pix21a & 0x00ff00ff; | |
| uint32 pix22b = pix22a & 0x00ff00ff; | |
| pix11a = (pix11a & 0xff00ff00) >> 8; | |
| pix12a = (pix12a & 0xff00ff00) >> 8; | |
| pix21a = (pix21a & 0xff00ff00) >> 8; | |
| pix22a = (pix22a & 0xff00ff00) >> 8; | |
| uint32 col1ag = ((ufrac1 * pix11a + ufrac2 * pix12a) & 0xff00ff00) >> 8; | |
| uint32 col2ag = ((ufrac1 * pix21a + ufrac2 * pix22a) & 0xff00ff00) >> 8; | |
| uint32 col1rb = ((ufrac1 * pix11b + ufrac2 * pix12b) & 0xff00ff00) >> 8; | |
| uint32 col2rb = ((ufrac1 * pix21b + ufrac2 * pix22b) & 0xff00ff00) >> 8; | |
| *dest++ = (((vfrac1 * col1ag + vfrac2 * col2ag) & 0xff00ff00)) | |
| | (((vfrac1 * col1rb + vfrac2 * col2rb) & 0xff00ff00) >> 8); | |
| u += info->ustep; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| void Surface::BlitImage(const Surface& source, BlitMode mode) | |
| { | |
| // validate surfaces | |
| if ( !(width && height && image && source.width && source.height && source.image) ) | |
| return; | |
| bool resize = width != source.width || height != source.height; | |
| // choose blitter mode | |
| int type = 0; | |
| if ( source.format != format ) type |= BLIT_REMAP; | |
| if ( mode==BLIT_SCALE && resize ) type |= BLIT_STRETCH; | |
| if ( mode==BLIT_BILINEAR_SCALE && resize ) type |= BLIT_BILINEAR | BLIT_STRETCH; | |
| // plain row-by-row copying if !conversion && !stretching | |
| if ( !type ) | |
| { | |
| int minwidth = MIN(width,source.width); | |
| int minheight = MIN(height,source.height); | |
| int length = minwidth * format.GetBytes(); | |
| uint8* s = source.image; | |
| uint8* d = image; | |
| for ( int y=0; y<minheight; ++y ) | |
| { | |
| memcpy(d,s,length); | |
| s += source.pitch; | |
| d += pitch; | |
| } | |
| } | |
| else | |
| { | |
| // delegate the workload for floating-point blitting module | |
| // if either source or destination pixelformat is floating-point | |
| if ( format.IsFloat() || source.format.IsFloat() ) | |
| { | |
| BlitImageFloat(source,mode); | |
| return; | |
| } | |
| // get a suitable blitter | |
| Blitter* blitter = GetBlitter(format,source.format,type); | |
| if ( !blitter ) | |
| return; | |
| InnerInfo innerinfo; | |
| innerinfo.dest = reinterpret_cast<uint8*>(image); | |
| // stretching | |
| if ( blitter->convtype & BLIT_STRETCH ) | |
| { | |
| uint32 vstep,v; | |
| // bilinear stretch has special UV calculations | |
| if ( blitter->convtype & BLIT_BILINEAR ) | |
| { | |
| if ( width < source.width ) | |
| { | |
| innerinfo.ustep = (source.width << 16) / width; | |
| innerinfo.ustart = (innerinfo.ustep >> 1) - 0x8000; | |
| } | |
| else | |
| { | |
| int div = width - 1; | |
| if ( !div ) div = 1; | |
| innerinfo.ustep = ((source.width - 1) << 16) / div; | |
| innerinfo.ustart = 0; | |
| } | |
| if ( height < source.height ) | |
| { | |
| vstep = (source.height << 16) / height; | |
| v = (vstep >> 1) - 0x8000; | |
| } | |
| else | |
| { | |
| int div = height - 1; | |
| if ( !div ) div = 1; | |
| vstep = ((source.height - 1) << 16) / div; | |
| v = 0; | |
| } | |
| } | |
| else // !bilinear | |
| { | |
| innerinfo.ustep = (source.width << 16) / width; | |
| innerinfo.ustart = (innerinfo.ustep >> 1); | |
| vstep = (source.height << 16) / height; | |
| v = vstep >> 1; | |
| } | |
| innerinfo.width = width; | |
| for ( int y=0; y<height; ++y ) | |
| { | |
| innerinfo.src = reinterpret_cast<uint8*>(source.image) + ((v >> 16) * source.pitch); | |
| innerinfo.src2 = innerinfo.src + source.pitch; | |
| // clamp lower scanline - just in case | |
| // the delta calculation above should ensure this is not required, | |
| // but, rgb888_bilinear innerloops pagefault -- fix this performance/quality | |
| // caveat sometime. ;-) | |
| if ( y == (height - 1) ) | |
| innerinfo.src2 = innerinfo.src; | |
| innerinfo.vfrac = v & 0xffff; | |
| blitter->Blit(&innerinfo); | |
| v += vstep; | |
| innerinfo.dest += pitch; | |
| } | |
| } | |
| else // conversion && !stretching | |
| { | |
| int minwidth = MIN(width,source.width); | |
| int minheight = MIN(height,source.height); | |
| innerinfo.width = minwidth; | |
| innerinfo.src = reinterpret_cast<uint8*>(source.image); | |
| for ( int y=0; y<minheight; ++y ) | |
| { | |
| blitter->Blit(&innerinfo); | |
| innerinfo.dest += pitch; | |
| innerinfo.src += source.pitch; | |
| } | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| //----------------------------------------------------------------------- | |
| // Область для рисования | |
| //----------------------------------------------------------------------- | |
| struct SurfaceDesc | |
| { | |
| public: | |
| typedef iml::core::PixelFormat PixFormat_t; | |
| typedef iml::uint8 byte; | |
| SurfaceDesc() | |
| : width(0),height(0),pitch(0),image(NULL) | |
| { | |
| } | |
| SurfaceDesc(int w, int h, int p, const PixFormat_t& pxf, void* i) | |
| : width(w),height(h),pitch(p),format(pxf),image(reinterpret_cast<byte*>(i)) | |
| { | |
| IMLASSERT( width > 0 && height > 0 ); | |
| } | |
| SurfaceDesc(const SurfaceDesc& desc) | |
| : width(desc.width),height(desc.height),pitch(desc.pitch),format(desc.format),image(desc.image) | |
| { | |
| IMLASSERT( width > 0 && height > 0 ); | |
| } | |
| int GetWidth() const | |
| { | |
| return width; | |
| } | |
| int GetHeight() const | |
| { | |
| return height; | |
| } | |
| int GetPitch() const | |
| { | |
| return pitch; | |
| } | |
| const PixFormat_t& GetPixelFormat() const | |
| { | |
| return format; | |
| } | |
| byte* GetImage() const | |
| { | |
| return image; | |
| } | |
| Size_i GetSize() const | |
| { | |
| return Size_i(width, height); | |
| } | |
| Rect_i GetRect() const | |
| { | |
| return Rect_i(0,0,width,height); | |
| } | |
| SurfaceDesc GetSurfacePart(const Rect_i& rect) const | |
| { | |
| // clip | |
| Rect_i q; | |
| if ( !Rect_i::Intersect(q, GetRect(), rect) ) | |
| return *this; | |
| SurfaceDesc surface; | |
| surface.width = q.right - q.left; | |
| surface.height = q.bottom - q.top; | |
| surface.pitch = pitch; | |
| surface.format = format; | |
| surface.image = image + q.top * pitch + q.left * format.GetBytes(); | |
| return surface; | |
| } | |
| protected: | |
| int width; // width in pixels | |
| int height; // height in pixels | |
| int pitch; // width in bytes | |
| PixFormat_t format; // pixel format | |
| byte* image; // image pointer | |
| }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment