1db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra/* 2db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra * Copyright (C) 2010 The Android Open Source Project 3db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra * 4db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra * Licensed under the Apache License, Version 2.0 (the "License"); 5db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra * you may not use this file except in compliance with the License. 6db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra * You may obtain a copy of the License at 7db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra * 8db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra * http://www.apache.org/licenses/LICENSE-2.0 9db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra * 10db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra * Unless required by applicable law or agreed to in writing, software 11db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra * distributed under the License is distributed on an "AS IS" BASIS, 12db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra * See the License for the specific language governing permissions and 14db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra * limitations under the License. 15db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra */ 16db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 17db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra#define LOG_NDEBUG 0 18db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra#define LOG_TAG "YUVCanvas" 19db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 20f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong#include <media/stagefright/foundation/ADebug.h> 21db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra#include <media/stagefright/YUVCanvas.h> 22db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra#include <media/stagefright/YUVImage.h> 23db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra#include <ui/Rect.h> 24db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 25db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatranamespace android { 26db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 27db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun KwatraYUVCanvas::YUVCanvas(YUVImage &yuvImage) 28db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra : mYUVImage(yuvImage) { 29db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra} 30db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 31db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun KwatraYUVCanvas::~YUVCanvas() { 32db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra} 33db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 34db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatravoid YUVCanvas::FillYUV(uint8_t yValue, uint8_t uValue, uint8_t vValue) { 35db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra for (int32_t y = 0; y < mYUVImage.height(); ++y) { 36db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra for (int32_t x = 0; x < mYUVImage.width(); ++x) { 37db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra mYUVImage.setPixelValue(x, y, yValue, uValue, vValue); 38db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra } 39db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra } 40db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra} 41db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 42db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatravoid YUVCanvas::FillYUVRectangle(const Rect& rect, 43db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra uint8_t yValue, uint8_t uValue, uint8_t vValue) { 44db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra for (int32_t y = rect.top; y < rect.bottom; ++y) { 45db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra for (int32_t x = rect.left; x < rect.right; ++x) { 46db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra mYUVImage.setPixelValue(x, y, yValue, uValue, vValue); 47db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra } 48db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra } 49db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra} 50db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 51db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatravoid YUVCanvas::CopyImageRect( 52db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra const Rect& srcRect, 53db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra int32_t destStartX, int32_t destStartY, 54db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra const YUVImage &srcImage) { 55db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 56db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra // Try fast copy first 57db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra if (YUVImage::fastCopyRectangle( 58db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra srcRect, 59db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra destStartX, destStartY, 60db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra srcImage, mYUVImage)) { 61db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra return; 62db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra } 63db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 64db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra int32_t srcStartX = srcRect.left; 65db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra int32_t srcStartY = srcRect.top; 66db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra for (int32_t offsetY = 0; offsetY < srcRect.height(); ++offsetY) { 67db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra for (int32_t offsetX = 0; offsetX < srcRect.width(); ++offsetX) { 68db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra int32_t srcX = srcStartX + offsetX; 69db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra int32_t srcY = srcStartY + offsetY; 70db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 71db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra int32_t destX = destStartX + offsetX; 72db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra int32_t destY = destStartY + offsetY; 73db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 74db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra uint8_t yValue; 75db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra uint8_t uValue; 76db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra uint8_t vValue; 77db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 78c0d936ddacc4f7d883f3bd1dd8099586836c820fNipun Kwatra srcImage.getPixelValue(srcX, srcY, &yValue, &uValue, &vValue); 79db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra mYUVImage.setPixelValue(destX, destY, yValue, uValue, vValue); 80db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra } 81db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra } 82db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra} 83db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra 84c0d936ddacc4f7d883f3bd1dd8099586836c820fNipun Kwatravoid YUVCanvas::downsample( 85c0d936ddacc4f7d883f3bd1dd8099586836c820fNipun Kwatra int32_t srcOffsetX, int32_t srcOffsetY, 86c0d936ddacc4f7d883f3bd1dd8099586836c820fNipun Kwatra int32_t skipX, int32_t skipY, 87c0d936ddacc4f7d883f3bd1dd8099586836c820fNipun Kwatra const YUVImage &srcImage) { 88c0d936ddacc4f7d883f3bd1dd8099586836c820fNipun Kwatra // TODO: Add a low pass filter for downsampling. 89c0d936ddacc4f7d883f3bd1dd8099586836c820fNipun Kwatra 90c0d936ddacc4f7d883f3bd1dd8099586836c820fNipun Kwatra // Check that srcImage is big enough to fill mYUVImage. 91c0d936ddacc4f7d883f3bd1dd8099586836c820fNipun Kwatra CHECK((srcOffsetX + (mYUVImage.width() - 1) * skipX) < srcImage.width()); 92c0d936ddacc4f7d883f3bd1dd8099586836c820fNipun Kwatra CHECK((srcOffsetY + (mYUVImage.height() - 1) * skipY) < srcImage.height()); 93c0d936ddacc4f7d883f3bd1dd8099586836c820fNipun Kwatra 94c0d936ddacc4f7d883f3bd1dd8099586836c820fNipun Kwatra uint8_t yValue; 95c0d936ddacc4f7d883f3bd1dd8099586836c820fNipun Kwatra uint8_t uValue; 96c0d936ddacc4f7d883f3bd1dd8099586836c820fNipun Kwatra uint8_t vValue; 97c0d936ddacc4f7d883f3bd1dd8099586836c820fNipun Kwatra 98c0d936ddacc4f7d883f3bd1dd8099586836c820fNipun Kwatra int32_t srcY = srcOffsetY; 99c0d936ddacc4f7d883f3bd1dd8099586836c820fNipun Kwatra for (int32_t y = 0; y < mYUVImage.height(); ++y) { 100c0d936ddacc4f7d883f3bd1dd8099586836c820fNipun Kwatra int32_t srcX = srcOffsetX; 101c0d936ddacc4f7d883f3bd1dd8099586836c820fNipun Kwatra for (int32_t x = 0; x < mYUVImage.width(); ++x) { 102c0d936ddacc4f7d883f3bd1dd8099586836c820fNipun Kwatra srcImage.getPixelValue(srcX, srcY, &yValue, &uValue, &vValue); 103c0d936ddacc4f7d883f3bd1dd8099586836c820fNipun Kwatra mYUVImage.setPixelValue(x, y, yValue, uValue, vValue); 104c0d936ddacc4f7d883f3bd1dd8099586836c820fNipun Kwatra 105c0d936ddacc4f7d883f3bd1dd8099586836c820fNipun Kwatra srcX += skipX; 106c0d936ddacc4f7d883f3bd1dd8099586836c820fNipun Kwatra } 107c0d936ddacc4f7d883f3bd1dd8099586836c820fNipun Kwatra srcY += skipY; 108c0d936ddacc4f7d883f3bd1dd8099586836c820fNipun Kwatra } 109c0d936ddacc4f7d883f3bd1dd8099586836c820fNipun Kwatra} 110c0d936ddacc4f7d883f3bd1dd8099586836c820fNipun Kwatra 111db205a1d75c1e9a7d0dbd8fa011335249ad6f4acNipun Kwatra} // namespace android 112