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

Побитовое чтение - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 32, средняя оценка - 4.88
Khelleos
37 / 37 / 7
Регистрация: 13.05.2010
Сообщений: 283
Записей в блоге: 1
24.07.2012, 21:42     Побитовое чтение #1
Есть файл видео и мне известна его структура.
Например структура следующая:
8 бит
1 бит
1 бит
1 бит
13 бит
и т.д.
Как мне считать данные побитово? Или можно только считывать побайтово и выделять потом биты? Если побайтово, то как потом выделить биты из него? Можете объяснить, ну и показать пару примеров.
Заранее благодарю.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
alex_x_x
бжни
 Аватар для alex_x_x
2441 / 1646 / 84
Регистрация: 14.05.2009
Сообщений: 7,163
24.07.2012, 21:53     Побитовое чтение #2
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <fstream>
 
struct VideoPacketHeader
{
  unsigned m1 : 8;
  unsigned m2 : 1;
  unsigned m3 : 1;
  unsigned m4 : 1;
  unsigned m5 : 13;
};
 
int main () {
  std::ifstream f ("file.mkv");
  if (!f) return -1;
  
  VideoPacketHeader hdr;
  f.read ((char*)&hdr, sizeof(hdr));
}
битовые поля
но вообще есть еще вопросы с выравниванием и упаковкой
canopen
411 / 410 / 12
Регистрация: 16.07.2012
Сообщений: 886
24.07.2012, 21:54     Побитовое чтение #3
http://chipenable.ru/index.php/progr...vr-define.html
alex_x_x
бжни
 Аватар для alex_x_x
2441 / 1646 / 84
Регистрация: 14.05.2009
Сообщений: 7,163
24.07.2012, 22:29     Побитовое чтение #4
зачем, если для этого есть битовые поля?
Khelleos
37 / 37 / 7
Регистрация: 13.05.2010
Сообщений: 283
Записей в блоге: 1
25.07.2012, 00:51  [ТС]     Побитовое чтение #5
Еще есть небольшой вопрос. Мне надо парсить Transport Stream. Вот его структура
transport_packet()
{
sync_byte : 8
transport_error_indicator : 1
payload_unit_start_indicator : 1
transport_priority : 1
PID : 13
transport_scrambling_control : 2
adaptation_field_control : 2
continuity_counter : 4
if(adaptation_field_control = = '10' || adaptation_field_control = = '11')
{
adaptation_field()
}
if(adaptation_field_control = = '01' || adaptation_field_control = = '11')
{
for (i = 0; i < N; i++)
{
data_byte
}
}
}
Как теперь считать данные битово понятно, но как мне теперь правильно сравнить значение поля adaptation_field_control с '10' или '01'?
alex_x_x
бжни
 Аватар для alex_x_x
2441 / 1646 / 84
Регистрация: 14.05.2009
Сообщений: 7,163
25.07.2012, 01:14     Побитовое чтение #6
pkt.adaptation_field_control == 2 || pkt.adaptation_field_control = 3

тут 2 бита - арифметика банальная

еще один момент - размер структуры - 32 бита, то бишь 4 байта
для 32 размерной системы все будет ок, но на 64 она будет выравнена до 64 бит
чтобы такого не происходило следует использовать pragma'ы своего компилятора (чтото вроде pragma pack)
alkagolik
 Аватар для alkagolik
1510 / 616 / 79
Регистрация: 15.07.2011
Сообщений: 3,552
25.07.2012, 01:28     Побитовое чтение #7
так вроде же '10' == 0, а не 2.
Цитата Сообщение от alex_x_x Посмотреть сообщение
(чтото вроде pragma pack)
или __attribute__((packed)) для гнутых.
alex_x_x
бжни
 Аватар для alex_x_x
2441 / 1646 / 84
Регистрация: 14.05.2009
Сообщений: 7,163
25.07.2012, 01:34     Побитовое чтение #8
alkagolik, каким образом?
я полагаю, что это 102
alkagolik
 Аватар для alkagolik
