Чтение двоичного 16-битного потокового файла и запись в 16-битный PGM (C ++)

0

это мой первый пост, поскольку я пришел с помощью функции поиска до сих пор. Но теперь я потратил целый день на следующий вопрос:

Я записал 12-битное (написанное как 16-битное) черно-белое видео и записал его непосредственно в бинарный поток файл (без заголовков и т.д.).

Теперь задача состоит в том, чтобы прочитать файл и вывести каждый кадр в виде 16-битного pgm.

Следующий снимок показывает, что я пытался. Выход является допустимым pgm, но с "белым шумом".

    ...
    imageBufferShort = new short[imageWidth*imageHeight* sizeof(short)];
    ...
    streamFileHandle.read(reinterpret_cast<char*>(imageBufferShort),2*imageWidth*imageHeight); //double amount because 8bit chars!
    // As .read only takes chars, I thought, that I just read the double amount of char-bytes and when it is interpreted as short (=16bit) everything is ok?!?

    ...now the pgm output:

    std::ofstream f_hnd(fileName,std::ios_base::out |std::ios_base::binary |std::ios_base::trunc);
    // write simple header
    f_hnd.write("P5\n",3);
    f_hnd << imageWidth << " " << imageHeight << "\n4095\n";  //4095 should tell the pgm to use 2 bytes for each pixel

    f_hnd.write(reinterpret_cast<char*>(imageBufferShort),2*imageWidth*imageHeight);
    f_hnd.close();

Опять же, файл создается и отображается, но содержит мусор. Является ли первоначальное предположение нормально? читать 2 "символа" и обрабатывать их как один "короткий"? Я также пробую пробел после каждой строки, но это ничего не меняет, поэтому я решил опубликовать этот более короткий код.

Спасибо за любую помощь!

  • 0
    Вы убедились, что на входе нет шума?
  • 0
    Также, если вы используете new , вам не нужно умножать на sizeof (T). Это не влияет на правильность, хотя.
Показать ещё 4 комментария
Теги:
binary
pgm

2 ответа

1

Как @Domi и @JoeZ отметили: Ваша сущность, вероятно, испорчена. Значит, порядок ваших байтов неверен.

Чтобы исправить вашу проблему, вам придется перебирать каждый пиксель и обменивать его байтами, прежде чем записывать его обратно в файл.

  • 0
    Хорошо. Большое спасибо. Я никогда не сталкивался с порядком вещей. Я попробую это в понедельник и сообщу.
0

Задача решена. Спасибо вам большое. Проблема Endianess действительно была проблемой. Решение приведено ниже:

    f_hnd << "P5" << " " << imDimensions.GetWidth() << " " << imDimensions.GetHeight() << " " << "4095\n";

    // convert imageBufferShort to Big-Endian format
    unsigned short imageBufferShortBigEndian[imDimensions.GetWidth()*imDimensions.GetHeight()];

    for (int k=0 ; k<imDimensions.GetWidth()*imDimensions.GetHeight() ; k++)
    {
        imageBufferShortBigEndian[k] = ( (imageBufferShort[k] << 8) | (imageBufferShort[k] >> 8) );
    }

    f_hnd.write(reinterpret_cast<char*>(imageBufferShortBigEndian),2*imDimensions.GetWidth()*imDimensions.GetHeight());
    f_hnd.close();

imageBufferShort также имеет неподписанный короткий массив. Если используются типы подписей, преобразование бит-сдвига становится немного сложнее.

Еще раз спасибо!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню