14aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy/* 24aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * Copyright (C) 2010 The Android Open Source Project 34aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * 44aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * Licensed under the Apache License, Version 2.0 (the "License"); 54aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * you may not use this file except in compliance with the License. 64aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * You may obtain a copy of the License at 74aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * 84aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * http://www.apache.org/licenses/LICENSE-2.0 94aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * 104aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * Unless required by applicable law or agreed to in writing, software 114aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * distributed under the License is distributed on an "AS IS" BASIS, 124aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * See the License for the specific language governing permissions and 144aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * limitations under the License. 154aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy */ 164aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy 175b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy#define LOG_NDEBUG 0 185b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy#define LOG_TAG "YUVCanvas" 194aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy 209fded232a9548a304e0145011df8849fba0dcda7Chris Craik#include <media/stagefright/foundation/ADebug.h> 219fded232a9548a304e0145011df8849fba0dcda7Chris Craik#include <media/stagefright/YUVCanvas.h> 229fded232a9548a304e0145011df8849fba0dcda7Chris Craik#include <media/stagefright/YUVImage.h> 239fded232a9548a304e0145011df8849fba0dcda7Chris Craik#include <ui/Rect.h> 249fded232a9548a304e0145011df8849fba0dcda7Chris Craik 259fded232a9548a304e0145011df8849fba0dcda7Chris Craiknamespace android { 269fded232a9548a304e0145011df8849fba0dcda7Chris Craik 279fded232a9548a304e0145011df8849fba0dcda7Chris CraikYUVCanvas::YUVCanvas(YUVImage &yuvImage) 2809c2d4fe15fbac2faf8a97ba2cc59132ee12222aDerek Sollenberger : mYUVImage(yuvImage) { 294aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy} 304aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy 314aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain GuyYUVCanvas::~YUVCanvas() { 322dc236b2bae13b9a0ed9b3f7320502aecd7983b3Tom Hudson} 3309c2d4fe15fbac2faf8a97ba2cc59132ee12222aDerek Sollenberger 347953745dd565167113f8cbfc461bc0521d32d870Romain Guyvoid YUVCanvas::FillYUV(uint8_t yValue, uint8_t uValue, uint8_t vValue) { 357953745dd565167113f8cbfc461bc0521d32d870Romain Guy for (int32_t y = 0; y < mYUVImage.height(); ++y) { 364aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy for (int32_t x = 0; x < mYUVImage.width(); ++x) { 374aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy mYUVImage.setPixelValue(x, y, yValue, uValue, vValue); 384aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy } 394aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy } 404aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy} 414aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy 424aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guyvoid YUVCanvas::FillYUVRectangle(const Rect& rect, 43ffac7fc5042296a459d0f5a450dbfe20917093dcRomain Guy uint8_t yValue, uint8_t uValue, uint8_t vValue) { 44ffac7fc5042296a459d0f5a450dbfe20917093dcRomain Guy for (int32_t y = rect.top; y < rect.bottom; ++y) { 455baa3a62a97544669fba6d65a11c07f252e654ddSteve Block for (int32_t x = rect.left; x < rect.right; ++x) { 46ffac7fc5042296a459d0f5a450dbfe20917093dcRomain Guy mYUVImage.setPixelValue(x, y, yValue, uValue, vValue); 47ffac7fc5042296a459d0f5a450dbfe20917093dcRomain Guy } 48ffac7fc5042296a459d0f5a450dbfe20917093dcRomain Guy } 49ffac7fc5042296a459d0f5a450dbfe20917093dcRomain Guy} 504aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy 51b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guyvoid YUVCanvas::CopyImageRect( 524aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy const Rect& srcRect, 534aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy int32_t destStartX, int32_t destStartY, 54c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik const YUVImage &srcImage) { 5512f5e3433226f0a2886a98b0b8da8d5e947c5cdeJohn Reck 562af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik // Try fast copy first 572af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik if (YUVImage::fastCopyRectangle( 588d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik srcRect, 592dc236b2bae13b9a0ed9b3f7320502aecd7983b3Tom Hudson destStartX, destStartY, 602af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik srcImage, mYUVImage)) { 612af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik return; 62b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy } 63d6b65f67717025b1162f86f04e2caa5723566cacChris Craik 64b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy int32_t srcStartX = srcRect.left; 65db663fe83f976107fd8fd9307d871b37d9e47370Chris Craik int32_t srcStartY = srcRect.top; 66b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy for (int32_t offsetY = 0; offsetY < srcRect.height(); ++offsetY) { 67cc882b6518129a11fa007f8c9343e972f03607b4Derek Sollenberger for (int32_t offsetX = 0; offsetX < srcRect.width(); ++offsetX) { 68db663fe83f976107fd8fd9307d871b37d9e47370Chris Craik int32_t srcX = srcStartX + offsetX; 69b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy int32_t srcY = srcStartY + offsetY; 70cc882b6518129a11fa007f8c9343e972f03607b4Derek Sollenberger 719fded232a9548a304e0145011df8849fba0dcda7Chris Craik int32_t destX = destStartX + offsetX; 725977baa1fa24125c148a72699b53e62abaf08960Chet Haase int32_t destY = destStartY + offsetY; 7314e513058ed4168c94e015638d16f5f87fd8063aChris Craik 748dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson uint8_t yValue; 7514e513058ed4168c94e015638d16f5f87fd8063aChris Craik uint8_t uValue; 76984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson uint8_t vValue; 77cc882b6518129a11fa007f8c9343e972f03607b4Derek Sollenberger 784aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy srcImage.getPixelValue(srcX, srcY, &yValue, &uValue, &vValue); 7914e513058ed4168c94e015638d16f5f87fd8063aChris Craik mYUVImage.setPixelValue(destX, destY, yValue, uValue, vValue); 808dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson } 8114e513058ed4168c94e015638d16f5f87fd8063aChris Craik } 8214e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 8314e513058ed4168c94e015638d16f5f87fd8063aChris Craik 848dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudsonvoid YUVCanvas::downsample( 85072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi int32_t srcOffsetX, int32_t srcOffsetY, 86072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi int32_t skipX, int32_t skipY, 87072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi const YUVImage &srcImage) { 888dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson // TODO: Add a low pass filter for downsampling. 8952244fff29042926e21fa897ef5ab11148e35299John Reck 9014e513058ed4168c94e015638d16f5f87fd8063aChris Craik // Check that srcImage is big enough to fill mYUVImage. 914aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy CHECK((srcOffsetX + (mYUVImage.width() - 1) * skipX) < srcImage.width()); 9214e513058ed4168c94e015638d16f5f87fd8063aChris Craik CHECK((srcOffsetY + (mYUVImage.height() - 1) * skipY) < srcImage.height()); 938dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson 9414e513058ed4168c94e015638d16f5f87fd8063aChris Craik uint8_t yValue; 953aadd60521960be063ee06208562ccb63dc414e3Chris Craik uint8_t uValue; 96956f340aacc7d8fc2d10f776551f13fde2d8d3abChris Craik uint8_t vValue; 974aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy 9814e513058ed4168c94e015638d16f5f87fd8063aChris Craik int32_t srcY = srcOffsetY; 99956f340aacc7d8fc2d10f776551f13fde2d8d3abChris Craik for (int32_t y = 0; y < mYUVImage.height(); ++y) { 1005ff9df658230d49e42c43586997a02d8e4dd417eRomain Guy int32_t srcX = srcOffsetX; 101984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson for (int32_t x = 0; x < mYUVImage.width(); ++x) { 1028dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson srcImage.getPixelValue(srcX, srcY, &yValue, &uValue, &vValue); 103984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson mYUVImage.setPixelValue(x, y, yValue, uValue, vValue); 104e84a208317e0ed388fcdad1e6743c7849acb51b0Chris Craik 105e84a208317e0ed388fcdad1e6743c7849acb51b0Chris Craik srcX += skipX; 1066b109c74982033d4a220cd10a0eab8b024b351c9Chris Craik } 107984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson srcY += skipY; 1088dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson } 1098dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson} 1108dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson 1111db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger} // namespace android 1121db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger