Извлечь полноразмерное изображение из файла SVS - PullRequest
0 голосов
/ 10 декабря 2018

Я пытаюсь извлечь первую страницу файла SVS, используя Libtiff.Файл SVS использует сжатие JPEG2000 для этого изображения.

Мой план:

  1. извлечение необработанных плиток с первой страницы SVS и
  2. декодирование его с использованиемOpenJPEG.

Ниже я попытался извлечь необработанные плитки из SVS.Я получил только 43 КБ выходной файл из 152 МБ svs-файла (он не смог извлечь необработанные листы).

Я надеюсь, что кто-то может сообщить мне, как извлечь листы из файла SVS.

int main()
{
    const char* filename = "input.svs";
    TIFF* tiff_in = TIFFOpen(filename, "r");
    TIFF* tiff_out = TIFFOpen("output.raw", "w");
    if (tiff_in) {
        uint32 imageWidth, imageLength;
        uint32 tileWidth, tileLength;
        uint32 tileCount, tileByteCounts;
        uint32 samplePerPixel, bitsPerSample;
        uint32 orientation, planarConfig, photoMetric;
        uint32 xResolution, yResolution;
        uint32 x, y;
        ttile_t tile;
        // get fileds from the input file
        TIFFGetField(tiff_in, TIFFTAG_IMAGEWIDTH, &imageWidth);
        TIFFGetField(tiff_in, TIFFTAG_IMAGELENGTH, &imageLength);
        TIFFGetField(tiff_in, TIFFTAG_TILEWIDTH, &tileWidth);
        TIFFGetField(tiff_in, TIFFTAG_TILELENGTH, &tileLength);
        TIFFGetField(tiff_in, TIFFTAG_SAMPLESPERPIXEL, &samplePerPixel);
        TIFFGetField(tiff_in, TIFFTAG_BITSPERSAMPLE, &bitsPerSample);
        TIFFGetField(tiff_in, TIFFTAG_TILEBYTECOUNTS, &tileByteCounts);
        TIFFGetField(tiff_in, TIFFTAG_ORIENTATION, &orientation);
        TIFFGetField(tiff_in, TIFFTAG_PLANARCONFIG, &planarConfig);
        TIFFGetField(tiff_in, TIFFTAG_PHOTOMETRIC, &photoMetric);
        TIFFGetField(tiff_in, TIFFTAG_XRESOLUTION, &xResolution);
        TIFFGetField(tiff_in, TIFFTAG_YRESOLUTION, &yResolution);

        // set files to the output file
        TIFFSetField(tiff_out, TIFFTAG_IMAGEWIDTH, imageWidth);
        TIFFSetField(tiff_out, TIFFTAG_IMAGELENGTH, imageLength);
        TIFFSetField(tiff_out, TIFFTAG_TILEWIDTH, tileWidth);
        TIFFSetField(tiff_out, TIFFTAG_TILELENGTH, tileLength);
        TIFFSetField(tiff_out, TIFFTAG_SAMPLESPERPIXEL, samplePerPixel);
        TIFFSetField(tiff_out, TIFFTAG_BITSPERSAMPLE, bitsPerSample);
        TIFFSetField(tiff_out, TIFFTAG_PLANARCONFIG, planarConfig);
        TIFFSetField(tiff_out, TIFFTAG_PHOTOMETRIC, photoMetric);
        TIFFSetField(tiff_out, TIFFTAG_XRESOLUTION, xResolution);
        TIFFSetField(tiff_out, TIFFTAG_YRESOLUTION, yResolution);
        //TIFFSetField(tiff_out, TIFFTAG_ROWSPERSTRIP, 1);

        tdata_t buf = _TIFFmalloc(TIFFTileSize(tiff_in));
        for (int tile = 0; tile < TIFFNumberOfTiles(tiff_in); tile++)
        {
            TIFFReadRawTile(tiff_in, tile, buf, (tsize_t)-1);
            TIFFWriteRawTile(tiff_out, tile, buf, (tsize_t)sizeof(buf));
        }
        _TIFFfree(buf);
        TIFFClose(tiff_in);
        TIFFClose(tiff_out);
    }
    return 0;
}

1 Ответ

0 голосов
/ 10 декабря 2018

Вы пишете плитки с 8 байтами каждая.sizeof(buf) - это размер в байтах указателя buf.Вы хотите использовать количество фактически прочитанных байтов, которое возвращается TIFFReadRawTile:

tsize_t size = TIFFReadRawTile(tiff_in, tile, buf, (tsize_t)-1);
TIFFWriteRawTile(tiff_out, tile, buf, size);

Обратите внимание, что здесь вы копируете сжатые JPEG2000 данные в выходной файл.Вам нужно будет распаковать эти данные с помощью OpenJPEG, а затем записать данные о размере несжатой плитки, которая равна tileWidth * tileLength * samplePerPixel * bitsPerSample / 8 в непрерывной плоской конфигурации или tileWidth * tileLength * bitsPerSample / 8 в отдельной плоской конфигурации.


При использовании TIFFGetField и TIFFSetField необходимо проверить возвращаемые значения.0 возвращается, если произошла ошибка.Вы не можете зависеть от значений, которые были прочитаны неправильно.

Другие ошибки и предупреждения обычно выводятся на stderr.Если вы разрабатываете под Windows, они обычно не будут отображаться.Я рекомендую вам взглянуть на TIFFSetErrorHandler и TIFFSetWarningHandler, установка подходящих функций отображения сообщений здесь очень поможет вам во время разработки.

...