PERL: распаковка огромных данных приводит к необычно долгому времени обработки

Я пытаюсь отделить данные заголовка и пикселя от растрового файла. Используя следующий код

($bmpHdr1, @bmpData1[0..$bmpSize-1]) = unpack "(H$hdrNibbleLen)(H2)*", $data1;

Прекрасно работает с небольшими файлами, но приводит к нелепому увеличению времени обработки при использовании с большим файлом. Например, растровое изображение размером 16 МБ, на самом деле я никогда не ждал его завершения достаточно долго.

($bmpHdr1, @bmpData1) = unpack "(H$hdrNibbleLen)(H*)", $data1;

работает хорошо, но я получаю все пиксельные данные в первом элементе списка, нужны дополнительные операции с регулярными выражениями, чтобы получить данные в нужном формате. Есть ли способ сделать это только с unpack?

Ожидаемый результат: упакуйте пиксельные данные с детализацией на уровне байтов и сохраните каждый байт в другом элементе списка.

Реальное ожидание:

Я хочу сравнить два растровых изображения и найти X, Y несовпадающего пикселя и соответствующие данные. Из-за заполнения и разных битов на пиксель (некоторые из них 24 бита на пиксель) поиск несовпадающего пикселя становится кошмаром, если он не разделен на уровне байтов. Ну по крайней мере так, как я это делаю.

my $errPixY = floor($errByte/$rowSize);
my $errPixX = ($errByte - ($errPixY * $rowSize))/($header1{DibHdrBpp}/8);

person Ranju    schedule 12.08.2014    source источник
comment
Что вы надеетесь делать с данными после извлечения?   -  person Mark Setchell    schedule 12.08.2014
comment
Зачем вам каждый байт как отдельный элемент списка? Это ужасно расточительно для места и времени обработки.   -  person Jim Garrison    schedule 12.08.2014
comment
Я хочу сравнить два растровых изображения и найти X, Y несовпадающего пикселя и соответствующие данные. Из-за заполнения и разного бит-на-пиксель становится кошмаром, если он не разделен на уровне байтов.   -  person Ranju    schedule 12.08.2014
comment
Пиксель или пиксели? Вы имеете в виду, что только один пиксель отличается?   -  person Mark Setchell    schedule 12.08.2014
comment
пока только первый несоответствующий пиксель в хронологическом порядке.   -  person Ranju    schedule 12.08.2014
comment
Я хочу сравнить два растровых изображения и найти X, Y несовпадающего пикселя и соответствующие данные. Из-за заполнения и разного бита на пиксель (некоторые из них 24 бита на пиксель) поиск несовпадающего пикселя становится кошмаром, если он не разделен на уровне байтов. Ну по крайней мере так, как я это делаю. мой $errPixY = floor($errByte/$rowSize); мой $errPixX = ($errByte - ($errPixY * $rowSize))/($header1{DibHdrBpp}/8);   -  person Ranju    schedule 12.08.2014
comment
Вы не можете использовать модуль metacpan.org/pod/Image::BMP?   -  person jm666    schedule 12.08.2014
comment
хотел сделать его доступным для расширенной аудитории, без использования модулей.. Просто установите базовый perl. Немногие в нашей группе еще про-perl.   -  person Ranju    schedule 12.08.2014
comment
Если вы не являетесь сторонником Perl, это еще одна причина использовать существующий код.   -  person ikegami    schedule 12.08.2014


Ответы (1)


Исключающее ИЛИ:

0 0 -> 0
0 1 -> 1
1 0 -> 1
1 1 -> 0

Оставьте полезную нагрузку в виде строки и XOR двух строк:

my $xor = $bmp_data1 ^ $bmp_data2;
while ($xor =~ /[^\0]/g) {
   my $pos = $-[0];
   printf "Difference at byte %d (%02X vs %02X)\n",
      $pos,
      ord(substr($bmp_data1, $pos, 1)),
      ord(substr($bmp_data2, $pos, 1));
}

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

sub to_num { unpack('N', substr(("\0"x4).$_[0], -4)) }

my $Bpp = $bpp<8 ? 1 : $bpp/8;
die "Unsupported number of bits per pixel\n" if $Bpp != int($Bpp);
die "Unsupported number of bits per pixel\n" if $Bpp > 4;

my $xor = $data1 ^ $data2;
while ($xor =~ /[^\0]/g) {
   my $pos = $-[0] - ($-[0] % $Bpp);
   pos($xor) = $pos + $Bpp;

   if ($bpp >= 8) {
      my $pixel = $pos / $Bpp
      my $x = $pixel % $row_size;
      my $y = ($pixel - $x) / $row_size;
      my $val1 = to_num(substr($data1, $pos, $Bpp));
      my $val2 = to_num(substr($data2, $pos, $Bpp));
      ...
   } else {
      my $sub_data1 = substr($data1, $pos, 1);
      my $sub_data2 = substr($data2, $pos, 1);
      ... split into pixels and compare those ...
   }
}
person ikegami    schedule 12.08.2014
comment
Спасибо! что будет делать! - person Ranju; 12.08.2014