使用jpeg_read_raw_data函数从jpeg文件中读取原始数据

时间:2010-08-11 11:08:10

标签: c++

抱歉我的英语不好......

因此,我尝试解压缩在Microsoft Paint中创建的128x128 jpeg图像。图像全黑。

我使用xawtv源作为示例创建我自己的jpeg到yuv解压缩器(http://xawtv.sourcearchive.com/documentation/3.95.dfsg.1/conv-mjpeg_8c-source.html)。解压缩器仅适用于yuv子采样的4:2:0级别。

当i等于112时,应用程序在jpeg_read_raw_data函数中抛出访问冲突。任何人都可以帮忙解决这个问题吗?

#include <fstream>
#include <iostream>
#include <string>
#include <vector>

#include "jpeglib.h"

typedef std::vector<unsigned char> buffer;

class decompressor
{
public:

    decompressor(buffer& ibuf)
          : ibuf_(ibuf), yuvbuf_(3)
    {
        info_.err = jpeg_std_error(&e_);

        jpeg_create_decompress(&info_);

        jpeg_mem_src(&info_, &ibuf_[0], ibuf_.size());
    }

    virtual ~decompressor()
    {
        jpeg_destroy_decompress(&info_);
    }

    virtual void decompress(buffer& obuf)
    {
        jpeg_read_header(&info_, 1);

        info_.raw_data_out = 1;

        jpeg_start_decompress(&info_);

        obuf.resize(
            info_.output_width *
            info_.output_height *
            info_.output_components);

        for (std::size_t i = 0; i < yuvbuf_.size(); ++i)
        {
            yuvbuf_[i].resize(info_.output_width);
            yuvptr_[i] = &yuvbuf_[i][0];
        }

        unsigned char* row = &obuf[0];

        for (std::size_t i = 0; i < info_.output_height; ++i, row += info_.output_width)
        {
            yuvptr_[0][i] = row;
        }

        row = &obuf[0] + info_.output_width * info_.output_height;

        for (std::size_t i = 0; i < info_.output_height; i += 2, row += info_.output_width / 2)
        {
            yuvptr_[1][i / 2] = row;
        }

        row = &obuf[0] + info_.output_width * info_.output_height * 5 / 4;

        for (std::size_t i = 0; i < info_.output_height; i += 2, row += info_.output_width / 2)
        {
            yuvptr_[2][i / 2] = row;
        }

        for (std::size_t i = 0; i < info_.output_height; i += 16)
        {
            jpeg_read_raw_data(&info_, yuvptr_, 16);

            yuvptr_[0] += 16;
            yuvptr_[1] += 8;
            yuvptr_[2] += 8;
        }

        jpeg_finish_decompress(&info_);
    }

protected:

    jpeg_decompress_struct info_;

    jpeg_error_mgr e_;

    buffer& ibuf_;

    std::vector<
        std::vector<unsigned char*>
    > yuvbuf_;

    unsigned char** yuvptr_[3];
};

int main()
{
    std::string filename;

    filename = "i.jpg";

    std::fstream ifs(filename.c_str(), std::ios::in | std::ios::binary);
    if (!ifs)
    {
        std::cout << "can not open file " << filename;
        return 1;
    }

    filename = "o.dat";

    std::fstream ofs(filename.c_str(), std::ios::out | std::ios::binary);
    if (!ofs)
    {
        std::cout << "can not open file " << filename;
        return 1;
    }

    std::size_t size;

    ifs.seekg(0, std::ios::end);
    size = ifs.tellg();
    ifs.seekg(0);

    buffer ibuf(size);
    buffer obuf;

    ifs.read((char*)&ibuf[0], ibuf.size());

    decompressor d(ibuf);

    d.decompress(obuf);

    ofs.write((char*)&obuf[0], obuf.size());

    return 1;
}

1 个答案:

答案 0 :(得分:0)

我发现了一个错误,但输出宽度和输出高度都等于128.所以问题不在这里......

for (std::size_t i = 0; i < yuvbuf_.size(); ++i)
{
    yuvbuf_[i].resize(info_.output_width);
    yuvptr_[i] = &yuvbuf_[i][0];
}