Образ рисунка в файле
Исторически стандарт BMP предназначался для Windows, а в ней при построении изображений "по умолчанию" начало координат расположено в нижнем левом углу экрана. Значения по оси х возрастают слева направо, а по оси Y – снизу вверх. На первый взгляд ничего особенного в этом нет, именно так расположены и направлены оси координат при черчении или рисовании различных графиков на бумаге. Однако это только на первый взгляд.
Расположение строк
При таком расположении осей координат последняя строка рисунка оказывается первой, а его первая строка – последней. Обычно образ рисунка записывают в файл так, чтобы его было удобно все производить на экране.
Разработчики BMP так и поступили – образ рисунка хранится в файле в перевернутом виде, сначала записана его последняя строка, за ней предпоследняя и так вплоть до первой строки, которая записана последней. В таком случае, для построения рисунка снизу вверх строки из файла считываются последовательно друг за другом.
Следует отметить, что в перевернутом виде изображение хранится во всех графических форматах, предназначенных для использования Windows и ее приложениями. В частности, в соответствующем разделе данной книги уже говорилось, что так хранятся рисунки курсоров (файлы типа cur) и пиктограмм (файлы типа ico).
На практике эта особенность форматов для Windows приводит к необходимости применения специальных подпрограмм, переворачивающих образ рисунка в процессе его воспроизведения.
Упаковка кодов точек
Если в образе рисунка использовано 2 или 16 цветов, то для сокращения размера файла он хранится в упакованном виде.
У 16-цветных рисунков значения кодов точек изменяются от о до огь, поэтому в одном байте можно записать коды двух подряд расположенных точек. Код левой точки записывается в старшую тетраду, а код правой – в младшую тетраду байта.
У 2-цветных рисунков значения кодов точек изменяются от о до 1 и в одном байте можно записать коды восьми подряд расположенных точек. Код левой точки группы записывается в старший (седьмой), а код правой точки группы – в младший (нулевой) разряд байта.
Такой способ упаковки точек рисунков, содержащих небольшое количество цветов, применяется не только в формате BMP, но также в PCX, GIF и других форматах. В соответствующем разделе были приведены примеры подпрограмм 3.17 и 3.18, выполняющих распаковку в процессе построения строки рисунка.
Сжатие образа рисунка
Образы рисунков, содержащих более 2-х цветов, могут быть подвергнуты сжатию по способу RLE (Run-Length-Encoding). Прежде всего, отметим, что сжатие возможно только в формате для Windows, в формате для OS/2 оно просто не предусмотрено.
В формате для Windows (см. Табл. А.1.) имеется поле BiCompr, в котором указано состояние образа рисунка. Если в этом поле указан о, то образ рисунка хранится в естественном виде. Bicompr=1 означает, что рисунок, содержащий 256 цветов, сжат по способу RLE. BiCompr=2 означает, что рисунок, содержащий 16 цветов, предварительно упакован по 2 точки в байт, а затем сжат по способу RLE.
Алгоритм декомпрессии файла, сжатого по способу RLE, следующий:
- Если значение текущего (первого) байта отлично от нуля, то оно указывает, сколько раз надо повторить в выходном массиве код, находящийся в следующем байте. В противном случае проверяется код следующего байта.
- Если он больше двух (от 3 до 255), то соответствующее количество последующих байтов просто копируется в выходной массив, т. к. они не упакованы.
- Значения второго байта 0, 1 и 2 являются признаками конца строки (0), конца рисунка (1) и изменения текущих координат (2). В последнем случае в двух следующих байтах указаны приращения значений координат х и Y, которые надо прибавить к их текущим значениям.
Таким образом, в основе упаковки по способу RLE лежит замена группы подряд расположенных одинаковых кодов двумя байтами, в первом указываются количество повторов, а во втором – повторяемый код. Сама по себе эта идея не принадлежит разработчикам стандарта BMP, они только выбирали конкретную реализацию. Аналогичный способ используется и в стандарте сх, но его реализация несколько проще. Мы обсуждали ее ранее в разделе основной части книги.
Замечание
Автор исследовал достаточно много файлов формата BMP, но не обнаружил ни одного сжатого рисунка. Напомним также, что в формате для OS/2 сжатие просто исключено. Остается только гадать, зачем надо было описывать способ сжатия и не использовать его на практике? Ведь аналогичный способ сжатия применяется при подготовке файлов формата PCX. Мы не будем рассматривать программирование распаковки именно по причине отсутствия упакованных рисунков.