X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=platform-abstractions%2Fportable%2Fimage-operations.cpp;h=a1408cea6e872ca8999cf005df5367e5f5a4f064;hb=0e18992346b92b3951f71616ffe18230ff79b3b3;hp=e8c47d63c91f26d4ce853df138b9e6b1396fa776;hpb=48f616cfd9c078b2101879837ca31595e98605c1;p=platform%2Fcore%2Fuifw%2Fdali-adaptor.git diff --git a/platform-abstractions/portable/image-operations.cpp b/platform-abstractions/portable/image-operations.cpp index e8c47d6..a1408ce 100644 --- a/platform-abstractions/portable/image-operations.cpp +++ b/platform-abstractions/portable/image-operations.cpp @@ -411,30 +411,17 @@ void CalculateBordersFromFittingMode( ImageDimensions sourceSize, FittingMode:: } /** - * @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; } @@ -454,13 +441,43 @@ ImageDimensions CalculateDesiredDimensions( unsigned int bitmapWidth, unsigned i // If no dimensions have been requested, default to the source ones: if( requestedWidth == 0 && requestedHeight == 0 ) { - return ImageDimensions( std::min( bitmapWidth, maxSize ), std::min( bitmapHeight, maxSize ) ); + 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( std::min( requestedWidth, maxSize ), std::min( requestedHeight, maxSize ) ); + 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 @@ -495,14 +512,14 @@ ImageDimensions CalculateDesiredDimensions( ImageDimensions rawDimensions, Image * 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. @@ -514,41 +531,34 @@ Integration::BitmapPtr CropAndPadForFittingMode( Integration::BitmapPtr bitmap, */ 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 ) { @@ -593,18 +603,16 @@ BitmapPtr CropAndPadForFittingMode( BitmapPtr bitmap, ImageDimensions desiredDim 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 ); @@ -632,7 +640,7 @@ BitmapPtr CropAndPadForFittingMode( BitmapPtr bitmap, ImageDimensions desiredDim // 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; } @@ -689,26 +697,26 @@ void AddBorders( PixelBuffer *targetPixels, const unsigned int bytesPerPixel, co } } -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; @@ -726,16 +734,17 @@ Integration::BitmapPtr DownscaleBitmap( Integration::Bitmap& bitmap, 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; } @@ -744,7 +753,7 @@ Integration::BitmapPtr DownscaleBitmap( Integration::Bitmap& bitmap, // 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 ); } }