Skip to content

input a JPG image that is not 4-byte aligned, decode error #107

@libaineu2004

Description

@libaineu2004

If input a JPG image whose width is not aligned in 4-byte increments, after opening and decoding, and then saving it using OpenCV, the image will be in a disorderly state.

src image, the image resolution is 61*57.
Image

target image, not good
Image

gpujpeg_decoder_decode(m_pDecoder, input_image, input_image_size, &decoder_output);
decoder_output.param_image.width_padding is always equal to 0


bool UseGpuJpeg::decode(const std::string &pathname, void *&buf, int &width, int &height, int &bytesPerLine, int &channel)
{
    if (m_pDecoder == nullptr)
    {
        return false;
    }

    //load image
    size_t input_image_size = 0;
    uint8_t *input_image;
    if (gpujpeg_image_load_from_file(pathname.c_str(), &input_image, &input_image_size) != 0)
    {
        return false;
    }

    //set decoder default output destination
    struct gpujpeg_decoder_output decoder_output;
    gpujpeg_decoder_output_set_default(&decoder_output);

    //decompress the image
    if (gpujpeg_decoder_decode(m_pDecoder, input_image, input_image_size, &decoder_output) != 0)
    {
        return false;
    }

    gpujpeg_image_destroy(input_image);

    //output
    buf = decoder_output.data;
    width = decoder_output.param_image.width;
    height = decoder_output.param_image.height;

    if (decoder_output.param_image.pixel_format == GPUJPEG_U8)
    {
        channel = 1;
    }
    else if (decoder_output.param_image.pixel_format == GPUJPEG_4444_U8_P0123)
    {
        channel = 4;
    }
    else
    {
        channel = 3;
    }

    // Fix me: param_image.width_padding is always equal to 0
    int bytesPerLine1 = width * channel + decoder_output.param_image.width_padding;
    bytesPerLine = ((width * channel * 8) + 31) / 32 * 4;

    return true;
}
void *buf = 0;
            int width = 0;
            int height = 0;
            int bytesPerLine = 0;
            int channel = 0;
            m_pGpuJpeg->decode("src.jpg", buf, width, height, bytesPerLine, channel);

            //use opencv
            cv::Mat m;
            if (channel == 1)
            {
                m = cv::Mat(height, width, CV_8UC1, buf, bytesPerLine);
            }
            else if (channel == 3)
            {
                m = cv::Mat(height, width, CV_8UC3, buf, bytesPerLine);
                cv::cvtColor(m, m, cv::COLOR_RGB2BGR);
            }
            
            cv::imwrite("d:/decode.jpg", m);

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions