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