使用 OpenJPEG 在 C++ 中解码 jpeg2000 时出错
got an error on decoding jpeg2000 in c++ with OpenJPEG
我正在尝试使用 OpenJPEG 解码 JPEG2000 格式。
(仅解码 svs 文件中的一个原始图块缓冲区。)
但是我在 opj_read_header() 上遇到错误。
在调用 opj_read_header() 之前我忘记设置了什么吗?
opj_image_t *image = NULL;
int32_t datalen = tileByteCounts[test_num];
opj_stream_t *stream = opj_stream_create(datalen, true);
struct buffer_state state =
{
.data = buffer,
.length = datalen,
};
opj_stream_set_user_data(stream, &state, NULL);
opj_stream_set_user_data_length(stream, datalen);
opj_stream_set_read_function(stream, read_callback);
opj_stream_set_skip_function(stream, skip_callback);
opj_stream_set_seek_function(stream, seek_callback);
opj_codec_t *codec = opj_create_decompress(OPJ_CODEC_JP2);
opj_dparameters_t parameters;
opj_set_default_decoder_parameters(¶meters);
parameters.decod_format = 1;
parameters.cod_format = 2;
parameters.DA_x0 = 0;
parameters.DA_y0 = 0;
parameters.DA_x1 = tileWidth;
parameters.DA_y1 = tileHeight;
opj_setup_decoder(codec, ¶meters);
// enable error handlers
opj_set_warning_handler(codec, warning_callback, NULL);
opj_set_error_handler(codec, error_callback, NULL);
// read header
if (!opj_read_header(stream, codec, &image)) // It's calling error_callback !
{
printf("error on reading header");
return 1;
}
我会使用 libvips 从 SVS 图像中读取。它有一个由 openslide 开发人员编写的良好的 openslide 导入操作,可以很好地处理这种事情。它是免费的和跨平台的。大多数 linux 的包管理器中都有它。
在命令行你可以写:
$ vipsheader CMU-1.svs
CMU-1.svs: 46000x32914 uchar, 4 bands, rgb, openslideload
$ time vips crop CMU-1.svs x.jpg 10 10 100 100
real 0m0.058s
user 0m0.050s
sys 0m0.008s
请注意 jp2k 的解码速度相当慢。要转换整个图像,我看到:
$ time vips copy CMU-1.svs x.jpg --vips-progress
vips temp-5: 46000 x 32914 pixels, 8 threads, 128 x 128 tiles, 256 lines in buffer
vips temp-5: done in 14.6s
real 0m14.720s
user 1m10.978s
sys 0m1.179s
在 C++ 中:
// compile with
// g++ crop.cpp `pkg-config vips-cpp --cflags --libs`
#include <vips/vips8>
int
main (int argc, char **argv)
{
if (VIPS_INIT (argv[0]))
vips_error_exit (NULL);
vips::VImage image = vips::VImage::new_from_file (argv[1]);
image.write_to_file (argv[2]);
}
还有 C、Python、Ruby、JavaScript、PHP、C#、Go、Rust 等绑定。
您可以通过更改输出文件名或在 C++ 代码中设置可选参数来编写其他格式。例如,您可以 运行 该 C++ 程序:
$ ./a.out CMU-1.svs x.tif[compression=jpeg,tile,pyramid]
或者您可以将 write_to_file
更改为:
image.tiffsave (argv[2], VImage::option()
->set ("compression", "jpeg")
->set ("tile", TRUE)
->set ("pyramid", TRUE));
我正在尝试使用 OpenJPEG 解码 JPEG2000 格式。
(仅解码 svs 文件中的一个原始图块缓冲区。)
但是我在 opj_read_header() 上遇到错误。
在调用 opj_read_header() 之前我忘记设置了什么吗?
opj_image_t *image = NULL;
int32_t datalen = tileByteCounts[test_num];
opj_stream_t *stream = opj_stream_create(datalen, true);
struct buffer_state state =
{
.data = buffer,
.length = datalen,
};
opj_stream_set_user_data(stream, &state, NULL);
opj_stream_set_user_data_length(stream, datalen);
opj_stream_set_read_function(stream, read_callback);
opj_stream_set_skip_function(stream, skip_callback);
opj_stream_set_seek_function(stream, seek_callback);
opj_codec_t *codec = opj_create_decompress(OPJ_CODEC_JP2);
opj_dparameters_t parameters;
opj_set_default_decoder_parameters(¶meters);
parameters.decod_format = 1;
parameters.cod_format = 2;
parameters.DA_x0 = 0;
parameters.DA_y0 = 0;
parameters.DA_x1 = tileWidth;
parameters.DA_y1 = tileHeight;
opj_setup_decoder(codec, ¶meters);
// enable error handlers
opj_set_warning_handler(codec, warning_callback, NULL);
opj_set_error_handler(codec, error_callback, NULL);
// read header
if (!opj_read_header(stream, codec, &image)) // It's calling error_callback !
{
printf("error on reading header");
return 1;
}
我会使用 libvips 从 SVS 图像中读取。它有一个由 openslide 开发人员编写的良好的 openslide 导入操作,可以很好地处理这种事情。它是免费的和跨平台的。大多数 linux 的包管理器中都有它。
在命令行你可以写:
$ vipsheader CMU-1.svs
CMU-1.svs: 46000x32914 uchar, 4 bands, rgb, openslideload
$ time vips crop CMU-1.svs x.jpg 10 10 100 100
real 0m0.058s
user 0m0.050s
sys 0m0.008s
请注意 jp2k 的解码速度相当慢。要转换整个图像,我看到:
$ time vips copy CMU-1.svs x.jpg --vips-progress
vips temp-5: 46000 x 32914 pixels, 8 threads, 128 x 128 tiles, 256 lines in buffer
vips temp-5: done in 14.6s
real 0m14.720s
user 1m10.978s
sys 0m1.179s
在 C++ 中:
// compile with
// g++ crop.cpp `pkg-config vips-cpp --cflags --libs`
#include <vips/vips8>
int
main (int argc, char **argv)
{
if (VIPS_INIT (argv[0]))
vips_error_exit (NULL);
vips::VImage image = vips::VImage::new_from_file (argv[1]);
image.write_to_file (argv[2]);
}
还有 C、Python、Ruby、JavaScript、PHP、C#、Go、Rust 等绑定。
您可以通过更改输出文件名或在 C++ 代码中设置可选参数来编写其他格式。例如,您可以 运行 该 C++ 程序:
$ ./a.out CMU-1.svs x.tif[compression=jpeg,tile,pyramid]
或者您可以将 write_to_file
更改为:
image.tiffsave (argv[2], VImage::option()
->set ("compression", "jpeg")
->set ("tile", TRUE)
->set ("pyramid", TRUE));