Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit eca8194f authored by Ram Mohan's avatar Ram Mohan Committed by Dichen Zhang
Browse files

ultrahdr: update jpegencoderhelper to accept uncompressed struct fields

With this change we can now pass luma/chroma ptrs and stride information
to jpegencoderhelper class during compression. This by passes
intermediate copy whenever possible

Also updated fuzzer to incorporate 420 stride support

updated jpegr unit tests for more combinations of gamuts and unusual strides

Bug: 294218453
Test: ./ultrahdr_unit_test
Test: ./ultrahdr_enc_fuzzer

Change-Id: Ic50dd34b0c680618e73e0cb27f554b9bf8272e8f
parent 88c57a25
Loading
Loading
Loading
Loading
+78 −38
Original line number Diff line number Diff line
@@ -23,8 +23,8 @@

// User include files
#include "ultrahdr/gainmapmath.h"
#include "ultrahdr/jpegencoderhelper.h"
#include "ultrahdr/jpegdecoderhelper.h"
#include "ultrahdr/jpegencoderhelper.h"
#include "utils/Log.h"

using namespace android::ultrahdr;
@@ -50,7 +50,7 @@ public:
    UltraHdrEncFuzzer(const uint8_t* data, size_t size) : mFdp(data, size){};
    void process();
    void fillP010Buffer(uint16_t* data, int width, int height, int stride);
    void fill420Buffer(uint8_t* data, int size);
    void fill420Buffer(uint8_t* data, int width, int height, int stride);

private:
    FuzzedDataProvider mFdp;
@@ -73,14 +73,19 @@ void UltraHdrEncFuzzer::fillP010Buffer(uint16_t* data, int width, int height, in
    }
}

