Форум программистов, компьютерный форум CyberForum.ru

Маска байта - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 25, средняя оценка - 4.60
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
20.06.2012, 16:13     Маска байта #1
Есть переменная uint8_t, например,
C++
1
uint8_t red;
, маска uint32_t, например,
C++
1
uint32_t RedMask;
, нетипизированный указатель, например,
C++
1
void *p;
и переменная типа uint8_t, хранящая фактический размер данных по указателю в битах и равная 16, 24, или 32, например,
C++
1
uint8_t BitPerixel
. Требуется взять данные по указателю и с учётом маски скопировать не более восьми бит в переменную red. Если в маске установлены больше 8-ми бит, лишние младшие биты отбросить и просто не копировать в red, а скопировать 8 старших, если же в маске установлено меньше восьми бит, не достающие младшие биты переменной red обнулить. Перед копированием требуется проверить маску на "дырявость", то есть встречаются ли в ней ноли между единицами, в этом случае копировать ничего не надо, а следует вернуть false.

Добавлено через 1 час 29 минут
Например, RedMask=0x07C00000, BitPerPixel=32, по указателю p валяется цвет 0x5EF55ED3, надо получить 0xB8. Если RedMask=0x00FF0000, по указателю p валяется тот же цвет 0x5EF55ED3, то надо получить 0xF5. А если RedMask=FFC00000, по указателю p валяется всё тот же цвет 0x5EF55ED3, то надо получить 0x5E.

Добавлено через 1 минуту
И ещё надо проверить, не вылезают ли единицы в маске за отведённую длину.

Добавлено через 4 минуты
Битовые операции я знаю. Но надо ещё измерить величину сдвига. Как это лучше сделать?

Добавлено через 2 часа 27 минут
32-х битная “маска” считается действительной, если ее двоичное представление содержит непрерывный ряд “1″ и следующий за ним ряд “0″.
, вот только по дефолту нет ни какой гарантии валидности маски, надо сделать проверку такой вилидности.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
20.06.2012, 16:13     Маска байта
Посмотрите здесь:

C++ битовая маска
C++ Маска
Размер байта C++
C++ Маска, алгоритм решения
получить 4бит из байта C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
20.06.2012, 16:23     Маска байта #2
А как Вы будете брать данные по указателю типа void? Его в любом случае нужно сначала приводить к какому либо типу, и только потом разыменовывать, а дальше уже взятие нужных битов думаю большого труда не составит.
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
20.06.2012, 16:33  [ТС]     Маска байта #3
Сколько всего может быть масок длиной 32 бита, считая и 0x00000000 и 0xFFFFFFFF и с учётом того, что маска может начинаться нулевым битом, а завершаться единичным и даже начинаться и завершаться нулевыми битами и иметь сплошной ряд единичных бит где то в середине?

Добавлено через 4 минуты
Цитата Сообщение от Toshkarik Посмотреть сообщение
Его в любом случае нужно сначала приводить к какому либо типу, и только потом разыменовывать,
К чему приводить? К uint16_t *? К uint32_t *? До конца валидного массива могут оставаться 3 байта, а BitPerPixel равняться 24-м. Но какие операции будут внутри, я как раз и спрашиваю, а void* на входе. Если внутри надо приводить, значит черед приведение. Но надо учесть, что за концом массива нет валидной памяти в адресном пространстве процесса.

Добавлено через 4 минуты
Цитата Сообщение от Toshkarik Посмотреть сообщение
а дальше уже взятие нужных битов думаю большого труда не составит.
Задача не только в том, что надо выделить биты. Надо ещё валидировать маску и сдвинуть результат операции. А насколько двигать?
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
20.06.2012, 17:01     Маска байта #4
Все намного проще чем Вы думаете:
Для 32 битного числа:
C++
1
2
3
red = 255 & ( p >> 24 );
green = 255 & ( p >> 16 );
blue = 255 & ( p >> 8 );
Для 24 битного числа:
C++
1
2
3
red = 255 & ( p >> 16 );
green = 255 & ( p >> 8 );
blue = 255 & p;
ADD: конечно, под p я подразумеваю переменную, а не указатель.


