2013-02-14 5 views
0

У меня есть двоичный файл данных изображения, где каждый пиксель точно 4 бита. Данные изображения выложены следующим образом:двоичный файл бит бит

Там N изображений, где первое изображение 1x1, второе изображение 2x2, третье - 4x4 и т. Д. (Они являются мипмапами, если вы хотите знать).

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

Теперь я знаю, сколько байтов я хочу пропустить, но есть это раздражающее изображение 1x1 в начале, которое составляет 4 бита. В любом случае, я не знаю, как увеличить шаг указателя.

Как я могу успешно извлечь данные, не отключаясь на 4 бита?

+1

Именно поэтому обычно используется прокладка, и вы тоже должны. –

+4

Храните наименьшее изображение в виде одного байта (или четыре, если вы входите в производительность), и вы закончили –

+0

Если у вас есть контроль над форматом файла изображения ... просто используйте [DDS] (http: // ru. wikipedia.org/wiki/DirectDraw_Surface). Действительно, это хороший кросс-платформенный формат для хранения данных текстур. В них нет ни Windows, ни Direct3D. Если вы абсолютно не можете, используйте [KTX] (http://www.khronos.org/opengles/sdk/tools/KTX/file_format_spec/), который имеет гораздо меньшую поддержку, но он настолько же всеобъемлющий, как DDS. –

ответ

4

Предполагая, что вы можете изменить формат файла, который вы можете сделать одно из следующих действий:

  • Добавить отступы в 1x1 изображение
  • магазин изображения в обратном порядке (фактически те же, что и выше, но не идеальные для MIP-карты, потому что вы не обязательно знать, сколько изображений вы будете иметь)

Если вы не можете изменить свой формат, у вас есть такой выбор:

  • Преобразование данных
  • Признайте, что буфер со смещением на половину байта и работать с ним соответственно

Вы сказали:

Как я могу успешно получить данные без все время выключения на 4 бита?

Это значит, что вам нужно преобразовать. Когда вы вычисляете смещение в байтах, вы обнаружите, что первый содержит половину байта предыдущего изображения. Таким образом, в крайнем случае вы можете перетасовать их, как это:

for(i = start; i < end; i++) { 
    p[i] = (p[i] << 4) | (p[i+1] >> 4); 
} 

Это предполагает, что первый пиксель является биты 4-7, а второй пиксель биты 0-3, и так далее ... Если это наоборот , просто инвертируйте эти две смены.

0
// this assumes pixels points to bytes(unsigned chars) 
index = ?;// your index to the pixel 

byte_t b = pixels[index/2]; 
if (index % 2) pixel = b >> 4; 
else pixel = b & 15; 

// Or you can use 
byte_t b = pixels[index >> 1]; 
if (index & 1) pixel = b >> 4; 
else pixel = b & 15; 

В любом случае просто вычислите логический индекс в файле. Разделение на два приводит вас к началу байта, где находится пиксель. А затем просто прочитайте правильную половину байта.

Так сделайте функцию

byte_t GetMyPixel(unsigned char* pixels, unsigned index) { 
    byte_t b = pixels[index >> 1]; 
    byte_t pixel; 
    if (index & 1) pixel = b >> 4; 
    else pixel = b & 15; 
    return pixel; 
} 

Чтобы прочитать первое изображение.

Image1x1 = GetMyPixel(pixels,0); 



Image2x2_1 = GetMyPixel(pixels,1);// Top left pixel of second image 
Image2x2_2 = GetMyPixel(pixels,2);// Top Right pixel of second image 
Image2x2_3 = GetMyPixel(pixels,3);// Bottom left pixel of second image 
... etc 

Так что это один из способов обойти это. Возможно, вам нужно будет учитывать конечный смысл, который вы используете, поэтому, если это кажется неправильным, тогда переключите логику для пикселя, прочитанного таким образом ...

byte_t GetMyPixel(unsigned char* pixels, unsigned index) { 
    byte_t b = pixels[index >> 1]; 
    byte_t pixel; 
    #if OTHER_ENDIAN 
    if (index & 1) pixel = b >> 4; 
    else pixel = b & 15; 
    #else 
    if (index & 1) pixel = b & 15; 
    else pixel = b >> 4; 
    #endif 
    return pixel; 
} 
Смежные вопросы