// ----------------------------------------------------------- // Analyzes the Parallaxer Image and returns a ParallaxFrame // ----------------------------------------------------------- ParallaxFrame AnalyzeImage( cSurface * parallaxImage, bool direction, bool smoothLines, int smoothAmount ){ ParallaxFrame frame; ParallaxFrame nullframe; nullframe.startArray = NULL; nullframe.lengthArray = NULL; nullframe.blockArray = NULL; nullframe.parallaxImage = NULL; if( parallaxImage == NULL || !parallaxImage->IsValid() ) return nullframe; frame.parallaxImage = parallaxImage; //Analyze image for width/height of lines int width = parallaxImage->GetWidth(); int height = parallaxImage->GetHeight(); int arrayLength = direction ? width : height; if(width == 0 || height == 0) return nullframe; frame.startArray = new int [ arrayLength ]; frame.lengthArray = new int [ arrayLength ]; frame.blockArray = new int [ arrayLength ]; frame.blurredLength = new double[arrayLength]; //Set all blocksizes to 1 for( int l=0; l < arrayLength; l++) { frame.startArray[l] = 0; frame.blockArray[l] = 1; frame.lengthArray[l] = 1; frame.blurredLength[l] = 1; } COLORREF transparent = parallaxImage->GetTransparentColor(); bool hasAlpha = parallaxImage->HasAlpha() == 1; int pitch = 1; //Lock resources LPBYTE lock = parallaxImage->LockBuffer(); LPBYTE aLock = NULL; if(hasAlpha) { aLock = parallaxImage->LockAlpha(); pitch = parallaxImage->GetAlphaPitch(); transparent = 0; } //Horizontal if( direction == HORIZONTAL ) { bool metLine; for( int y = 0; y < height; y++ ) { metLine = false; for( int xa = 0; xa < width; xa++ ) { COLORREF color = (!hasAlpha) ? parallaxImage->GetPixelFast(xa,y) : (COLORREF)aLock[pitch*y+xa]; if( color != transparent ) { metLine = true; frame.startArray[y] = xa; break; } } if( metLine ) for( int xb = width-1; xb > 0; xb-- ) { COLORREF color = (!hasAlpha) ? parallaxImage->GetPixelFast(xb,y) : (COLORREF)aLock[pitch*y+xb]; if( color != transparent ) { frame.lengthArray[y] = xb - frame.startArray[y] + 1; frame.blurredLength[y] = frame.lengthArray[y]; break; } } else { frame.startArray[y] = 0; frame.lengthArray[y] = width; frame.blurredLength[y] = width; } } } //Vertical else { bool metLine; for( int x = 0; x < width; x++ ){ metLine = false; for( int ya = 0; ya < height; ya++ ) { COLORREF color = (!hasAlpha) ? parallaxImage->GetPixelFast(x,ya) : (COLORREF)aLock[width*ya+x]; if( color != transparent ) { metLine = true; frame.startArray[x] = ya; break; } } if( metLine ) for( int yb = height-1; yb > 0; yb-- ) { COLORREF color = (!hasAlpha) ? parallaxImage->GetPixelFast(x,yb) : (COLORREF)aLock[width*yb+x]; if( color != transparent ){ frame.lengthArray[x] = yb - frame.startArray[x] + 1; frame.blurredLength[x] = frame.lengthArray[x]; break; } } else{ frame.startArray[x] = 0; frame.lengthArray[x] = height; frame.blurredLength[x] = height; } } } //Unlock resources parallaxImage->UnlockBuffer(lock); if(hasAlpha) parallaxImage->UnlockAlpha(); if(smoothLines) SmoothLine(&frame, arrayLength, smoothAmount); int blockStart = 0; for( int i = 0; i < arrayLength; i++ ) { //Block copy optimization //If previous line is equal (start/length), increase blocksize if( frame.startArray[ blockStart ] == frame.startArray[ i ] && frame.blurredLength[ blockStart ] == frame.blurredLength[ i ] && blockStart != 0) frame.blockArray[ blockStart ] += 1; else blockStart = i; } return frame; }
void CDX9Renderer::SmoothLine(cr_float x1, cr_float y1, cr_float x2, cr_float y2, cr_float width, const color &c) { SmoothLine(point(x1, y1), point(x2, y2), width, c); }