Если данные цветов всегда хранятся в верхних разрядах то можно свести к такому виду:

C++
1
2
3
red = 255 & ( p >> ( BitPerPixel - 8 ));
green = 255 & ( p >> ( BitPerPixel - 16 ));
blue = 255 & ( p >> ( BitPerPixel - 24 ));
Добавлено через 11 минут
Так, я понял, что Вы имели ввиду. Сейчас попробую сделать для 32 битной маски. Хотя идея в принципе та же. Только единственно не понятно - зачем проверять маску?
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
20.06.2012, 18:37  [ТС]     Маска байта #5
Цитата Сообщение от Toshkarik Посмотреть сообщение
Все намного проще чем Вы думаете:
Для 32 битного числа:
red = 255 & ( p >> 24 );
green = 255 & ( p >> 16 );
blue = 255 & ( p >> 8 );
Для 24 битного числа:
red = 255 & ( p >> 16 );
green = 255 & ( p >> 8 );
blue = 255 & p;
Во-первых ты забыл про целую разрядность, во вторых маска предназначена как раз для того, чтоб на одной разрядности поддерживать несколько вариантов, например, rgb101010 и rgba8888 одновременно и разные порядки цветности rgb, bgr и т.д., а ты свёл к одному варианту. У меня сейчас книга по форматам на столе и там приведены разные варианты по одной разрядности, например, rgb555 и rgb565 на разрядность 16. Это разные маски. 555 - это
1111 1000 0000 0000 0000 0000 0000 0000
0000 0111 1100 0000 0000 0000 0000 0000
0000 0000 0011 1110 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
, а 565 -
1111 1000 0000 0000 0000 0000 0000 0000
0000 0111 1110 0000 0000 0000 0000 0000
0000 0000 0001 1111 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
. Это разные четвёрки масок. А в четвёртых где у тебя вообще альфа? В заголовке файла 4 маски.

Добавлено через 4 минуты
Я сосчитал вручную валидные маски. С учётом не стандартных типа 4 миллиардов градаций красного. Всего 529 масок на компонент. Ещё надо проверить маски на непересекабельность, но это проше некуда.

Добавлено через 4 минуты
C++
1
(RedMask&GreenMask=0x00000000)&&(RedMask&BlueMask=0x00000000)&&(RedMask&AlphaMask=0x00000000)&&(GreenMask&BlueMask=0x00000000)&&(GreenMask&AlphaMask=0x00000000)&&(BlueMask&AlphaMask=0x00000000)
Добавлено через 1 минуту
Цитата Сообщение от Toshkarik Посмотреть сообщение
Только единственно не понятно - зачем проверять маску?
Для валидации графического файла. Если он не валиден, то надо не пытаться его прочитать, множа глюки, а закрыть прогу и логировать фатальную гогу.
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
20.06.2012, 18:40     Маска байта #6
Я показал пример, я никогда не писал подобные программы, это всего лишь предположение. Теперь, когда Вы хоть примерно объяснили, что Вы хотите сделать, все стало более или менее понятно. Но опять же не понятно, если у Вас есть эти самые "разные" форматы, в них ведь уже задана маска числом, и порядок цветов/альфы, зачем проверять?

Добавлено через 2 минуты
Цитата Сообщение от taras atavin Посмотреть сообщение
Для валидации графического файла. Если он не валиден, то надо не пытаться его прочитать, множа глюки, а закрыть прогу и логировать фатальную гогу.
С этим все ясно. Но опять же, у Вас есть некие форматы, сравнивайте на валидность им, если нет ни одного совпадения, то выкидывайте ошибку.
castaway
Эксперт С++
4839 / 2978 / 367
Регистрация: 10.11.2010
Сообщений: 11,012
Записей в блоге: 10
Завершенные тесты: 1
20.06.2012, 20:33     Маска байта #7
Цитата Сообщение от taras atavin Посмотреть сообщение
Например, RedMask=0x07C00000, BitPerPixel=32, по указателю p валяется цвет 0x5EF55ED3, надо получить 0xB8.
Что-то я не совсем понял почему должно получится 0xB8, поясни.