1510 / 616 / 79
Регистрация: 15.07.2011
Сообщений: 3,552
25.07.2012, 01:35     Побитовое чтение #9
alex_x_x, ну я в замешательстве. Я ставлю акцент на кавычки, если код так написан, то '10' == 0
Khelleos
37 / 37 / 7
Регистрация: 13.05.2010
Сообщений: 283
Записей в блоге: 1
25.07.2012, 09:36  [ТС]     Побитовое чтение #10
Возникла еще одна проблема с чтением
Если мне надо считать не в структура, а только в одной поле структуры, то как в этом случае считывать?
Пытался сделать так
C++
1
fin.read((char*)hdr.transport_error_indicator, sizeof(hdr.transport_error_indicator)
Но выдается ошибка при компиляции. Да и sizeof возвращет байты. Как решить такую проблему?

Добавлено через 9 минут
А в unsigned запишется поле длинной 33 бита?
alex_x_x
бжни
 Аватар для alex_x_x
2441 / 1646 / 84
Регистрация: 14.05.2009
Сообщений: 7,163
25.07.2012, 10:57     Побитовое чтение #11
Khelleos, нет, так не бывает
в машинах биты не существуют отдельно от байтов
хотя бы ваша файловая.система и драйвер жесткого диска побитовое чтение не поддерживает
Khelleos
37 / 37 / 7
Регистрация: 13.05.2010
Сообщений: 283
Записей в блоге: 1
25.07.2012, 11:39  [ТС]     Побитовое чтение #12
Тогда как мне реазлизовать следующий код

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
adaptation_field() 
{
   adaptation_field_length (8)
   if (adaptation_field_length > 0) 
   {
      discontinuity_indicator (1)
      random_access_indicator (1)
      elementary_stream_priority_indicator (1)
      PCR_flag (1)
      OPCR_flag (1)
      splicing_point_flag (1)
      transport_private_data_flag (1)
      adaptation_field_extension_flag (1)
      if (PCR_flag = = '1')                                              
      {
         program_clock_reference_base (33)
         reserved (6)
         program_clock_reference_extension (9)
      }
      if (OPCR_flag = = '1') 
      {
         original_program_clock_reference_base (33)
         reserved (6)
         original_program_clock_reference_extension (9)  
      }
      if (splicing_point_flag = = '1') 
      {
         splice_countdown (8)
      }
      if (transport_private_data_flag = = '1') 
      {
         transport_private_data_length (8)
         for (i = 0; i < transport_private_data_length; i++) 
         {
            private_data_byte (8)
         }
      }
      if (adaptation_field_extension_flag = = '1') 
      {
         adaptation_field_extension_length (8)
         ltw_flag (1)
         piecewise_rate_flag (1)
         seamless_splice_flag (1)
         reserved (5)
         if (ltw_flag = = '1') 
         {
            ltw_valid_flag (1)
            ltw_offset (15)
         }
         if (piecewise_rate_flag = = '1') 
         {
            reserved (2)
            piecewise_rate (22)
         }
         if (seamless_splice_flag = = '1') 
         {
            splice_type (4)
            DTS_next_AU[32..30] (3)
            marker_bit (1)
            DTS_next_AU[29..15] (15)
            marker_bit (1)
            DTS_next_AU[14..0] (14)
            marker_bit (1)
         }
         for (i = 0; i < N; i++) 
         {
            reserved (8)
         }
      }
   }
   for (i = 0; i < N; i++) 
   {
      stuffing_byte (8)
   }
}
В скобках указано количество бит

Добавлено через 2 минуты
Думал, реализовать несколько структур для каждого условия, но не слишком ли это? По мне так это будет некрасиво иметь для каждого условия структуру, особенно там где только одно поле. Кстати, а что делать с полем 33 бита? Оно разве запишеться в unsigned?
Jupiter
25.07.2012, 11:45
  #13

Не по теме:

Цитата Сообщение от alkagolik Посмотреть сообщение
или __attribute__((packed)) для гнутых.
http://gcc.gnu.org/onlinedocs/gcc/St...g-Pragmas.html

Khelleos
37 / 37 / 7
Регистрация: 13.05.2010
Сообщений: 283
Записей в блоге: 1
25.07.2012, 12:12  [ТС]     Побитовое чтение #14
Походу единственный способ - это считывать побайтово, а потом разбирать каждый байт на нужные биты.
А вот тогда лучше ответьте мне на такой вопрос.
Есть поле длиной 13 бит. Я считаю это поле в 2 байта. Впервом байте я беру 8 бит(то есть весь байт), а из второго 5 бит. если я потом сложу переменные, в которые я записал 8 и 5 бит, то я получу нужное мне поле(13 бит), да?
canopen
411 / 410 / 12
Регистрация: 16.07.2012
Сообщений: 886
25.07.2012, 12:17     Побитовое чтение #15
Нет, не получите. Вам сначала нужно будет сдвинуть 8 бит на пять разрядов влево, а 5 бит на три разряда вправо. Прочитали бы все-таки что-нибудь на тему битовых операций.
Khelleos
37 / 37 / 7
Регистрация: 13.05.2010
Сообщений: 283
Записей в блоге: 1
26.07.2012, 01:08  [ТС]     Побитовое чтение #16
Цитата Сообщение от canopen Посмотреть сообщение
Нет, не получите. Вам сначала нужно будет сдвинуть 8 бит на пять разрядов влево, а 5 бит на три разряда вправо. Прочитали бы все-таки что-нибудь на тему битовых операций.
Точно, второй байт я сдвинул на 3 разряда вправо, а вот первый байт забыл сдвинуть влево на 5 разрядов.

Добавлено через 12 часов 30 минут
Хочу уточнить одну вещь, файл длиной 16 бит, структура файла следующая
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
struct file
{
   unsigned m1 : 1;
   unsigned m2 : 2;
   unsgined m3 : 13
};
 
int main()
{
   int infile = open(NAME, O_RDONLY);
   
   char buf[2];
   read(fin, buf, 2);
 
   file hdr;
   hdr.m1 = (buf[0] & 1) != 0;  //получаю первый бит 
   hdr.m2 = ((buf[0] & 1 << 2) << 1) + (buf[0] & 1 << 1) //получаю 2-ой и 3-ий бит
   hdr.m3 = ((buf[0] >> 3) << 8) + buf[1]; //получаю 13 бит
   
   return 0;
}
Я все правильно сделал? А это я не уверен правильно ли я получаю поле длинной 13 бит.

Добавлено через 12 минут
Напутал, вот так должно быть правильно
C++
1
2
3
hdr.m1 = (buf[0] & 1);  //получаю первый бит 
hdr.m2 = ((buf[0] & (1 << 2)) + (buf[0] & (1 << 1))) >> 1 //получаю 2-ой и 3-ий бит
hdr.m3 = ((buf[0] >> 3) << 8) + buf[1]; //получаю 13 бит
да?
alex_x_x
бжни
 Аватар для alex_x_x
2441 / 1646 / 84
Регистрация: 14.05.2009
Сообщений: 7,163
26.07.2012, 01:25     Побитовое чтение #17
вообще както все проще

C
1
2
3
4
5
6
7
8
#include <stdint.h>
#include <stdio.h>
 
int main() {
  uint16_t value = 100500;
  printf ("%u\n", 0x1FFF & value);
  return 0;
}
value это ваши два байта прочитанные из файла
0x1FFF - маска - первые 13 бит - 1, остальные - 0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
26.07.2012, 01:35     Побитовое чтение
Еще ссылки по теме:

Побитовое вычитание C++
C++ Работа с пикселями, побитовое копирование
C++ Побитовое чтение/запись в файл

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

Или воспользуйтесь поиском по форуму:
Khelleos
37 / 37 / 7
Регистрация: 13.05.2010
Сообщений: 283
Записей в блоге: 1
26.07.2012, 01:35  [ТС]     Побитовое чтение #18
Но то, что я предложил тоже правильно(но ваш вариант проще, чем мой)?
Yandex
Объявления
26.07.2012, 01:35     Побитовое чтение
Ответ Создать тему
Опции темы

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