mirror of
https://github.com/zhigang1992/libpag.git
synced 2026-01-12 22:48:25 +08:00
313 lines
12 KiB
C++
313 lines
12 KiB
C++
/////////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Tencent is pleased to support the open source community by making libpag available.
|
|
//
|
|
// Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
|
|
// except in compliance with the License. You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// unless required by applicable law or agreed to in writing, software distributed under the
|
|
// license is distributed on an "as is" basis, without warranties or conditions of any kind,
|
|
// either express or implied. see the license for the specific language governing permissions
|
|
// and limitations under the license.
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include <fstream>
|
|
#include <vector>
|
|
#include "framework/pag_test.h"
|
|
#include "framework/utils/PAGTestUtils.h"
|
|
#include "gpu/Surface.h"
|
|
#include "gpu/opengl/GLUtil.h"
|
|
#include "image/Image.h"
|
|
#include "image/PixelMap.h"
|
|
#include "nlohmann/json.hpp"
|
|
#include "platform/NativeGLDevice.h"
|
|
|
|
namespace pag {
|
|
using nlohmann::json;
|
|
|
|
#define CHECK_PIXELS(info, pixels, key) \
|
|
{ \
|
|
PixelMap pm(info, pixels); \
|
|
auto md5 = DumpMD5(pm); \
|
|
outputJson[key] = md5; \
|
|
TraceIf(pm, "../test/out/" + std::string(key) + ".png", compareJson[key] != md5); \
|
|
EXPECT_EQ(compareJson[key].get<std::string>(), md5); \
|
|
}
|
|
|
|
/**
|
|
* 用例描述: 像素格式转换相关功能测试-PixelMap
|
|
*/
|
|
PAG_TEST(ReadPixelsTest, TestPixelMap) {
|
|
auto image = Image::MakeFrom("../resources/apitest/test_timestretch.png");
|
|
EXPECT_TRUE(image != nullptr);
|
|
auto width = image->width();
|
|
auto height = image->height();
|
|
auto RGBAInfo = ImageInfo::Make(width, height, ColorType::RGBA_8888, AlphaType::Unpremultiplied);
|
|
auto byteSize = RGBAInfo.byteSize();
|
|
auto pixelsA = new uint8_t[byteSize];
|
|
auto pixelsB = new uint8_t[byteSize];
|
|
auto result = image->readPixels(RGBAInfo, pixelsA);
|
|
EXPECT_TRUE(result);
|
|
|
|
json compareJson = PAGTestEnvironment::CompareJson["PixelMapTest"];
|
|
json outputJson = {};
|
|
|
|
PixelMap RGBAMap(RGBAInfo, pixelsA);
|
|
CHECK_PIXELS(RGBAInfo, pixelsA, "PixelMap_RGBA_Original");
|
|
|
|
result = RGBAMap.readPixels(RGBAInfo, pixelsB);
|
|
EXPECT_TRUE(result);
|
|
CHECK_PIXELS(RGBAInfo, pixelsB, "PixelMap_RGBA_to_RGBA");
|
|
|
|
memset(pixelsB, 0, RGBAInfo.byteSize());
|
|
result = RGBAMap.readPixels(RGBAInfo, pixelsB, 100, 100);
|
|
ASSERT_TRUE(result);
|
|
CHECK_PIXELS(RGBAInfo, pixelsB, "PixelMap_RGBA_to_RGBA_100_100");
|
|
|
|
auto RGBARectInfo = ImageInfo::Make(500, 500, ColorType::RGBA_8888, AlphaType::Premultiplied);
|
|
memset(pixelsB, 0, RGBARectInfo.byteSize());
|
|
result = RGBAMap.readPixels(RGBARectInfo, pixelsB, -100, -100);
|
|
ASSERT_TRUE(result);
|
|
CHECK_PIXELS(RGBARectInfo, pixelsB, "PixelMap_RGBA_to_RGBA_-100_-100");
|
|
|
|
memset(pixelsB, 0, RGBARectInfo.byteSize());
|
|
result = RGBAMap.readPixels(RGBARectInfo, pixelsB, 100, -100);
|
|
ASSERT_TRUE(result);
|
|
CHECK_PIXELS(RGBARectInfo, pixelsB, "PixelMap_RGBA_to_RGBA_100_-100");
|
|
|
|
auto rgbAInfo = RGBAInfo.makeAlphaType(AlphaType::Premultiplied);
|
|
result = RGBAMap.readPixels(rgbAInfo, pixelsB);
|
|
EXPECT_TRUE(result);
|
|
CHECK_PIXELS(rgbAInfo, pixelsB, "PixelMap_RGBA_to_rgbA");
|
|
|
|
auto bgrAInfo = rgbAInfo.makeColorType(ColorType::BGRA_8888);
|
|
result = RGBAMap.readPixels(bgrAInfo, pixelsB);
|
|
EXPECT_TRUE(result);
|
|
CHECK_PIXELS(bgrAInfo, pixelsB, "PixelMap_RGBA_to_bgrA");
|
|
|
|
auto BGRAInfo = bgrAInfo.makeAlphaType(AlphaType::Unpremultiplied);
|
|
result = RGBAMap.readPixels(BGRAInfo, pixelsB);
|
|
EXPECT_TRUE(result);
|
|
CHECK_PIXELS(BGRAInfo, pixelsB, "PixelMap_RGBA_to_BGRA");
|
|
|
|
PixelMap BGRAMap(BGRAInfo, pixelsB);
|
|
|
|
result = BGRAMap.readPixels(BGRAInfo, pixelsA);
|
|
EXPECT_TRUE(result);
|
|
CHECK_PIXELS(BGRAInfo, pixelsA, "PixelMap_BGRA_to_BGRA");
|
|
|
|
result = BGRAMap.readPixels(RGBAInfo, pixelsA);
|
|
EXPECT_TRUE(result);
|
|
CHECK_PIXELS(RGBAInfo, pixelsA, "PixelMap_BGRA_to_RGBA");
|
|
|
|
result = BGRAMap.readPixels(rgbAInfo, pixelsA);
|
|
EXPECT_TRUE(result);
|
|
CHECK_PIXELS(rgbAInfo, pixelsA, "PixelMap_BGRA_to_rgbA");
|
|
|
|
PixelMap rgbAMap(rgbAInfo, pixelsA);
|
|
|
|
result = rgbAMap.readPixels(RGBAInfo, pixelsB);
|
|
EXPECT_TRUE(result);
|
|
CHECK_PIXELS(RGBAInfo, pixelsB, "PixelMap_rgbA_to_RGBA");
|
|
|
|
result = rgbAMap.readPixels(BGRAInfo, pixelsB);
|
|
EXPECT_TRUE(result);
|
|
CHECK_PIXELS(BGRAInfo, pixelsB, "PixelMap_rgbA_to_BGRA");
|
|
|
|
result = rgbAMap.readPixels(bgrAInfo, pixelsB);
|
|
EXPECT_TRUE(result);
|
|
CHECK_PIXELS(bgrAInfo, pixelsB, "PixelMap_rgbA_to_bgrA");
|
|
|
|
auto A8Info = ImageInfo::Make(width, height, ColorType::ALPHA_8, AlphaType::Unpremultiplied);
|
|
EXPECT_EQ(A8Info.alphaType(), AlphaType::Premultiplied);
|
|
auto alphaByteSize = A8Info.byteSize();
|
|
auto pixelsC = new uint8_t[alphaByteSize];
|
|
|
|
result = rgbAMap.readPixels(A8Info, pixelsC);
|
|
EXPECT_TRUE(result);
|
|
CHECK_PIXELS(A8Info, pixelsC, "PixelMap_rgbA_to_alpha");
|
|
|
|
PixelMap A8Map(A8Info, pixelsC);
|
|
|
|
result = A8Map.readPixels(rgbAInfo, pixelsB);
|
|
EXPECT_TRUE(result);
|
|
CHECK_PIXELS(rgbAInfo, pixelsB, "PixelMap_alpha_to_rgbA");
|
|
|
|
result = A8Map.readPixels(BGRAInfo, pixelsB);
|
|
EXPECT_TRUE(result);
|
|
CHECK_PIXELS(BGRAInfo, pixelsB, "PixelMap_alpha_to_BGRA");
|
|
|
|
delete[] pixelsA;
|
|
delete[] pixelsB;
|
|
delete[] pixelsC;
|
|
PAGTestEnvironment::DumpJson["PixelMapTest"] = outputJson;
|
|
}
|
|
|
|
/**
|
|
* 用例描述: 像素格式转换相关功能测试-SurfaceReadPixels
|
|
*/
|
|
PAG_TEST(ReadPixelsTest, TestSurfaceReadPixels) {
|
|
auto image = Image::MakeFrom("../resources/apitest/test_timestretch.png");
|
|
ASSERT_TRUE(image != nullptr);
|
|
Bitmap bitmap = {};
|
|
auto result = bitmap.allocPixels(image->width(), image->height());
|
|
ASSERT_TRUE(result);
|
|
auto pixels = bitmap.lockPixels();
|
|
result = image->readPixels(bitmap.info(), pixels);
|
|
bitmap.unlockPixels();
|
|
ASSERT_TRUE(result);
|
|
|
|
auto device = NativeGLDevice::Make();
|
|
auto context = device->lockContext();
|
|
ASSERT_TRUE(context != nullptr);
|
|
auto texture = bitmap.makeTexture(context);
|
|
ASSERT_TRUE(texture != nullptr);
|
|
auto surface = Surface::Make(context, bitmap.width(), bitmap.height());
|
|
ASSERT_TRUE(surface != nullptr);
|
|
auto canvas = surface->getCanvas();
|
|
canvas->drawTexture(texture.get());
|
|
|
|
BitmapLock lock(bitmap);
|
|
auto width = bitmap.width();
|
|
auto height = bitmap.height();
|
|
pixels = lock.pixels();
|
|
json outputJson = {};
|
|
json compareJson = PAGTestEnvironment::CompareJson["SurfaceReadPixelsTest"];
|
|
|
|
auto RGBAInfo = ImageInfo::Make(width, height, ColorType::RGBA_8888, AlphaType::Premultiplied);
|
|
result = surface->readPixels(RGBAInfo, pixels);
|
|
ASSERT_TRUE(result);
|
|
CHECK_PIXELS(RGBAInfo, pixels, "Surface_rgbA_to_rgbA");
|
|
|
|
auto BGRAInfo = ImageInfo::Make(width, height, ColorType::BGRA_8888, AlphaType::Premultiplied);
|
|
result = surface->readPixels(BGRAInfo, pixels);
|
|
ASSERT_TRUE(result);
|
|
CHECK_PIXELS(BGRAInfo, pixels, "Surface_rgbA_to_bgrA");
|
|
|
|
memset(pixels, 0, RGBAInfo.byteSize());
|
|
result = surface->readPixels(RGBAInfo, pixels, 100, 100);
|
|
ASSERT_TRUE(result);
|
|
CHECK_PIXELS(RGBAInfo, pixels, "Surface_rgbA_to_rgbA_100_100");
|
|
|
|
auto RGBARectInfo = ImageInfo::Make(500, 500, ColorType::RGBA_8888, AlphaType::Premultiplied);
|
|
memset(pixels, 0, RGBARectInfo.byteSize());
|
|
result = surface->readPixels(RGBARectInfo, pixels, -100, -100);
|
|
ASSERT_TRUE(result);
|
|
CHECK_PIXELS(RGBARectInfo, pixels, "Surface_rgbA_to_rgbA_-100_-100");
|
|
|
|
memset(pixels, 0, RGBARectInfo.byteSize());
|
|
result = surface->readPixels(RGBARectInfo, pixels, 100, -100);
|
|
ASSERT_TRUE(result);
|
|
CHECK_PIXELS(RGBARectInfo, pixels, "Surface_rgbA_to_rgbA_100_-100");
|
|
|
|
surface = Surface::Make(context, bitmap.width(), bitmap.height(), true);
|
|
ASSERT_TRUE(surface != nullptr);
|
|
canvas = surface->getCanvas();
|
|
canvas->drawTexture(texture.get());
|
|
|
|
auto A8Info = ImageInfo::Make(width, height, ColorType::ALPHA_8, AlphaType::Premultiplied);
|
|
result = surface->readPixels(A8Info, pixels);
|
|
ASSERT_TRUE(result);
|
|
CHECK_PIXELS(A8Info, pixels, "Surface_alpha_to_alpha");
|
|
|
|
result = surface->readPixels(RGBAInfo, pixels);
|
|
ASSERT_TRUE(result);
|
|
CHECK_PIXELS(RGBAInfo, pixels, "Surface_alpha_to_rgba");
|
|
|
|
auto AlphaRectInfo = ImageInfo::Make(500, 500, ColorType::ALPHA_8, AlphaType::Premultiplied);
|
|
memset(pixels, 0, AlphaRectInfo.byteSize());
|
|
result = surface->readPixels(AlphaRectInfo, pixels, 100, -100);
|
|
ASSERT_TRUE(result);
|
|
CHECK_PIXELS(AlphaRectInfo, pixels, "Surface_alpha_to_alpha_100_-100");
|
|
|
|
auto gl = GLContext::Unwrap(context);
|
|
GLTextureInfo textureInfo = {};
|
|
result = CreateTexture(gl, width, height, &textureInfo);
|
|
ASSERT_TRUE(result);
|
|
auto backendTexture = BackendTexture(textureInfo, width, height);
|
|
surface = Surface::MakeFrom(context, backendTexture, ImageOrigin::BottomLeft);
|
|
ASSERT_TRUE(surface != nullptr);
|
|
canvas = surface->getCanvas();
|
|
canvas->clear();
|
|
canvas->drawTexture(texture.get());
|
|
|
|
result = surface->readPixels(RGBAInfo, pixels);
|
|
ASSERT_TRUE(result);
|
|
CHECK_PIXELS(RGBAInfo, pixels, "Surface_BL_rgbA_to_rgbA");
|
|
|
|
memset(pixels, 0, RGBAInfo.byteSize());
|
|
result = surface->readPixels(RGBAInfo, pixels, 100, 100);
|
|
ASSERT_TRUE(result);
|
|
CHECK_PIXELS(RGBAInfo, pixels, "Surface_BL_rgbA_to_rgbA_100_100");
|
|
|
|
memset(pixels, 0, RGBARectInfo.byteSize());
|
|
result = surface->readPixels(RGBARectInfo, pixels, -100, -100);
|
|
ASSERT_TRUE(result);
|
|
CHECK_PIXELS(RGBARectInfo, pixels, "Surface_BL_rgbA_to_rgbA_-100_-100");
|
|
|
|
memset(pixels, 0, RGBARectInfo.byteSize());
|
|
result = surface->readPixels(RGBARectInfo, pixels, 100, -100);
|
|
ASSERT_TRUE(result);
|
|
CHECK_PIXELS(RGBARectInfo, pixels, "Surface_BL_rgbA_to_rgbA_100_-100");
|
|
|
|
gl->deleteTextures(1, &textureInfo.id);
|
|
device->unlock();
|
|
PAGTestEnvironment::DumpJson["SurfaceReadPixelsTest"] = outputJson;
|
|
}
|
|
|
|
/**
|
|
* 用例描述: Webp解码测试
|
|
*/
|
|
PAG_TEST(ReadPixelsTest, WebpCodec) {
|
|
auto image = Image::MakeFrom("../resources/apitest/imageReplacement.webp");
|
|
ASSERT_TRUE(image != nullptr);
|
|
ASSERT_EQ(image->width(), 110);
|
|
ASSERT_EQ(image->height(), 110);
|
|
ASSERT_EQ(static_cast<int>(image->orientation()), static_cast<int>(Orientation::TopLeft));
|
|
auto rowBytes = image->width() * 4;
|
|
auto pixels = new (std::nothrow) uint8_t[rowBytes * image->height()];
|
|
ASSERT_TRUE(pixels);
|
|
auto info = ImageInfo::Make(110, 110, ColorType::RGBA_8888, AlphaType::Premultiplied);
|
|
bool res = image->readPixels(info, pixels);
|
|
ASSERT_TRUE(res);
|
|
PixelMap pixelMap(info, pixels);
|
|
Image::Encode(pixelMap.info(), pixelMap.pixels(), EncodedFormat::PNG, 100);
|
|
Image::Encode(pixelMap.info(), pixelMap.pixels(), EncodedFormat::WEBP, 100);
|
|
Image::Encode(pixelMap.info(), pixelMap.pixels(), EncodedFormat::JPEG, 100);
|
|
delete[] pixels;
|
|
}
|
|
|
|
/**
|
|
* 用例描述: Jpeg解码测试
|
|
*/
|
|
PAG_TEST(ReadPixelsTest, JpegCodec) {
|
|
auto image = Image::MakeFrom("../resources/apitest/rotation.jpg");
|
|
ASSERT_TRUE(image != nullptr);
|
|
ASSERT_EQ(image->width(), 4032);
|
|
ASSERT_EQ(image->height(), 3024);
|
|
ASSERT_EQ(static_cast<int>(image->orientation()), static_cast<int>(Orientation::RightTop));
|
|
ColorType outputColorType = ColorType::RGBA_8888;
|
|
auto pixels = new (std::nothrow)
|
|
uint8_t[image->height() * image->width() * ImageInfo::GetBytesPerPixel(outputColorType)];
|
|
ASSERT_TRUE(pixels);
|
|
auto info = ImageInfo::Make(4032, 3024, outputColorType, AlphaType::Premultiplied);
|
|
bool res = image->readPixels(info, pixels);
|
|
PixelMap pixelMap(info, pixels);
|
|
|
|
auto bytes = Image::Encode(pixelMap.info(), pixelMap.pixels(), EncodedFormat::WEBP, 20);
|
|
if (bytes) {
|
|
std::ofstream out("../test/out/tet.webp");
|
|
out.write(reinterpret_cast<const char*>(bytes->data()), bytes->size());
|
|
out.close();
|
|
}
|
|
delete[] pixels;
|
|
ASSERT_TRUE(res);
|
|
}
|
|
|
|
} // namespace pag
|