Цитата Сообщение от taras atavin Посмотреть сообщение
А если RedMask=FFC00000, по указателю p валяется всё тот же цвет 0x5EF55ED3, то надо получить 0x5E.
Тут BitPerPixel=32 ? Если да, то R = 0xF5 & 0xC0 = 0xC0. Если же формат цвета RGB101010, тогда R = 0x5EF & 0xFFC = 0x5EC . В любом случае откуда 0x5E ?

Добавлено через 2 минуты
Да, и какой именно формат цвета у тебя при BitPerPixel=32 ?
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
20.06.2012, 20:54     Маска байта #8
Вот мне тоже интересно, хотел спросить раньше, но не стал. Спрошу сейчас: какие данные хранятся в файле? Как хранится сам этот формат? Или нужно самому угадывать?

Добавлено через 15 минут
lazybiz, FFC00000 - FF это восемь бит, все что ниже в маске усекается как я понял. Получается 0xFF000000 & 0x5EF55ED3 == 0x5E000000. Вот эти 8 бит нужно "спустить" в самый низ, что бы записать в однобайтовую переменную. Но откуда берутся данные о формате, что именно 8 бит, к примеру, на красный канал, Тарас так и не написал.
castaway
Эксперт С++
4839 / 2978 / 367
Регистрация: 10.11.2010
Сообщений: 11,012
Записей в блоге: 10
Завершенные тесты: 1
20.06.2012, 21:01     Маска байта #9
Toshkarik, в том то и дело что обычно старшие 8 бит это либо альфа, либо ничего. Это обычно, но не всегда. И еще меня ввел в заблуждение первый пример, в котором я вообще ничего не понял...
Toshkarik
20.06.2012, 21:09
  #10

Не по теме:

Да тут почти все не понятно Мне просто уже в лом все выпытывать у Тараса.

taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
21.06.2012, 09:49  [ТС]     Маска байта #11
Цитата Сообщение от Toshkarik Посмотреть сообщение
Но опять же не понятно, если у Вас есть эти самые "разные" форматы, в них ведь уже задана маска числом, и порядок цветов/альфы, зачем проверять?
Оттуда, что это стандартные маски для .bmp v 4. Правда переменный порядок компонент в спецификации не упомянут, как стандартная возможность. Но я хочу ещё и отойти от стандарта, сохранив лишь сам заголовок, варианты BitPetPixel и расширение файла, но запихав туда произвольные маски от 8-ми цветной (rgb111) до миллионов и даже миллиардов градаций синего, но приводить только при визуализации к rgba8888 путём отбрасывания младших бит цветности. И я сейчас решил несколько усложнить задачу: если не хватает битов определённого цвета, то недостающие биты заполняются не нолями, а копией самого младшего бита из уже имеющихся, тогда r=1, g=1, b=1 в rgb111 даст не серый, а белый. И только если маска определённого компонента обнулена, тогда весь байт подлежит дефолтному заполнению, для цветности это 0x00, а для альфы полная не прозрачность, вроде бы 0xFF.

Добавлено через 1 минуту
Цитата Сообщение от Toshkarik Посмотреть сообщение
FFC00000 - FF это восемь бит, все что ниже в маске усекается как я понял.
Да. FFC00000 принимается за FF000000.

Добавлено через 4 минуты
Цитата Сообщение от Toshkarik Посмотреть сообщение
Но откуда берутся данные о формате, что именно 8 бит, к примеру, на красный канал, Тарас так и не написал.
Выходной формат имеет по 8 бит на красный, зелёный, синий и альфу. На самом деле red не переменная, а поле
C++
1
Pixel->rgbRed
.

Добавлено через 14 минут
Цитата Сообщение от lazybiz Посмотреть сообщение
Что-то я не совсем понял почему должно получится 0xB8, поясни.
Код
Mask   =0000 0111 1100 0000 0000 0000 0000 0000
Color  =0101 1110 1111 0101 0101 1110 1101 0011
              110 11
