/*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include <dali/public-api/common/dali-vector.h>
#include <dali/public-api/math/vector2.h>
#include <resampler.h>
+#include <image-loading.h>
// INTERNAL INCLUDES
// Constants used by the ImageResampler.
const float DEFAULT_SOURCE_GAMMA = 1.75f; ///< Default source gamma value used in the Resampler() function. Partial gamma correction looks better on mips. Set to 1.0 to disable gamma correction.
const float FILTER_SCALE = 1.f; ///< Default filter scale value used in the Resampler() function. Filter scale - values < 1.0 cause aliasing, but create sharper looking mips.
-const char* const FILTER_TYPE = "lanczos4"; ///< Default filter used in the Resampler() function. Possible Lanczos filters are: lanczos3, lanczos4, lanczos6, lanczos12
using Integration::Bitmap;
using Integration::BitmapPtr;
DALI_ASSERT_DEBUG( scanline2 && "Null pointer." );
DALI_ASSERT_DEBUG( outputScanline && "Null pointer." );
DALI_ASSERT_DEBUG( ((scanline1 >= scanline2 + widthInComponents) || (scanline2 >= scanline1 + widthInComponents )) && "Scanlines alias." );
- DALI_ASSERT_DEBUG( ((((void*)outputScanline) >= (void*)(scanline2 + widthInComponents)) || (((void*)scanline2) >= (void*)(scanline1 + widthInComponents))) && "Scanline 2 aliases output." );
+ DALI_ASSERT_DEBUG( ((outputScanline >= (scanline2 + widthInComponents)) || (scanline2 >= (scanline1 + widthInComponents))) && "Scanline 2 aliases output." );
}
/**
}
/**
- * @brief Construct a bitmap with format and dimensions requested.
+ * @brief Construct a pixel buffer object from a copy of the pixel array passed in.
*/
-BitmapPtr MakeEmptyBitmap( Pixel::Format pixelFormat, unsigned int width, unsigned int height )
-{
- DALI_ASSERT_DEBUG( Pixel::GetBytesPerPixel(pixelFormat) && "Compressed formats not supported." );
-
- // Allocate a pixel buffer to hold the image passed in:
- Integration::BitmapPtr newBitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::OWNED_DISCARD );
- newBitmap->GetPackedPixelsProfile()->ReserveBuffer( pixelFormat, width, height, width, height );
- return newBitmap;
-}
-
-/**
- * @brief Construct a bitmap object from a copy of the pixel array passed in.
- */
-BitmapPtr MakeBitmap( const uint8_t * const pixels, Pixel::Format pixelFormat, unsigned int width, unsigned int height )
+Dali::Devel::PixelBuffer MakePixelBuffer( const uint8_t * const pixels, Pixel::Format pixelFormat, unsigned int width, unsigned int height )
{
DALI_ASSERT_DEBUG( pixels && "Null bitmap buffer to copy." );
// Allocate a pixel buffer to hold the image passed in:
- Integration::BitmapPtr newBitmap = MakeEmptyBitmap( pixelFormat, width, height );
+ auto newBitmap = Dali::Devel::PixelBuffer::New( width, height, pixelFormat );
// Copy over the pixels from the downscaled image that was generated in-place in the pixel buffer of the input bitmap:
- memcpy( newBitmap->GetBuffer(), pixels, width * height * Pixel::GetBytesPerPixel( pixelFormat ) );
+ memcpy( newBitmap.GetBuffer(), pixels, width * height * Pixel::GetBytesPerPixel( pixelFormat ) );
return newBitmap;
}
*/
ImageDimensions CalculateDesiredDimensions( unsigned int bitmapWidth, unsigned int bitmapHeight, unsigned int requestedWidth, unsigned int requestedHeight )
{
+ unsigned int maxSize = Dali::GetMaxTextureSize();
+
// If no dimensions have been requested, default to the source ones:
if( requestedWidth == 0 && requestedHeight == 0 )
{
- return ImageDimensions( bitmapWidth, bitmapHeight );
+ if( bitmapWidth <= maxSize && bitmapHeight <= maxSize )
+ {
+ return ImageDimensions( bitmapWidth, bitmapHeight );
+ }
+ else
+ {
+ // Calculate the size from the max texture size and the source image aspect ratio
+ if( bitmapWidth > bitmapHeight )
+ {
+ return ImageDimensions( maxSize, bitmapHeight * maxSize / static_cast< float >( bitmapWidth ) + 0.5f );
+ }
+ else
+ {
+ return ImageDimensions( bitmapWidth * maxSize / static_cast< float >( bitmapHeight ) + 0.5f, maxSize );
+ }
+ }
}
// If both dimensions have values requested, use them both:
if( requestedWidth != 0 && requestedHeight != 0 )
{
- return ImageDimensions( requestedWidth, requestedHeight );
+ if( requestedWidth <= maxSize && requestedHeight <= maxSize )
+ {
+ return ImageDimensions( requestedWidth, requestedHeight );
+ }
+ else
+ {
+ // Calculate the size from the max texture size and the source image aspect ratio
+ if( requestedWidth > requestedHeight )
+ {
+ return ImageDimensions( maxSize, requestedHeight * maxSize / static_cast< float >( requestedWidth ) + 0.5f );
+ }
+ else
+ {
+ return ImageDimensions( requestedWidth * maxSize / static_cast< float >( requestedHeight ) + 0.5f, maxSize );
+ }
+ }
}
// Only one of the dimensions has been requested. Calculate the other from
// the requested one and the source image aspect ratio:
if( requestedWidth != 0 )
{
+ requestedWidth = std::min( requestedWidth, maxSize );
return ImageDimensions( requestedWidth, bitmapHeight / float(bitmapWidth) * requestedWidth + 0.5f );
}
+
+ requestedHeight = std::min( requestedHeight, maxSize );
return ImageDimensions( bitmapWidth / float(bitmapHeight) * requestedHeight + 0.5f, requestedHeight );
}
* bitmaps dimensions to only be as large as necessary, as a memory saving optimization. This will cause
* GPU scaling to be performed at render time giving the same result with less texture traversal.
*
- * @param[in] bitmap The source bitmap to perform modifications on.
+ * @param[in] bitmap The source pixel buffer to perform modifications on.
* @param[in] desiredDimensions The target dimensions to aim to fill based on the fitting mode.
* @param[in] fittingMode The fitting mode to use.
*
* @return A new bitmap with the padding and cropping required for fitting mode applied.
* If no modification is needed or possible, the passed in bitmap is returned.
*/
-Integration::BitmapPtr CropAndPadForFittingMode( Integration::BitmapPtr bitmap, ImageDimensions desiredDimensions, FittingMode::Type fittingMode );
+Dali::Devel::PixelBuffer CropAndPadForFittingMode( Dali::Devel::PixelBuffer& bitmap, ImageDimensions desiredDimensions, FittingMode::Type fittingMode );
/**
* @brief Adds horizontal or vertical borders to the source image.
*/
void AddBorders( PixelBuffer *targetPixels, const unsigned int bytesPerPixel, const ImageDimensions targetDimensions, const ImageDimensions padDimensions );
-BitmapPtr ApplyAttributesToBitmap( BitmapPtr bitmap, ImageDimensions dimensions, FittingMode::Type fittingMode, SamplingMode::Type samplingMode )
+Dali::Devel::PixelBuffer ApplyAttributesToBitmap( Dali::Devel::PixelBuffer bitmap, ImageDimensions dimensions, FittingMode::Type fittingMode, SamplingMode::Type samplingMode )
{
if( bitmap )
{
// Calculate the desired box, accounting for a possible zero component:
- const ImageDimensions desiredDimensions = CalculateDesiredDimensions( bitmap->GetImageWidth(), bitmap->GetImageHeight(), dimensions.GetWidth(), dimensions.GetHeight() );
+ const ImageDimensions desiredDimensions = CalculateDesiredDimensions( bitmap.GetWidth(), bitmap.GetHeight(), dimensions.GetWidth(), dimensions.GetHeight() );
// If a different size than the raw one has been requested, resize the image
// maximally using a repeated box filter without making it smaller than the
// requested size in either dimension:
- bitmap = DownscaleBitmap( *bitmap, desiredDimensions, fittingMode, samplingMode );
+ bitmap = DownscaleBitmap( bitmap, desiredDimensions, fittingMode, samplingMode );
// Cut the bitmap according to the desired width and height so that the
// resulting bitmap has the same aspect ratio as the desired dimensions.
// Add crop and add borders if necessary depending on fitting mode.
- if( bitmap && bitmap->GetPackedPixelsProfile() )
+ if( bitmap )
{
bitmap = CropAndPadForFittingMode( bitmap, desiredDimensions, fittingMode );
}
-
- // Examine the image pixels remaining after cropping and scaling to see if all
- // are opaque, allowing faster rendering, or some have non-1.0 alpha:
- if( bitmap && bitmap->GetPackedPixelsProfile() && Pixel::HasAlpha( bitmap->GetPixelFormat() ) )
- {
- bitmap->GetPackedPixelsProfile()->TestForTransparency();
- }
}
return bitmap;
}
-BitmapPtr CropAndPadForFittingMode( BitmapPtr bitmap, ImageDimensions desiredDimensions, FittingMode::Type fittingMode )
+Dali::Devel::PixelBuffer CropAndPadForFittingMode( Dali::Devel::PixelBuffer& bitmap, ImageDimensions desiredDimensions, FittingMode::Type fittingMode )
{
- const unsigned int inputWidth = bitmap->GetImageWidth();
- const unsigned int inputHeight = bitmap->GetImageHeight();
+ const unsigned int inputWidth = bitmap.GetWidth();
+ const unsigned int inputHeight = bitmap.GetHeight();
if( desiredDimensions.GetWidth() < 1u || desiredDimensions.GetHeight() < 1u )
{
return bitmap;
}
- // Create a new bitmap with the desired size.
- BitmapPtr croppedBitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::OWNED_DISCARD );
- Integration::Bitmap::PackedPixelsProfile *packedView = croppedBitmap->GetPackedPixelsProfile();
- DALI_ASSERT_DEBUG( packedView );
- const Pixel::Format pixelFormat = bitmap->GetPixelFormat();
- packedView->ReserveBuffer( pixelFormat, desiredWidth, desiredHeight, desiredWidth, desiredHeight );
+ // Create new PixelBuffer with the desired size.
+ const auto pixelFormat = bitmap.GetPixelFormat();
+
+ auto croppedBitmap = Devel::PixelBuffer::New( desiredWidth, desiredHeight, pixelFormat );
// Add some pre-calculated offsets to the bitmap pointers so this is not done within a loop.
// The cropping is added to the source pointer, and the padding is added to the destination.
- const unsigned int bytesPerPixel = Pixel::GetBytesPerPixel( pixelFormat );
- const PixelBuffer * const sourcePixels = bitmap->GetBuffer() + ( ( ( ( scanlinesToCrop / 2 ) * inputWidth ) + ( columnsToCrop / 2 ) ) * bytesPerPixel );
- PixelBuffer * const targetPixels = croppedBitmap->GetBuffer();
+ const auto bytesPerPixel = Pixel::GetBytesPerPixel( pixelFormat );
+ const PixelBuffer * const sourcePixels = bitmap.GetBuffer() + ( ( ( ( scanlinesToCrop / 2 ) * inputWidth ) + ( columnsToCrop / 2 ) ) * bytesPerPixel );
+ PixelBuffer * const targetPixels = croppedBitmap.GetBuffer();
PixelBuffer * const targetPixelsActive = targetPixels + ( ( ( ( scanlinesToPad / 2 ) * desiredWidth ) + ( columnsToPad / 2 ) ) * bytesPerPixel );
DALI_ASSERT_DEBUG( sourcePixels && targetPixels );
// Add vertical or horizontal borders to the final image (if required).
desiredDimensions.SetWidth( desiredWidth );
desiredDimensions.SetHeight( desiredHeight );
- AddBorders( croppedBitmap->GetBuffer(), bytesPerPixel, desiredDimensions, ImageDimensions( columnsToPad, scanlinesToPad ) );
+ AddBorders( croppedBitmap.GetBuffer(), bytesPerPixel, desiredDimensions, ImageDimensions( columnsToPad, scanlinesToPad ) );
// Overwrite the loaded bitmap with the cropped version
bitmap = croppedBitmap;
}
}
}
-Integration::BitmapPtr DownscaleBitmap( Integration::Bitmap& bitmap,
+Dali::Devel::PixelBuffer DownscaleBitmap( Dali::Devel::PixelBuffer bitmap,
ImageDimensions desired,
FittingMode::Type fittingMode,
SamplingMode::Type samplingMode )
{
// Source dimensions as loaded from resources (e.g. filesystem):
- const unsigned int bitmapWidth = bitmap.GetImageWidth();
- const unsigned int bitmapHeight = bitmap.GetImageHeight();
+ auto bitmapWidth = bitmap.GetWidth();
+ auto bitmapHeight = bitmap.GetHeight();
// Desired dimensions (the rectangle to fit the source image to):
- const unsigned int desiredWidth = desired.GetWidth();
- const unsigned int desiredHeight = desired.GetHeight();
+ auto desiredWidth = desired.GetWidth();
+ auto desiredHeight = desired.GetHeight();
- BitmapPtr outputBitmap( &bitmap );
+ Dali::Devel::PixelBuffer outputBitmap { bitmap };
// If a different size than the raw one has been requested, resize the image:
- if( bitmap.GetPackedPixelsProfile() &&
+ if(
(desiredWidth > 0.0f) && (desiredHeight > 0.0f) &&
((desiredWidth < bitmapWidth) || (desiredHeight < bitmapHeight)) )
{
- const Pixel::Format pixelFormat = bitmap.GetPixelFormat();
+ auto pixelFormat = bitmap.GetPixelFormat();
// Do the fast power of 2 iterated box filter to get to roughly the right side if the filter mode requests that:
unsigned int shrunkWidth = -1, shrunkHeight = -1;
if( samplingMode == SamplingMode::LINEAR || samplingMode == SamplingMode::BOX_THEN_LINEAR ||
samplingMode == SamplingMode::NEAREST || samplingMode == SamplingMode::BOX_THEN_NEAREST )
{
- outputBitmap = MakeEmptyBitmap( pixelFormat, filteredWidth, filteredHeight );
+ outputBitmap = Dali::Devel::PixelBuffer::New( filteredWidth, filteredHeight, pixelFormat );
+
if( outputBitmap )
{
if( samplingMode == SamplingMode::LINEAR || samplingMode == SamplingMode::BOX_THEN_LINEAR )
{
- LinearSample( bitmap.GetBuffer(), ImageDimensions(shrunkWidth, shrunkHeight), pixelFormat, outputBitmap->GetBuffer(), filteredDimensions );
+ LinearSample( bitmap.GetBuffer(), ImageDimensions(shrunkWidth, shrunkHeight), pixelFormat, outputBitmap.GetBuffer(), filteredDimensions );
}
else
{
- PointSample( bitmap.GetBuffer(), shrunkWidth, shrunkHeight, pixelFormat, outputBitmap->GetBuffer(), filteredWidth, filteredHeight );
+ PointSample( bitmap.GetBuffer(), shrunkWidth, shrunkHeight, pixelFormat, outputBitmap.GetBuffer(), filteredWidth, filteredHeight );
}
filtered = true;
}
// Copy out the 2^x downscaled, box-filtered pixels if no secondary filter (point or linear) was applied:
if( filtered == false && ( shrunkWidth < bitmapWidth || shrunkHeight < bitmapHeight ) )
{
- outputBitmap = MakeBitmap( bitmap.GetBuffer(), pixelFormat, shrunkWidth, shrunkHeight );
+ outputBitmap = MakePixelBuffer( bitmap.GetBuffer(), pixelFormat, shrunkWidth, shrunkHeight );
}
}
DALI_ASSERT_DEBUG( ((desiredWidth <= inputWidth && desiredHeight <= inputHeight) ||
outPixels >= inPixels + inputWidth * inputHeight * sizeof(PIXEL) || outPixels <= inPixels - desiredWidth * desiredHeight * sizeof(PIXEL)) &&
"The input and output buffers must not overlap for an upscaling.");
- DALI_ASSERT_DEBUG( ((uint64_t) inPixels) % sizeof(PIXEL) == 0 && "Pixel pointers need to be aligned to the size of the pixels (E.g., 4 bytes for RGBA, 2 bytes for RGB565, ...)." );
- DALI_ASSERT_DEBUG( ((uint64_t) outPixels) % sizeof(PIXEL) == 0 && "Pixel pointers need to be aligned to the size of the pixels (E.g., 4 bytes for RGBA, 2 bytes for RGB565, ...)." );
+ DALI_ASSERT_DEBUG( reinterpret_cast< uint64_t >( inPixels ) % sizeof(PIXEL) == 0 && "Pixel pointers need to be aligned to the size of the pixels (E.g., 4 bytes for RGBA, 2 bytes for RGB565, ...)." );
+ DALI_ASSERT_DEBUG( reinterpret_cast< uint64_t >( outPixels ) % sizeof(PIXEL) == 0 && "Pixel pointers need to be aligned to the size of the pixels (E.g., 4 bytes for RGBA, 2 bytes for RGB565, ...)." );
if( inputWidth < 1u || inputHeight < 1u || desiredWidth < 1u || desiredHeight < 1u )
{
"Input and output buffers cannot overlap.");
if( DEBUG_ASSERT_ALIGNMENT )
{
- DALI_ASSERT_DEBUG( ((uint64_t) inPixels) % sizeof(PIXEL) == 0 && "Pixel pointers need to be aligned to the size of the pixels (E.g., 4 bytes for RGBA, 2 bytes for RGB565, ...)." );
- DALI_ASSERT_DEBUG( ((uint64_t) outPixels) % sizeof(PIXEL) == 0 && "Pixel pointers need to be aligned to the size of the pixels (E.g., 4 bytes for RGBA, 2 bytes for RGB565, ...)." );
+ DALI_ASSERT_DEBUG( reinterpret_cast< uint64_t >( inPixels ) % sizeof(PIXEL) == 0 && "Pixel pointers need to be aligned to the size of the pixels (E.g., 4 bytes for RGBA, 2 bytes for RGB565, ...)." );
+ DALI_ASSERT_DEBUG( reinterpret_cast< uint64_t >( outPixels) % sizeof(PIXEL) == 0 && "Pixel pointers need to be aligned to the size of the pixels (E.g., 4 bytes for RGBA, 2 bytes for RGB565, ...)." );
}
if( inputWidth < 1u || inputHeight < 1u || desiredWidth < 1u || desiredHeight < 1u )
LinearSampleGeneric<Pixel4Bytes, BilinearFilter4Bytes, true>( inPixels, inputDimensions, outPixels, desiredDimensions );
}
-void LanczosSample4BPP( const unsigned char * __restrict__ inPixels,
- ImageDimensions inputDimensions,
- unsigned char * __restrict__ outPixels,
- ImageDimensions desiredDimensions )
+
+void Resample( const unsigned char * __restrict__ inPixels,
+ ImageDimensions inputDimensions,
+ unsigned char * __restrict__ outPixels,
+ ImageDimensions desiredDimensions,
+ Resampler::Filter filterType,
+ int numChannels, bool hasAlpha )
{
// Got from the test.cpp of the ImageResampler lib.
const float ONE_DIV_255 = 1.0f / 255.0f;
const int MAX_UNSIGNED_CHAR = std::numeric_limits<uint8_t>::max();
const int LINEAR_TO_SRGB_TABLE_SIZE = 4096;
- const int ALPHA_CHANNEL = 3;
- const int NUMBER_OF_CHANNELS = 4;
+ const int ALPHA_CHANNEL = hasAlpha ? (numChannels-1) : 0;
- float srgbToLinear[MAX_UNSIGNED_CHAR + 1];
- for( int i = 0; i <= MAX_UNSIGNED_CHAR; ++i )
- {
- srgbToLinear[i] = pow( static_cast<float>( i ) * ONE_DIV_255, DEFAULT_SOURCE_GAMMA );
- }
-
- unsigned char linearToSrgb[LINEAR_TO_SRGB_TABLE_SIZE];
-
- const float invLinearToSrgbTableSize = 1.0f / static_cast<float>( LINEAR_TO_SRGB_TABLE_SIZE );
- const float invSourceGamma = 1.0f / DEFAULT_SOURCE_GAMMA;
+ static bool loadColorSpaces = true;
+ static float srgbToLinear[MAX_UNSIGNED_CHAR + 1];
+ static unsigned char linearToSrgb[LINEAR_TO_SRGB_TABLE_SIZE];
- for( int i = 0; i < LINEAR_TO_SRGB_TABLE_SIZE; ++i )
+ if( loadColorSpaces ) // Only create the color space conversions on the first execution
{
- int k = static_cast<int>( 255.0f * pow( static_cast<float>( i ) * invLinearToSrgbTableSize, invSourceGamma ) + 0.5f );
- if( k < 0 )
+ loadColorSpaces = false;
+
+ for( int i = 0; i <= MAX_UNSIGNED_CHAR; ++i )
{
- k = 0;
+ srgbToLinear[i] = pow( static_cast<float>( i ) * ONE_DIV_255, DEFAULT_SOURCE_GAMMA );
}
- else if( k > MAX_UNSIGNED_CHAR )
+
+ const float invLinearToSrgbTableSize = 1.0f / static_cast<float>( LINEAR_TO_SRGB_TABLE_SIZE );
+ const float invSourceGamma = 1.0f / DEFAULT_SOURCE_GAMMA;
+
+ for( int i = 0; i < LINEAR_TO_SRGB_TABLE_SIZE; ++i )
{
- k = MAX_UNSIGNED_CHAR;
+ int k = static_cast<int>( 255.0f * pow( static_cast<float>( i ) * invLinearToSrgbTableSize, invSourceGamma ) + 0.5f );
+ if( k < 0 )
+ {
+ k = 0;
+ }
+ else if( k > MAX_UNSIGNED_CHAR )
+ {
+ k = MAX_UNSIGNED_CHAR;
+ }
+ linearToSrgb[i] = static_cast<unsigned char>( k );
}
- linearToSrgb[i] = static_cast<unsigned char>( k );
}
- Resampler* resamplers[NUMBER_OF_CHANNELS] = { 0 };
- Vector<float> samples[NUMBER_OF_CHANNELS];
+ Resampler* resamplers[numChannels];
+ Vector<float> samples[numChannels];
const int srcWidth = inputDimensions.GetWidth();
const int srcHeight = inputDimensions.GetHeight();
Resampler::BOUNDARY_CLAMP,
0.0f, // sample_low,
1.0f, // sample_high. Clamp output samples to specified range, or disable clamping if sample_low >= sample_high.
- FILTER_TYPE, // The type of filter. Currently Lanczos.
+ filterType, // The type of filter.
NULL, // Pclist_x,
NULL, // Pclist_y. Optional pointers to contributor lists from another instance of a Resampler.
FILTER_SCALE, // src_x_ofs,
FILTER_SCALE ); // src_y_ofs. Offset input image by specified amount (fractional values okay).
samples[0].Resize( srcWidth );
- for( int i = 1; i < NUMBER_OF_CHANNELS; ++i )
+ for( int i = 1; i < numChannels; ++i )
{
resamplers[i] = new Resampler( srcWidth,
srcHeight,
Resampler::BOUNDARY_CLAMP,
0.0f,
1.0f,
- FILTER_TYPE,
+ filterType,
resamplers[0]->get_clist_x(),
resamplers[0]->get_clist_y(),
FILTER_SCALE,
samples[i].Resize( srcWidth );
}
- const int srcPitch = srcWidth * NUMBER_OF_CHANNELS;
- const int dstPitch = dstWidth * NUMBER_OF_CHANNELS;
+ const int srcPitch = srcWidth * numChannels;
+ const int dstPitch = dstWidth * numChannels;
int dstY = 0;
for( int srcY = 0; srcY < srcHeight; ++srcY )
for( int x = 0; x < srcWidth; ++x )
{
- for( int c = 0; c < NUMBER_OF_CHANNELS; ++c )
+ for( int c = 0; c < numChannels; ++c )
{
- if( c == ALPHA_CHANNEL )
+ if( c == ALPHA_CHANNEL && hasAlpha )
{
samples[c][x] = *pSrc++ * ONE_DIV_255;
}
}
}
- for( int c = 0; c < NUMBER_OF_CHANNELS; ++c )
+ for( int c = 0; c < numChannels; ++c )
{
if( !resamplers[c]->put_line( &samples[c][0] ) )
{
for(;;)
{
int compIndex;
- for( compIndex = 0; compIndex < NUMBER_OF_CHANNELS; ++compIndex )
+ for( compIndex = 0; compIndex < numChannels; ++compIndex )
{
const float* pOutputSamples = resamplers[compIndex]->get_line();
if( !pOutputSamples )
break;
}
- const bool isAlphaChannel = ( compIndex == ALPHA_CHANNEL );
+ const bool isAlphaChannel = ( compIndex == ALPHA_CHANNEL && hasAlpha );
DALI_ASSERT_DEBUG( dstY < dstHeight );
unsigned char* pDst = &outPixels[dstY * dstPitch + compIndex];
*pDst = linearToSrgb[j];
}
- pDst += NUMBER_OF_CHANNELS;
+ pDst += numChannels;
}
}
- if( compIndex < NUMBER_OF_CHANNELS )
+ if( compIndex < numChannels )
{
break;
}
}
// Delete the resamplers.
- for( int i = 0; i < NUMBER_OF_CHANNELS; ++i )
+ for( int i = 0; i < numChannels; ++i )
{
delete resamplers[i];
}
}
+void LanczosSample4BPP( const unsigned char * __restrict__ inPixels,
+ ImageDimensions inputDimensions,
+ unsigned char * __restrict__ outPixels,
+ ImageDimensions desiredDimensions )
+{
+ Resample( inPixels, inputDimensions, outPixels, desiredDimensions, Resampler::LANCZOS4, 4, true );
+}
+
+void LanczosSample1BPP( const unsigned char * __restrict__ inPixels,
+ ImageDimensions inputDimensions,
+ unsigned char * __restrict__ outPixels,
+ ImageDimensions desiredDimensions )
+{
+ // For L8 images
+ Resample( inPixels, inputDimensions, outPixels, desiredDimensions, Resampler::LANCZOS4, 1, false );
+}
+
// Dispatch to a format-appropriate linear sampling function:
void LinearSample( const unsigned char * __restrict__ inPixels,
ImageDimensions inDimensions,