diff options
author | Ram Mohan <ram.mohan@ittiam.com> | 2023-10-28 15:02:48 +0530 |
---|---|---|
committer | Ram Mohan M <ram.mohan@ittiam.com> | 2023-11-02 04:47:42 +0530 |
commit | 57d807e662e6c7bc1e98603b4625e6e56655ffb4 (patch) | |
tree | 930c147adfd1c55ebfb22125e6f4664e37745c9a /tests | |
parent | 54c14925d2430b03e93ef0441e5cbfda441ed14e (diff) | |
download | libultrahdr-57d807e662e6c7bc1e98603b4625e6e56655ffb4.tar.gz |
relocate source files to desired folders
library files are moved to lib/ folder and sample application is
moved to examples/ folder
Diffstat (limited to 'tests')
-rw-r--r-- | tests/Android.bp | 21 | ||||
-rw-r--r-- | tests/gainmapmath_test.cpp | 2 | ||||
-rw-r--r-- | tests/icchelper_test.cpp | 2 | ||||
-rw-r--r-- | tests/jpegdecoderhelper_test.cpp | 6 | ||||
-rw-r--r-- | tests/jpegencoderhelper_test.cpp | 6 | ||||
-rw-r--r-- | tests/jpegr_test.cpp | 6 | ||||
-rw-r--r-- | tests/ultrahdr_app.cpp | 921 |
7 files changed, 11 insertions, 953 deletions
diff --git a/tests/Android.bp b/tests/Android.bp index e175155..8fe1621 100644 --- a/tests/Android.bp +++ b/tests/Android.bp @@ -22,27 +22,6 @@ package { } cc_test { - name: "ultrahdr_sample_app", - host_supported: true, - gtest: false, - test_suites: ["device-tests"], - srcs: [ - "ultrahdr_app.cpp", - ], - shared_libs: [ - "libbase", - "libimage_io", - "libjpeg", - "liblog", - ], - static_libs: [ - "libjpegdecoder", - "libjpegencoder", - "libultrahdr", - ], -} - -cc_test { name: "ultrahdr_unit_test", test_suites: ["device-tests"], srcs: [ diff --git a/tests/gainmapmath_test.cpp b/tests/gainmapmath_test.cpp index e73419c..d0b838b 100644 --- a/tests/gainmapmath_test.cpp +++ b/tests/gainmapmath_test.cpp @@ -17,7 +17,7 @@ #include <gtest/gtest.h> #include <gmock/gmock.h> -#include "ultrahdr/gainmapmath.h" +#include "gainmapmath.h" namespace ultrahdr { diff --git a/tests/icchelper_test.cpp b/tests/icchelper_test.cpp index 081ef0e..7d47381 100644 --- a/tests/icchelper_test.cpp +++ b/tests/icchelper_test.cpp @@ -16,7 +16,7 @@ #include <gtest/gtest.h> -#include "ultrahdr/icc.h" +#include "icc.h" namespace ultrahdr { diff --git a/tests/jpegdecoderhelper_test.cpp b/tests/jpegdecoderhelper_test.cpp index 838c911..fd0f51b 100644 --- a/tests/jpegdecoderhelper_test.cpp +++ b/tests/jpegdecoderhelper_test.cpp @@ -17,9 +17,9 @@ #include <fcntl.h> #include <gtest/gtest.h> -#include "ultrahdr/ultrahdrcommon.h" -#include "ultrahdr/jpegdecoderhelper.h" -#include "ultrahdr/icc.h" +#include "ultrahdrcommon.h" +#include "jpegdecoderhelper.h" +#include "icc.h" namespace ultrahdr { diff --git a/tests/jpegencoderhelper_test.cpp b/tests/jpegencoderhelper_test.cpp index 37aa995..457e47c 100644 --- a/tests/jpegencoderhelper_test.cpp +++ b/tests/jpegencoderhelper_test.cpp @@ -17,9 +17,9 @@ #include <fcntl.h> #include <gtest/gtest.h> -#include "ultrahdr/ultrahdrcommon.h" -#include "ultrahdr/ultrahdr.h" -#include "ultrahdr/jpegencoderhelper.h" +#include "ultrahdrcommon.h" +#include "ultrahdr.h" +#include "jpegencoderhelper.h" namespace ultrahdr { diff --git a/tests/jpegr_test.cpp b/tests/jpegr_test.cpp index d3832e8..068dd58 100644 --- a/tests/jpegr_test.cpp +++ b/tests/jpegr_test.cpp @@ -20,9 +20,9 @@ #include <fstream> #include <iostream> -#include "ultrahdr/ultrahdrcommon.h" -#include "ultrahdr/jpegr.h" -#include "ultrahdr/jpegrutils.h" +#include "ultrahdrcommon.h" +#include "jpegr.h" +#include "jpegrutils.h" //#define DUMP_OUTPUT diff --git a/tests/ultrahdr_app.cpp b/tests/ultrahdr_app.cpp deleted file mode 100644 index ca237c7..0000000 --- a/tests/ultrahdr_app.cpp +++ /dev/null @@ -1,921 +0,0 @@ -/* - * Copyright 2023 The Android Open Source Project - * - * 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 <sys/time.h> -#include <unistd.h> - -#include <algorithm> -#include <cmath> -#include <fstream> -#include <iostream> - -#include "ultrahdr/ultrahdrcommon.h" -#include "ultrahdr/gainmapmath.h" -#include "ultrahdr/jpegr.h" - -using namespace ultrahdr; - -const float BT601YUVtoRGBMatrix[9] = - {1, 0, 1.402, 1, (-0.202008 / 0.587), (-0.419198 / 0.587), 1.0, 1.772, 0.0}; -const float BT709YUVtoRGBMatrix[9] = - {1, 0, 1.5748, 1, (-0.13397432 / 0.7152), (-0.33480248 / 0.7152), 1.0, 1.8556, 0.0}; -const float BT2020YUVtoRGBMatrix[9] = - {1, 0, 1.4746, 1, (-0.11156702 / 0.6780), (-0.38737742 / 0.6780), 1, 1.8814, 0}; - -const float BT601RGBtoYUVMatrix[9] = {0.299, - 0.587, - 0.114, - (-0.299 / 1.772), - (-0.587 / 1.772), - 0.5, - 0.5, - (-0.587 / 1.402), - (-0.114 / 1.402)}; -const float BT709RGBtoYUVMatrix[9] = {0.2126, - 0.7152, - 0.0722, - (-0.2126 / 1.8556), - (-0.7152 / 1.8556), - 0.5, - 0.5, - (-0.7152 / 1.5748), - (-0.0722 / 1.5748)}; -const float BT2020RGBtoYUVMatrix[9] = {0.2627, - 0.6780, - 0.0593, - (-0.2627 / 1.8814), - (-0.6780 / 1.8814), - 0.5, - 0.5, - (-0.6780 / 1.4746), - (-0.0593 / 1.4746)}; - -//#define PROFILE_ENABLE 1 -class Profiler { -public: - void timerStart() { gettimeofday(&mStartingTime, nullptr); } - - void timerStop() { gettimeofday(&mEndingTime, nullptr); } - - int64_t elapsedTime() { - struct timeval elapsedMicroseconds; - elapsedMicroseconds.tv_sec = mEndingTime.tv_sec - mStartingTime.tv_sec; - elapsedMicroseconds.tv_usec = mEndingTime.tv_usec - mStartingTime.tv_usec; - return elapsedMicroseconds.tv_sec * 1000000 + elapsedMicroseconds.tv_usec; - } - -private: - struct timeval mStartingTime; - struct timeval mEndingTime; -}; - -static bool loadFile(const char* filename, void*& result, int length) { - std::ifstream ifd(filename, std::ios::binary | std::ios::ate); - if (ifd.good()) { - int size = ifd.tellg(); - if (size < length) { - std::cerr << "requested to read " << length << " bytes from file : " << filename - << ", file contains only " << size << " bytes" << std::endl; - return false; - } - ifd.seekg(0, std::ios::beg); - result = malloc(length); - if (result == nullptr) { - std::cerr << "failed to allocate memory to store contents of file : " << filename - << std::endl; - return false; - } - ifd.read(static_cast<char*>(result), length); - return true; - } - std::cerr << "unable to open file : " << filename << std::endl; - return false; -} - -static bool writeFile(const char* filename, void*& result, int length) { - std::ofstream ofd(filename, std::ios::binary); - if (ofd.is_open()) { - ofd.write(static_cast<char*>(result), length); - return true; - } - std::cerr << "unable to write to file : " << filename << std::endl; - return false; -} - -class UltraHdrAppInput { -public: - UltraHdrAppInput(const char* p010File, const char* yuv420File, const char* yuv420JpegFile, - size_t width, size_t height, - ultrahdr_color_gamut p010Cg = ULTRAHDR_COLORGAMUT_BT709, - ultrahdr_color_gamut yuv420Cg = ULTRAHDR_COLORGAMUT_BT709, - ultrahdr_transfer_function tf = ULTRAHDR_TF_HLG, int quality = 100, - ultrahdr_output_format of = ULTRAHDR_OUTPUT_HDR_HLG) - : mP010File(p010File), - mYuv420File(yuv420File), - mYuv420JpegFile(yuv420JpegFile), - mJpegRFile(nullptr), - mWidth(width), - mHeight(height), - mP010Cg(p010Cg), - mYuv420Cg(yuv420Cg), - mTf(tf), - mQuality(quality), - mOf(of), - mMode(0){}; - - UltraHdrAppInput(const char* jpegRFile, ultrahdr_output_format of = ULTRAHDR_OUTPUT_HDR_HLG) - : mP010File(nullptr), - mYuv420File(nullptr), - mJpegRFile(jpegRFile), - mWidth(0), - mHeight(0), - mP010Cg(ULTRAHDR_COLORGAMUT_UNSPECIFIED), - mYuv420Cg(ULTRAHDR_COLORGAMUT_UNSPECIFIED), - mTf(ULTRAHDR_TF_UNSPECIFIED), - mQuality(100), - mOf(of), - mMode(1){}; - - ~UltraHdrAppInput() { - if (mRawP010Image.data) free(mRawP010Image.data); - if (mRawP010Image.chroma_data) free(mRawP010Image.chroma_data); - if (mRawRgba1010102Image.data) free(mRawRgba1010102Image.data); - if (mRawRgba1010102Image.chroma_data) free(mRawRgba1010102Image.chroma_data); - if (mRawYuv420Image.data) free(mRawYuv420Image.data); - if (mRawYuv420Image.chroma_data) free(mRawYuv420Image.chroma_data); - if (mRawRgba8888Image.data) free(mRawRgba8888Image.data); - if (mRawRgba8888Image.chroma_data) free(mRawRgba8888Image.chroma_data); - if (mJpegImgR.data) free(mJpegImgR.data); - if (mDestImage.data) free(mDestImage.data); - if (mDestImage.chroma_data) free(mDestImage.chroma_data); - if (mDestYUV444Image.data) free(mDestYUV444Image.data); - if (mDestYUV444Image.chroma_data) free(mDestYUV444Image.chroma_data); - } - - bool fillJpegRImageHandle(); - bool fillP010ImageHandle(); - bool convertP010ToRGBImage(); - bool fillYuv420ImageHandle(); - bool fillYuv420JpegImageHandle(); - bool convertYuv420ToRGBImage(); - bool convertRgba8888ToYUV444Image(); - bool convertRgba1010102ToYUV444Image(); - bool encode(); - bool decode(); - void computeRGBHdrPSNR(); - void computeRGBSdrPSNR(); - void computeYUVHdrPSNR(); - void computeYUVSdrPSNR(); - - const char* mP010File; - const char* mYuv420File; - const char* mYuv420JpegFile; - const char* mJpegRFile; - const int mWidth; - const int mHeight; - const ultrahdr_color_gamut mP010Cg; - const ultrahdr_color_gamut mYuv420Cg; - const ultrahdr_transfer_function mTf; - const int mQuality; - const ultrahdr_output_format mOf; - const int mMode; - jpegr_uncompressed_struct mRawP010Image{}; - jpegr_uncompressed_struct mRawRgba1010102Image{}; - jpegr_uncompressed_struct mRawYuv420Image{}; - jpegr_compressed_struct mYuv420JpegImage{}; - jpegr_uncompressed_struct mRawRgba8888Image{}; - jpegr_compressed_struct mJpegImgR{}; - jpegr_uncompressed_struct mDestImage{}; - jpegr_uncompressed_struct mDestYUV444Image{}; - double mPsnr[3]{}; -}; - -bool UltraHdrAppInput::fillP010ImageHandle() { - const int bpp = 2; - int p010Size = mWidth * mHeight * bpp * 1.5; - mRawP010Image.width = mWidth; - mRawP010Image.height = mHeight; - mRawP010Image.colorGamut = mP010Cg; - return loadFile(mP010File, mRawP010Image.data, p010Size); -} - -bool UltraHdrAppInput::fillYuv420ImageHandle() { - int yuv420Size = mWidth * mHeight * 1.5; - mRawYuv420Image.width = mWidth; - mRawYuv420Image.height = mHeight; - mRawYuv420Image.colorGamut = mYuv420Cg; - return loadFile(mYuv420File, mRawYuv420Image.data, yuv420Size); -} - -bool UltraHdrAppInput::fillYuv420JpegImageHandle() { - std::ifstream ifd(mYuv420JpegFile, std::ios::binary | std::ios::ate); - if (ifd.good()) { - int size = ifd.tellg(); - mYuv420JpegImage.length = size; - mYuv420JpegImage.maxLength = size; - mYuv420JpegImage.data = nullptr; - mYuv420JpegImage.colorGamut = mYuv420Cg; - ifd.close(); - return loadFile(mYuv420JpegFile, mYuv420JpegImage.data, size); - } - return false; -} - -bool UltraHdrAppInput::fillJpegRImageHandle() { - std::ifstream ifd(mJpegRFile, std::ios::binary | std::ios::ate); - if (ifd.good()) { - int size = ifd.tellg(); - mJpegImgR.length = size; - mJpegImgR.maxLength = size; - mJpegImgR.data = nullptr; - mJpegImgR.colorGamut = mYuv420Cg; - ifd.close(); - return loadFile(mJpegRFile, mJpegImgR.data, size); - } - return false; -} - -bool UltraHdrAppInput::encode() { - if (!fillP010ImageHandle()) return false; - if (mYuv420File != nullptr && !fillYuv420ImageHandle()) return false; - if (mYuv420JpegFile != nullptr && !fillYuv420JpegImageHandle()) return false; - - mJpegImgR.maxLength = std::max(static_cast<size_t>(8 * 1024) /* min size 8kb */, - mRawP010Image.width * mRawP010Image.height * 3 * 2); - mJpegImgR.data = malloc(mJpegImgR.maxLength); - if (mJpegImgR.data == nullptr) { - std::cerr << "unable to allocate memory to store compressed image" << std::endl; - return false; - } - - JpegR jpegHdr; - status_t status = UNKNOWN_ERROR; -#ifdef PROFILE_ENABLE - const int profileCount = 10; - Profiler profileEncode; - profileEncode.timerStart(); - for (auto i = 0; i < profileCount; i++) { -#endif - if (mYuv420File == nullptr && mYuv420JpegFile == nullptr) { // api-0 - status = jpegHdr.encodeJPEGR(&mRawP010Image, mTf, &mJpegImgR, mQuality, nullptr); - if (OK != status) { - std::cerr << "Encountered error during encodeJPEGR call, error code " << status - << std::endl; - return false; - } - } else if (mYuv420File != nullptr && mYuv420JpegFile == nullptr) { // api-1 - status = jpegHdr.encodeJPEGR(&mRawP010Image, &mRawYuv420Image, mTf, &mJpegImgR, mQuality, - nullptr); - if (OK != status) { - std::cerr << "Encountered error during encodeJPEGR call, error code " << status - << std::endl; - return false; - } - } else if (mYuv420File != nullptr && mYuv420JpegFile != nullptr) { // api-2 - status = jpegHdr.encodeJPEGR(&mRawP010Image, &mRawYuv420Image, &mYuv420JpegImage, mTf, - &mJpegImgR); - if (OK != status) { - std::cerr << "Encountered error during encodeJPEGR call, error code " << status - << std::endl; - return false; - } - } else if (mYuv420File == nullptr && mYuv420JpegFile != nullptr) { // api-3 - status = jpegHdr.encodeJPEGR(&mRawP010Image, &mYuv420JpegImage, mTf, &mJpegImgR); - if (OK != status) { - std::cerr << "Encountered error during encodeJPEGR call, error code " << status - << std::endl; - return false; - } - } -#ifdef PROFILE_ENABLE - } - profileEncode.timerStop(); - auto avgEncTime = profileEncode.elapsedTime() / (profileCount * 1000.f); - printf("Average encode time for res %d x %d is %f ms \n", mWidth, mHeight, avgEncTime); -#endif - writeFile("out.jpeg", mJpegImgR.data, mJpegImgR.length); - return true; -} - -bool UltraHdrAppInput::decode() { - if (mMode == 1 && !fillJpegRImageHandle()) return false; - std::vector<uint8_t> iccData(0); - std::vector<uint8_t> exifData(0); - jpegr_info_struct info{0, 0, &iccData, &exifData}; - JpegR jpegHdr; - status_t status = jpegHdr.getJPEGRInfo(&mJpegImgR, &info); - if (OK == status) { - size_t outSize = info.width * info.height * ((mOf == ULTRAHDR_OUTPUT_HDR_LINEAR) ? 8 : 4); - mDestImage.data = malloc(outSize); - if (mDestImage.data == nullptr) { - std::cerr << "failed to allocate memory to store decoded output" << std::endl; - return false; - } -#ifdef PROFILE_ENABLE - const int profileCount = 10; - Profiler profileDecode; - profileDecode.timerStart(); - for (auto i = 0; i < profileCount; i++) { -#endif - status = jpegHdr.decodeJPEGR(&mJpegImgR, &mDestImage, FLT_MAX, nullptr, mOf, nullptr, - nullptr); - if (OK != status) { - std::cerr << "Encountered error during decodeJPEGR call, error code " << status - << std::endl; - return false; - } -#ifdef PROFILE_ENABLE - } - profileDecode.timerStop(); - auto avgDecTime = profileDecode.elapsedTime() / (profileCount * 1000.f); - printf("Average decode time for res %ld x %ld is %f ms \n", info.width, info.height, - avgDecTime); -#endif - writeFile("outrgb.raw", mDestImage.data, outSize); - } else { - std::cerr << "Encountered error during getJPEGRInfo call, error code " << status - << std::endl; - return false; - } - return true; -} - -bool UltraHdrAppInput::convertP010ToRGBImage() { - const float* coeffs = BT2020YUVtoRGBMatrix; - if (mP010Cg == ULTRAHDR_COLORGAMUT_BT709) { - coeffs = BT709YUVtoRGBMatrix; - } else if (mP010Cg == ULTRAHDR_COLORGAMUT_BT2100) { - coeffs = BT2020YUVtoRGBMatrix; - } else if (mP010Cg == ULTRAHDR_COLORGAMUT_P3) { - coeffs = BT601YUVtoRGBMatrix; - } else { - std::cerr << "color matrix not present for gamut " << mP010Cg << " using BT2020Matrix" - << std::endl; - } - - mRawRgba1010102Image.data = malloc(mRawP010Image.width * mRawP010Image.height * 4); - if (mRawRgba1010102Image.data == nullptr) { - std::cerr << "failed to allocate memory to store Rgba1010102" << std::endl; - return false; - } - mRawRgba1010102Image.width = mRawP010Image.width; - mRawRgba1010102Image.height = mRawP010Image.height; - mRawRgba1010102Image.colorGamut = mRawP010Image.colorGamut; - uint32_t* rgbData = static_cast<uint32_t*>(mRawRgba1010102Image.data); - uint16_t* y = static_cast<uint16_t*>(mRawP010Image.data); - uint16_t* u = y + mRawP010Image.width * mRawP010Image.height; - uint16_t* v = u + 1; - - for (size_t i = 0; i < mRawP010Image.height; i++) { - for (size_t j = 0; j < mRawP010Image.width; j++) { - float y0 = float(y[mRawP010Image.width * i + j] >> 6); - float u0 = float(u[mRawP010Image.width * (i / 2) + (j / 2) * 2] >> 6); - float v0 = float(v[mRawP010Image.width * (i / 2) + (j / 2) * 2] >> 6); - - y0 = CLIP3(y0, 64.0f, 940.0f); - u0 = CLIP3(u0, 64.0f, 960.0f); - v0 = CLIP3(v0, 64.0f, 960.0f); - - y0 = (y0 - 64.0f) / 876.0f; - u0 = (u0 - 64.0f) / 896.0f - 0.5f; - v0 = (v0 - 64.0f) / 896.0f - 0.5f; - - float r = coeffs[0] * y0 + coeffs[1] * u0 + coeffs[2] * v0; - float g = coeffs[3] * y0 + coeffs[4] * u0 + coeffs[5] * v0; - float b = coeffs[6] * y0 + coeffs[7] * u0 + coeffs[8] * v0; - - r = CLIP3(r * 1023.0f + 0.5f, 0.0f, 1023.0f); - g = CLIP3(g * 1023.0f + 0.5f, 0.0f, 1023.0f); - b = CLIP3(b * 1023.0f + 0.5f, 0.0f, 1023.0f); - - int32_t r0 = int32_t(r); - int32_t g0 = int32_t(g); - int32_t b0 = int32_t(b); - *rgbData = (0x3ff & r0) | ((0x3ff & g0) << 10) | ((0x3ff & b0) << 20) | - (0x3 << 30); // Set alpha to 1.0 - - rgbData++; - } - } - writeFile("inRgba1010102.raw", mRawRgba1010102Image.data, - mRawP010Image.width * mRawP010Image.height * 4); - return true; -} - -bool UltraHdrAppInput::convertYuv420ToRGBImage() { - mRawRgba8888Image.data = malloc(mRawYuv420Image.width * mRawYuv420Image.height * 4); - if (mRawRgba8888Image.data == nullptr) { - std::cerr << "failed to allocate memory to store rgba888" << std::endl; - return false; - } - mRawRgba8888Image.width = mRawYuv420Image.width; - mRawRgba8888Image.height = mRawYuv420Image.height; - mRawRgba8888Image.colorGamut = mRawYuv420Image.colorGamut; - uint32_t* rgbData = static_cast<uint32_t*>(mRawRgba8888Image.data); - uint8_t* y = static_cast<uint8_t*>(mRawYuv420Image.data); - uint8_t* u = y + (mRawYuv420Image.width * mRawYuv420Image.height); - uint8_t* v = u + (mRawYuv420Image.width * mRawYuv420Image.height / 4); - - const float* coeffs = BT601YUVtoRGBMatrix; - for (size_t i = 0; i < mRawYuv420Image.height; i++) { - for (size_t j = 0; j < mRawYuv420Image.width; j++) { - float y0 = float(y[mRawYuv420Image.width * i + j]); - float u0 = float(u[mRawYuv420Image.width / 2 * (i / 2) + (j / 2)] - 128); - float v0 = float(v[mRawYuv420Image.width / 2 * (i / 2) + (j / 2)] - 128); - - y0 /= 255.0f; - u0 /= 255.0f; - v0 /= 255.0f; - - float r = coeffs[0] * y0 + coeffs[1] * u0 + coeffs[2] * v0; - float g = coeffs[3] * y0 + coeffs[4] * u0 + coeffs[5] * v0; - float b = coeffs[6] * y0 + coeffs[7] * u0 + coeffs[8] * v0; - - r = r * 255.0f + 0.5f; - g = g * 255.0f + 0.5f; - b = b * 255.0f + 0.5f; - - r = CLIP3(r, 0.0f, 255.0f); - g = CLIP3(g, 0.0f, 255.0f); - b = CLIP3(b, 0.0f, 255.0f); - - int32_t r0 = int32_t(r); - int32_t g0 = int32_t(g); - int32_t b0 = int32_t(b); - *rgbData = r0 | (g0 << 8) | (b0 << 16) | (255 << 24); // Set alpha to 1.0 - - rgbData++; - } - } - writeFile("inRgba8888.raw", mRawRgba8888Image.data, - mRawYuv420Image.width * mRawYuv420Image.height * 4); - return true; -} - -bool UltraHdrAppInput::convertRgba8888ToYUV444Image() { - mDestYUV444Image.data = malloc(mDestImage.width * mDestImage.height * 3); - if (mDestYUV444Image.data == nullptr) { - std::cerr << "failed to allocate memory to store yuv444" << std::endl; - return false; - } - mDestYUV444Image.width = mDestImage.width; - mDestYUV444Image.height = mDestImage.height; - mDestYUV444Image.colorGamut = mDestImage.colorGamut; - - uint32_t* rgbData = static_cast<uint32_t*>(mDestImage.data); - - uint8_t* yData = static_cast<uint8_t*>(mDestYUV444Image.data); - uint8_t* uData = yData + (mDestYUV444Image.width * mDestYUV444Image.height); - uint8_t* vData = uData + (mDestYUV444Image.width * mDestYUV444Image.height); - - const float* coeffs = BT601RGBtoYUVMatrix; - for (size_t i = 0; i < mDestImage.height; i++) { - for (size_t j = 0; j < mDestImage.width; j++) { - float r0 = float(rgbData[mDestImage.width * i + j] & 0xff); - float g0 = float((rgbData[mDestImage.width * i + j] >> 8) & 0xff); - float b0 = float((rgbData[mDestImage.width * i + j] >> 16) & 0xff); - - r0 /= 255.0f; - g0 /= 255.0f; - b0 /= 255.0f; - - float y = coeffs[0] * r0 + coeffs[1] * g0 + coeffs[2] * b0; - float u = coeffs[3] * r0 + coeffs[4] * g0 + coeffs[5] * b0; - float v = coeffs[6] * r0 + coeffs[7] * g0 + coeffs[8] * b0; - - y = y * 255.0f + 0.5f; - u = u * 255.0f + 0.5f + 128.0f; - v = v * 255.0f + 0.5f + 128.0f; - - y = CLIP3(y, 0.0f, 255.0f); - u = CLIP3(u, 0.0f, 255.0f); - v = CLIP3(v, 0.0f, 255.0f); - - yData[mDestYUV444Image.width * i + j] = uint8_t(y); - uData[mDestYUV444Image.width * i + j] = uint8_t(u); - vData[mDestYUV444Image.width * i + j] = uint8_t(v); - } - } - writeFile("outyuv444.yuv", mDestYUV444Image.data, - mDestYUV444Image.width * mDestYUV444Image.height * 3); - return true; -} - -bool UltraHdrAppInput::convertRgba1010102ToYUV444Image() { - const float* coeffs = BT2020RGBtoYUVMatrix; - if (mP010Cg == ULTRAHDR_COLORGAMUT_BT709) { - coeffs = BT709RGBtoYUVMatrix; - } else if (mP010Cg == ULTRAHDR_COLORGAMUT_BT2100) { - coeffs = BT2020RGBtoYUVMatrix; - } else if (mP010Cg == ULTRAHDR_COLORGAMUT_P3) { - coeffs = BT601RGBtoYUVMatrix; - } else { - std::cerr << "color matrix not present for gamut " << mP010Cg << " using BT2020Matrix" - << std::endl; - } - - mDestYUV444Image.data = malloc(mDestImage.width * mDestImage.height * 3 * 2); - if (mDestYUV444Image.data == nullptr) { - std::cerr << "failed to allocate memory to store yuv444" << std::endl; - return false; - } - mDestYUV444Image.width = mDestImage.width; - mDestYUV444Image.height = mDestImage.height; - mDestYUV444Image.colorGamut = mDestImage.colorGamut; - - uint32_t* rgbData = static_cast<uint32_t*>(mDestImage.data); - - uint16_t* yData = static_cast<uint16_t*>(mDestYUV444Image.data); - uint16_t* uData = yData + (mDestYUV444Image.width * mDestYUV444Image.height); - uint16_t* vData = uData + (mDestYUV444Image.width * mDestYUV444Image.height); - - for (size_t i = 0; i < mDestImage.height; i++) { - for (size_t j = 0; j < mDestImage.width; j++) { - float r0 = float(rgbData[mDestImage.width * i + j] & 0x3ff); - float g0 = float((rgbData[mDestImage.width * i + j] >> 10) & 0x3ff); - float b0 = float((rgbData[mDestImage.width * i + j] >> 20) & 0x3ff); - - r0 /= 1023.0f; - g0 /= 1023.0f; - b0 /= 1023.0f; - - float y = coeffs[0] * r0 + coeffs[1] * g0 + coeffs[2] * b0; - float u = coeffs[3] * r0 + coeffs[4] * g0 + coeffs[5] * b0; - float v = coeffs[6] * r0 + coeffs[7] * g0 + coeffs[8] * b0; - - y = (y * 876.0f) + 64.0f + 0.5f; - u = (u * 896.0f) + 64.0f + 512.0f + 0.5f; - v = (v * 896.0f) + 64.0f + 512.0f + 0.5f; - - y = CLIP3(y, 64.0f, 940.0f); - u = CLIP3(u, 64.0f, 960.0f); - v = CLIP3(v, 64.0f, 960.0f); - - yData[mDestYUV444Image.width * i + j] = uint16_t(y); - uData[mDestYUV444Image.width * i + j] = uint16_t(u); - vData[mDestYUV444Image.width * i + j] = uint16_t(v); - } - } - writeFile("outyuv444.yuv", mDestYUV444Image.data, - mDestYUV444Image.width * mDestYUV444Image.height * 3 * 2); - return true; -} - -void UltraHdrAppInput::computeRGBHdrPSNR() { - if (mOf == ULTRAHDR_OUTPUT_SDR || mOf == ULTRAHDR_OUTPUT_HDR_LINEAR) { - std::cout << "psnr not supported for output format " << mOf << std::endl; - return; - } - uint32_t* rgbDataSrc = static_cast<uint32_t*>(mRawRgba1010102Image.data); - uint32_t* rgbDataDst = static_cast<uint32_t*>(mDestImage.data); - if (rgbDataSrc == nullptr || rgbDataDst == nullptr) { - std::cerr << "invalid src or dst pointer for psnr computation " << std::endl; - return; - } - if ((mOf == ULTRAHDR_OUTPUT_HDR_PQ && mTf != ULTRAHDR_TF_PQ) || - (mOf == ULTRAHDR_OUTPUT_HDR_HLG && mTf != ULTRAHDR_TF_HLG)) { - std::cout << "input transfer function and output format are not compatible, psnr results " - "may be unreliable" - << std::endl; - } - uint64_t rSqError = 0, gSqError = 0, bSqError = 0; - for (size_t i = 0; i < mRawP010Image.width * mRawP010Image.height; i++) { - int rSrc = *rgbDataSrc & 0x3ff; - int rDst = *rgbDataDst & 0x3ff; - rSqError += (rSrc - rDst) * (rSrc - rDst); - - int gSrc = (*rgbDataSrc >> 10) & 0x3ff; - int gDst = (*rgbDataDst >> 10) & 0x3ff; - gSqError += (gSrc - gDst) * (gSrc - gDst); - - int bSrc = (*rgbDataSrc >> 20) & 0x3ff; - int bDst = (*rgbDataDst >> 20) & 0x3ff; - bSqError += (bSrc - bDst) * (bSrc - bDst); - - rgbDataSrc++; - rgbDataDst++; - } - double meanSquareError = (double)rSqError / (mRawP010Image.width * mRawP010Image.height); - mPsnr[0] = meanSquareError ? 10 * log10((double)1023 * 1023 / meanSquareError) : 100; - - meanSquareError = (double)gSqError / (mRawP010Image.width * mRawP010Image.height); - mPsnr[1] = meanSquareError ? 10 * log10((double)1023 * 1023 / meanSquareError) : 100; - - meanSquareError = (double)bSqError / (mRawP010Image.width * mRawP010Image.height); - mPsnr[2] = meanSquareError ? 10 * log10((double)1023 * 1023 / meanSquareError) : 100; - - std::cout << "psnr r :: " << mPsnr[0] << " psnr g :: " << mPsnr[1] << " psnr b :: " << mPsnr[2] - << std::endl; -} - -void UltraHdrAppInput::computeRGBSdrPSNR() { - if (mOf != ULTRAHDR_OUTPUT_SDR) { - std::cout << "psnr not supported for output format " << mOf << std::endl; - return; - } - uint32_t* rgbDataSrc = static_cast<uint32_t*>(mRawRgba8888Image.data); - uint32_t* rgbDataDst = static_cast<uint32_t*>(mDestImage.data); - if (rgbDataSrc == nullptr || rgbDataDst == nullptr) { - std::cerr << "invalid src or dst pointer for psnr computation " << std::endl; - return; - } - - uint64_t rSqError = 0, gSqError = 0, bSqError = 0; - for (size_t i = 0; i < mRawYuv420Image.width * mRawYuv420Image.height; i++) { - int rSrc = *rgbDataSrc & 0xff; - int rDst = *rgbDataDst & 0xff; - rSqError += (rSrc - rDst) * (rSrc - rDst); - - int gSrc = (*rgbDataSrc >> 8) & 0xff; - int gDst = (*rgbDataDst >> 8) & 0xff; - gSqError += (gSrc - gDst) * (gSrc - gDst); - - int bSrc = (*rgbDataSrc >> 16) & 0xff; - int bDst = (*rgbDataDst >> 16) & 0xff; - bSqError += (bSrc - bDst) * (bSrc - bDst); - - rgbDataSrc++; - rgbDataDst++; - } - double meanSquareError = (double)rSqError / (mRawYuv420Image.width * mRawYuv420Image.height); - mPsnr[0] = meanSquareError ? 10 * log10((double)255 * 255 / meanSquareError) : 100; - - meanSquareError = (double)gSqError / (mRawYuv420Image.width * mRawYuv420Image.height); - mPsnr[1] = meanSquareError ? 10 * log10((double)255 * 255 / meanSquareError) : 100; - - meanSquareError = (double)bSqError / (mRawYuv420Image.width * mRawYuv420Image.height); - mPsnr[2] = meanSquareError ? 10 * log10((double)255 * 255 / meanSquareError) : 100; - - std::cout << "psnr r :: " << mPsnr[0] << " psnr g :: " << mPsnr[1] << " psnr b :: " << mPsnr[2] - << std::endl; -} - -void UltraHdrAppInput::computeYUVHdrPSNR() { - if (mOf == ULTRAHDR_OUTPUT_SDR || mOf == ULTRAHDR_OUTPUT_HDR_LINEAR) { - std::cout << "psnr not supported for output format " << mOf << std::endl; - return; - } - uint16_t* yuvDataSrc = static_cast<uint16_t*>(mRawP010Image.data); - uint16_t* yuvDataDst = static_cast<uint16_t*>(mDestYUV444Image.data); - if (yuvDataSrc == nullptr || yuvDataDst == nullptr) { - std::cerr << "invalid src or dst pointer for psnr computation " << std::endl; - return; - } - if ((mOf == ULTRAHDR_OUTPUT_HDR_PQ && mTf != ULTRAHDR_TF_PQ) || - (mOf == ULTRAHDR_OUTPUT_HDR_HLG && mTf != ULTRAHDR_TF_HLG)) { - std::cout << "input transfer function and output format are not compatible, psnr results " - "may be unreliable" - << std::endl; - } - - uint16_t* yDataSrc = static_cast<uint16_t*>(mRawP010Image.data); - uint16_t* uDataSrc = yDataSrc + (mRawP010Image.width * mRawP010Image.height); - uint16_t* vDataSrc = uDataSrc + 1; - - uint16_t* yDataDst = static_cast<uint16_t*>(mDestYUV444Image.data); - uint16_t* uDataDst = yDataDst + (mDestYUV444Image.width * mDestYUV444Image.height); - uint16_t* vDataDst = uDataDst + (mDestYUV444Image.width * mDestYUV444Image.height); - - uint64_t ySqError = 0, uSqError = 0, vSqError = 0; - for (size_t i = 0; i < mDestYUV444Image.height; i++) { - for (size_t j = 0; j < mDestYUV444Image.width; j++) { - int ySrc = (yDataSrc[mRawP010Image.width * i + j] >> 6) & 0x3ff; - ySrc = CLIP3(ySrc, 64, 940); - int yDst = yDataDst[mDestYUV444Image.width * i + j] & 0x3ff; - ySqError += (ySrc - yDst) * (ySrc - yDst); - - if (i % 2 == 0 && j % 2 == 0) { - int uSrc = (uDataSrc[mRawP010Image.width * (i / 2) + (j / 2) * 2] >> 6) & 0x3ff; - uSrc = CLIP3(uSrc, 64, 960); - int uDst = uDataDst[mDestYUV444Image.width * i + j] & 0x3ff; - uDst += uDataDst[mDestYUV444Image.width * i + j + 1] & 0x3ff; - uDst += uDataDst[mDestYUV444Image.width * (i + 1) + j + 1] & 0x3ff; - uDst += uDataDst[mDestYUV444Image.width * (i + 1) + j + 1] & 0x3ff; - uDst = (uDst + 2) >> 2; - uSqError += (uSrc - uDst) * (uSrc - uDst); - - int vSrc = (vDataSrc[mRawP010Image.width * (i / 2) + (j / 2) * 2] >> 6) & 0x3ff; - vSrc = CLIP3(vSrc, 64, 960); - int vDst = vDataDst[mDestYUV444Image.width * i + j] & 0x3ff; - vDst += vDataDst[mDestYUV444Image.width * i + j + 1] & 0x3ff; - vDst += vDataDst[mDestYUV444Image.width * (i + 1) + j + 1] & 0x3ff; - vDst += vDataDst[mDestYUV444Image.width * (i + 1) + j + 1] & 0x3ff; - vDst = (vDst + 2) >> 2; - vSqError += (vSrc - vDst) * (vSrc - vDst); - } - } - } - - double meanSquareError = (double)ySqError / (mDestYUV444Image.width * mDestYUV444Image.height); - mPsnr[0] = meanSquareError ? 10 * log10((double)1023 * 1023 / meanSquareError) : 100; - - meanSquareError = (double)uSqError / (mDestYUV444Image.width * mDestYUV444Image.height / 4); - mPsnr[1] = meanSquareError ? 10 * log10((double)1023 * 1023 / meanSquareError) : 100; - - meanSquareError = (double)vSqError / (mDestYUV444Image.width * mDestYUV444Image.height / 4); - mPsnr[2] = meanSquareError ? 10 * log10((double)1023 * 1023 / meanSquareError) : 100; - - std::cout << "psnr y :: " << mPsnr[0] << " psnr u :: " << mPsnr[1] << " psnr v :: " << mPsnr[2] - << std::endl; -} - -void UltraHdrAppInput::computeYUVSdrPSNR() { - if (mOf != ULTRAHDR_OUTPUT_SDR) { - std::cout << "psnr not supported for output format " << mOf << std::endl; - return; - } - - uint8_t* yDataSrc = static_cast<uint8_t*>(mRawYuv420Image.data); - uint8_t* uDataSrc = yDataSrc + (mRawYuv420Image.width * mRawYuv420Image.height); - uint8_t* vDataSrc = uDataSrc + (mRawYuv420Image.width * mRawYuv420Image.height / 4); - - uint8_t* yDataDst = static_cast<uint8_t*>(mDestYUV444Image.data); - uint8_t* uDataDst = yDataDst + (mDestYUV444Image.width * mDestYUV444Image.height); - uint8_t* vDataDst = uDataDst + (mDestYUV444Image.width * mDestYUV444Image.height); - - uint64_t ySqError = 0, uSqError = 0, vSqError = 0; - for (size_t i = 0; i < mDestYUV444Image.height; i++) { - for (size_t j = 0; j < mDestYUV444Image.width; j++) { - int ySrc = yDataSrc[mRawYuv420Image.width * i + j]; - int yDst = yDataDst[mDestYUV444Image.width * i + j]; - ySqError += (ySrc - yDst) * (ySrc - yDst); - - if (i % 2 == 0 && j % 2 == 0) { - int uSrc = uDataSrc[mRawYuv420Image.width / 2 * (i / 2) + j / 2]; - int uDst = uDataDst[mDestYUV444Image.width * i + j]; - uDst += uDataDst[mDestYUV444Image.width * i + j + 1]; - uDst += uDataDst[mDestYUV444Image.width * (i + 1) + j]; - uDst += uDataDst[mDestYUV444Image.width * (i + 1) + j + 1]; - uDst = (uDst + 2) >> 2; - uSqError += (uSrc - uDst) * (uSrc - uDst); - - int vSrc = vDataSrc[mRawYuv420Image.width / 2 * (i / 2) + j / 2]; - int vDst = vDataDst[mDestYUV444Image.width * i + j]; - vDst += vDataDst[mDestYUV444Image.width * i + j + 1]; - vDst += vDataDst[mDestYUV444Image.width * (i + 1) + j]; - vDst += vDataDst[mDestYUV444Image.width * (i + 1) + j + 1]; - vDst = (vDst + 2) >> 2; - vSqError += (vSrc - vDst) * (vSrc - vDst); - } - } - } - double meanSquareError = (double)ySqError / (mDestYUV444Image.width * mDestYUV444Image.height); - mPsnr[0] = meanSquareError ? 10 * log10((double)255 * 255 / meanSquareError) : 100; - - meanSquareError = (double)uSqError / (mDestYUV444Image.width * mDestYUV444Image.height / 4); - mPsnr[1] = meanSquareError ? 10 * log10((double)255 * 255 / meanSquareError) : 100; - - meanSquareError = (double)vSqError / (mDestYUV444Image.width * mDestYUV444Image.height / 4); - mPsnr[2] = meanSquareError ? 10 * log10((double)255 * 255 / meanSquareError) : 100; - - std::cout << "psnr y :: " << mPsnr[0] << " psnr u:: " << mPsnr[1] << " psnr v :: " << mPsnr[2] - << std::endl; -} - -static void usage(const char* name) { - fprintf(stderr, "\n## ultra hdr demo application.\nUsage : %s \n", name); - fprintf(stderr, " -m mode of operation. [0: encode, 1:decode] \n"); - fprintf(stderr, "\n## encoder options : \n"); - fprintf(stderr, " -p raw 10 bit input resource in p010 color format, mandatory. \n"); - fprintf(stderr, " -y raw 8 bit input resource in yuv420, optional. \n" - " if not provided tonemapping happens internally. \n"); - fprintf(stderr, " -i compressed 8 bit jpeg file path, optional \n"); - fprintf(stderr, " -w input file width, mandatory. \n"); - fprintf(stderr, " -h input file height, mandatory. \n"); - fprintf(stderr, " -C 10 bit input color gamut, optional. [0:bt709, 1:p3, 2:bt2100] \n"); - fprintf(stderr, " -c 8 bit input color gamut, optional. [0:bt709, 1:p3, 2:bt2100] \n"); - fprintf(stderr, " -t input transfer function, optional. [0:linear, 1:hlg, 2:pq] \n"); - fprintf(stderr, " -q quality factor to be used while encoding 8 bit image, optional. [0-100].\n" - " gain map image does not use this quality factor. \n" - " for now gain map image quality factor is not configurable. \n"); - fprintf(stderr, " -e compute psnr, optional. [0:yes, 1:no] \n"); - fprintf(stderr, "\n## decoder options : \n"); - fprintf(stderr, " -j ultra hdr input resource, mandatory in decode mode. \n"); - fprintf(stderr, " -o output transfer function, optional. [0:sdr, 1:hdr_linear, 2:hdr_pq, 3:hdr_hlg] \n"); - fprintf(stderr, "\n## examples of usage :\n"); - fprintf(stderr, "\n## encode api-0 :\n"); - fprintf(stderr, " ultrahdr_app -m 0 -p cosmat_1920x1080_p010.yuv -w 1920 -h 1080 -q 97\n"); - fprintf(stderr, " ultrahdr_app -m 0 -p cosmat_1920x1080_p010.yuv -w 1920 -h 1080 -q 97 -C 2 -t 2\n"); - fprintf(stderr, "\n## encode api-1 :\n"); - fprintf(stderr, " ultrahdr_app -m 0 -p cosmat_1920x1080_p010.yuv -y cosmat_1920x1080_420.yuv -w 1920 -h 1080 -q 97\n"); - fprintf(stderr, " ultrahdr_app -m 0 -p cosmat_1920x1080_p010.yuv -y cosmat_1920x1080_420.yuv -w 1920 -h 1080 -q 97\n"); - fprintf(stderr, " ultrahdr_app -m 0 -p cosmat_1920x1080_p010.yuv -y cosmat_1920x1080_420.yuv -w 1920 -h 1080 -q 97 -C 2 -c 1 -t 1\n"); - fprintf(stderr, " ultrahdr_app -m 0 -p cosmat_1920x1080_p010.yuv -y cosmat_1920x1080_420.yuv -w 1920 -h 1080 -q 97 -C 2 -c 1 -t 1 -e 1\n"); - fprintf(stderr, "\n## encode api-2 :\n"); - fprintf(stderr, " ultrahdr_app -m 0 -p cosmat_1920x1080_p010.yuv -y cosmat_1920x1080_420.yuv -i cosmat_1920x1080_420_8bit.jpg -w 1920 -h 1080 -t 1 -o 3 -e 1\n"); - fprintf(stderr, "\n## encode api-3 :\n"); - fprintf(stderr, " ultrahdr_app -m 0 -p cosmat_1920x1080_p010.yuv -i cosmat_1920x1080_420_8bit.jpg -w 1920 -h 1080 -t 1 -o 3 -e 1\n"); - fprintf(stderr, "\n## decode api :\n"); - fprintf(stderr, " ultrahdr_app -m 1 -j cosmat_1920x1080_hdr.jpg \n"); - fprintf(stderr, " ultrahdr_app -m 1 -j cosmat_1920x1080_hdr.jpg -o 2\n"); - fprintf(stderr, "\n"); -} - -int main(int argc, char* argv[]) { - char *p010_file = nullptr, *yuv420_file = nullptr, *jpegr_file = nullptr, - *yuv420_jpeg_file = nullptr; - int width = 0, height = 0; - ultrahdr_color_gamut p010Cg = ULTRAHDR_COLORGAMUT_BT709; - ultrahdr_color_gamut yuv420Cg = ULTRAHDR_COLORGAMUT_BT709; - ultrahdr_transfer_function tf = ULTRAHDR_TF_HLG; - int quality = 100; - ultrahdr_output_format of = ULTRAHDR_OUTPUT_HDR_HLG; - int mode = 0; - int compute_psnr = 0; - int ch; - while ((ch = getopt(argc, argv, "p:y:i:w:h:C:c:t:q:o:m:j:e:")) != -1) { - switch (ch) { - case 'p': - p010_file = optarg; - break; - case 'y': - yuv420_file = optarg; - break; - case 'i': - yuv420_jpeg_file = optarg; - break; - case 'w': - width = atoi(optarg); - break; - case 'h': - height = atoi(optarg); - break; - case 'C': - p010Cg = static_cast<ultrahdr_color_gamut>(atoi(optarg)); - break; - case 'c': - yuv420Cg = static_cast<ultrahdr_color_gamut>(atoi(optarg)); - break; - case 't': - tf = static_cast<ultrahdr_transfer_function>(atoi(optarg)); - break; - case 'q': - quality = atoi(optarg); - break; - case 'o': - of = static_cast<ultrahdr_output_format>(atoi(optarg)); - break; - case 'm': - mode = atoi(optarg); - break; - case 'j': - jpegr_file = optarg; - break; - case 'e': - compute_psnr = atoi(optarg); - break; - default: - usage(argv[0]); - return -1; - } - } - if (mode == 0) { - if (width <= 0 || height <= 0 || p010_file == nullptr) { - usage(argv[0]); - return -1; - } - UltraHdrAppInput appInput(p010_file, yuv420_file, yuv420_jpeg_file, width, height, p010Cg, - yuv420Cg, tf, quality, of); - if (!appInput.encode()) return -1; - if (compute_psnr == 1) { - if (!appInput.decode()) return -1; - if (of == ULTRAHDR_OUTPUT_SDR && yuv420_file != nullptr) { - appInput.convertYuv420ToRGBImage(); - appInput.computeRGBSdrPSNR(); - appInput.convertRgba8888ToYUV444Image(); - appInput.computeYUVSdrPSNR(); - } else if (of == ULTRAHDR_OUTPUT_HDR_HLG || of == ULTRAHDR_OUTPUT_HDR_PQ) { - appInput.convertP010ToRGBImage(); - appInput.computeRGBHdrPSNR(); - appInput.convertRgba1010102ToYUV444Image(); - appInput.computeYUVHdrPSNR(); - } - } - } else if (mode == 1) { - if (jpegr_file == nullptr) { - usage(argv[0]); - return -1; - } - UltraHdrAppInput appInput(jpegr_file, of); - if (!appInput.decode()) return -1; - } else { - std::cerr << "unrecognized input mode " << mode << std::endl; - usage(argv[0]); - return -1; - } - - return 0; -} |