, в результате всего 5 бит, я их дополнил до 1101 1000, что даёт D8. Ошибся при наборе. Но теперь задача несколько другая,
Код
Mask   =0000 0111 1100 0000 0000 0000 0000 0000
Color  =0101 1110 1111 0101 0101 1110 1101 0011
должно давать не 1101 1000=D8, а 1110 1111=EF, а
Код
Mask   =0000 0111 1100 0000 0000 0000 0000 0000
Color  =0101 1110 1011 0101 0101 1110 1101 0011
должно давать 1110 0000=D0. Выделение по маске даёт 1101 0 и дополняем нулевыми битами, а 1101 1 дополняется единичными.

Добавлено через 7 минут
При валидации массив разрашённых масок не использовать, так как их больше, чем бит в маске. Валидными считаются: 0b1111 1111 1111 1111 1111 1111 1111 1111, 0b0000 0000 0000 0000 0000 0000 0000 0000 и все маски, содержащие одновременно ноли и единицы в любом количестве, но не содержащие ноли между единицами. Если единицы есть, но их меньше 32-х, то они располагаться в начале маски, или в её конце, а если их меньше 31-й, то в начале, в конце и в любом месте в середине, но обязательно подряд.

Добавлено через 12 минут
Цитата Сообщение от lazybiz Посмотреть сообщение
Тут BitPerPixel=32 ? Если да, то R = 0xF5 & 0xC0 = 0xC0. Если же формат цвета RGB101010, тогда R = 0x5EF & 0xFFC = 0x5EC . В любом случае откуда 0x5E ?
BitPerPixel не может быть равен 30, а ближайшее разрешённое значение не меньше 30-ти 32, это формат rgb101010 с двумя не значащими битами на конце, усекаемый с учётом выходного формата rgba8888. По маске получаем 0b01011 11011, это 10 бит, а мне надо восемь, беру 8 старших и получаю 0b0101 1110=0x5E.

Добавлено через 1 минуту
В файле маска одна, она проходит валидацию и ни каких сообщений об ошибках не выводится, но вместо этой маски фактически подставляется другая.

Добавлено через 4 минуты
Но если в файле маска не 0b11111111110000000000000000000000=0xFFC00000, а 0b11111111010000000000000000000000=0xFF400000, то надо вывести сообщение об ошибке, такая маска не валидна, а вместе с ней не валиден весь файл.

Добавлено через 19 минут
Решить надо следующие подзадачи:
1. Дано 32-х битное число, надо определить позицию старшего единичного бита. Решить без использования массивов.
2. Дано 32-х битное число, надо определить позицию младшего единичного бита. Решить без использования массивов.
3. Дано 32-х битное число, надо проверить, образуют ли единичные биты непрерывную последовательность. Решить без использования массивов.
4. Даны 8-ми битное число и позиция бита, надо скопировать этот бит во все биты младше его. Допускается использовать массивы из 8-ми и 16-ти масок.
5. Дан указатель
C++
1
void *p;
, его значение указывает в массив за 3 байта до конца массива, адрес байта сразу за границей массива не валиден в адресном пространстве процесса, надо взять 3 байта по указателю и использовать их в поразрядной логической операции с 32-х битным вторым операндом с фактически нулевым младшим байтом. Есть вариант решения:
C++
1
2
3
4
5
6
7
8
uint8_t *p1;
uint8_t *p2;
uint32_t buffer;
for (p1=((uint8_t*)p)+3, p2=((uint8_t)&buffer)+3; p1>=(uint8_t*)p; --p1, --p2)
{
 *p2=*p1;
}
red=(uint8_t)((buffer&RedMask)>>n);
. Прошу критику, и предложения лучших вариантов, чем этот.

Добавлено через 6 минут
И прошу не строить домыслов о значениях не стандартных масок, так как заранее они не известны.