void UltraHdrEncFuzzer::fill420Buffer(uint8_t* data, int size) {
void UltraHdrEncFuzzer::fill420Buffer(uint8_t* data, int width, int height, int stride) {
    uint8_t* tmp = data;
    std::vector<uint8_t> buffer(16);
    mFdp.ConsumeData(buffer.data(), buffer.size());
    for (int i = 0; i < size; i += buffer.size()) {
        memcpy(data + i, buffer.data(), std::min((int)buffer.size(), (size - i)));
    for (int j = 0; j < height; j++) {
        for (int i = 0; i < width; i += buffer.size()) {
            memcpy(tmp + i, buffer.data(),
                   std::min((int)buffer.size(), (width - i)) * sizeof(*data));
            std::shuffle(buffer.begin(), buffer.end(),
                         std::default_random_engine(std::random_device{}()));
        }
        tmp += stride;
    }
}

void UltraHdrEncFuzzer::process() {
@@ -120,9 +125,10 @@ void UltraHdrEncFuzzer::process() {
        int height = mFdp.ConsumeIntegralInRange<int>(kMinHeight, kMaxHeight);
        height = (height >> 1) << 1;

        std::unique_ptr<uint16_t[]> bufferY = nullptr;
        std::unique_ptr<uint16_t[]> bufferUV = nullptr;
        std::unique_ptr<uint8_t[]> yuv420ImgRaw = nullptr;
        std::unique_ptr<uint16_t[]> bufferYHdr = nullptr;
        std::unique_ptr<uint16_t[]> bufferUVHdr = nullptr;
        std::unique_ptr<uint8_t[]> bufferYSdr = nullptr;
        std::unique_ptr<uint8_t[]> bufferUVSdr = nullptr;
        std::unique_ptr<uint8_t[]> grayImgRaw = nullptr;
        if (muxSwitch != 4) {
            // init p010 image
@@ -136,30 +142,29 @@ void UltraHdrEncFuzzer::process() {
            int bppP010 = 2;
            if (isUVContiguous) {
                size_t p010Size = yStride * height * 3 / 2;
                bufferY = std::make_unique<uint16_t[]>(p010Size);
                p010Img.data = bufferY.get();
                bufferYHdr = std::make_unique<uint16_t[]>(p010Size);
                p010Img.data = bufferYHdr.get();
                p010Img.chroma_data = nullptr;
                p010Img.chroma_stride = 0;
                fillP010Buffer(bufferY.get(), width, height, yStride);
                fillP010Buffer(bufferY.get() + yStride * height, width, height / 2, yStride);
                fillP010Buffer(bufferYHdr.get(), width, height, yStride);
                fillP010Buffer(bufferYHdr.get() + yStride * height, width, height / 2, yStride);
            } else {
                int uvStride = mFdp.ConsumeIntegralInRange<int>(width, width + 128);
                size_t p010YSize = yStride * height;
                bufferY = std::make_unique<uint16_t[]>(p010YSize);
                p010Img.data = bufferY.get();
                fillP010Buffer(bufferY.get(), width, height, yStride);
                bufferYHdr = std::make_unique<uint16_t[]>(p010YSize);
                p010Img.data = bufferYHdr.get();
                fillP010Buffer(bufferYHdr.get(), width, height, yStride);
                size_t p010UVSize = uvStride * p010Img.height / 2;
                bufferUV = std::make_unique<uint16_t[]>(p010UVSize);
                p010Img.chroma_data = bufferUV.get();
                bufferUVHdr = std::make_unique<uint16_t[]>(p010UVSize);
                p010Img.chroma_data = bufferUVHdr.get();
                p010Img.chroma_stride = uvStride;
                fillP010Buffer(bufferUV.get(), width, height / 2, uvStride);
                fillP010Buffer(bufferUVHdr.get(), width, height / 2, uvStride);
            }
        } else {
            int map_width = width / kMapDimensionScaleFactor;
            int map_height = height / kMapDimensionScaleFactor;
            map_width = static_cast<size_t>(floor((map_width + kJpegBlock - 1) / kJpegBlock)) *
                    kJpegBlock;
            map_height = ((map_height + 1) >> 1) << 1;
            size_t map_width = static_cast<size_t>(
                    floor((width + kMapDimensionScaleFactor - 1) / kMapDimensionScaleFactor));
            size_t map_height = static_cast<size_t>(
                    floor((height + kMapDimensionScaleFactor - 1) / kMapDimensionScaleFactor));
            // init 400 image
            grayImg.width = map_width;
            grayImg.height = map_height;
@@ -168,7 +173,7 @@ void UltraHdrEncFuzzer::process() {
            const size_t graySize = map_width * map_height;
            grayImgRaw = std::make_unique<uint8_t[]>(graySize);
            grayImg.data = grayImgRaw.get();
            fill420Buffer(grayImgRaw.get(), graySize);
            fill420Buffer(grayImgRaw.get(), map_width, map_height, map_width);
            grayImg.chroma_data = nullptr;
            grayImg.luma_stride = 0;
            grayImg.chroma_stride = 0;
@@ -176,17 +181,38 @@ void UltraHdrEncFuzzer::process() {

        if (muxSwitch > 0) {
            // init 420 image
            bool isUVContiguous = mFdp.ConsumeBool();
            bool hasYStride = mFdp.ConsumeBool();
            int yStride = hasYStride ? mFdp.ConsumeIntegralInRange<int>(width, width + 128) : width;
            yuv420Img.width = width;
            yuv420Img.height = height;
            yuv420Img.colorGamut = yuv420Cg;

            const size_t yuv420Size = (yuv420Img.width * yuv420Img.height * 3) / 2;
            yuv420ImgRaw = std::make_unique<uint8_t[]>(yuv420Size);
            yuv420Img.data = yuv420ImgRaw.get();
            fill420Buffer(yuv420ImgRaw.get(), yuv420Size);
            yuv420Img.luma_stride = hasYStride ? yStride : 0;
            if (isUVContiguous) {
                size_t yuv420Size = yStride * height * 3 / 2;
                bufferYSdr = std::make_unique<uint8_t[]>(yuv420Size);
                yuv420Img.data = bufferYSdr.get();
                yuv420Img.chroma_data = nullptr;
            yuv420Img.luma_stride = 0;
                yuv420Img.chroma_stride = 0;
                fill420Buffer(bufferYSdr.get(), width, height, yStride);
                fill420Buffer(bufferYSdr.get() + yStride * height, width / 2, height / 2,
                              yStride / 2);
                fill420Buffer(bufferYSdr.get() + yStride * height * 5 / 4, width / 2, height / 2,
                              yStride / 2);
            } else {
                int uvStride = mFdp.ConsumeIntegralInRange<int>(width / 2, width / 2 + 128);
                size_t yuv420YSize = yStride * height;
                bufferYSdr = std::make_unique<uint8_t[]>(yuv420YSize);
                yuv420Img.data = bufferYSdr.get();
                fill420Buffer(bufferYSdr.get(), width, height, yStride);
                size_t yuv420UVSize = uvStride * yuv420Img.height / 2 * 2;
                bufferUVSdr = std::make_unique<uint8_t[]>(yuv420UVSize);
                yuv420Img.chroma_data = bufferYSdr.get();
                yuv420Img.chroma_stride = uvStride;
                fill420Buffer(bufferUVSdr.get(), width / 2, height / 2, uvStride);
                fill420Buffer(bufferUVSdr.get() + uvStride * height / 2, width / 2, height / 2,
                              uvStride);
            }
        }

        // dest
@@ -203,6 +229,8 @@ void UltraHdrEncFuzzer::process() {
        std::cout << "p010 luma stride " << p010Img.luma_stride << std::endl;
        std::cout << "p010 chroma stride " << p010Img.chroma_stride << std::endl;
        std::cout << "420 color gamut " << yuv420Img.colorGamut << std::endl;
        std::cout << "420 luma stride " << yuv420Img.luma_stride << std::endl;
        std::cout << "420 chroma stride " << yuv420Img.chroma_stride << std::endl;
        std::cout << "quality factor " << quality << std::endl;
#endif

@@ -217,8 +245,19 @@ void UltraHdrEncFuzzer::process() {
        } else {
            // compressed img
            JpegEncoderHelper encoder;
            if (encoder.compressImage(yuv420Img.data, yuv420Img.width, yuv420Img.height, quality,
                                      nullptr, 0)) {
            struct jpegr_uncompressed_struct yuv420ImgCopy = yuv420Img;
            if (yuv420ImgCopy.luma_stride == 0) yuv420ImgCopy.luma_stride = yuv420Img.width;
            if (!yuv420ImgCopy.chroma_data) {
                uint8_t* data = reinterpret_cast<uint8_t*>(yuv420Img.data);
                yuv420ImgCopy.chroma_data = data + yuv420Img.luma_stride * yuv420Img.height;
                yuv420ImgCopy.chroma_stride = yuv420Img.luma_stride >> 1;
            }

            if (encoder.compressImage(reinterpret_cast<uint8_t*>(yuv420ImgCopy.data),
                                      reinterpret_cast<uint8_t*>(yuv420ImgCopy.chroma_data),
                                      yuv420ImgCopy.width, yuv420ImgCopy.height,
                                      yuv420ImgCopy.luma_stride, yuv420ImgCopy.chroma_stride,
                                      quality, nullptr, 0)) {
                jpegImg.length = encoder.getCompressedImageSize();
                jpegImg.maxLength = jpegImg.length;
                jpegImg.data = encoder.getCompressedImagePtr();
@@ -233,8 +272,9 @@ void UltraHdrEncFuzzer::process() {
                } else if (muxSwitch == 4) { // api 4
                    jpegImgR.length = 0;
                    JpegEncoderHelper gainMapEncoder;
                    if (gainMapEncoder.compressImage(grayImg.data, grayImg.width, grayImg.height,
                                                     quality, nullptr, 0, true)) {
                    if (gainMapEncoder.compressImage(reinterpret_cast<uint8_t*>(grayImg.data),
                                                     nullptr, grayImg.width, grayImg.height,
                                                     grayImg.width, 0, quality, nullptr, 0)) {
                        jpegGainMap.length = gainMapEncoder.getCompressedImageSize();
                        jpegGainMap.maxLength = jpegImg.length;
                        jpegGainMap.data = gainMapEncoder.getCompressedImagePtr();
+13 −8
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@

// We must include cstdio before jpeglib.h. It is a requirement of libjpeg.
#include <cstdio>
#include <vector>

extern "C" {
#include <jerror.h>
@@ -26,10 +27,11 @@ extern "C" {
}

#include <utils/Errors.h>
#include <vector>

namespace android::ultrahdr {

#define ALIGNM(x, m) ((((x) + ((m)-1)) / (m)) * (m))

/*
 * Encapsulates a converter from raw image (YUV420planer or grey-scale) to JPEG format.
 * This class is not thread-safe.
@@ -46,8 +48,9 @@ public:
     * ICC segment which will be added to the compressed image.
     * Returns false if errors occur during compression.
     */
    bool compressImage(const void* image, int width, int height, int quality,
                       const void* iccBuffer, unsigned int iccSize, bool isSingleChannel = false);
    bool compressImage(const uint8_t* yBuffer, const uint8_t* uvBuffer, int width, int height,
                       int lumaStride, int chromaStride, int quality, const void* iccBuffer,
                       unsigned int iccSize);

    /*
     * Returns the compressed JPEG buffer pointer. This method must be called only after calling
@@ -66,6 +69,7 @@ public:
     * We must pass at least 16 scanlines according to libjpeg documentation.
     */
    static const int kCompressBatchSize = 16;

private:
    // initDestination(), emptyOutputBuffer() and emptyOutputBuffer() are callback functions to be
    // passed into jpeg library.
@@ -75,15 +79,16 @@ private:
    static void outputErrorMessage(j_common_ptr cinfo);

    // Returns false if errors occur.
    bool encode(const void* inYuv, int width, int height, int jpegQuality,
                const void* iccBuffer, unsigned int iccSize, bool isSingleChannel);
    bool encode(const uint8_t* yBuffer, const uint8_t* uvBuffer, int width, int height,
                int lumaStride, int chromaStride, int quality, const void* iccBuffer,
                unsigned int iccSize);
    void setJpegDestination(jpeg_compress_struct* cinfo);
    void setJpegCompressStruct(int width, int height, int quality, jpeg_compress_struct* cinfo,
                               bool isSingleChannel);
    // Returns false if errors occur.
    bool compress(jpeg_compress_struct* cinfo, const uint8_t* image, bool isSingleChannel);
    bool compressYuv(jpeg_compress_struct* cinfo, const uint8_t* yuv);
    bool compressSingleChannel(jpeg_compress_struct* cinfo, const uint8_t* image);
    bool compressYuv(jpeg_compress_struct* cinfo, const uint8_t* yBuffer, const uint8_t* uvBuffer,
                     int lumaStride, int chromaStride);
    bool compressY(jpeg_compress_struct* cinfo, const uint8_t* yBuffer, int lumaStride);

    // The block size for encoded jpeg image buffer.
    static const int kBlockSize = 16384;
+34 −39
Original line number Diff line number Diff line
@@ -23,8 +23,6 @@

namespace android::ultrahdr {

#define ALIGNM(x, m) ((((x) + ((m)-1)) / (m)) * (m))

// The destination manager that can access |mResultBuffer| in JpegEncoderHelper.
struct destination_mgr {
    struct jpeg_destination_mgr mgr;
@@ -35,11 +33,12 @@ JpegEncoderHelper::JpegEncoderHelper() {}

JpegEncoderHelper::~JpegEncoderHelper() {}

bool JpegEncoderHelper::compressImage(const void* image, int width, int height, int quality,
                                      const void* iccBuffer, unsigned int iccSize,
                                      bool isSingleChannel) {
bool JpegEncoderHelper::compressImage(const uint8_t* yBuffer, const uint8_t* uvBuffer, int width,
                                      int height, int lumaStride, int chromaStride, int quality,
                                      const void* iccBuffer, unsigned int iccSize) {
    mResultBuffer.clear();
    if (!encode(image, width, height, quality, iccBuffer, iccSize, isSingleChannel)) {
    if (!encode(yBuffer, uvBuffer, width, height, lumaStride, chromaStride, quality, iccBuffer,
                iccSize)) {
        return false;
    }
    ALOGI("Compressed JPEG: %d[%dx%d] -> %zu bytes", (width * height * 12) / 8, width, height,
@@ -87,25 +86,24 @@ void JpegEncoderHelper::outputErrorMessage(j_common_ptr cinfo) {
    ALOGE("%s\n", buffer);
}

bool JpegEncoderHelper::encode(const void* image, int width, int height, int jpegQuality,
                               const void* iccBuffer, unsigned int iccSize, bool isSingleChannel) {
bool JpegEncoderHelper::encode(const uint8_t* yBuffer, const uint8_t* uvBuffer, int width,
                               int height, int lumaStride, int chromaStride, int quality,
                               const void* iccBuffer, unsigned int iccSize) {
    jpeg_compress_struct cinfo;
    jpeg_error_mgr jerr;

    cinfo.err = jpeg_std_error(&jerr);
    // Override output_message() to print error log with ALOGE().
    cinfo.err->output_message = &outputErrorMessage;
    jpeg_create_compress(&cinfo);
    setJpegDestination(&cinfo);

    setJpegCompressStruct(width, height, jpegQuality, &cinfo, isSingleChannel);
    setJpegCompressStruct(width, height, quality, &cinfo, uvBuffer == nullptr);
    jpeg_start_compress(&cinfo, TRUE);

    if (iccBuffer != nullptr && iccSize > 0) {
        jpeg_write_marker(&cinfo, JPEG_APP0 + 2, static_cast<const JOCTET*>(iccBuffer), iccSize);
    }

    bool status = compress(&cinfo, static_cast<const uint8_t*>(image), isSingleChannel);
    bool status = cinfo.num_components == 1
            ? compressY(&cinfo, yBuffer, lumaStride)
            : compressYuv(&cinfo, yBuffer, uvBuffer, lumaStride, chromaStride);
    jpeg_finish_compress(&cinfo);
    jpeg_destroy_compress(&cinfo);

@@ -141,27 +139,23 @@ void JpegEncoderHelper::setJpegCompressStruct(int width, int height, int quality
    }
}

bool JpegEncoderHelper::compress(jpeg_compress_struct* cinfo, const uint8_t* image,
                                 bool isSingleChannel) {
    return isSingleChannel ? compressSingleChannel(cinfo, image) : compressYuv(cinfo, image);
}

bool JpegEncoderHelper::compressYuv(jpeg_compress_struct* cinfo, const uint8_t* yuv) {
bool JpegEncoderHelper::compressYuv(jpeg_compress_struct* cinfo, const uint8_t* yBuffer,
                                    const uint8_t* uvBuffer, int lumaStride, int chromaStride) {
    JSAMPROW y[kCompressBatchSize];
    JSAMPROW cb[kCompressBatchSize / 2];
    JSAMPROW cr[kCompressBatchSize / 2];
    JSAMPARRAY planes[3]{y, cb, cr};

    size_t y_plane_size = cinfo->image_width * cinfo->image_height;
    size_t uv_plane_size = y_plane_size / 4;
    uint8_t* y_plane = const_cast<uint8_t*>(yuv);
    uint8_t* u_plane = const_cast<uint8_t*>(yuv + y_plane_size);
    uint8_t* v_plane = const_cast<uint8_t*>(yuv + y_plane_size + uv_plane_size);
    size_t y_plane_size = lumaStride * cinfo->image_height;
    size_t u_plane_size = chromaStride * cinfo->image_height / 2;
    uint8_t* y_plane = const_cast<uint8_t*>(yBuffer);
    uint8_t* u_plane = const_cast<uint8_t*>(uvBuffer);
    uint8_t* v_plane = const_cast<uint8_t*>(u_plane + u_plane_size);
    std::unique_ptr<uint8_t[]> empty = std::make_unique<uint8_t[]>(cinfo->image_width);
    memset(empty.get(), 0, cinfo->image_width);

    const int aligned_width = ALIGNM(cinfo->image_width, kCompressBatchSize);
    const bool is_width_aligned = (aligned_width == cinfo->image_width);
    const bool need_padding = (lumaStride < aligned_width);
    std::unique_ptr<uint8_t[]> buffer_intrm = nullptr;
    uint8_t* y_plane_intrm = nullptr;
    uint8_t* u_plane_intrm = nullptr;
@@ -170,7 +164,7 @@ bool JpegEncoderHelper::compressYuv(jpeg_compress_struct* cinfo, const uint8_t*
    JSAMPROW cb_intrm[kCompressBatchSize / 2];
    JSAMPROW cr_intrm[kCompressBatchSize / 2];
    JSAMPARRAY planes_intrm[3]{y_intrm, cb_intrm, cr_intrm};
    if (!is_width_aligned) {
    if (need_padding) {
        size_t mcu_row_size = aligned_width * kCompressBatchSize * 3 / 2;
        buffer_intrm = std::make_unique<uint8_t[]>(mcu_row_size);
        y_plane_intrm = buffer_intrm.get();
@@ -195,11 +189,11 @@ bool JpegEncoderHelper::compressYuv(jpeg_compress_struct* cinfo, const uint8_t*
        for (int i = 0; i < kCompressBatchSize; ++i) {
            size_t scanline = cinfo->next_scanline + i;
            if (scanline < cinfo->image_height) {
                y[i] = y_plane + scanline * cinfo->image_width;
                y[i] = y_plane + scanline * lumaStride;
            } else {
                y[i] = empty.get();
            }
            if (!is_width_aligned) {
            if (need_padding) {
                memcpy(y_intrm[i], y[i], cinfo->image_width);
            }
        }
@@ -207,18 +201,18 @@ bool JpegEncoderHelper::compressYuv(jpeg_compress_struct* cinfo, const uint8_t*
        for (int i = 0; i < kCompressBatchSize / 2; ++i) {
            size_t scanline = cinfo->next_scanline / 2 + i;
            if (scanline < cinfo->image_height / 2) {
                int offset = scanline * (cinfo->image_width / 2);
                int offset = scanline * chromaStride;
                cb[i] = u_plane + offset;
                cr[i] = v_plane + offset;
            } else {
                cb[i] = cr[i] = empty.get();
            }
            if (!is_width_aligned) {
            if (need_padding) {
                memcpy(cb_intrm[i], cb[i], cinfo->image_width / 2);
                memcpy(cr_intrm[i], cr[i], cinfo->image_width / 2);
            }
        }
        int processed = jpeg_write_raw_data(cinfo, is_width_aligned ? planes : planes_intrm,
        int processed = jpeg_write_raw_data(cinfo, need_padding ? planes_intrm : planes,
                                            kCompressBatchSize);
        if (processed != kCompressBatchSize) {
            ALOGE("Number of processed lines does not equal input lines.");
@@ -228,22 +222,23 @@ bool JpegEncoderHelper::compressYuv(jpeg_compress_struct* cinfo, const uint8_t*
    return true;
}

bool JpegEncoderHelper::compressSingleChannel(jpeg_compress_struct* cinfo, const uint8_t* image) {
bool JpegEncoderHelper::compressY(jpeg_compress_struct* cinfo, const uint8_t* yBuffer,
                                  int lumaStride) {
    JSAMPROW y[kCompressBatchSize];
    JSAMPARRAY planes[1]{y};

    uint8_t* y_plane = const_cast<uint8_t*>(image);
    uint8_t* y_plane = const_cast<uint8_t*>(yBuffer);
    std::unique_ptr<uint8_t[]> empty = std::make_unique<uint8_t[]>(cinfo->image_width);
    memset(empty.get(), 0, cinfo->image_width);

    const int aligned_width = ALIGNM(cinfo->image_width, kCompressBatchSize);
    bool is_width_aligned = (aligned_width == cinfo->image_width);
    const bool need_padding = (lumaStride < aligned_width);
    std::unique_ptr<uint8_t[]> buffer_intrm = nullptr;
    uint8_t* y_plane_intrm = nullptr;
    uint8_t* u_plane_intrm = nullptr;
    JSAMPROW y_intrm[kCompressBatchSize];
    JSAMPARRAY planes_intrm[]{y_intrm};
    if (!is_width_aligned) {
    if (need_padding) {
        size_t mcu_row_size = aligned_width * kCompressBatchSize;
        buffer_intrm = std::make_unique<uint8_t[]>(mcu_row_size);
        y_plane_intrm = buffer_intrm.get();
@@ -257,15 +252,15 @@ bool JpegEncoderHelper::compressSingleChannel(jpeg_compress_struct* cinfo, const
        for (int i = 0; i < kCompressBatchSize; ++i) {
            size_t scanline = cinfo->next_scanline + i;
            if (scanline < cinfo->image_height) {
                y[i] = y_plane + scanline * cinfo->image_width;
                y[i] = y_plane + scanline * lumaStride;
            } else {
                y[i] = empty.get();
            }
            if (!is_width_aligned) {
            if (need_padding) {
                memcpy(y_intrm[i], y[i], cinfo->image_width);
            }
        }
        int processed = jpeg_write_raw_data(cinfo, is_width_aligned ? planes : planes_intrm,
        int processed = jpeg_write_raw_data(cinfo, need_padding ? planes_intrm : planes,
                                            kCompressBatchSize);
        if (processed != kCompressBatchSize / 2) {
            ALOGE("Number of processed lines does not equal input lines.");
+69 −40

File changed.

Preview size limit exceeded, changes collapsed.

+10 −7
Original line number Diff line number Diff line
@@ -120,7 +120,7 @@ public:
      0xB0, 0xB1,
      0xB2, 0xB3,
    };
    return { pixels, 4, 4, ULTRAHDR_COLORGAMUT_BT709 };
    return { pixels, 4, 4, ULTRAHDR_COLORGAMUT_BT709, pixels + 16, 4, 2 };
  }

  Color (*Yuv420Colors())[4] {
@@ -153,7 +153,7 @@ public:
      0xA0 << 6, 0xB0 << 6, 0xA1 << 6, 0xB1 << 6,
      0xA2 << 6, 0xB2 << 6, 0xA3 << 6, 0xB3 << 6,
    };
    return { pixels, 4, 4, ULTRAHDR_COLORGAMUT_BT709 };
    return { pixels, 4, 4, ULTRAHDR_COLORGAMUT_BT709, pixels + 16, 4, 4 };
  }

  Color (*P010Colors())[4] {
@@ -625,7 +625,7 @@ TEST_F(GainMapMathTest, Bt2100ToBt601YuvConversion) {
  EXPECT_YUV_NEAR(yuv2100To601(yuv_b), P3YuvBlue());
}

TEST_F(GainMapMathTest, DISABLED_TransformYuv420) {
TEST_F(GainMapMathTest, TransformYuv420) {
  ColorTransformFn transforms[] = { yuv709To601, yuv709To2100, yuv601To709, yuv601To2100,
                                    yuv2100To709, yuv2100To601 };
  for (const ColorTransformFn& transform : transforms) {
@@ -636,6 +636,9 @@ TEST_F(GainMapMathTest, DISABLED_TransformYuv420) {
    memcpy(out_buf.get(), input.data, out_buf_size);
    jpegr_uncompressed_struct output = Yuv420Image();
    output.data = out_buf.get();
    output.chroma_data = out_buf.get() + input.width * input.height;
    output.luma_stride = input.width;
    output.chroma_stride = input.width / 2;

    transformYuv420(&output, 1, 1, transform);

@@ -1042,7 +1045,7 @@ TEST_F(GainMapMathTest, ApplyGain) {
                applyGain(e, 1.0f, &metadata, displayBoost));
}

TEST_F(GainMapMathTest, DISABLED_GetYuv420Pixel) {
TEST_F(GainMapMathTest, GetYuv420Pixel) {
  jpegr_uncompressed_struct image = Yuv420Image();
  Color (*colors)[4] = Yuv420Colors();

@@ -1053,7 +1056,7 @@ TEST_F(GainMapMathTest, DISABLED_GetYuv420Pixel) {
  }
}

TEST_F(GainMapMathTest, DISABLED_GetP010Pixel) {
TEST_F(GainMapMathTest, GetP010Pixel) {
  jpegr_uncompressed_struct image = P010Image();
  Color (*colors)[4] = P010Colors();

@@ -1064,7 +1067,7 @@ TEST_F(GainMapMathTest, DISABLED_GetP010Pixel) {
  }
}

TEST_F(GainMapMathTest, DISABLED_SampleYuv420) {
TEST_F(GainMapMathTest, SampleYuv420) {
  jpegr_uncompressed_struct image = Yuv420Image();
  Color (*colors)[4] = Yuv420Colors();

@@ -1090,7 +1093,7 @@ TEST_F(GainMapMathTest, DISABLED_SampleYuv420) {
  }
}

TEST_F(GainMapMathTest, DISABLED_SampleP010) {
TEST_F(GainMapMathTest, SampleP010) {
  jpegr_uncompressed_struct image = P010Image();
  Color (*colors)[4] = P010Colors();

Loading