- status_t status = B_BAD_VALUE;
-
- if ( bitmap && bitmap->IsValid()
- && ( bitmap->ColorSpace() == B_RGB32 || bitmap->ColorSpace() == B_RGBA32 ) )
- {
- status = B_MISMATCHED_VALUES;
- // we only support upscaling as of now
- uint32 destWidth = bitmap->Bounds().IntegerWidth() + 1;
- uint32 destHeight = bitmap->Bounds().IntegerHeight() + 1;
- if ( fromWidth <= destWidth && fromHeight <= destHeight )
- {
- status = B_OK;
- uint32 bpr = bitmap->BytesPerRow();
- if ( fromWidth < destWidth )
- {
- // scale horizontally
- uint8* src = (uint8*)bitmap->Bits();
- uint8* p = new uint8[fromWidth * 4]; // temp buffer
- for ( uint32 y = 0; y < fromHeight; y++ )
- {
- // copy valid pixels into temp buffer
- memcpy( p, src, fromWidth * 4 );
- for ( uint32 x = 0; x < destWidth; x++ )
- {
- // mix colors of left and right pixels and write it back
- // into the bitmap
- float xPos = ( (float)x / (float)destWidth ) * (float)fromWidth;
- uint32 leftIndex = (uint32)floorf( xPos ) * 4;
- uint32 rightIndex = (uint32)ceilf( xPos ) * 4;
- rgb_color left;
- left.red = p[leftIndex + 2];
- left.green = p[leftIndex + 1];
- left.blue = p[leftIndex + 0];
- rgb_color right;
- right.red = p[rightIndex + 2];
- right.green = p[rightIndex + 1];
- right.blue = p[rightIndex + 0];
- rgb_color mix;
- mix_colors( left.red, left.green, left.blue,
- right.red, right.green, right.blue,
- mix.red, mix.green, mix.blue, xPos - floorf( xPos ) );
- uint32 destIndex = x * 4;
- src[destIndex + 2] = mix.red;
- src[destIndex + 1] = mix.green;
- src[destIndex + 0] = mix.blue;
- }
- src += bpr;
- }
- delete[] p;
- }
- if ( fromHeight < destHeight )
- {
- // scale vertically
- uint8* src = (uint8*)bitmap->Bits();
- uint8* p = new uint8[fromHeight * 3]; // temp buffer
- for ( uint32 x = 0; x < destWidth; x++ )
- {
- // copy valid pixels into temp buffer
- for ( uint32 y = 0; y < fromHeight; y++ )
- {
- uint32 destIndex = y * 3;
- uint32 srcIndex = x * 4 + y * bpr;
- p[destIndex + 0] = src[srcIndex + 0];
- p[destIndex + 1] = src[srcIndex + 1];
- p[destIndex + 2] = src[srcIndex + 2];
- }
- // do the scaling
- for ( uint32 y = 0; y < destHeight; y++ )
- {
- // mix colors of upper and lower pixels and write it back
- // into the bitmap
- float yPos = ( (float)y / (float)destHeight ) * (float)fromHeight;
- uint32 upperIndex = (uint32)floorf( yPos ) * 3;
- uint32 lowerIndex = (uint32)ceilf( yPos ) * 3;
- rgb_color upper;
- upper.red = p[upperIndex + 2];
- upper.green = p[upperIndex + 1];
- upper.blue = p[upperIndex + 0];
- rgb_color lower;
- lower.red = p[lowerIndex + 2];
- lower.green = p[lowerIndex + 1];
- lower.blue = p[lowerIndex + 0];
- rgb_color mix;
- mix_colors( upper.red, upper.green, upper.blue,
- lower.red, lower.green, lower.blue,
- mix.red, mix.green, mix.blue, yPos - floorf( yPos ) );
- uint32 destIndex = x * 4 + y * bpr;
- src[destIndex + 2] = mix.red;
- src[destIndex + 1] = mix.green;
- src[destIndex + 0] = mix.blue;
- }
- }
- delete[] p;
- }
- }
- }
- return status;
+ status_t status = B_BAD_VALUE;
+
+ if ( bitmap && bitmap->IsValid()
+ && ( bitmap->ColorSpace() == B_RGB32 || bitmap->ColorSpace() == B_RGBA32 ) )
+ {
+ status = B_MISMATCHED_VALUES;
+ // we only support upscaling as of now
+ uint32 destWidth = bitmap->Bounds().IntegerWidth() + 1;
+ uint32 destHeight = bitmap->Bounds().IntegerHeight() + 1;
+ if ( fromWidth <= destWidth && fromHeight <= destHeight )
+ {
+ status = B_OK;
+ uint32 bpr = bitmap->BytesPerRow();
+ if ( fromWidth < destWidth )
+ {
+ // scale horizontally
+ uint8* src = (uint8*)bitmap->Bits();
+ uint8* p = new uint8[fromWidth * 4]; // temp buffer
+ for ( uint32 y = 0; y < fromHeight; y++ )
+ {
+ // copy valid pixels into temp buffer
+ memcpy( p, src, fromWidth * 4 );
+ for ( uint32 x = 0; x < destWidth; x++ )
+ {
+ // mix colors of left and right pixels and write it back
+ // into the bitmap
+ float xPos = ( (float)x / (float)destWidth ) * (float)fromWidth;
+ uint32 leftIndex = (uint32)floorf( xPos ) * 4;
+ uint32 rightIndex = (uint32)ceilf( xPos ) * 4;
+ rgb_color left;
+ left.red = p[leftIndex + 2];
+ left.green = p[leftIndex + 1];
+ left.blue = p[leftIndex + 0];
+ rgb_color right;
+ right.red = p[rightIndex + 2];
+ right.green = p[rightIndex + 1];
+ right.blue = p[rightIndex + 0];
+ rgb_color mix;
+ mix_colors( left.red, left.green, left.blue,
+ right.red, right.green, right.blue,
+ mix.red, mix.green, mix.blue, xPos - floorf( xPos ) );
+ uint32 destIndex = x * 4;
+ src[destIndex + 2] = mix.red;
+ src[destIndex + 1] = mix.green;
+ src[destIndex + 0] = mix.blue;
+ }
+ src += bpr;
+ }
+ delete[] p;
+ }
+ if ( fromHeight < destHeight )
+ {
+ // scale vertically
+ uint8* src = (uint8*)bitmap->Bits();
+ uint8* p = new uint8[fromHeight * 3]; // temp buffer
+ for ( uint32 x = 0; x < destWidth; x++ )
+ {
+ // copy valid pixels into temp buffer
+ for ( uint32 y = 0; y < fromHeight; y++ )
+ {
+ uint32 destIndex = y * 3;
+ uint32 srcIndex = x * 4 + y * bpr;
+ p[destIndex + 0] = src[srcIndex + 0];
+ p[destIndex + 1] = src[srcIndex + 1];
+ p[destIndex + 2] = src[srcIndex + 2];
+ }
+ // do the scaling
+ for ( uint32 y = 0; y < destHeight; y++ )
+ {
+ // mix colors of upper and lower pixels and write it back
+ // into the bitmap
+ float yPos = ( (float)y / (float)destHeight ) * (float)fromHeight;
+ uint32 upperIndex = (uint32)floorf( yPos ) * 3;
+ uint32 lowerIndex = (uint32)ceilf( yPos ) * 3;
+ rgb_color upper;
+ upper.red = p[upperIndex + 2];
+ upper.green = p[upperIndex + 1];
+ upper.blue = p[upperIndex + 0];
+ rgb_color lower;
+ lower.red = p[lowerIndex + 2];
+ lower.green = p[lowerIndex + 1];
+ lower.blue = p[lowerIndex + 0];
+ rgb_color mix;
+ mix_colors( upper.red, upper.green, upper.blue,
+ lower.red, lower.green, lower.blue,
+ mix.red, mix.green, mix.blue, yPos - floorf( yPos ) );
+ uint32 destIndex = x * 4 + y * bpr;
+ src[destIndex + 2] = mix.red;
+ src[destIndex + 1] = mix.green;
+ src[destIndex + 0] = mix.blue;
+ }
+ }
+ delete[] p;
+ }
+ }
+ }
+ return status;