Добавлено через 34 минуты
Цитата Сообщение от taras atavin Посмотреть сообщение
4. Даны 8-ми битное число и позиция бита, надо скопировать этот бит во все биты младше его. Допускается использовать массивы из 8-ми и 16-ти масок.
Мой вариант:
C++
1
2
3
4
5
6
7
static uint8_t TestMasks      [8]= {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
static uint8_t Masks          [8]= {0xFF, 0xFE, 0xFC, 0xF8, 0xF0, 0xE0, 0xC0, 0x80};
static uint8_t CorrectMasks[2][8]={{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
                                   {0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F}};
       bool    TestResult;
TestResult=(*Color&Testmask[bit])!=0x00;
*Color=((*Color)&Mask[bit])|CorrectMasks[TestResult][bit];
. Здесь число берётся по указателю. Прошу критику.
Deviaphan
Делаю внезапно и красиво
Эксперт C++
 Аватар для Deviaphan
1283 / 1217 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
21.06.2012, 10:19     Маска байта #12
Тарас, я вообще не понимаю, в чём у тебя тут проблема и чем конкретно тебе нужно помочь?
Как я понял, задачи(проблемы) такие:
1. проверить, что маска непрерывна (не содержит 0 между 1)
2. Выделить 8 (или от 1 до 8) старших бит маски (ненулевых), обнулив все прочие

Я что-то упустил? Вышеозначенные проблемы решаются простеньким циклом без премудростей.

Добавлено через 13 минут
Цитата Сообщение от taras atavin Посмотреть сообщение
Решить без использования массивов.
Определяем младший единичный бит, старший бит и что между 1 нету 0
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
unsigned value = ...;
unsigned position = 0;
unsigned minPos = -1;
unsigned maxPos = -1;
unsigned flag = 0;
unsigned test = 1;
for( ; position < 32; ++position )
{
     if( value & test)
     {
          if( minPos == -1 )
             minPos = position;
 
         maxPos = position;
         ++flag;
     }
 
     test <<= 1;
}
 
if( (maxPos - minPos) > flag )
    ; /// есть разрывы в маске
modwind
 Аватар для modwind
52 / 52 / 1
Регистрация: 09.03.2012
Сообщений: 101
21.06.2012, 11:51     Маска байта #13
Тарас, программа должна выглядеть примерно так. Могут быть ошибки, примеров маловато...
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#include <assert.h>
 
typedef unsigned __int8 uint8_t;
typedef unsigned __int32 uint32_t;
 
bool FixMask(uint32_t Mask, uint8_t BitPerixel, uint8_t* shift, uint8_t* cut)
{
    const uint8_t MaxByte = 0xFF;
    const uint8_t MaxBpp = 32;
    const uint8_t MaxRed = 8;
 
    uint8_t i = 0;
    while (!(Mask & 1) && (i<MaxBpp))
    {
        i++;
        Mask >>= 1;
    }
    uint8_t from = i;
 
    while ((Mask & 1) && (i<MaxBpp))
    {
        i++;
        Mask >>= 1;
    }
    uint8_t to = i;
 
    while (i<MaxBpp)
    {
        i++;
        Mask >>= 1;
        if (Mask & 1) return false;
    }
 
    if (to > BitPerixel) return false;
    if (to - from > MaxRed) from = to - MaxRed;
 
    *shift=from;
    *cut=to - from;
    return true;
}
 
uint8_t GetRed(uint32_t col, uint8_t shift, uint8_t cut)
{
    const uint8_t MaxBpp = 32;
    const uint8_t MaxRed = 8;
    col <<= (MaxBpp - shift -cut);
    col >>= (MaxBpp - cut);
 
    // col <<= (MaxRed - cut);
 
    if (!(col&1))
    {
        col <<= (MaxRed - cut);
    }
    else
    {
        col <<= (MaxRed - cut);
        col |= (0xFF >> cut);
    }
    return (uint8_t)col;
}
 
uint32_t GetCol(void* p, uint8_t BitPerixel)
{
    assert(BitPerixel % 8 == 0);
 
    uint32_t col = 0;
    uint8_t* src=(uint8_t*)p;
    uint8_t* dst=(uint8_t*)&col;
 
    
    while (BitPerixel)
    {
        *dst = *src;
        dst++;
        src++;
        BitPerixel -= 8;
    }
    return col;
}
 
int main()
{
    uint32_t col;
    uint32_t mask;
    uint8_t  bpp;
 
    bool r;
    uint8_t shift;
    uint8_t cut;
    uint8_t red;
 
    col = 0x5EF55ED3;
    bpp = 32;
 
    assert(GetCol(&col,8)==0xD3);
    assert(GetCol(&col,16)==0x5ED3);
    assert(GetCol(&col,32)==0x5EF55ED3);
 
    mask = 0x07C00000;
    r = FixMask(mask,bpp,&shift,&cut);
    assert(r == true);
    red=GetRed(col,shift,cut);
    //assert(red == 0xD8);
    assert(red == 0xDF);
 
    mask = 0x00FF0000;
    r = FixMask(mask,bpp,&shift,&cut);
    assert(r == true);
    red=GetRed(col,shift,cut);
    assert(red == 0xF5);
 
    mask = 0xFFC00000;
    r = FixMask(mask,bpp,&shift,&cut);
    assert(r == true);
    red=GetRed(col,shift,cut);
    assert(red == 0x5E);
 
    mask = 0x07C00001;
    r = FixMask(mask,bpp,&shift,&cut);
    assert(r == false);
 
    return 0;
}
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
21.06.2012, 13:06     Маска байта
Еще ссылки по теме:

C++ битовая маска
C++ Чтение байта по адресу
Битовое представление каждого байта C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
21.06.2012, 13:06  [ТС]     Маска байта #14
Я вообще первый раз столкнулся с длинными битовыми полями неизвестных в десигнотайме длины и положения. Но вроде сделал:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
//=================================================================================================
bool                       ChaeckMask           (DWORD                  Mask       ,
                                                 uint8_t               &Start      ,
                                                 uint8_t               &End        )
{
 uint32_t LastBit;
 uint32_t FirstBit;
 uint32_t Bit;
 Start=0xFFFFFFFF;
 End  =0xFFFFFFFF;
 for (FirstBit=31; FirstBit<32; --FirstBit)
 {
  if ((Mask&(1<<FirstBit))!=0x00000000)
  {
   Start=FirstBit;
   break;
  }
 }
 if (Start==0xFFFFFFFF)
 {
  return true;
 }
 for (LastBit=0; LastBit<=FirstBit; ++LastBit)
 {
  if ((Mask&(1<<LastBit))!=0x00000000)
  {
   End=LastBit;
   break;
  }
 }
 if (FirstBit==LastBit)
 {
  return true;
 }
 for (Bit=LastBit+1; Bit<FirstBit; ++Bit)
 {
  if ((Mask&(1<<Bit))==0x00000000)
  {
   return false;
  }
 }
 return true;
}
//=================================================================================================
uint32_t                   CopyFilePixel        (uint8_t               *Pixel      ,
                                                 WORD                   BitPerPixel)
{
 uint8_t  *p1;
 uint8_t  *p2;
 uint32_t  Result;
 uint8_t   BytePerPixel;
 BytePerPixel=BitPerPixel/8;
 for (p1=((uint8_t *)&Result)+BytePerPixel-1, p2=Pixel+BytePerPixel-1; p2>=Pixel; --p1, --p2)
 {
  *p1=*p2;
 }
}
//=================================================================================================
uint8_t                    CopyColor            (uint32_t               Buffer     ,
                                                 DWORD                  Mask       ,
                                                 uint8_t                Start      ,
                                                 uint8_t                End        )
{
 static uint8_t TestMasks      [8]= {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
 static uint8_t CorrectMasks[2][8]={{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
                                    {0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F}};
        bool    TestResult;
        uint8_t Shift;
 if (Start==0xFFFFFFFF)
 {
  return 0x00;
 }
 Buffer&=Mask;
 Shift=Start-7;
 if (Shift>0)
 {
  Buffer>>=Shift;
 }
 if (Start<0)
 {
  Buffer<<=-Shift;
 }
 if (End>Shift)
 {
  End-=Shift;
  TestResult=(Buffer&TestMasks[End])!=0x00;
  Buffer|=CorrectMasks[TestResult][End];
 }
 return (uint8_t)Buffer;
}
//=================================================================================================
. Прошу критику.

Добавлено через 1 минуту
Раньше у меня все форматы были фиксированные.
Yandex
Объявления
21.06.2012, 13:06     Маска байта
Ответ Создать тему
Опции темы

Текущее время: 06:07. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru