BMP

Поделись знанием:
Перейти к: навигация, поиск
Windows Bitmap
Тип формата

растровая графика

BMP (от англ. Bitmap Picture) — формат хранения растровых изображений, разработанный компанией Microsoft. Файлы формата BMP могут иметь расширения .bmp, .dib и .rle.

С форматом BMP работает огромное количество программ, так как его поддержка интегрирована в операционные системы Windows и OS/2. Кроме того, данные этого формата включаются в двоичные файлы ресурсов RES и в PE-файлы.

В данном формате можно хранить только однослойные растры. На каждый пиксель в разных файлах может приходиться разное количество бит (глубина цвета). Microsoft предлагает битности 1, 2, 4, 8, 16, 24, 32, 48 и 64. В битностях 8 и ниже, цвет указывается индексом из таблицы цветов (палитры), а при больших непосредственным значением. Цвет же в любом случае можно задать только в цветовой модели RGB (как при непосредственном указании в пикселе, так и в таблице цветов), но в битностях 16 и 32 можно получить Grayscale с глубиной до 16 и 32 бит соответственно. Частичная прозрачность реализована альфа-каналом различных битностей, но при этом прозрачность без градаций можно косвенно получить RLE-кодированием.

В большинстве случаев пиксели хранятся в виде относительно простого двумерного массива. Для битностей 4 и 8 доступно RLE-кодирование, которое может уменьшить их размер. Формат BMP также поддерживает встраивание данных в форматах JPEG и PNG. Но последнее скорее больше предназначено не для компактного хранения, а для обхода ограничений архитектуры GDI, которая не предусматривает прямую работу с изображениями отличных от BMP форматов.

В последних версиях формата BMP также появились возможности по управлению цветом. В частности, можно указывать конечные точки, производить гамма-коррекцию и встраивать цветовые профили ICC.





DIB и DDB

При использовании формата DIB (англ. Device Independent Bitmap, аппаратно-независимый растр) программист может получить доступ ко всем элементам структур, описывающих изображение, при помощи обычного указателя. Но эти данные не используются для непосредственного управления экраном, так как они всегда хранятся в системной памяти, а не в специализированной видеопамяти. Формат пикселя в оперативной памяти может отличаться от того формата, который должен заноситься в видеопамять для индикации точки такого же цвета. Например, в DIB-формате может использоваться 24 бита для задания пикселя, а графический адаптер в этот момент может работать в режиме HiColor с цветовой глубиной 16 бит. При этом ярко-красная точка в аппаратно-независимом формате будет задаваться тремя байтами 0000FF16, а в видеопамяти — словом F80016. При копировании картинки на экран система будет тратить дополнительное время на преобразование кодов цвета из 24-битного формата в формат видеобуфера.

Формат DDB (англ. Device Dependent Bitmap, аппаратно-зависимый растр) всегда содержит цветовые коды, совпадающие с кодами видеобуфера, но храниться он может как в системной, так и в видеопамяти. В обоих случаях он содержит только коды цвета в том формате, который обеспечит пересылку изображения из ОЗУ в видеопамять при помощи простого копирования[1].

Внутреннее строение

Официальную информацию по формату BMP можно найти в MSDN или справке Microsoft Windows SDK (может идти в комплекте с некоторыми IDE). В файле WinGDI.h от компании Microsoft есть все объявления на языке C++, которые касаются данного формата. В данную статью же не были включены объявления типов, так как от этого она может быть слишком громоздкой. К тому же официальные объявления некоторые разработчики могут посчитать неудобными и поэтому их востребованность сомнительна. Если вам потребуются оригинальные имена констант, структур, типов и их полей, то они все есть в тексте данной статьи.

Максимальный размер неделимых ячеек (исключая поля битовых структур): 32 бита и поэтому формат можно классифицировать как 32-битный. Исключением могут быть 64-битные пиксели, но значения их каналов можно обрабатывать и 16-битными словами. Порядок байт в 16-битных и 32-битных ячейках повсюду от младшего к старшему (little-endian). Целые числа записываются в прямом коде, со знаком — в дополнительном. Если сравнивать с аппаратными архитектурами, то порядок байт и формат чисел соответствует x86.

В данной статье для указания типов используются имена типов WinAPI как в документации Microsoft. Кроме специфических (описаны отдельно в тексте статьи) можно встретить четыре числовых типа:

  • BYTE — 8-битное беззнаковое целое.
  • WORD — 16-битное беззнаковое целое.
  • DWORD — 32-битное беззнаковое целое.
  • LONG — 32-битное целое со знаком.

В формате Windows Bitmap под структурами понимается блок с идущими подряд ячейками различного фиксированного размера, у которых есть условные имена (есть во многих языках программирования), а не что-то сложнее (например, поток команд произвольного размера).

У некоторых элементов формата указана версия Windows, начиная с которой он поддерживается. Речь идёт в первую очередь об основных библиотеках WinAPI таких как gdi32.dll, shell32.dll, user32.dll и kernel32.dll. Другие компоненты операционной системы (например, GDI+, .NET, DirectX) могут иметь другие более широкие возможности.

Общая структура

Данные в формате BMP состоят из трёх основных блоков различного размера:

  1. Заголовок из структуры BITMAPFILEHEADER и блока BITMAPINFO. Последний содержит:
    1. Информационные поля.
    2. Битовые маски для извлечения значений цветовых каналов (опциональные).
    3. Таблица цветов (опциональная).
  2. Цветовой профиль (опциональный).
  3. Пиксельные данные.

При хранении в файле все заголовки идут с самого первого байта. Пиксельные данные могут находиться на произвольной позиции в файле (она указывается в поле OffBits структуры BITMAPFILEHEADER), в том числе и в удалении от заголовков. Опциональный цветовой профиль появился в версии 5 и он также может свободно располагаться, но его позиция указывается от начала BITMAPINFO (в поле ProfileData).

В оперативной памяти (например, при взаимодействии с WinAPI-функциями GDI) из заголовков исключается структура BITMAPFILEHEADER. При этом Microsoft рекомендует располагать цветовой профиль сразу за заголовками в едином блоке[2]. Пиксельные данные могут иметь произвольное расположение в памяти и их адрес указывается в параметрах процедур. В любом случае рекомендуется в памяти все блоки содержать по адресам кратным четырём: в заголовках присутствуют 32-битные ячейки, а к пиксельным данным такое требование указано в документации[3]. Это требование справедливо только для оперативной памяти: при хранении в файле его придерживаться не обязательно.

BITMAPFILEHEADER

BITMAPFILEHEADER — 14-байтная структура, которая располагается в самом начале файла. Обратите внимание на то, что с самого начала структуры сбивается выравнивание ячеек. Если для вас оно важно, то в оперативной памяти данный заголовок располагайте по чётным адресам, которые не кратны четырём (тогда 32-битные ячейки попадут на выравненные позиции).

Поз.
(hex)
Размер
(байты)
Имя Тип WinAPI Описание
00 2 bfType WORD Отметка для отличия формата от других (сигнатура формата). Может содержать единственное значение 4D4216/424D16 (little-endian/big-endian).
02 4 bfSize DWORD Размер файла в байтах.
06 2 bfReserved1 WORD Зарезервированы и должны содержать ноль.
08 2 bfReserved2 WORD
0A 4 bfOffBits DWORD Положение пиксельных данных относительно начала данной структуры (в байтах).

Сигнатура формата при просмотре содержимого файла текстом в двоичном режиме выглядит как пара ASCII-символов «BM».

BITMAPINFO

BITMAPINFO в файле идёт сразу за BITMAPFILEHEADER. Адрес этого блока в памяти напрямую также передаётся некоторым функциям WinAPI (например, SetDIBitsToDevice или CreateDIBitmap). Кроме этого, этот же блок используется в форматах значков и курсоров Windows, но в данной статье этот момент не рассматривается (см. отдельные описания этих форматов). Данная структура является основной и описательной в формате BMP и поэтому когда просто упомянуто имя поля, то речь идёт о поле в данной структуре.

Блок BITMAPINFO состоит из трёх частей:

  1. Структура с информационными полями.
  2. Битовые маски для извлечения значений цветовых каналов (присутствуют не всегда).
  3. Таблица цветов (присутствует не всегда).

Про битовые маски и таблицу цветов смотрите ниже в отдельных разделах. Здесь далее пойдёт описание структуры с информационными полями.

В момент написания данной статьи структура с информационными полями имела четыре версии[4]: CORE, 3, 4 и 5 (обозначения версий приведены условные в рамках данной статьи для краткости). Для каждой версии Microsoft объявила четыре отдельные структуры с разными именами полей. В данной статье при упоминании поля, которое присутствует в нескольких структурах, берётся общая для всех структур часть в конце имени (например, BitCount вместо bcBitCount, biBitCount, bV4BitCount или bV5BitCount). Версию структуры можно определить по первой 32-битной ячейке (WinAPI-тип DWORD), которая содержит её размер в байтах (беззнаковым целым). Версия CORE отличается от всех своей компактностью и использованием исключительно 16-битных беззнаковых полей. Остальные три содержат идентичные ячейки, к которым в каждой новой версии добавлялись новые.

Ниже представлена обзорная таблица по информационным структурам:

Версия</small> Размер
(байты)
Имя структуры Версия Windows 9x/NT[5] Версия Windows CE/Mobile[6] Примечания
CORE 12 BITMAPCOREHEADER 95/NT 3.1 и старше CE 2.0/Mobile 5.0 и старше Содержит только ширину, высоту и битность растра.
3 40 BITMAPINFOHEADER 95/NT 3.1 и старше CE 1.0/Mobile 5.0 и старше Содержит ширину, высоту и битность растра, а также формат пикселей, информацию о цветовой таблице и разрешении.
4 108 BITMAPV4HEADER 95/NT 4.0 и старше не поддерживается Отдельно выделены маски каналов, добавлена информация о цветовом пространстве и гамме.
5 124 BITMAPV5HEADER 98/2000 и старше не поддерживается Добавлено указание предпочтительной стратегии отображения и поддержка профилей ICC.

Из-за идентичности полей в версиях 3, 4 и 5 может показаться, что полем Size можно регулировать количество полей, убирая неиспользуемые. В действительности это не корректно, так как здесь размер играет роль версии (в версии CORE хоть и тоже идентичные поля, но другого размера и типа). Никто не гарантирует, что вам не могут попасться заголовки меньших или больших размеров с другим набором полей. Тем не менее, Adobe Photoshop может при сохранении файлов BMP записывать структуры информационных полей с размерами 52 и 56 байт. По сути это урезанная 4-я версия, которая содержат только битовые маски каналов (56 байт — версия с альфа-каналом).

16-битные информационные поля (версия CORE)

Обратите внимание на то, что здесь поля ширины и высоты содержат беззнаковые целые, в то время как 32-битные структуры хранят значения со знаком.

Позиция
в файле
(hex)
Позиция
в структуре
(hex)
Размер
(байты)
Имя Тип WinAPI Описание
0E 00 4 bcSize DWORD Размер данной структуры в байтах, указывающий также на версию структуры (здесь должно быть значение 12).
12 04 2 bcWidth WORD Ширина (bcWidth) и высота (bcHeight) растра в пикселях. Указываются целым числом без знака. Значение 0 не документировано.
14 06 2 bcHeight WORD
16 08 2 bcPlanes WORD В BMP допустимо только значение 1. Это поле используется в значках и курсорах Windows.
18 0A 2 bcBitCount WORD Количество бит на пиксель (список поддерживаемых смотрите в отдельном разделе ниже).

32-битные информационные поля (версии 3, 4 и 5)

В таблице ниже поля представлены обзорно. Подробную информацию вы можете найти в разделах далее.

Позиция
в файле
(hex)
Позиция
в структуре
(hex)
Размер
(байты)
Имя
(версии 3/4/5)
Тип WinAPI Описание
0E 00 4 biSize
bV4Size
bV5Size
DWORD Размер данной структуры в байтах, указывающий также на версию структуры (см. таблицу версий выше).
12 04 4 biWidth
bV4Width
bV5Width
LONG Ширина растра в пикселях. Указывается целым числом со знаком. Ноль и отрицательные не документированы.
16 08 4 biHeight
bV4Height
bV5Height
LONG Целое число со знаком, содержащее два параметра: высота растра в пикселях (абсолютное значение числа) и порядок следования строк в двумерных массивах (знак числа). Нулевое значение не документировано.
1A 0C 2 biPlanes
bV4Planes
bV5Planes
WORD В BMP допустимо только значение 1. Это поле используется в значках и курсорах Windows.
1C 0E 2 biBitCount
bV4BitCount
bV5BitCount
WORD Количество бит на пиксель (список поддерживаемых смотрите в отдельном разделе ниже).
1E 10 4 biCompression
bV4V4Compression[7]
bV5Compression
DWORD Указывает на способ хранения пикселей (см. в разделе ниже).
22 14 4 biSizeImage
bV4SizeImage
bV5SizeImage
DWORD Размер пиксельных данных в байтах. Может быть обнулено если хранение осуществляется двумерным массивом.
26 18 4 biXPelsPerMeter
bV4XPelsPerMeter
bV5XPelsPerMeter
LONG Количество пикселей на метр по горизонтали и вертикали (см. раздел «Разрешение изображения» данной статьи).
2A 1C 4 biYPelsPerMeter
bV4YPelsPerMeter
bV5YPelsPerMeter
LONG
2E 20 4 biClrUsed
bV4ClrUsed
bV5ClrUsed
DWORD Размер таблицы цветов в ячейках.
32 24 4 biClrImportant
bV4ClrImportant
bV5ClrImportant
DWORD Количество ячеек от начала таблицы цветов до последней используемой (включая её саму).
Добавлены в версии 4
Позиция
в файле
(hex)
Позиция
в структуре
(hex)
Размер
(байты)
Имя
(версии 4/5)
Тип WinAPI Описание
36 28 4 bV4RedMask
bV5RedMask
DWORD Битовые маски для извлечения значений каналов: интенсивность красного, зелёного, синего и значение альфа-канала.
3A 2C 4 bV4GreenMask
bV5GreenMask
DWORD
3E 30 4 bV4BlueMask
bV5BlueMask
DWORD
42 34 4 bV4AlphaMask
bV5AlphaMask
DWORD
46 38 4 bV4CSType
bV5CSType
DWORD Вид цветового пространства.
4A 3C 36 bV4Endpoints
bV5Endpoints
CIEXYZTRIPLE Значение этих четырёх полей берётся во внимание только если поле CSType содержит 0 (LCS_CALIBRATED_RGB). Тогда конечные точки и значения гаммы для трёх цветовых компонент указываются в этих полях.
6E 60 4 bV4GammaRed
bV5GammaRed
DWORD[8]
72 64 4 bV4GammaGreen
bV5GammaGreen
DWORD[8]
76 68 4 bV4GammaBlue
bV5GammaBlue
DWORD[8]
Добавлены в версии 5
Позиция
в файле
(hex)
Позиция
в структуре
(hex)
Размер
(байты)
Имя</small> Тип WinAPI Описание
7A 6C 4 bV5Intent DWORD Предпочтения при рендеринге растра.
7E 70 4 bV5ProfileData DWORD Смещение в байтах цветового профиля от начала BITMAPINFO (см. также раздел «Цветовой профиль» ниже в этой статье).
82 74 4 bV5ProfileSize DWORD Если в BMP непосредственно включается цветовой профиль, то здесь указывается его размер в байтах.
86 78 4 bV5Reserved DWORD Зарезервировано и должно быть обнулено.

Битность изображения (поле BitCount)

Поле BitCount содержит количество бит, которое приходится на каждый пиксель. Если там указано отличное от нуля значение, то это и есть реальная битность. Нулевое же содержимое поля BitCount указывается если пиксели хранятся в формате JPEG или PNG. Тогда действительная битность будет определяться уже этими форматами. Битности чисто BMP формата представлены в таблице ниже:

Бит Байт BITMAPINFO RLE Маски каналов Поддержка программным обеспечением
CORE 3, 4, 5 Windows 9x и NT Windows CE и Mobile GDI+ и .NET
1 Да Да Нет Нет Да Да Да
2 ¼ Да Да Нет Нет Нет Да Нет
4 ½ Да Да Да Нет Да Да Да
8 1 Да Да Да Нет Да Да Да
16 2 Нет Да Нет Да Да Да Да
24 3 Да Да Нет Нет Да Да Да
32 4 Нет Да Нет Да Да Да Да
48 6 Нет Да Нет Нет Нет Нет Да
64 8 Нет Да Нет Нет Нет Нет Да

Примечания к таблице:
1. В колонке «BITMAPINFO» указана поддержка битностей только со стороны Microsoft.
2. Windows CE 1.0 и 1.01 поддерживает только битности 1 и 2[9].
3. GDI+ версии 1.0 16-битные цветовые каналы умеет только считывать сразу переводя их в 8-битные[10].

В битностях 8 и ниже цвет пикселя указывается индексом в таблице цветов, в высших: непосредственным значением в цветовой модели RGB. Альфа-канал опционально может быть добавлен в битностях 16 и 32. В битности 64 он присутствует перманентно.

В таблице представлены только битности, которые документировала корпорация Microsoft. Сам формат не содержит никаких принципиальных ограничений на использование каких-либо не упомянутых здесь битностей.

1-битные BMP-файлы с чисто чёрным (сброшенный бит) и белым (установленный бит) цветами называют монохромными. Такие файлы обычно используются в качестве масок для других растров. Возможно вам постоянно попадались на глаза именно такие 1-битные растры. В действительности формат Windows Bitmap не накладывает никаких ограничений на то, какие цвета будут использоваться для каждого из значений бит.

Вы можете также встретить следующие названия битностей: CGA для двух бит, EGA для четырёх, HiColor (HighColor) для 16 бит, TrueColor для 24-ёх и 32-ух бит с полупрозрачностью, DeepColor для больших битностей и возможно другие. Эти названия появились в период развития цветных растровых дисплеев и относятся больше к их глубине цвета. К моменту написания данной статьи (2014-й год) такие названия уже давно не используются из-за сильного распространения 24-битных устройств (вместо этого просто указывается глубина цвета в битах или их количество). А BMP-файлы в меньшей битности сохраняются в большей степени не для отображения на CGA или EGA-устройствах, а для компактности по сравнению с 24-битными и 32-битными форматами если используется малое количество цветов.

Поле Compression

Для каждой группы битностей используются отдельные ограниченные значения Compression, но в совокупности их значения уникальны. Microsoft документировала следующие значения (в таблице указаны имена констант от этой корпорации):

Значение Имя константы Применимо
к BitCount
Хранение пикселей Знак Height Версия Windows
9x/NT CE
0 BI_RGB любым кроме нуля двумерный массив +/− 95/NT 3.1 CE 1.0
1 BI_RLE8 8 RLE-кодирование + 95/NT 3.1 (не подд.)
2 BI_RLE4 4 RLE-кодирование + 95/NT 3.1 (не подд.)
3 BI_BITFIELDS 16 и 32 двумерный массив с масками цветовых каналов +/− 95/NT 3.1 CE 2.0
4 BI_JPEG 0 во встроенном JPEG-файле  ?/−[11] 98/2000 (не подд.)
5 BI_PNG 0 во встроенном PNG-файле  ?/−[11] 98/2000 (не подд.)
6 BI_ALPHABITFIELDS 16 и 32 двумерный массив с масками цветовых и альфа-канала +/− (не подд.) .NET 4.0

Таблица цветов

Таблица цветов является частью блока BITMAPINFO и может использоваться в двух случаях:

  1. Она обязательно присутствует при битностях 8 и ниже, в которых цвет пикселей задаётся индексом ячейки из неё.
  2. При битностях 8 и выше, в которых цвет указывается непосредственным значением, таблица присутствует если используется заголовок не CORE-версии, у которого поле ClrUsed содержит не нулевое значение. Здесь она задействуется уже для оптимизации цветов при работе с использующими палитры устройствами (как именно производится оптимизация в документации не сказано).

Позиция таблицы цветов указывается от его начала блока BITMAPINFO. По умолчанию она идёт сразу за информационной структурой (её беззнаковый размер в байтах можно прочитать из первого 32-битного поля). Но между структурой с полями и цветовой таблицей могут идти четырёхбайтные битовые маски для извлечения цветовых каналов (касается только битностей 16 и 32). Они там находятся только если используется информационная структура 3-ей версии (Size = 40) и поле Compression содержит 3 (BI_BITFIELDS) или 6 (BI_ALPHABITFIELDS). Тогда к размеру информационных полей нужно прибавить 12 (при значении BI_BITFIELDS) или 16 байт (если указано BI_ALPHABITFIELDS)[12]. Получается 6 вариантов расположения таблицы:

Версия
заголовка
Позиция (hex) Примечания
В файле В BITMAPINFO
CORE 1A 0C маски каналов не поддерживаются
3 36 28 Compression не содержит 3 или 6
42 34 Compression = 3 (BI_BITFIELDS)
46 38 Compression = 6 (BI_ALPHABITFIELDS)
4 7A 6C маски каналов встроены
в информационные поля
5 8A 7B

Количество ячеек в таблице определяется по полям BitCount и ClrUsed. При битностях 8 и ниже максимальное количество ячеек в таблице принимается за 2битность: 2 в однобитном растре, 4 в двухбитном, 16 в 4-ёхбитном и 256 в 8-битном. В данных битностях таблица всегда содержит это максимальное количество ячеек если используется заголовок версии CORE (Size = 12) или если в других версиях поле ClrUsed содержит 0. Во всех остальных случаях, независимо от битности, в таблице находится столько же ячеек, сколько указано в поле ClrUsed[13].

Сама таблица же представляет собой одномерный массив, который может содержать ячейки трёх типов:

  1. 32-битная структура RGBQUAD. Применяется если в BITMAPINFO использована информационная структура версии 3, 4 или 5. В самой же структуре RGBQUAD указывается цвет в модели RGB в четырёх байтовых ячейках (все имеют WinAPI-тип BYTE): rgbBlue (синий), rgbGreen (зелёный), rgbRed (красный) и rgbReserved (зарезервирована и должна быть обнулена).
  2. 24-битная структура RGBTRIPLE. Применяется если BITMAPINFO начинается со структуры BITMAPCOREHEADER. RGBTRIPLE состоит из трёх байтовых ячеек (WinAPI-тип BYTE), в которых указывается цвет в модели RGB: rgbtBlue (синий), rgbtGreen (зелёный) и rgbtRed (красный).
  3. 16-битные индексы цветов (беззнаковые целые числа) в текущей логической палитре контекста устройства (системные объекты Windows GDI). Этот вид доступен только во время выполнения приложения. Формат BMP не поддерживает явное указание, что используется такая таблица и поэтому приложение само извещает WinAPI-функции об этом в специальных параметрах (как правило константой DIB_PAL_COLORS).

Во всей таблице могут быть задействованы не все ячейки и в поле ClrImportant помещается количество ячеек от начала таблицы до последней используемой (включая её саму). Содержимое 0 поля ClrImportant указывает на то, что используется вся таблица. Задействованные ячейки лучше размещать в самом начале таблицы и рекомендуется при этом отсортировать их по убыванию степени важности (на случай если придётся уменьшить их количество).

Маски для извлечения значений цветовых каналов

Если битность изображения 16 или 32, то могут быть указаны 32-битные маски для извлечения цветовых каналов. Это связано с тем, что 16 не кратно трём и поэтому биты могут быть распределены разными способами. В 32-битных изображениях из-за удобства используют 8-битные каналы и поэтому поддержка для них может показаться избыточной. В действительности здесь маска даёт возможность включить/отключить альфа-канал или установить удобный вам порядок следования компонент, а не только регулировать их разрешение. При применении масок ячейка пикселя считывается целиком как соответствующее машинное слово в litte-endian.

Наличие битовых масок зависит от версии информационных полей структуры BITMAPINFO и поля Compression в ней. Для версии CORE произвольные маски указать нельзя, так как там отсутствует поле Compression и отдельные поля масок. В остальных версиях цветовые маски задействуются если Compression содержит 3 (BI_BITFIELDS). Маска альфа-канала используется всегда в версиях 4 и 5. Так как Windows CE не поддерживает эти две версии, в которых для неё есть специальное поле, для третьей версии было введено значение 6 (BI_ALPHABITFIELDS) поля Compression, которое добавляет сразу цветовые маски и маску альфа-канала (поддерживается начиная с Windows CE .NET 4.0).

Положение битовых масок фиксировано независимо от версии заголовка: 36h во всём файле или 28h от начала блока BITMAPINFO. В версиях 4 и 5 на этом месте располагаются предназначенные специально для них поля. В версии же 3 битовые маски должны располагаться сразу за информационными полями и таким образом они точно попадают на позиции соответствующих полей в старших версиях. Обратите внимание на то, что в третьей версии при наличии масок сдвигается таблица цветов на 12 или 16 байт вперёд, располагаясь сразу за ними. 4-байтные маски цветов следуют в порядке красная, зелёная, синяя. Маска альфа-канала располагается уже за ними.

В документации Microsoft к битовым маскам применяется только одно обязательное требование: каждая маска должна быть непрерывной. Про случай пересечения масок там сказано, что желательно этого не делать[14]. Microsoft также говорит о том, что не обязательно задействовать все биты пикселя[15]. Какие-либо требования к содержимому неиспользуемых бит отсутствуют.

Обратите внимание на то, что никто не гарантирует, что могут быть использованы маски шире 8 бит. И ничего не сказано про случай, когда у какого-либо канала будет нулевая маска (например, когда он действительно не используется). Здесь возможна ситуация когда нулевые маски будут у всех компонентов и останется один альфа-канал (который при этом может занять все биты). Нулевую маску цветового канала можно трактовать двумя способами: его значение принимается за ноль или же при прорисовке пиксели этого канала не затрагиваются. Если взять первый вариант интерпретации с единственным альфа-каналом, то альфа-канал по сути будет задавать степень зачернения пикселя. Кроме неопределённых вариантов есть также и интересный. Так как пересечения не запрещены, то можно все каналы выставить на одну позицию и тем самым получить Grayscale.

Некоторое ПО имеет ограниченный набор поддерживаемых битовых масок. В таблице ниже приведены доступные варианты в таких ограниченных средах:

Битность * Значения масок (hex) Поддержка в ПО
Красный Зелёный Синий Альфа Неиспользуемые Windows 9x[16] GDI+[17] и .NET[18]
16 (a) 7C00 03E0 001F 0000 8000 Да Да
7C00 03E0 001F 8000 0000 Нет Да
F800 07E0 001F 0000 0000 Да Да
(b) FFFF FFFF FFFF 0000 0000 Нет Да
32 (a) 00FF:0000 0000:FF00 0000:00FF 0000:0000 FF00:0000 Да Да
00FF:0000 0000:FF00 0000:00FF FF00:0000 0000:0000 Нет Да

Примечания к таблице:
(a) Эти наборы используются по умолчанию в битностях 16 и 32 если маски для извлечения цветов не заданы.
(b) Данный набор масок по своей сути реализует 16-битный Grayscale.

Пиксельные данные

В файле положение пиксельных данных можно узнать из поля OffBits структуры BITMAPFILEHEADER. Во время выполнения приложение хранит адрес пиксельных данных там, где удобней. В документации Microsoft также упоминаются так называемые пакетные (англ. packed) битмапы, которые указываются одним адресом блока BITMAPINFO. У таких битмапов пиксельные данные следуют сразу за заголовком (включая помимо информационных полей битовые маски и таблицу цветов)[19].

Размер пиксельных данных в байтах записывается в поле SizeImage структуры BITMAPINFO. Туда записываются именно «сырой» размер того непрерывного блока, который содержит данные для формирования пикселей (независимо от формата), а не какой-нибудь распакованный. По умолчанию это поле обязательно должно содержать актуальное значение, так как по нему можно точно узнать сколько именно байт нужно считать из файла для получения пикселей. Тем не менее, допустимо содержать в этом поле ноль при хранении пикселей двумерными массивами (когда поле Compression содержит значение 0 (BI_RGB), 3 (BI_BITFIELDS) или 6 (BI_ALPHABITFIELDS)[20]). Тогда размер пикселей при необходимости можно относительно быстро рассчитать исходя из битности, ширины и высоты растра.

В формате Windows Bitmap доступно три способа хранения пикселей (см. также раздел «Поле Compression» данной статьи):

  1. Двумерный массив.
  2. RLE-кодирование (только для битностей 4 и 8).
  3. В форматах JPEG или PNG.

В подразделах далее отдельно описан каждый из них.

Указание цвета и значения альфа-канала

Для указания цвета при хранении в формате BMP независимо от способа задания используются только беззнаковые целые числа. Сам же цвет пикселя может задаваться двумя способами:

  1. Индексом в таблице цветов (при битностях 8 и ниже).
  2. Непосредственным значением в цветовой модели RGB (при битностях выше 8).

Второй целесообразно использовать когда набор цветов довольно большой или непредсказуем (например, во время обработки изображения). Первый же способ обеспечивает как компактную компоновку при малом наборе цветов, так и некоторое удобство в управлении используемыми цветами (достаточно изменить значение цвета в палитре). В самой таблице цветов указываются или 16-битные беззнаковые индексы в системной палитре (см. раздел «Таблица цветов» в данной статье), или же в RGB как в пикселе, но исключительно 8-битными значениями каналов.

Индекс в таблице цветов — это номер ячейки в ней от начала таблицы (используется непрерывная нумерация начиная с нуля). Для каждой битности максимальный индекс принципиально ограничен значением 2битность − 1. В действительности же он ограничен ещё и количеством элементов в таблице (подробности в разделе «Таблица цветов» данной статьи). Microsoft не документировала поведение в случае когда указывается индекс за пределами таблицы, но GDI в этом случае берёт чёрный цвет.

В битностях выше 8 цвет пикселя указывается непосредственно в цветовой модели RGB: отдельно указывается уровень красного цвета, зелёного и синего. Нулевое значение любого из каналов означает полное отсутствие соответствующего оттенка, а максимальное: полное его присутствие. Разрешение же значений каналов переменное и в каждой битности оно своё (конкретные значения смотрите в разделе про хранение пикселей в двумерном массиве этой статьи). При этом в битностях 16 и 32 может быть задано не только произвольное разрешение, но и индивидуальное для каждого канала (например, 5 бит для красной и синей, но 6 бит для зелёной). Несмотря на большое количество вариантов задания разрешения значений, в документации Microsoft не сказано как производить изменение разрешения значения. Из-за этого у разных производителей программного обеспечения могут получаться различные результаты при смене битности.

При непосредственном задании цвета пикселя кроме значений RGB формат Windows Bitmap опционально позволяет ещё задать значения альфа-канала. В плане битности и кодировании значений он идентичен цветовым каналам: у него произвольная битность и используются беззнаковые целые. Что же касается сопоставления значений, то ноль соответствует полной прозрачности, а максимальное доступное число — полной заполненности.

Двумерный массив

В двумерном массиве можно хранить пиксели любой битности. При таком способе хранения поле Compression содержит значение 0 (BI_RGB), 3 (BI_BITFIELDS) или 6 (BI_ALPHABITFIELDS). Если используется заголовок версии CORE, то пиксели в любом случае хранятся только двумерным массивом.

В данной компоновке пиксели растра записываются однопиксельными горизонтальными полосками, которые Microsoft в своей документации часто называет «scans» (в русском языке наиболее близкое слово: строки). В памяти эти ряды записываются по-порядку, но при положительном Height: начиная с самого нижнего (англ. bottom-up bitmap), а при отрицательном: с самого верхнего (англ. top-down bitmap). Внутри каждого горизонтального ряда пиксели записываются строго только от левого к правому. Пиксели меньше 8 бит размещаются в байтах, заполняя биты от старших к младшим, в результате чего шестнадцатиричные/двоичные числовые значения пикселей более похожи на выводимое изображение. Если битность 16 или 32, то обработка осуществляется цельными машинными словами аналогичного размера с порядком бит от младшего к старшему (little-endian). Ряды, независимо от размера ячеек, обязательно должны дополняться нулями до кратного четырём байтам размера[3]. Из-за этого, при некратной ширине изображения, в конце рядов могут оказываться неиспользуемые биты или целые байты. Но благодаря гарантированной кратности размера ряда, обработку можно производить 8-ми, 16-ти или 32-битными машинными словами, по выбору. И у Microsoft ещё прослеживается следующая тенденция в битностях больше 8: компонент Blue (синий цвет) размещается в младших битах/первых байтах, Green (зелёный) в последующих, а Red (красный) старше/дальше всех, и если есть альфа-канал, то он находится в самых старших битах/последних байтах.

Диаграмма ниже отображает расположение пикселей в битностях меньше 8:

Биты 7 6 5 4 3 2 1 0
1 бит 0 1 2 3 4 5 6 7
2 бита 0 1 2 3
4 бита 0 1

В битностях 16 и 32 пиксели обрабатываются машинными словами аналогичного размера (предполагается порядок байт little-endian), которым применяются битовые маски каналов. Если индивидуальные битовые маски не заданы, то структура будет следующая. При 16 бит на каждый канал отводится по 5 бит. Синий располагается в младших битах (маска 001F16), зелёный на позиции 5 (маска 03E016), красный: начиная с 10-го бита (маска 7C0016), а старший оставшийся бит 15 не используется. Если используется битность 32, то по умолчанию на каждый канал отводится уже по байту (8 бит). Компоненты располагаются аналогично: синий в младших битах (маска 0000:00FF16), зелёный начиная с бита 8 (маска 0000:FF0016), красный начинается с бита 16 (маска 00FF:000016), а старший байт не используется (он используется в качестве альфа-канала только если прямо это показать)[21]. Так как предполагается чтение в порядке байта little-endian, то если читать значения из памяти по-байтово, они будут располагать в таком же порядке (синий будет идти первым).

При битности 24 на каждый канал приходится по байту, а в битностях 48 и 64: по 16-битному машинному слову. Во всех трёх случаях в памяти цветовые компоненты идут в порядке: синий, зелёный, красный. В 64-битных BMP за цветами дополнительно следует 16-битный альфа-канал. Если захотите 64-битный пиксель обработать цельным машинным словом, то в little-endian синий окажется в младших 16 битах, а альфа-канал: в старших. Зелёный, соответственно, будет рядом к красным, а синий — рядом с альфа. И можно заметить что в 24-ёх битах формат пикселя соответствует структуре RGBTRIPLE из таблицы цветов.

RLE-кодирование

Применение RLE-кодирования компанией Microsoft документировано только для битностей 4 и 8. При её использовании в BITMAPINFO поле Compression должно содержать 2 (BI_RLE4) при битности 4 или 1 (BI_RLE8) с восьмибитными пикселями. Высота растра при этом должна быть указана положительным числом.

В формате Windows Bitmap RLE-кодирование можно сравнить с прорисовкой простыми командами. Прорисовка начинается с левого нижнего пикселя (будьте внимательней: в растрах в целом привычней может быть верхний правый) и осуществляется вправо и вверх. Пиксели за пределами размера растра не прорисовываются (об этом в документации не сказано, но GDI проявляет такое поведение). Инструкции RLE позволяют прерывать прорисовку горизонтали, всего изображения, а также перемещать курсор прорисовки на другую позицию. В результате некоторые пиксели могут оказаться не зарисованными. Формат не предусматривает цвета для незарисованных пикселей, в документации ничего про них не сказано, а системные функции просто не трогают незакрашенные пиксели. Так как нет веской причины в начале закрашивать прямоугольник под растром неопределённым цветом, то можно говорить о том что RLE косвенно поддерживает прозрачность.

Формирование изображения при RLE-кодировании осуществляется командами. Каждая команда обязательно должна начинаться с чётного адреса (выравнена на 16-битную границу). Существует пять команд, которые определяются парой байт:

Байт 1
(hex)
Байт 2
(hex)
Описание
01..FF 00..FF Начиная с текущей позиции и далее вправо прорисовать столько пикселей, сколько указано в первом байте. Значения для пикселей берутся из второго байта. В 8-битных BMP весь байт целиком является значением. В 4-битных из него по-очереди берётся сначала старший, а потом младший ниббл (четвёрка бит).
00 00 Переместить курсор в начало (самое лево) следующей (верхней) горизонтали.
00 01 Прекратить прорисовку (достигнут конец).
00 02 Переместить курсор вправо и вверх на указанные в следующих далее двух байтах значения. В первом следующем байте содержится значение для горизонтального сдвига, а в следующем — для вертикального. Оба значения: целые беззнаковые числа (влево и вниз сдвинуть нельзя).
00 03..FF С текущей позиции и далее вправо зарисовать пиксели значениями, которые идут после этой пары байт. Во втором байте команды содержится количество пикселей, которое нужно закрасить (именно пикселей, а не байт). В 8-битном растре берётся поток байт как есть. В 4-битном считывается уже нибблы: старшие 4 бита из байта для первого пикселя, младшие 4 бита — для следующего, и так из последующих байт. Данный поток может закончиться нечётным количеством байт, а команды требуют 16-битного выравнивания. Если это произошло, то дописывается дополнительный байт (его содержимое значения не имеет).

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

Встраивание данных в форматах JPEG и PNG

Начиная с версий Windows 98/ME и 2000/XP системные функции позволяют хранить пиксели в форматах JPEG и PNG. Про степень поддержки этих двух форматов системой ничего не известно.

Для встраивания JPEG или PNG нужно в BITMAPINFO обнулить поле BitCount, а в Compression указать значение 4 (BI_JPEG) или 5 (PI_PNG). Значение поля SizeImage в данном случае будет равно размеру JPEG или PNG-файла, который встраивается на место пиксельных данных как есть. Ширина же с высотой в заголовке указываются уже для раскодированного изображения. Про знак поля Height именно для этого случая в документации напрямую ничего не сказано, но судя по всему нужно записывать отрицательное значение[11].

Разрешение изображения

Для сопоставления безразмерных пикселей с материальными размерами используются поля XPelsPerMeter и YPelsPerMeter. В этих полях целым числом указывается сколько в данном изображении пикселей приходится на один линейный метр, отдельно по горизонтали (XPelsPerMeter) и вертикали (YPelsPerMeter). Microsoft объявила эти два поля числовым типом со знаком, но в документации ничего не сказано про отрицательные значения. Про значение ноль также ничего не сказано, но логичней его принимать за неопределённое разрешение, когда оно неизвестно или не имеет значения.

Разрешение часто указывается с привязкой не к метрическим размерностям, а в точках на дюйм (DPI/PPI). Для перевода туда и обратно дюйм принимается равным 25,4 мм (английский дюйм). Математические формулы для перевода пиксели/дюйм (PPI) в пиксели/метр (PPM) и наоборот:

<math>PPM = \frac{PPI}{25,4} * 1000</math>
<math>PPI = \frac{PPM}{1000} * 25,4</math>

Если интересует точный целочисленный перевод, то выходят следующие выражения:

PPM = (PPI * 5000 + 64) / 127
PPI = (PPM * 127 + 2500) / 5000

После них округление будет произведено к ближайшему целому. Если хотите округление вниз, то не прибавляйте половину делителя. Если хотите вверх, то прибавляйте уменьшенный на единицу делитель.

Ниже представлены заранее вычисленные значения PPM для некоторых PPI/DPI:

  • 96 ppi ≈ 3780 ppm (для мониторов у Microsoft)
  • 72 ppi ≈ 2835 ppm (Apple для мониторов)
  • 150 dpi ≈ 5906 ppm
  • 300 dpi ≈ 11811 ppm
  • 600 dpi ≈ 23622 ppm

Цветовое пространство

В информационных полях основным полем задающим цветовое пространство является поле CSType. Допустимые его значения приведены в таблице ниже:

Значение Версия
BITMAPINFO[22]
Имя константы Описание
Hex Текст
0 (нет) 4 LCS_CALIBRATED_RGB Корректировка исходя из значений Endpoints, GammaRed, GammaGreen и GammaBlue.
73524742 'sRGB' 4 LCS_sRGB Используется цветовое пространство sRGB.
57696E20 'Win '[23] 4 LCS_WINDOWS_COLOR_SPACE Системное пространство по умолчанию (sRGB).
4C494E4B 'LINK' 5 PROFILE_LINKED Цветовой профиль в другом файле.
4D424544 'MBED' 5 PROFILE_EMBEDDED Включённый в данный файл цветовой профиль.

Microsoft объявила значения констант не числовыми значениями, а текстовыми из четырёх символов[24]. В данном случае коды символов формируют байты 32-битного значения (ASCII-код самого правого символа является младшим байтом, код самого левого — старшим). При просмотре двоичного содержимого файла в виде текста такие значения в кодировке ASCII будут отображаться задом-наперёд (например, «KNIL», а не «LINK»).

Конечные точки и значение гаммы

Формат Windows Bitmap позволяет производить цветокоррекцию указанием конечных точек для красного, зелёного и синего цветов, а также значений гаммы. Для этого поле CSType должно содержать значение 0 (LCS_CALIBRATED_RGB). Корректирующие же значения записываются в поля Endpoints, GammaRed, GammaGreen и GammaBlue (при других значениях CSType эти четыре поля игнорируются).

36-байтное поле EndPoints является структурой CIEXYZTRIPLE, которая состоит из трёх полей ciexyzRed (конечная точка красного), ciexyzGreen (точка зелёного) и ciexyzBlue (синяя). Эти три поля в свою очередь также являются структурами CIEXYZ с тремя полями ciexyzX, ciexyzY и ciexyzZ типа FXPT2DOT30. PXPT2DOT30 — это 32-битное беззнаковое число с фиксированной запятой, у которого 2 старших бита отводятся под целую часть, а 30 младших — под дробную.

Значение гаммы записывается в соответствующие поля для каждого цветового канала отдельно: GammaRed (красный), GammaGreen (зелёный) и GammaBlue (синий). В объявлении информационных структур Microsoft указала у данных полей тип DWORD. В это же время в файле WinGDI.h есть более подходящее объявление типа FXPT16DOT16 (на основе типа long), который представляет собой 32-битное беззнаковое число с дробной частью в младших 16 битах и целой — в 16 старших. Следует отметить, что в MSDN на страницах про структуры [msdn.microsoft.com/en-us/library/dd183380%28v=vs.85%29.aspx BITMAPV4HEADER] и [msdn.microsoft.com/en-us/library/dd183381%28v=vs.85%29.aspx BITMAPV5HEADER] только это и сказано. В статье же про структуру LOGCOLORSPACE сказано, что у неё в аналогичных полях должны быть обнулены старший и младший байт (по сути вместо формата 16.16 используется формат 8.8, который располагается в середине 32-битной ячейки)[25].

Ниже приведены значения указанных выше четырёх полей в соответствии с цветовым пространством sRGB[26]:

Поле Значение
Дробное Hex
EndPoints.ciexyzRed.ciexyzX 0,64 28F5C28F
EndPoints.ciexyzRed.ciexyzY 0,33 151EB852
EndPoints.ciexyzRed.ciexyzZ 0,03 01EB851F
EndPoints.ciexyzGreen.ciexyzX 0,30 13333333
EndPoints.ciexyzGreen.ciexyzY 0,60 26666666
EndPoints.ciexyzGreen.ciexyzZ 0,10 06666666
EndPoints.ciexyzBlue.ciexyzX 0,15 0999999A
EndPoints.ciexyzBlue.ciexyzY 0,06 03D70A3D
EndPoints.ciexyzBlue.ciexyzZ 0,79 328F5C29
GammaRed
GammaGreen
GammaBlue
2,20 0002199A[27]

Цветовой профиль

В файле BMP при необходимости может быть указан цветовой профиль как непосредственным включением, так и ссылкой на другой файл. Профили появились в пятой версии BMP и пока только здесь есть специальные для них поля. Поддерживаются же цветовые профили только в формате ICC[28][29].

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

  • 4C494E4B16 (PROFILE_LINKED) — если используется профиль в другом файле.
  • 4D42454416 (PROFILE_EMBEDDED) — если профиль непосредственно встраивается в BMP.

В любом случае в поле ProfileData указывается смещение профиля в байтах от начала блока BITMAPINFO. Если профиль встроенный, то в ProfileSize нужно указать его размер в байтах (если он подключаемый, то это поле должно быть обнулено). Независимо от варианта, Microsoft рекомендует размещать профиль при хранении в файле за пиксельными данными, а в оперативной памяти при взаимодействии с WinAPI-функциями: сразу за заголовком[30].

Формат ICC в своём заголовке использует преимущественно 32-битные или кратные этому размеру ячейки[31]. Исходя из этого, если профиль непосредственно включается в BMP, то в оперативной памяти его рекомендуется хранить по кратному четырём байтам адресу.

Когда профиль внешний, то вместо его содержимого в BMP размещается текстовая строка с путём к файлу. Он обязательно должен быть в однобайтовой кодировке Windows 1252 (стандартная кодировка для западноевропейских языков) и заканчиваться нулевым байтом. Про разделители компонентов пути в документации ничего не сказано и поэтому скорее всего можно использовать как левые слэши «\», так и «правые» «/». Путь же может быть как относительным, так и полным и сетевым[30]. И так как в указании пути используется однобайтовая кодировка, то эту строку в оперативной памяти выравнивать не обязательно.

Предпочтения при рендеринге

Предпочтения при рендеринге (англ. rendering intents) были введены Международным концорциумом по цвету (International Color Consortium) и определяют приоритеты в случае когда при переходе из цветового подпространства, поддерживаемого одним устройством (англ. gamut), в подпространство другого, в изображении использованы цвета, отсутствующие в целевом. Также есть определение от ICC, которое определяется предпочтения при рендеринге как стиль сопоставления цветовых значений из одного описателя изображения в другое (оригинал на английском языке: «style of mapping colour values from one image description to another»)[32]. Корпорация Microsoft включила в формат BMP специальное поле Intent, которое может принимать значения полностью по спецификации ICC. Поэтому за подробной информации обращайтесь к документации консорциума, последнюю версию которой можно скачать с сайта [color.org/ color.org][33]. У Microsoft же эти предпочтения коротко описаны в статье «[msdn.microsoft.com/en-us/library/dd372183%28v=vs.85%29.aspx Rendering Intents]» на MSDN.

Предпочтение указывается в поле Intent блока BITMAPINFO и доступны только с 5-й версией информационных полей. Значения же могут быть следующими:

Значение Имя константы
для BMP
Название
ICC
Название
Microsoft
Константа
из файла Icm.h
Константа
для DEVMODE
1 LCS_GM_BUSINESS saturation Graphic INTENT_SATURATION (2) DMICM_SATURATE (1)
2 LCS_GM_GRAPHICS media-relative colorimetric Proof INTENT_RELATIVE_COLORIMETRIC (1) DMICM_COLORIMETRIC (3)
4 LCS_GM_IMAGES perceptual Picture INTENT_PERCEPTUAL (0) DMICM_CONTRAST (2)
8 LCS_GM_ABS_COLORIMETRIC ICC-absolute colorimetric
(relative colometric)
Match INTENT_ABSOLUTE_COLORIMETRIC (3) DMICM_ABS_COLORIMETRIC (4)

Microsoft для данной характеристики объявила как минимум три набора констант, которые отличаются своими значениями и используются в разных местах[34]. Здесь они приведены на случай если вам нужно будет быстро их сопоставить. Значения констант с префиксом «INTENT_» полностью совпадают с теми значениями, которые используются в файлах профилей ICC[35]. Константы с префиксом «DMICM_» объявлены в файле WinGDI.h для структуры DEVMODE. Константы «LCS_GM_», которые используются в BMP, объявлены там же и предназначены в первую очередь для структуры LOGCOLORSPACE. Есть также названия для свойств принтеров. Они аналогичны тем, что в колонке «Название Microsoft», но с «Graphics» и «Pictures».

За значение по умолчанию, которое в первую очередь подходит для фотографий и картинок, можно принимать 4 (LCS_GM_IMAGES). В таком качестве его рекомендует как Microsoft[36], так и ICC[37].

Пример программы на C

Следующая программа открывает 24 битный BMP файл в окне XWindow, глубина цвета должна составлять 32 бита, на меньшей цветопередаче не работает, так как это усложняет пример:

/* Компилируется строкой: cc -o xtest xtest.c -I/usr/X11R6/include -L/usr/X11R6/lib -lX11 -lm  */
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <X11/keysym.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <math.h>
#include "bitmap.h" /* Здесь определения заголовков BMP как было описано выше в этой статье (структуры должны быть упакованы на 2 байта!) */

static XImage *CreateImageFromBuffer(Display*, unsigned char *, int, int);

main(int argc, char *argv[])
{
    Display *dis;
    Window win;/* Наше окно */
    XEvent event;/* События */
    GC gc;/* Графический контекст */

    XImage *image;
    int  n, width, height, fd, size;
    unsigned char *data;
    BITMAPFILEHEADER bmp;
    BITMAPINFOHEADER inf;
    char* buf;

    if (argc < 2) {
	perror("use: xtest file.bmp\n");
	exit(1);
    }

  if ((fd = open(argv[1], O_RDONLY)) == -1) {
        printf("Error open bitmap\n");
        exit(1);
    }

  read(fd, &bmp, sizeof(BITMAPFILEHEADER));
  read(fd, &inf,sizeof(BITMAPINFOHEADER));

  width = inf.biWidth;
  height = inf.biHeight;

    if ((dis = XOpenDisplay(getenv("DISPLAY"))) == NULL) {
	printf("Can't connect X server:%s\n", strerror(errno));
	exit(1);
    }

    win = XCreateSimpleWindow(dis, RootWindow(dis, DefaultScreen(dis)), 0, 0, width, height, 5,
                   BlackPixel(dis, DefaultScreen(dis)), WhitePixel(dis, DefaultScreen(dis)));

    XSetStandardProperties(dis, win, argv[1], argv[0], None, argv, argc, NULL);
    gc = DefaultGC(dis, DefaultScreen(dis));

 /* Иногда в структуре это место не заполнено */
    if(inf.biSizeImage == 0)  {
    /* Вычислим размер */
     size = width * 3 + width % 4;
     size = size * height;
    } else {
      size = inf.biSizeImage;
     }
    
    buf = malloc(size);
    if(buf == NULL) {
	perror("malloc");
	exit(1);
    }
    printf("size =%d байтов выделено\n", size);

     /* Сместимся на начало самого изображения */
    lseek(fd, bmp.bfOffBits, SEEK_SET);

    /* Читаем в буфер */
    n = read(fd, buf, size);
    printf("size =%d байт прочитано\n", n);

   image = CreateImageFromBuffer(dis, buf, width, height);

   /* Удалим буфер - он нам больше не нужен */
   free(buf);

    XMapWindow(dis, win);
    XSelectInput(dis, win, ExposureMask | KeyPressMask);
    while (1) {
	XNextEvent(dis, &event);
	if (event.xany.window == win) {
	    switch (event.type) {
	    case Expose:
		XPutImage(dis, win, gc, image, 0, 0, 0, 0, image->width, image->height);
		break;

	    case KeyPress:
		if (XLookupKeysym(&event.xkey, 0) == XK_q) {
		    XDestroyImage(image);
		    XCloseDisplay(dis);
    	    	    close(fd);
		    exit(EXIT_SUCCESS);
		}
		break;

	    default:
		break;
	    }
	}
    }
}

/* Создает Ximage из файла BMP, так как изображение BMP хранится первернутым
 * и зеркальным-в цикле это исправляется */ 
XImage *CreateImageFromBuffer(Display * dis, unsigned char *buf, int width,  int height)
{
    int depth, screen;
    XImage *img = NULL;
    int i, j;
    int numBmpBytes;
    size_t numImgBytes;
    int32_t *imgBuf;
    int ind = 0;
    int line;
    int temp;
    int ih, iw; /* Номера строки и столбца для отражения  */
    int new_ind; /* Новый индекс */

    screen = DefaultScreen(dis);
    depth = DefaultDepth(dis, screen);
    temp = width * 3;
    line = temp + width % 4; /* Длина строки с учетом выравнивания */
    numImgBytes = (4 * (width * height));
    imgBuf = malloc(numImgBytes);

    /* Размер, отведенный на BMP в файле с учетом выравнивания */
    numBmpBytes = line * height;
    for (i = 0; i < numBmpBytes; i++) {
	unsigned int r, g, b;

	/* Пропускаем padding */
	if (i >= temp && (i % line) >= temp)
	    continue;
	
	b = buf[i];
	i++;
	g = buf[i];
	i++;
	r = buf[i];

	
	/* Вычисляем новый индекс для отражения по вертикали */
	iw = ind % width;
	ih = ind / width;
	new_ind = iw + (height - ih - 1) * width;
	
	imgBuf[new_ind] = (r | g << 8 | b << 16) << 8;
	ind++;
    }

    img = XCreateImage(dis, CopyFromParent, depth, ZPixmap, 0, (char *) imgBuf, width, height, 32, 0);
    XInitImage(img);

    /* Порядок битов и байтов на PC должен быть таким */
    img->byte_order = MSBFirst;

    img->bitmap_bit_order = MSBFirst;
    return img;
}

См. также

  • ICO (формат файлов) — родственный формат от Microsoft для хранения значков и курсоров мыши.

Напишите отзыв о статье "BMP"

Примечания

  1. Евченко А. И. OpenGL и DirectX. Программирование графики (Для профессионалов), 2006 г. Стр. 183.
  2. См. раздел «Remarks» статьи «[msdn.microsoft.com/en-us/library/windows/desktop/dd183381%28v=vs.85%29.aspx BITMAPV5HEADER structure]» на MSDN.
  3. 1 2 См. раздел «Remarks» в статье «[msdn.microsoft.com/en-us/library/windows/desktop/dd183375%28v=vs.85%29.aspx BITMAPINFO structure]» на MSDN.
  4. См. статью «[msdn.microsoft.com/en-us/library/dd183386%28v=vs.85%29.aspx Bitmap Header Types]» в MSDN.
  5. Информация о версиях взята из справки по Microsoft Windows SDK, идущая в комплекте с Microsoft Visual Studio 2008 и Embarcadero RAD Studio 2010 (раздел «Requirements» в статьях про данные структуры).
  6. См. разделы «Requirements» в статьях «[msdn.microsoft.com/en-us/library/aa931790.aspx BITMAPCOREHEADER]» и «[msdn.microsoft.com/en-us/library/aa930622.aspx BITMAPINFOHEADER]» применительно к Windows Mobile 6.5 на MSDN.
  7. Имя поля «bV4V4Compression» с удвоенным «V4» указано в документациях и объявлении структуры в файле WinGDI.h (смотрите, например, «[msdn.microsoft.com/en-us/library/dd183380%28v=vs.85%29.aspx BITMAPV4HEADER structure]» на MSDN.).
  8. 1 2 3 Microsoft объявила поля Gamma* с типом DWORD, но при этом в GDI есть специальный для таких полей тип FXPT16DOT16.
  9. См. раздел «Remarks» в статье [msdn.microsoft.com/en-us/library/aa930622.aspx BITMAPINFOHEADER] (рубрика «Windows Mobile 6.5») на MSDN.
  10. См. раздел «Remarks» в статье «[msdn.microsoft.com/en-us/library/ms534412%28v=vs.85%29.aspx Image Pixel Format Constants]» (рубрика «GDI+») на MSDN.
  11. 1 2 3 В MSDN в самом начале раздела «Remarks» [msdn.microsoft.com/en-us/library/dd183381%28v=vs.85%29.aspx страницы структуры BITMAPV5HEADER] есть предложение «If bV5Height is negative, indicating a top-down DIB, bV5Compression must be either BI_RGB or BI_BITFIELDS.» (перевод: «Если bV5Height отрицательный, обозначая DIB вида сверху-вниз, то bV5Compression должен быть либо BI_RGB, либо BI_BITFIELDS»). Здесь возможно не уточнили, что это касается только RLE-кодирования, так как в одном из примеров прорисовки JPEG-растра указывается именно отрицательная высота (ищите строку «bmi.bmiHeader.biHeight» в статье «[msdn.microsoft.com/en-us/library/windows/desktop/dd145131%28v=vs.85%29.aspx Testing a Printer for JPEG or PNG Support]» на MSDN).
  12. Будьте внимательны. В MSDN в статье «[msdn.microsoft.com/en-us/library/aa930622.aspx BITMAPINFOHEADER]» для Windows Mobile 6.5 в описании к полю biClrUsed есть предложение «If biBitCount equals 16 or 32, the optimal color palette starts immediately following the three DWORD masks.» (перевод: «Если biBitCount равно 16 или 32, то оптимальная цветовая палитра начинается следуя сразу за тремя DWORD-масками»). В этой же статье выше, в описании к полю biCompression сказано «Specifies that the bitmap is not compressed and that the color table consists of three DWORD color masks…» и ниже аналогичное с «consists of four DWORD color masks» (переводы: «Указывает, что битмап не сжат и что таблица цветов состоит из трёх цветовых DWORD-масок» и «состоит из четырёх цветовых DWORD-масок»). Аналогичная информация содержится в статье «[msdn.microsoft.com/en-us/library/dd183376%28v=vs.85%29.aspx BITMAPINFOHEADER structure]» для Windows 9x/NT. Всё это можно интерпретировать так, что в битности 16 и 32 за информационными полями (структурой BITMAPINFOHEADER) обязательно присутствуют три 32-битных маски для извлечения значений цветовых каналов. При этом если Compression содержит 3 (BI_BITFIELDS) или 6 (BI_ALPHABITFIELDS), то за ними добавляется ещё три или четыре аналогичных маски, которые в свою очередь занимают таблицу цветов делая невозможным использование 16-битных индексов оптимальных цветов в логической палитре (возможно при этом в поле biClrUsed нужно записать значение 6 или 8, а в biClrImportant обязательно 0, чтобы дополнительные маски случайно не обработались как индексы в палитре).
    В действительно всё несколько иначе.
  13. В документации MSDN на странице «[msdn.microsoft.com/en-us/library/dd183386%28v=vs.85%29.aspx Bitmap Header Types]» есть предложение «Bitmaps that are 1, 4, or 8 bpp must have a color table with a maximum size based on the bpp.» (перевод: «Битмапы с битностью 1, 4 или 8 должны содержать таблицу цветов с максимальным соответствующим битности размером.»). Это явно ошибка и писавший применил условия структуры CORE, у которой действительно должен быть максимум (см. раздел «Remarks» в статье «[msdn.microsoft.com/en-us/library/dd183373%28v=vs.85%29.aspx BITMAPCOREINFO structure]»), ко всем остальным версиям структур. В другой статье «[msdn.microsoft.com/en-us/library/dd183375%28v=vs.85%29.aspx BITMAPINFO structure]» про таблицу цветов сказано «The number of entries in the array depends on the values of the biBitCount and biClrUsed members of the BITMAPINFOHEADER structure.» (перевод: «количество элементов в массиве зависит от значений полей biBitCount и biClrUsed структуры BITMAPINFOHEADER»), а в статьях структур версий 3, 4, 5 (см., например, «[msdn.microsoft.com/en-us/library/dd183381%28v=vs.85%29.aspx BITMAPV5HEADER structure]») в описании поля BitCount везде написано «the bmiColors member of BITMAPINFO contains up to 256 entries» (аналогично про другие битности; перевод фразы: «член bmiColors BITMAPINFO содержит до 256 элементов»).
  14. См., например, описания к битностям 16 и 32 у поля bV5BitCount в статье «[msdn.microsoft.com/en-us/library/dd183381%28v=vs.85%29.aspx BITMAPV5HEADER structure]» на MSDN.
  15. На MSDN и справке Microsoft Windows SDK в статье «[msdn.microsoft.com/en-us/library/dd183376%28v=vs.85%29.aspx BITMAPINFOHEADER structure]» в описании значения 16 поля biBitCount есть сбивающее с толку предложение «All the bits in the pixel do not have to be used.» (перевод: «Не задействовать все биты в пикселе»). Это опечатка (написали «have» вместо «need»), которая отсутствует в аналогичном блоке в [msdn.microsoft.com/en-us/library/dd183381%28v=vs.85%29.aspx статье про пятую версию] (в четвёртой это предложение отсутствует).
  16. Данная информация есть в справке по Microsoft Windows SDK, которая идёт в комплекте вместе с крупными IDE.
  17. См. «[msdn.microsoft.com/en-us/library/ms534412%28v=vs.85%29.aspx Image Pixel Format Constants]» про GDI+ в MSDN.
  18. См. «[msdn.microsoft.com/en-us/library/system.drawing.imaging.pixelformat%28v=vs.71%29.aspx PixelFormat Enumeration]» про .NET Framework 1.1 в MSDN.
  19. См. раздел «[msdn.microsoft.com/en-us/library/dd183375%28v=vs.85%29.aspx Remarks]» в статье «BITMAPINFO» на MSDN.
  20. В документации (например, в статье «[msdn.microsoft.com/en-us/library/dd183381%28v=vs.85%29.aspx BITMAPV5HEADER structure]» на MSDN) сказано, что нулевой размер можно указывать при значении 0 (BI_RGB) поля Compression. Очевидно, что это применимо и к значениям 3 (BI_BITFIELDS) и 6 (BI_ALPHABITFIELDS), так как они вносят различие лишь во внутреннюю структуру пикселей, а не в их размер.
  21. По своей сути один-в-один как в структуре RGBQUAD, которая используется в таблице цветов.
  22. На MSDN в статье «[msdn.microsoft.com/en-us/library/dd183380%28v=vs.85%29.aspx BITMAPV4HEADER structure]» упоминается только одно значение поля CSType (LCS_CALIBRATED_RGB). Полный список доступных значений для версий 4 и 5 можно посмотреть в статье «[msdn.microsoft.com/en-us/library/dd372216%28v=vs.85%29.aspx Using Structures in WCS 1.0]».
  23. Здесь после «Win» идёт ещё пробел.
  24. Использование такого стиля значений констант только в поле CSType является скорее всего результатом влияния спецификации ICC, у которой в файлах цветовых профилей 32-битным меткам (англ. tags) значения выданы аналогично.
  25. См. раздел «Remarks» в статье «[msdn.microsoft.com/en-us/library/dd372165%28v=vs.85%29.aspx LOGCOLORSPACE Structure]» на MSDN.
  26. Числа взяты из стандарта «[www.w3.org/Graphics/Color/sRGB.html A Standard Default Color Space for the Internet — sRGB]». Все значения округлялись вверх если был установлен самый первый отброшенный права бит.
  27. С обнулённым младшим байтом будет значение 00001A0016 (округлено вверх).
  28. Описание данного формата есть в спецификации ICC.1:2010, ссылка на которую есть в конце данной статьи.
  29. См. раздел «Remarks» статьи «[msdn.microsoft.com/en-us/library/dd183381%28v=vs.85%29.aspx BITMAPV5HEADER structure]» на MSDN.
  30. 1 2 См. статью «[msdn.microsoft.com/en-us/library/dd372216%28v=vs.85%29.aspx Using Structures in WCS 1.0]» на MSDN.
  31. См. раздел «7.2 Profile header» в спецификации ICC.1:2010.
  32. Определение дано в спецификации ICC.1:2010 в разделе 3.1.27 на стр. 21.
  33. В версии 4.3 спецификации (последняя на момент написания статьи) данная тема широко освещается в разделах «0.4 Rendering intents» (во вступлении; стр. 8), «6.2 Rendering intent» (в основном содержимом; стр. 26) и «D.6 Discussion of colorimetric intents» (в приложениях; стр. 109).
  34. Сопоставления констант взяты из файла Icm.h (закомментированный блок прямо над объевлениями констант «INTENT_»).
  35. См. раздел «7.2.15 Rendering intent field (bytes 64 to 67)» спецификации ICC.
  36. См. раздел «Picture Intent» в статье «[msdn.microsoft.com/en-us/library/dd372183%28v=vs.85%29.aspx Rendering Intents]» на MSDN.
  37. В спецификации внизу страницы 41.

Источники и литература

Microsoft (MSDN и SDK)

Microsoft Windows SDK — комплект для разработчиков, который включает в себя справку и включаемые файлы на языке C++. По теме данной статьи актуальны файлы WinGDI.h и Icm.h, из которых были взяты в первую очередь значения констант. Последнюю версию данного комплекта можно [search.microsoft.com/en-us/DownloadResults.aspx?q=Microsoft%20Windows%20SDK&first=11&FORM=PEME бесплатно скачать с сайта Microsoft] (в данной статье использовались версии 6.0 и 7.1).

У Microsoft нет отдельной специальной документации именно по формату BMP. Но его структуры и прочие элементы описаны в рамках подсистемы GDI. Это описание есть в справке, которая включается в вышеупомянутое SDK, а также на MSDN. Причём в последнем она присутствует для разных платформ и независимо в справке по Visual Studio. В большинстве случаев там представлена идентичная информация, но в некоторых местах может быть немного больше фактов (например, в справке SDK больше информации о поддержке Windows).

Основная информацию находится в справке по GDI, которая относится к платформам Windows 9x и NT. Ссылки на страницы этого раздела, которые относятся только к формату, а не к WinAPI-функциям работы с ним:

  • «[msdn.microsoft.com/en-us/library/dd183382%28v=vs.85%29.aspx Bitmap Classifications]» — описание аппаратно-зависимых и аппаратно-независимых битмапов.
  • «[msdn.microsoft.com/en-us/library/dd183391%28v=vs.85%29.aspx Bitmap Storage]» — общее описание формата файла BMP.
  • «[msdn.microsoft.com/en-us/library/dd183386%28v=vs.85%29.aspx Bitmap Header Types]» — обзор по версиям заголовков BMP.
  • «[msdn.microsoft.com/en-us/library/dd183383%28v=vs.85%29.aspx Bitmap Compression]» — описание RLE-кодирования.
  • «[msdn.microsoft.com/en-us/library/dd183392%28v=vs.85%29.aspx Bitmap Structures]» — раздел с описаниями структур с полями. Для удобства прямые ссылки на ключевые:
    • [msdn.microsoft.com/en-us/library/dd183374%28v=vs.85%29.aspx BITMAPFILEHEADER]
    • [msdn.microsoft.com/en-us/library/dd183372%28v=vs.85%29.aspx BITMAPCOREHEADER]
    • [msdn.microsoft.com/en-us/library/dd183376%28v=vs.85%29.aspx BITMAPINFOHEADER]
    • [msdn.microsoft.com/en-us/library/dd183380%28v=vs.85%29.aspx BITMAPV4HEADER]
    • [msdn.microsoft.com/en-us/library/dd183381%28v=vs.85%29.aspx BITMAPV5HEADER]

У платформ Windows Compact 2013 (CE 6.0) и Mobile 6.5 есть только описания трёх структур, но применительно к данным платформам:

  • [msdn.microsoft.com/en-us/library/aa930979.aspx BITMAPFILEHEADER]
  • [msdn.microsoft.com/en-us/library/aa931790.aspx BITMAPCOREHEADER]
  • [msdn.microsoft.com/en-us/library/aa930622.aspx BITMAPINFOHEADER]

Ссылки на другие страницы из MSDN, которые относятся к формату BMP:

  • «[msdn.microsoft.com/en-us/library/ms534412%28v=vs.85%29.aspx Image Pixel Format Constants]» — константы форматов пикселей GDI+.
  • «[msdn.microsoft.com/en-us/library/system.drawing.imaging.pixelformat%28v=vs.71%29.aspx PixelFormat Enumeration]» — описание значений перечисляемого типа PixelFormat для .NET Framework 1.1 (самая ранняя версия).
  • «[msdn.microsoft.com/en-us/library/dd372216%28v=vs.85%29.aspx Using Structures in WCS 1.0]» — про используемые в управлении цветом в Windows структуры.
  • «[msdn.microsoft.com/en-us/library/dd372183%28v=vs.85%29.aspx Rendering Intents]» — описание предпочтений при рендеринге.

Другие

В спецификации ICC по управлению цветом можно найти информацию о цветовых профилях (в том числе о формате файлов ICC), а также о предпочтениях рендеринга. Данную спецификацию можно скачать с официального сайта концорциума [color.org/ color.org]. В момент написания статьи последней версией была 4.3 (декабрь 2010). Прямая ссылки на PDF с сайта ICC:

  • [www.color.org/specification/ICC1v43_2010-12.pdf Specification ICC.1:2010] (Profile version 4.3.0.0) «Image technology colour management — Architecture, profile format, and data structure».
  • [www.color.org/specification/ICC1-2010_Cumulative_Errata_List_2013-09-24.pdf Errata] к спецификации (обнаруженные ошибки и опечатки; опубликованы 24 сентября 2013 года).

Отрывок, характеризующий BMP

– Ваше положение вдвойне ужасно, милая княжна, – помолчав немного, сказала m lle Bourienne. – Я понимаю, что вы не могли и не можете думать о себе; но я моей любовью к вам обязана это сделать… Алпатыч был у вас? Говорил он с вами об отъезде? – спросила она.
Княжна Марья не отвечала. Она не понимала, куда и кто должен был ехать. «Разве можно было что нибудь предпринимать теперь, думать о чем нибудь? Разве не все равно? Она не отвечала.
– Вы знаете ли, chere Marie, – сказала m lle Bourienne, – знаете ли, что мы в опасности, что мы окружены французами; ехать теперь опасно. Ежели мы поедем, мы почти наверное попадем в плен, и бог знает…
Княжна Марья смотрела на свою подругу, не понимая того, что она говорила.
– Ах, ежели бы кто нибудь знал, как мне все все равно теперь, – сказала она. – Разумеется, я ни за что не желала бы уехать от него… Алпатыч мне говорил что то об отъезде… Поговорите с ним, я ничего, ничего не могу и не хочу…
– Я говорила с ним. Он надеется, что мы успеем уехать завтра; но я думаю, что теперь лучше бы было остаться здесь, – сказала m lle Bourienne. – Потому что, согласитесь, chere Marie, попасть в руки солдат или бунтующих мужиков на дороге – было бы ужасно. – M lle Bourienne достала из ридикюля объявление на нерусской необыкновенной бумаге французского генерала Рамо о том, чтобы жители не покидали своих домов, что им оказано будет должное покровительство французскими властями, и подала ее княжне.
– Я думаю, что лучше обратиться к этому генералу, – сказала m lle Bourienne, – и я уверена, что вам будет оказано должное уважение.
Княжна Марья читала бумагу, и сухие рыдания задергали ее лицо.
– Через кого вы получили это? – сказала она.
– Вероятно, узнали, что я француженка по имени, – краснея, сказала m lle Bourienne.
Княжна Марья с бумагой в руке встала от окна и с бледным лицом вышла из комнаты и пошла в бывший кабинет князя Андрея.
– Дуняша, позовите ко мне Алпатыча, Дронушку, кого нибудь, – сказала княжна Марья, – и скажите Амалье Карловне, чтобы она не входила ко мне, – прибавила она, услыхав голос m lle Bourienne. – Поскорее ехать! Ехать скорее! – говорила княжна Марья, ужасаясь мысли о том, что она могла остаться во власти французов.
«Чтобы князь Андрей знал, что она во власти французов! Чтоб она, дочь князя Николая Андреича Болконского, просила господина генерала Рамо оказать ей покровительство и пользовалась его благодеяниями! – Эта мысль приводила ее в ужас, заставляла ее содрогаться, краснеть и чувствовать еще не испытанные ею припадки злобы и гордости. Все, что только было тяжелого и, главное, оскорбительного в ее положении, живо представлялось ей. «Они, французы, поселятся в этом доме; господин генерал Рамо займет кабинет князя Андрея; будет для забавы перебирать и читать его письма и бумаги. M lle Bourienne lui fera les honneurs de Богучарово. [Мадемуазель Бурьен будет принимать его с почестями в Богучарове.] Мне дадут комнатку из милости; солдаты разорят свежую могилу отца, чтобы снять с него кресты и звезды; они мне будут рассказывать о победах над русскими, будут притворно выражать сочувствие моему горю… – думала княжна Марья не своими мыслями, но чувствуя себя обязанной думать за себя мыслями своего отца и брата. Для нее лично было все равно, где бы ни оставаться и что бы с ней ни было; но она чувствовала себя вместе с тем представительницей своего покойного отца и князя Андрея. Она невольно думала их мыслями и чувствовала их чувствами. Что бы они сказали, что бы они сделали теперь, то самое она чувствовала необходимым сделать. Она пошла в кабинет князя Андрея и, стараясь проникнуться его мыслями, обдумывала свое положение.
Требования жизни, которые она считала уничтоженными со смертью отца, вдруг с новой, еще неизвестной силой возникли перед княжной Марьей и охватили ее. Взволнованная, красная, она ходила по комнате, требуя к себе то Алпатыча, то Михаила Ивановича, то Тихона, то Дрона. Дуняша, няня и все девушки ничего не могли сказать о том, в какой мере справедливо было то, что объявила m lle Bourienne. Алпатыча не было дома: он уехал к начальству. Призванный Михаил Иваныч, архитектор, явившийся к княжне Марье с заспанными глазами, ничего не мог сказать ей. Он точно с той же улыбкой согласия, с которой он привык в продолжение пятнадцати лет отвечать, не выражая своего мнения, на обращения старого князя, отвечал на вопросы княжны Марьи, так что ничего определенного нельзя было вывести из его ответов. Призванный старый камердинер Тихон, с опавшим и осунувшимся лицом, носившим на себе отпечаток неизлечимого горя, отвечал «слушаю с» на все вопросы княжны Марьи и едва удерживался от рыданий, глядя на нее.
Наконец вошел в комнату староста Дрон и, низко поклонившись княжне, остановился у притолоки.
Княжна Марья прошлась по комнате и остановилась против него.
– Дронушка, – сказала княжна Марья, видевшая в нем несомненного друга, того самого Дронушку, который из своей ежегодной поездки на ярмарку в Вязьму привозил ей всякий раз и с улыбкой подавал свой особенный пряник. – Дронушка, теперь, после нашего несчастия, – начала она и замолчала, не в силах говорить дальше.
– Все под богом ходим, – со вздохом сказал он. Они помолчали.
– Дронушка, Алпатыч куда то уехал, мне не к кому обратиться. Правду ли мне говорят, что мне и уехать нельзя?
– Отчего же тебе не ехать, ваше сиятельство, ехать можно, – сказал Дрон.
– Мне сказали, что опасно от неприятеля. Голубчик, я ничего не могу, ничего не понимаю, со мной никого нет. Я непременно хочу ехать ночью или завтра рано утром. – Дрон молчал. Он исподлобья взглянул на княжну Марью.
– Лошадей нет, – сказал он, – я и Яков Алпатычу говорил.
– Отчего же нет? – сказала княжна.
– Все от божьего наказания, – сказал Дрон. – Какие лошади были, под войска разобрали, а какие подохли, нынче год какой. Не то лошадей кормить, а как бы самим с голоду не помереть! И так по три дня не емши сидят. Нет ничего, разорили вконец.
Княжна Марья внимательно слушала то, что он говорил ей.
– Мужики разорены? У них хлеба нет? – спросила она.
– Голодной смертью помирают, – сказал Дрон, – не то что подводы…
– Да отчего же ты не сказал, Дронушка? Разве нельзя помочь? Я все сделаю, что могу… – Княжне Марье странно было думать, что теперь, в такую минуту, когда такое горе наполняло ее душу, могли быть люди богатые и бедные и что могли богатые не помочь бедным. Она смутно знала и слышала, что бывает господский хлеб и что его дают мужикам. Она знала тоже, что ни брат, ни отец ее не отказали бы в нужде мужикам; она только боялась ошибиться как нибудь в словах насчет этой раздачи мужикам хлеба, которым она хотела распорядиться. Она была рада тому, что ей представился предлог заботы, такой, для которой ей не совестно забыть свое горе. Она стала расспрашивать Дронушку подробности о нуждах мужиков и о том, что есть господского в Богучарове.
– Ведь у нас есть хлеб господский, братнин? – спросила она.
– Господский хлеб весь цел, – с гордостью сказал Дрон, – наш князь не приказывал продавать.
– Выдай его мужикам, выдай все, что им нужно: я тебе именем брата разрешаю, – сказала княжна Марья.
Дрон ничего не ответил и глубоко вздохнул.
– Ты раздай им этот хлеб, ежели его довольно будет для них. Все раздай. Я тебе приказываю именем брата, и скажи им: что, что наше, то и ихнее. Мы ничего не пожалеем для них. Так ты скажи.
Дрон пристально смотрел на княжну, в то время как она говорила.
– Уволь ты меня, матушка, ради бога, вели от меня ключи принять, – сказал он. – Служил двадцать три года, худого не делал; уволь, ради бога.
Княжна Марья не понимала, чего он хотел от нее и от чего он просил уволить себя. Она отвечала ему, что она никогда не сомневалась в его преданности и что она все готова сделать для него и для мужиков.


Через час после этого Дуняша пришла к княжне с известием, что пришел Дрон и все мужики, по приказанию княжны, собрались у амбара, желая переговорить с госпожою.
– Да я никогда не звала их, – сказала княжна Марья, – я только сказала Дронушке, чтобы раздать им хлеба.
– Только ради бога, княжна матушка, прикажите их прогнать и не ходите к ним. Все обман один, – говорила Дуняша, – а Яков Алпатыч приедут, и поедем… и вы не извольте…
– Какой же обман? – удивленно спросила княжна
– Да уж я знаю, только послушайте меня, ради бога. Вот и няню хоть спросите. Говорят, не согласны уезжать по вашему приказанию.
– Ты что нибудь не то говоришь. Да я никогда не приказывала уезжать… – сказала княжна Марья. – Позови Дронушку.
Пришедший Дрон подтвердил слова Дуняши: мужики пришли по приказанию княжны.
– Да я никогда не звала их, – сказала княжна. – Ты, верно, не так передал им. Я только сказала, чтобы ты им отдал хлеб.
Дрон, не отвечая, вздохнул.
– Если прикажете, они уйдут, – сказал он.
– Нет, нет, я пойду к ним, – сказала княжна Марья
Несмотря на отговариванье Дуняши и няни, княжна Марья вышла на крыльцо. Дрон, Дуняша, няня и Михаил Иваныч шли за нею. «Они, вероятно, думают, что я предлагаю им хлеб с тем, чтобы они остались на своих местах, и сама уеду, бросив их на произвол французов, – думала княжна Марья. – Я им буду обещать месячину в подмосковной, квартиры; я уверена, что Andre еще больше бы сделав на моем месте», – думала она, подходя в сумерках к толпе, стоявшей на выгоне у амбара.
Толпа, скучиваясь, зашевелилась, и быстро снялись шляпы. Княжна Марья, опустив глаза и путаясь ногами в платье, близко подошла к ним. Столько разнообразных старых и молодых глаз было устремлено на нее и столько было разных лиц, что княжна Марья не видала ни одного лица и, чувствуя необходимость говорить вдруг со всеми, не знала, как быть. Но опять сознание того, что она – представительница отца и брата, придало ей силы, и она смело начала свою речь.
– Я очень рада, что вы пришли, – начала княжна Марья, не поднимая глаз и чувствуя, как быстро и сильно билось ее сердце. – Мне Дронушка сказал, что вас разорила война. Это наше общее горе, и я ничего не пожалею, чтобы помочь вам. Я сама еду, потому что уже опасно здесь и неприятель близко… потому что… Я вам отдаю все, мои друзья, и прошу вас взять все, весь хлеб наш, чтобы у вас не было нужды. А ежели вам сказали, что я отдаю вам хлеб с тем, чтобы вы остались здесь, то это неправда. Я, напротив, прошу вас уезжать со всем вашим имуществом в нашу подмосковную, и там я беру на себя и обещаю вам, что вы не будете нуждаться. Вам дадут и домы и хлеба. – Княжна остановилась. В толпе только слышались вздохи.
– Я не от себя делаю это, – продолжала княжна, – я это делаю именем покойного отца, который был вам хорошим барином, и за брата, и его сына.
Она опять остановилась. Никто не прерывал ее молчания.
– Горе наше общее, и будем делить всё пополам. Все, что мое, то ваше, – сказала она, оглядывая лица, стоявшие перед нею.
Все глаза смотрели на нее с одинаковым выражением, значения которого она не могла понять. Было ли это любопытство, преданность, благодарность, или испуг и недоверие, но выражение на всех лицах было одинаковое.
– Много довольны вашей милостью, только нам брать господский хлеб не приходится, – сказал голос сзади.
– Да отчего же? – сказала княжна.
Никто не ответил, и княжна Марья, оглядываясь по толпе, замечала, что теперь все глаза, с которыми она встречалась, тотчас же опускались.
– Отчего же вы не хотите? – спросила она опять.
Никто не отвечал.
Княжне Марье становилось тяжело от этого молчанья; она старалась уловить чей нибудь взгляд.
– Отчего вы не говорите? – обратилась княжна к старому старику, который, облокотившись на палку, стоял перед ней. – Скажи, ежели ты думаешь, что еще что нибудь нужно. Я все сделаю, – сказала она, уловив его взгляд. Но он, как бы рассердившись за это, опустил совсем голову и проговорил:
– Чего соглашаться то, не нужно нам хлеба.
– Что ж, нам все бросить то? Не согласны. Не согласны… Нет нашего согласия. Мы тебя жалеем, а нашего согласия нет. Поезжай сама, одна… – раздалось в толпе с разных сторон. И опять на всех лицах этой толпы показалось одно и то же выражение, и теперь это было уже наверное не выражение любопытства и благодарности, а выражение озлобленной решительности.
– Да вы не поняли, верно, – с грустной улыбкой сказала княжна Марья. – Отчего вы не хотите ехать? Я обещаю поселить вас, кормить. А здесь неприятель разорит вас…
Но голос ее заглушали голоса толпы.
– Нет нашего согласия, пускай разоряет! Не берем твоего хлеба, нет согласия нашего!
Княжна Марья старалась уловить опять чей нибудь взгляд из толпы, но ни один взгляд не был устремлен на нее; глаза, очевидно, избегали ее. Ей стало странно и неловко.
– Вишь, научила ловко, за ней в крепость иди! Дома разори да в кабалу и ступай. Как же! Я хлеб, мол, отдам! – слышались голоса в толпе.
Княжна Марья, опустив голову, вышла из круга и пошла в дом. Повторив Дрону приказание о том, чтобы завтра были лошади для отъезда, она ушла в свою комнату и осталась одна с своими мыслями.


Долго эту ночь княжна Марья сидела у открытого окна в своей комнате, прислушиваясь к звукам говора мужиков, доносившегося с деревни, но она не думала о них. Она чувствовала, что, сколько бы она ни думала о них, она не могла бы понять их. Она думала все об одном – о своем горе, которое теперь, после перерыва, произведенного заботами о настоящем, уже сделалось для нее прошедшим. Она теперь уже могла вспоминать, могла плакать и могла молиться. С заходом солнца ветер затих. Ночь была тихая и свежая. В двенадцатом часу голоса стали затихать, пропел петух, из за лип стала выходить полная луна, поднялся свежий, белый туман роса, и над деревней и над домом воцарилась тишина.
Одна за другой представлялись ей картины близкого прошедшего – болезни и последних минут отца. И с грустной радостью она теперь останавливалась на этих образах, отгоняя от себя с ужасом только одно последнее представление его смерти, которое – она чувствовала – она была не в силах созерцать даже в своем воображении в этот тихий и таинственный час ночи. И картины эти представлялись ей с такой ясностью и с такими подробностями, что они казались ей то действительностью, то прошедшим, то будущим.
То ей живо представлялась та минута, когда с ним сделался удар и его из сада в Лысых Горах волокли под руки и он бормотал что то бессильным языком, дергал седыми бровями и беспокойно и робко смотрел на нее.
«Он и тогда хотел сказать мне то, что он сказал мне в день своей смерти, – думала она. – Он всегда думал то, что он сказал мне». И вот ей со всеми подробностями вспомнилась та ночь в Лысых Горах накануне сделавшегося с ним удара, когда княжна Марья, предчувствуя беду, против его воли осталась с ним. Она не спала и ночью на цыпочках сошла вниз и, подойдя к двери в цветочную, в которой в эту ночь ночевал ее отец, прислушалась к его голосу. Он измученным, усталым голосом говорил что то с Тихоном. Ему, видно, хотелось поговорить. «И отчего он не позвал меня? Отчего он не позволил быть мне тут на месте Тихона? – думала тогда и теперь княжна Марья. – Уж он не выскажет никогда никому теперь всего того, что было в его душе. Уж никогда не вернется для него и для меня эта минута, когда бы он говорил все, что ему хотелось высказать, а я, а не Тихон, слушала бы и понимала его. Отчего я не вошла тогда в комнату? – думала она. – Может быть, он тогда же бы сказал мне то, что он сказал в день смерти. Он и тогда в разговоре с Тихоном два раза спросил про меня. Ему хотелось меня видеть, а я стояла тут, за дверью. Ему было грустно, тяжело говорить с Тихоном, который не понимал его. Помню, как он заговорил с ним про Лизу, как живую, – он забыл, что она умерла, и Тихон напомнил ему, что ее уже нет, и он закричал: „Дурак“. Ему тяжело было. Я слышала из за двери, как он, кряхтя, лег на кровать и громко прокричал: „Бог мой!Отчего я не взошла тогда? Что ж бы он сделал мне? Что бы я потеряла? А может быть, тогда же он утешился бы, он сказал бы мне это слово“. И княжна Марья вслух произнесла то ласковое слово, которое он сказал ей в день смерти. «Ду ше нь ка! – повторила княжна Марья это слово и зарыдала облегчающими душу слезами. Она видела теперь перед собою его лицо. И не то лицо, которое она знала с тех пор, как себя помнила, и которое она всегда видела издалека; а то лицо – робкое и слабое, которое она в последний день, пригибаясь к его рту, чтобы слышать то, что он говорил, в первый раз рассмотрела вблизи со всеми его морщинами и подробностями.
«Душенька», – повторила она.
«Что он думал, когда сказал это слово? Что он думает теперь? – вдруг пришел ей вопрос, и в ответ на это она увидала его перед собой с тем выражением лица, которое у него было в гробу на обвязанном белым платком лице. И тот ужас, который охватил ее тогда, когда она прикоснулась к нему и убедилась, что это не только не был он, но что то таинственное и отталкивающее, охватил ее и теперь. Она хотела думать о другом, хотела молиться и ничего не могла сделать. Она большими открытыми глазами смотрела на лунный свет и тени, всякую секунду ждала увидеть его мертвое лицо и чувствовала, что тишина, стоявшая над домом и в доме, заковывала ее.
– Дуняша! – прошептала она. – Дуняша! – вскрикнула она диким голосом и, вырвавшись из тишины, побежала к девичьей, навстречу бегущим к ней няне и девушкам.


17 го августа Ростов и Ильин, сопутствуемые только что вернувшимся из плена Лаврушкой и вестовым гусаром, из своей стоянки Янково, в пятнадцати верстах от Богучарова, поехали кататься верхами – попробовать новую, купленную Ильиным лошадь и разузнать, нет ли в деревнях сена.
Богучарово находилось последние три дня между двумя неприятельскими армиями, так что так же легко мог зайти туда русский арьергард, как и французский авангард, и потому Ростов, как заботливый эскадронный командир, желал прежде французов воспользоваться тем провиантом, который оставался в Богучарове.
Ростов и Ильин были в самом веселом расположении духа. Дорогой в Богучарово, в княжеское именье с усадьбой, где они надеялись найти большую дворню и хорошеньких девушек, они то расспрашивали Лаврушку о Наполеоне и смеялись его рассказам, то перегонялись, пробуя лошадь Ильина.
Ростов и не знал и не думал, что эта деревня, в которую он ехал, была именье того самого Болконского, который был женихом его сестры.
Ростов с Ильиным в последний раз выпустили на перегонку лошадей в изволок перед Богучаровым, и Ростов, перегнавший Ильина, первый вскакал в улицу деревни Богучарова.
– Ты вперед взял, – говорил раскрасневшийся Ильин.
– Да, всё вперед, и на лугу вперед, и тут, – отвечал Ростов, поглаживая рукой своего взмылившегося донца.
– А я на французской, ваше сиятельство, – сзади говорил Лаврушка, называя французской свою упряжную клячу, – перегнал бы, да только срамить не хотел.
Они шагом подъехали к амбару, у которого стояла большая толпа мужиков.
Некоторые мужики сняли шапки, некоторые, не снимая шапок, смотрели на подъехавших. Два старые длинные мужика, с сморщенными лицами и редкими бородами, вышли из кабака и с улыбками, качаясь и распевая какую то нескладную песню, подошли к офицерам.
– Молодцы! – сказал, смеясь, Ростов. – Что, сено есть?
– И одинакие какие… – сказал Ильин.
– Развесе…oo…ооо…лая бесе… бесе… – распевали мужики с счастливыми улыбками.
Один мужик вышел из толпы и подошел к Ростову.
– Вы из каких будете? – спросил он.
– Французы, – отвечал, смеючись, Ильин. – Вот и Наполеон сам, – сказал он, указывая на Лаврушку.
– Стало быть, русские будете? – переспросил мужик.
– А много вашей силы тут? – спросил другой небольшой мужик, подходя к ним.
– Много, много, – отвечал Ростов. – Да вы что ж собрались тут? – прибавил он. – Праздник, что ль?
– Старички собрались, по мирскому делу, – отвечал мужик, отходя от него.
В это время по дороге от барского дома показались две женщины и человек в белой шляпе, шедшие к офицерам.
– В розовом моя, чур не отбивать! – сказал Ильин, заметив решительно подвигавшуюся к нему Дуняшу.
– Наша будет! – подмигнув, сказал Ильину Лаврушка.
– Что, моя красавица, нужно? – сказал Ильин, улыбаясь.
– Княжна приказали узнать, какого вы полка и ваши фамилии?
– Это граф Ростов, эскадронный командир, а я ваш покорный слуга.
– Бе…се…е…ду…шка! – распевал пьяный мужик, счастливо улыбаясь и глядя на Ильина, разговаривающего с девушкой. Вслед за Дуняшей подошел к Ростову Алпатыч, еще издали сняв свою шляпу.
– Осмелюсь обеспокоить, ваше благородие, – сказал он с почтительностью, но с относительным пренебрежением к юности этого офицера и заложив руку за пазуху. – Моя госпожа, дочь скончавшегося сего пятнадцатого числа генерал аншефа князя Николая Андреевича Болконского, находясь в затруднении по случаю невежества этих лиц, – он указал на мужиков, – просит вас пожаловать… не угодно ли будет, – с грустной улыбкой сказал Алпатыч, – отъехать несколько, а то не так удобно при… – Алпатыч указал на двух мужиков, которые сзади так и носились около него, как слепни около лошади.
– А!.. Алпатыч… А? Яков Алпатыч!.. Важно! прости ради Христа. Важно! А?.. – говорили мужики, радостно улыбаясь ему. Ростов посмотрел на пьяных стариков и улыбнулся.
– Или, может, это утешает ваше сиятельство? – сказал Яков Алпатыч с степенным видом, не заложенной за пазуху рукой указывая на стариков.
– Нет, тут утешенья мало, – сказал Ростов и отъехал. – В чем дело? – спросил он.
– Осмелюсь доложить вашему сиятельству, что грубый народ здешний не желает выпустить госпожу из имения и угрожает отпречь лошадей, так что с утра все уложено и ее сиятельство не могут выехать.
– Не может быть! – вскрикнул Ростов.
– Имею честь докладывать вам сущую правду, – повторил Алпатыч.
Ростов слез с лошади и, передав ее вестовому, пошел с Алпатычем к дому, расспрашивая его о подробностях дела. Действительно, вчерашнее предложение княжны мужикам хлеба, ее объяснение с Дроном и с сходкою так испортили дело, что Дрон окончательно сдал ключи, присоединился к мужикам и не являлся по требованию Алпатыча и что поутру, когда княжна велела закладывать, чтобы ехать, мужики вышли большой толпой к амбару и выслали сказать, что они не выпустят княжны из деревни, что есть приказ, чтобы не вывозиться, и они выпрягут лошадей. Алпатыч выходил к ним, усовещивая их, но ему отвечали (больше всех говорил Карп; Дрон не показывался из толпы), что княжну нельзя выпустить, что на то приказ есть; а что пускай княжна остается, и они по старому будут служить ей и во всем повиноваться.
В ту минуту, когда Ростов и Ильин проскакали по дороге, княжна Марья, несмотря на отговариванье Алпатыча, няни и девушек, велела закладывать и хотела ехать; но, увидав проскакавших кавалеристов, их приняли за французов, кучера разбежались, и в доме поднялся плач женщин.
– Батюшка! отец родной! бог тебя послал, – говорили умиленные голоса, в то время как Ростов проходил через переднюю.
Княжна Марья, потерянная и бессильная, сидела в зале, в то время как к ней ввели Ростова. Она не понимала, кто он, и зачем он, и что с нею будет. Увидав его русское лицо и по входу его и первым сказанным словам признав его за человека своего круга, она взглянула на него своим глубоким и лучистым взглядом и начала говорить обрывавшимся и дрожавшим от волнения голосом. Ростову тотчас же представилось что то романическое в этой встрече. «Беззащитная, убитая горем девушка, одна, оставленная на произвол грубых, бунтующих мужиков! И какая то странная судьба натолкнула меня сюда! – думал Ростов, слушяя ее и глядя на нее. – И какая кротость, благородство в ее чертах и в выражении! – думал он, слушая ее робкий рассказ.
Когда она заговорила о том, что все это случилось на другой день после похорон отца, ее голос задрожал. Она отвернулась и потом, как бы боясь, чтобы Ростов не принял ее слова за желание разжалобить его, вопросительно испуганно взглянула на него. У Ростова слезы стояли в глазах. Княжна Марья заметила это и благодарно посмотрела на Ростова тем своим лучистым взглядом, который заставлял забывать некрасивость ее лица.
– Не могу выразить, княжна, как я счастлив тем, что я случайно заехал сюда и буду в состоянии показать вам свою готовность, – сказал Ростов, вставая. – Извольте ехать, и я отвечаю вам своей честью, что ни один человек не посмеет сделать вам неприятность, ежели вы мне только позволите конвоировать вас, – и, почтительно поклонившись, как кланяются дамам царской крови, он направился к двери.
Почтительностью своего тона Ростов как будто показывал, что, несмотря на то, что он за счастье бы счел свое знакомство с нею, он не хотел пользоваться случаем ее несчастия для сближения с нею.
Княжна Марья поняла и оценила этот тон.
– Я очень, очень благодарна вам, – сказала ему княжна по французски, – но надеюсь, что все это было только недоразуменье и что никто не виноват в том. – Княжна вдруг заплакала. – Извините меня, – сказала она.
Ростов, нахмурившись, еще раз низко поклонился и вышел из комнаты.


– Ну что, мила? Нет, брат, розовая моя прелесть, и Дуняшей зовут… – Но, взглянув на лицо Ростова, Ильин замолк. Он видел, что его герой и командир находился совсем в другом строе мыслей.
Ростов злобно оглянулся на Ильина и, не отвечая ему, быстрыми шагами направился к деревне.
– Я им покажу, я им задам, разбойникам! – говорил он про себя.
Алпатыч плывущим шагом, чтобы только не бежать, рысью едва догнал Ростова.
– Какое решение изволили принять? – сказал он, догнав его.
Ростов остановился и, сжав кулаки, вдруг грозно подвинулся на Алпатыча.
– Решенье? Какое решенье? Старый хрыч! – крикнул он на него. – Ты чего смотрел? А? Мужики бунтуют, а ты не умеешь справиться? Ты сам изменник. Знаю я вас, шкуру спущу со всех… – И, как будто боясь растратить понапрасну запас своей горячности, он оставил Алпатыча и быстро пошел вперед. Алпатыч, подавив чувство оскорбления, плывущим шагом поспевал за Ростовым и продолжал сообщать ему свои соображения. Он говорил, что мужики находились в закоснелости, что в настоящую минуту было неблагоразумно противуборствовать им, не имея военной команды, что не лучше ли бы было послать прежде за командой.
– Я им дам воинскую команду… Я их попротивоборствую, – бессмысленно приговаривал Николай, задыхаясь от неразумной животной злобы и потребности излить эту злобу. Не соображая того, что будет делать, бессознательно, быстрым, решительным шагом он подвигался к толпе. И чем ближе он подвигался к ней, тем больше чувствовал Алпатыч, что неблагоразумный поступок его может произвести хорошие результаты. То же чувствовали и мужики толпы, глядя на его быструю и твердую походку и решительное, нахмуренное лицо.
После того как гусары въехали в деревню и Ростов прошел к княжне, в толпе произошло замешательство и раздор. Некоторые мужики стали говорить, что эти приехавшие были русские и как бы они не обиделись тем, что не выпускают барышню. Дрон был того же мнения; но как только он выразил его, так Карп и другие мужики напали на бывшего старосту.
– Ты мир то поедом ел сколько годов? – кричал на него Карп. – Тебе все одно! Ты кубышку выроешь, увезешь, тебе что, разори наши дома али нет?
– Сказано, порядок чтоб был, не езди никто из домов, чтобы ни синь пороха не вывозить, – вот она и вся! – кричал другой.
– Очередь на твоего сына была, а ты небось гладуха своего пожалел, – вдруг быстро заговорил маленький старичок, нападая на Дрона, – а моего Ваньку забрил. Эх, умирать будем!
– То то умирать будем!
– Я от миру не отказчик, – говорил Дрон.
– То то не отказчик, брюхо отрастил!..
Два длинные мужика говорили свое. Как только Ростов, сопутствуемый Ильиным, Лаврушкой и Алпатычем, подошел к толпе, Карп, заложив пальцы за кушак, слегка улыбаясь, вышел вперед. Дрон, напротив, зашел в задние ряды, и толпа сдвинулась плотнее.
– Эй! кто у вас староста тут? – крикнул Ростов, быстрым шагом подойдя к толпе.
– Староста то? На что вам?.. – спросил Карп. Но не успел он договорить, как шапка слетела с него и голова мотнулась набок от сильного удара.
– Шапки долой, изменники! – крикнул полнокровный голос Ростова. – Где староста? – неистовым голосом кричал он.
– Старосту, старосту кличет… Дрон Захарыч, вас, – послышались кое где торопливо покорные голоса, и шапки стали сниматься с голов.
– Нам бунтовать нельзя, мы порядки блюдем, – проговорил Карп, и несколько голосов сзади в то же мгновенье заговорили вдруг:
– Как старички пороптали, много вас начальства…
– Разговаривать?.. Бунт!.. Разбойники! Изменники! – бессмысленно, не своим голосом завопил Ростов, хватая за юрот Карпа. – Вяжи его, вяжи! – кричал он, хотя некому было вязать его, кроме Лаврушки и Алпатыча.
Лаврушка, однако, подбежал к Карпу и схватил его сзади за руки.
– Прикажете наших из под горы кликнуть? – крикнул он.
Алпатыч обратился к мужикам, вызывая двоих по именам, чтобы вязать Карпа. Мужики покорно вышли из толпы и стали распоясываться.
– Староста где? – кричал Ростов.
Дрон, с нахмуренным и бледным лицом, вышел из толпы.
– Ты староста? Вязать, Лаврушка! – кричал Ростов, как будто и это приказание не могло встретить препятствий. И действительно, еще два мужика стали вязать Дрона, который, как бы помогая им, снял с себя кушан и подал им.
– А вы все слушайте меня, – Ростов обратился к мужикам: – Сейчас марш по домам, и чтобы голоса вашего я не слыхал.
– Что ж, мы никакой обиды не делали. Мы только, значит, по глупости. Только вздор наделали… Я же сказывал, что непорядки, – послышались голоса, упрекавшие друг друга.
– Вот я же вам говорил, – сказал Алпатыч, вступая в свои права. – Нехорошо, ребята!
– Глупость наша, Яков Алпатыч, – отвечали голоса, и толпа тотчас же стала расходиться и рассыпаться по деревне.
Связанных двух мужиков повели на барский двор. Два пьяные мужика шли за ними.
– Эх, посмотрю я на тебя! – говорил один из них, обращаясь к Карпу.
– Разве можно так с господами говорить? Ты думал что?
– Дурак, – подтверждал другой, – право, дурак!
Через два часа подводы стояли на дворе богучаровского дома. Мужики оживленно выносили и укладывали на подводы господские вещи, и Дрон, по желанию княжны Марьи выпущенный из рундука, куда его заперли, стоя на дворе, распоряжался мужиками.
– Ты ее так дурно не клади, – говорил один из мужиков, высокий человек с круглым улыбающимся лицом, принимая из рук горничной шкатулку. – Она ведь тоже денег стоит. Что же ты ее так то вот бросишь или пол веревку – а она потрется. Я так не люблю. А чтоб все честно, по закону было. Вот так то под рогожку, да сенцом прикрой, вот и важно. Любо!
– Ишь книг то, книг, – сказал другой мужик, выносивший библиотечные шкафы князя Андрея. – Ты не цепляй! А грузно, ребята, книги здоровые!
– Да, писали, не гуляли! – значительно подмигнув, сказал высокий круглолицый мужик, указывая на толстые лексиконы, лежавшие сверху.

Ростов, не желая навязывать свое знакомство княжне, не пошел к ней, а остался в деревне, ожидая ее выезда. Дождавшись выезда экипажей княжны Марьи из дома, Ростов сел верхом и до пути, занятого нашими войсками, в двенадцати верстах от Богучарова, верхом провожал ее. В Янкове, на постоялом дворе, он простился с нею почтительно, в первый раз позволив себе поцеловать ее руку.
– Как вам не совестно, – краснея, отвечал он княжне Марье на выражение благодарности за ее спасенье (как она называла его поступок), – каждый становой сделал бы то же. Если бы нам только приходилось воевать с мужиками, мы бы не допустили так далеко неприятеля, – говорил он, стыдясь чего то и стараясь переменить разговор. – Я счастлив только, что имел случай познакомиться с вами. Прощайте, княжна, желаю вам счастия и утешения и желаю встретиться с вами при более счастливых условиях. Ежели вы не хотите заставить краснеть меня, пожалуйста, не благодарите.
Но княжна, если не благодарила более словами, благодарила его всем выражением своего сиявшего благодарностью и нежностью лица. Она не могла верить ему, что ей не за что благодарить его. Напротив, для нее несомненно было то, что ежели бы его не было, то она, наверное, должна была бы погибнуть и от бунтовщиков и от французов; что он, для того чтобы спасти ее, подвергал себя самым очевидным и страшным опасностям; и еще несомненнее было то, что он был человек с высокой и благородной душой, который умел понять ее положение и горе. Его добрые и честные глаза с выступившими на них слезами, в то время как она сама, заплакав, говорила с ним о своей потере, не выходили из ее воображения.
Когда она простилась с ним и осталась одна, княжна Марья вдруг почувствовала в глазах слезы, и тут уж не в первый раз ей представился странный вопрос, любит ли она его?
По дороге дальше к Москве, несмотря на то, что положение княжны было не радостно, Дуняша, ехавшая с ней в карете, не раз замечала, что княжна, высунувшись в окно кареты, чему то радостно и грустно улыбалась.
«Ну что же, ежели бы я и полюбила его? – думала княжна Марья.
Как ни стыдно ей было признаться себе, что она первая полюбила человека, который, может быть, никогда не полюбит ее, она утешала себя мыслью, что никто никогда не узнает этого и что она не будет виновата, ежели будет до конца жизни, никому не говоря о том, любить того, которого она любила в первый и в последний раз.
Иногда она вспоминала его взгляды, его участие, его слова, и ей казалось счастье не невозможным. И тогда то Дуняша замечала, что она, улыбаясь, глядела в окно кареты.
«И надо было ему приехать в Богучарово, и в эту самую минуту! – думала княжна Марья. – И надо было его сестре отказать князю Андрею! – И во всем этом княжна Марья видела волю провиденья.
Впечатление, произведенное на Ростова княжной Марьей, было очень приятное. Когда ои вспоминал про нее, ему становилось весело, и когда товарищи, узнав о бывшем с ним приключении в Богучарове, шутили ему, что он, поехав за сеном, подцепил одну из самых богатых невест в России, Ростов сердился. Он сердился именно потому, что мысль о женитьбе на приятной для него, кроткой княжне Марье с огромным состоянием не раз против его воли приходила ему в голову. Для себя лично Николай не мог желать жены лучше княжны Марьи: женитьба на ней сделала бы счастье графини – его матери, и поправила бы дела его отца; и даже – Николай чувствовал это – сделала бы счастье княжны Марьи. Но Соня? И данное слово? И от этого то Ростов сердился, когда ему шутили о княжне Болконской.


Приняв командование над армиями, Кутузов вспомнил о князе Андрее и послал ему приказание прибыть в главную квартиру.
Князь Андрей приехал в Царево Займище в тот самый день и в то самое время дня, когда Кутузов делал первый смотр войскам. Князь Андрей остановился в деревне у дома священника, у которого стоял экипаж главнокомандующего, и сел на лавочке у ворот, ожидая светлейшего, как все называли теперь Кутузова. На поле за деревней слышны были то звуки полковой музыки, то рев огромного количества голосов, кричавших «ура!новому главнокомандующему. Тут же у ворот, шагах в десяти от князя Андрея, пользуясь отсутствием князя и прекрасной погодой, стояли два денщика, курьер и дворецкий. Черноватый, обросший усами и бакенбардами, маленький гусарский подполковник подъехал к воротам и, взглянув на князя Андрея, спросил: здесь ли стоит светлейший и скоро ли он будет?
Князь Андрей сказал, что он не принадлежит к штабу светлейшего и тоже приезжий. Гусарский подполковник обратился к нарядному денщику, и денщик главнокомандующего сказал ему с той особенной презрительностью, с которой говорят денщики главнокомандующих с офицерами:
– Что, светлейший? Должно быть, сейчас будет. Вам что?
Гусарский подполковник усмехнулся в усы на тон денщика, слез с лошади, отдал ее вестовому и подошел к Болконскому, слегка поклонившись ему. Болконский посторонился на лавке. Гусарский подполковник сел подле него.
– Тоже дожидаетесь главнокомандующего? – заговорил гусарский подполковник. – Говог'ят, всем доступен, слава богу. А то с колбасниками беда! Недаг'ом Ег'молов в немцы пг'осился. Тепег'ь авось и г'усским говог'ить можно будет. А то чег'т знает что делали. Все отступали, все отступали. Вы делали поход? – спросил он.
– Имел удовольствие, – отвечал князь Андрей, – не только участвовать в отступлении, но и потерять в этом отступлении все, что имел дорогого, не говоря об именьях и родном доме… отца, который умер с горя. Я смоленский.
– А?.. Вы князь Болконский? Очень г'ад познакомиться: подполковник Денисов, более известный под именем Васьки, – сказал Денисов, пожимая руку князя Андрея и с особенно добрым вниманием вглядываясь в лицо Болконского. – Да, я слышал, – сказал он с сочувствием и, помолчав немного, продолжал: – Вот и скифская война. Это все хог'ошо, только не для тех, кто своими боками отдувается. А вы – князь Андг'ей Болконский? – Он покачал головой. – Очень г'ад, князь, очень г'ад познакомиться, – прибавил он опять с грустной улыбкой, пожимая ему руку.
Князь Андрей знал Денисова по рассказам Наташи о ее первом женихе. Это воспоминанье и сладко и больно перенесло его теперь к тем болезненным ощущениям, о которых он последнее время давно уже не думал, но которые все таки были в его душе. В последнее время столько других и таких серьезных впечатлений, как оставление Смоленска, его приезд в Лысые Горы, недавнее известно о смерти отца, – столько ощущений было испытано им, что эти воспоминания уже давно не приходили ему и, когда пришли, далеко не подействовали на него с прежней силой. И для Денисова тот ряд воспоминаний, которые вызвало имя Болконского, было далекое, поэтическое прошедшее, когда он, после ужина и пения Наташи, сам не зная как, сделал предложение пятнадцатилетней девочке. Он улыбнулся воспоминаниям того времени и своей любви к Наташе и тотчас же перешел к тому, что страстно и исключительно теперь занимало его. Это был план кампании, который он придумал, служа во время отступления на аванпостах. Он представлял этот план Барклаю де Толли и теперь намерен был представить его Кутузову. План основывался на том, что операционная линия французов слишком растянута и что вместо того, или вместе с тем, чтобы действовать с фронта, загораживая дорогу французам, нужно было действовать на их сообщения. Он начал разъяснять свой план князю Андрею.
– Они не могут удержать всей этой линии. Это невозможно, я отвечаю, что пг'ог'ву их; дайте мне пятьсот человек, я г'азог'ву их, это вег'но! Одна система – паг'тизанская.
Денисов встал и, делая жесты, излагал свой план Болконскому. В средине его изложения крики армии, более нескладные, более распространенные и сливающиеся с музыкой и песнями, послышались на месте смотра. На деревне послышался топот и крики.
– Сам едет, – крикнул казак, стоявший у ворот, – едет! Болконский и Денисов подвинулись к воротам, у которых стояла кучка солдат (почетный караул), и увидали подвигавшегося по улице Кутузова, верхом на невысокой гнедой лошадке. Огромная свита генералов ехала за ним. Барклай ехал почти рядом; толпа офицеров бежала за ними и вокруг них и кричала «ура!».
Вперед его во двор проскакали адъютанты. Кутузов, нетерпеливо подталкивая свою лошадь, плывшую иноходью под его тяжестью, и беспрестанно кивая головой, прикладывал руку к бедой кавалергардской (с красным околышем и без козырька) фуражке, которая была на нем. Подъехав к почетному караулу молодцов гренадеров, большей частью кавалеров, отдававших ему честь, он с минуту молча, внимательно посмотрел на них начальническим упорным взглядом и обернулся к толпе генералов и офицеров, стоявших вокруг него. Лицо его вдруг приняло тонкое выражение; он вздернул плечами с жестом недоумения.
– И с такими молодцами всё отступать и отступать! – сказал он. – Ну, до свиданья, генерал, – прибавил он и тронул лошадь в ворота мимо князя Андрея и Денисова.
– Ура! ура! ура! – кричали сзади его.
С тех пор как не видал его князь Андрей, Кутузов еще потолстел, обрюзг и оплыл жиром. Но знакомые ему белый глаз, и рана, и выражение усталости в его лице и фигуре были те же. Он был одет в мундирный сюртук (плеть на тонком ремне висела через плечо) и в белой кавалергардской фуражке. Он, тяжело расплываясь и раскачиваясь, сидел на своей бодрой лошадке.
– Фю… фю… фю… – засвистал он чуть слышно, въезжая на двор. На лице его выражалась радость успокоения человека, намеревающегося отдохнуть после представительства. Он вынул левую ногу из стремени, повалившись всем телом и поморщившись от усилия, с трудом занес ее на седло, облокотился коленкой, крякнул и спустился на руки к казакам и адъютантам, поддерживавшим его.
Он оправился, оглянулся своими сощуренными глазами и, взглянув на князя Андрея, видимо, не узнав его, зашагал своей ныряющей походкой к крыльцу.
– Фю… фю… фю, – просвистал он и опять оглянулся на князя Андрея. Впечатление лица князя Андрея только после нескольких секунд (как это часто бывает у стариков) связалось с воспоминанием о его личности.
– А, здравствуй, князь, здравствуй, голубчик, пойдем… – устало проговорил он, оглядываясь, и тяжело вошел на скрипящее под его тяжестью крыльцо. Он расстегнулся и сел на лавочку, стоявшую на крыльце.
– Ну, что отец?
– Вчера получил известие о его кончине, – коротко сказал князь Андрей.
Кутузов испуганно открытыми глазами посмотрел на князя Андрея, потом снял фуражку и перекрестился: «Царство ему небесное! Да будет воля божия над всеми нами!Он тяжело, всей грудью вздохнул и помолчал. „Я его любил и уважал и сочувствую тебе всей душой“. Он обнял князя Андрея, прижал его к своей жирной груди и долго не отпускал от себя. Когда он отпустил его, князь Андрей увидал, что расплывшие губы Кутузова дрожали и на глазах были слезы. Он вздохнул и взялся обеими руками за лавку, чтобы встать.
– Пойдем, пойдем ко мне, поговорим, – сказал он; но в это время Денисов, так же мало робевший перед начальством, как и перед неприятелем, несмотря на то, что адъютанты у крыльца сердитым шепотом останавливали его, смело, стуча шпорами по ступенькам, вошел на крыльцо. Кутузов, оставив руки упертыми на лавку, недовольно смотрел на Денисова. Денисов, назвав себя, объявил, что имеет сообщить его светлости дело большой важности для блага отечества. Кутузов усталым взглядом стал смотреть на Денисова и досадливым жестом, приняв руки и сложив их на животе, повторил: «Для блага отечества? Ну что такое? Говори». Денисов покраснел, как девушка (так странно было видеть краску на этом усатом, старом и пьяном лице), и смело начал излагать свой план разрезания операционной линии неприятеля между Смоленском и Вязьмой. Денисов жил в этих краях и знал хорошо местность. План его казался несомненно хорошим, в особенности по той силе убеждения, которая была в его словах. Кутузов смотрел себе на ноги и изредка оглядывался на двор соседней избы, как будто он ждал чего то неприятного оттуда. Из избы, на которую он смотрел, действительно во время речи Денисова показался генерал с портфелем под мышкой.
– Что? – в середине изложения Денисова проговорил Кутузов. – Уже готовы?
– Готов, ваша светлость, – сказал генерал. Кутузов покачал головой, как бы говоря: «Как это все успеть одному человеку», и продолжал слушать Денисова.
– Даю честное благородное слово гусского офицег'а, – говорил Денисов, – что я г'азог'ву сообщения Наполеона.
– Тебе Кирилл Андреевич Денисов, обер интендант, как приходится? – перебил его Кутузов.
– Дядя г'одной, ваша светлость.
– О! приятели были, – весело сказал Кутузов. – Хорошо, хорошо, голубчик, оставайся тут при штабе, завтра поговорим. – Кивнув головой Денисову, он отвернулся и протянул руку к бумагам, которые принес ему Коновницын.
– Не угодно ли вашей светлости пожаловать в комнаты, – недовольным голосом сказал дежурный генерал, – необходимо рассмотреть планы и подписать некоторые бумаги. – Вышедший из двери адъютант доложил, что в квартире все было готово. Но Кутузову, видимо, хотелось войти в комнаты уже свободным. Он поморщился…
– Нет, вели подать, голубчик, сюда столик, я тут посмотрю, – сказал он. – Ты не уходи, – прибавил он, обращаясь к князю Андрею. Князь Андрей остался на крыльце, слушая дежурного генерала.
Во время доклада за входной дверью князь Андрей слышал женское шептанье и хрустение женского шелкового платья. Несколько раз, взглянув по тому направлению, он замечал за дверью, в розовом платье и лиловом шелковом платке на голове, полную, румяную и красивую женщину с блюдом, которая, очевидно, ожидала входа влавввквмандующего. Адъютант Кутузова шепотом объяснил князю Андрею, что это была хозяйка дома, попадья, которая намеревалась подать хлеб соль его светлости. Муж ее встретил светлейшего с крестом в церкви, она дома… «Очень хорошенькая», – прибавил адъютант с улыбкой. Кутузов оглянулся на эти слова. Кутузов слушал доклад дежурного генерала (главным предметом которого была критика позиции при Цареве Займище) так же, как он слушал Денисова, так же, как он слушал семь лет тому назад прения Аустерлицкого военного совета. Он, очевидно, слушал только оттого, что у него были уши, которые, несмотря на то, что в одном из них был морской канат, не могли не слышать; но очевидно было, что ничто из того, что мог сказать ему дежурный генерал, не могло не только удивить или заинтересовать его, но что он знал вперед все, что ему скажут, и слушал все это только потому, что надо прослушать, как надо прослушать поющийся молебен. Все, что говорил Денисов, было дельно и умно. То, что говорил дежурный генерал, было еще дельнее и умнее, но очевидно было, что Кутузов презирал и знание и ум и знал что то другое, что должно было решить дело, – что то другое, независимое от ума и знания. Князь Андрей внимательно следил за выражением лица главнокомандующего, и единственное выражение, которое он мог заметить в нем, было выражение скуки, любопытства к тому, что такое означал женский шепот за дверью, и желание соблюсти приличие. Очевидно было, что Кутузов презирал ум, и знание, и даже патриотическое чувство, которое выказывал Денисов, но презирал не умом, не чувством, не знанием (потому что он и не старался выказывать их), а он презирал их чем то другим. Он презирал их своей старостью, своею опытностью жизни. Одно распоряжение, которое от себя в этот доклад сделал Кутузов, откосилось до мародерства русских войск. Дежурный редерал в конце доклада представил светлейшему к подписи бумагу о взысканий с армейских начальников по прошению помещика за скошенный зеленый овес.
Кутузов зачмокал губами и закачал головой, выслушав это дело.
– В печку… в огонь! И раз навсегда тебе говорю, голубчик, – сказал он, – все эти дела в огонь. Пуская косят хлеба и жгут дрова на здоровье. Я этого не приказываю и не позволяю, но и взыскивать не могу. Без этого нельзя. Дрова рубят – щепки летят. – Он взглянул еще раз на бумагу. – О, аккуратность немецкая! – проговорил он, качая головой.


– Ну, теперь все, – сказал Кутузов, подписывая последнюю бумагу, и, тяжело поднявшись и расправляя складки своей белой пухлой шеи, с повеселевшим лицом направился к двери.
Попадья, с бросившеюся кровью в лицо, схватилась за блюдо, которое, несмотря на то, что она так долго приготовлялась, она все таки не успела подать вовремя. И с низким поклоном она поднесла его Кутузову.
Глаза Кутузова прищурились; он улыбнулся, взял рукой ее за подбородок и сказал:
– И красавица какая! Спасибо, голубушка!
Он достал из кармана шаровар несколько золотых и положил ей на блюдо.
– Ну что, как живешь? – сказал Кутузов, направляясь к отведенной для него комнате. Попадья, улыбаясь ямочками на румяном лице, прошла за ним в горницу. Адъютант вышел к князю Андрею на крыльцо и приглашал его завтракать; через полчаса князя Андрея позвали опять к Кутузову. Кутузов лежал на кресле в том же расстегнутом сюртуке. Он держал в руке французскую книгу и при входе князя Андрея, заложив ее ножом, свернул. Это был «Les chevaliers du Cygne», сочинение madame de Genlis [«Рыцари Лебедя», мадам де Жанлис], как увидал князь Андрей по обертке.
– Ну садись, садись тут, поговорим, – сказал Кутузов. – Грустно, очень грустно. Но помни, дружок, что я тебе отец, другой отец… – Князь Андрей рассказал Кутузову все, что он знал о кончине своего отца, и о том, что он видел в Лысых Горах, проезжая через них.
– До чего… до чего довели! – проговорил вдруг Кутузов взволнованным голосом, очевидно, ясно представив себе, из рассказа князя Андрея, положение, в котором находилась Россия. – Дай срок, дай срок, – прибавил он с злобным выражением лица и, очевидно, не желая продолжать этого волновавшего его разговора, сказал: – Я тебя вызвал, чтоб оставить при себе.
– Благодарю вашу светлость, – отвечал князь Андрей, – но я боюсь, что не гожусь больше для штабов, – сказал он с улыбкой, которую Кутузов заметил. Кутузов вопросительно посмотрел на него. – А главное, – прибавил князь Андрей, – я привык к полку, полюбил офицеров, и люди меня, кажется, полюбили. Мне бы жалко было оставить полк. Ежели я отказываюсь от чести быть при вас, то поверьте…
Умное, доброе и вместе с тем тонко насмешливое выражение светилось на пухлом лице Кутузова. Он перебил Болконского:
– Жалею, ты бы мне нужен был; но ты прав, ты прав. Нам не сюда люди нужны. Советчиков всегда много, а людей нет. Не такие бы полки были, если бы все советчики служили там в полках, как ты. Я тебя с Аустерлица помню… Помню, помню, с знаменем помню, – сказал Кутузов, и радостная краска бросилась в лицо князя Андрея при этом воспоминании. Кутузов притянул его за руку, подставляя ему щеку, и опять князь Андрей на глазах старика увидал слезы. Хотя князь Андрей и знал, что Кутузов был слаб на слезы и что он теперь особенно ласкает его и жалеет вследствие желания выказать сочувствие к его потере, но князю Андрею и радостно и лестно было это воспоминание об Аустерлице.
– Иди с богом своей дорогой. Я знаю, твоя дорога – это дорога чести. – Он помолчал. – Я жалел о тебе в Букареште: мне послать надо было. – И, переменив разговор, Кутузов начал говорить о турецкой войне и заключенном мире. – Да, немало упрекали меня, – сказал Кутузов, – и за войну и за мир… а все пришло вовремя. Tout vient a point a celui qui sait attendre. [Все приходит вовремя для того, кто умеет ждать.] A и там советчиков не меньше было, чем здесь… – продолжал он, возвращаясь к советчикам, которые, видимо, занимали его. – Ох, советчики, советчики! – сказал он. Если бы всех слушать, мы бы там, в Турции, и мира не заключили, да и войны бы не кончили. Всё поскорее, а скорое на долгое выходит. Если бы Каменский не умер, он бы пропал. Он с тридцатью тысячами штурмовал крепости. Взять крепость не трудно, трудно кампанию выиграть. А для этого не нужно штурмовать и атаковать, а нужно терпение и время. Каменский на Рущук солдат послал, а я их одних (терпение и время) посылал и взял больше крепостей, чем Каменский, и лошадиное мясо турок есть заставил. – Он покачал головой. – И французы тоже будут! Верь моему слову, – воодушевляясь, проговорил Кутузов, ударяя себя в грудь, – будут у меня лошадиное мясо есть! – И опять глаза его залоснились слезами.
– Однако до лжно же будет принять сражение? – сказал князь Андрей.
– До лжно будет, если все этого захотят, нечего делать… А ведь, голубчик: нет сильнее тех двух воинов, терпение и время; те всё сделают, да советчики n'entendent pas de cette oreille, voila le mal. [этим ухом не слышат, – вот что плохо.] Одни хотят, другие не хотят. Что ж делать? – спросил он, видимо, ожидая ответа. – Да, что ты велишь делать? – повторил он, и глаза его блестели глубоким, умным выражением. – Я тебе скажу, что делать, – проговорил он, так как князь Андрей все таки не отвечал. – Я тебе скажу, что делать и что я делаю. Dans le doute, mon cher, – он помолчал, – abstiens toi, [В сомнении, мой милый, воздерживайся.] – выговорил он с расстановкой.
– Ну, прощай, дружок; помни, что я всей душой несу с тобой твою потерю и что я тебе не светлейший, не князь и не главнокомандующий, а я тебе отец. Ежели что нужно, прямо ко мне. Прощай, голубчик. – Он опять обнял и поцеловал его. И еще князь Андрей не успел выйти в дверь, как Кутузов успокоительно вздохнул и взялся опять за неконченный роман мадам Жанлис «Les chevaliers du Cygne».
Как и отчего это случилось, князь Андрей не мог бы никак объяснить; но после этого свидания с Кутузовым он вернулся к своему полку успокоенный насчет общего хода дела и насчет того, кому оно вверено было. Чем больше он видел отсутствие всего личного в этом старике, в котором оставались как будто одни привычки страстей и вместо ума (группирующего события и делающего выводы) одна способность спокойного созерцания хода событий, тем более он был спокоен за то, что все будет так, как должно быть. «У него не будет ничего своего. Он ничего не придумает, ничего не предпримет, – думал князь Андрей, – но он все выслушает, все запомнит, все поставит на свое место, ничему полезному не помешает и ничего вредного не позволит. Он понимает, что есть что то сильнее и значительнее его воли, – это неизбежный ход событий, и он умеет видеть их, умеет понимать их значение и, ввиду этого значения, умеет отрекаться от участия в этих событиях, от своей личной волн, направленной на другое. А главное, – думал князь Андрей, – почему веришь ему, – это то, что он русский, несмотря на роман Жанлис и французские поговорки; это то, что голос его задрожал, когда он сказал: „До чего довели!“, и что он захлипал, говоря о том, что он „заставит их есть лошадиное мясо“. На этом же чувстве, которое более или менее смутно испытывали все, и основано было то единомыслие и общее одобрение, которое сопутствовало народному, противному придворным соображениям, избранию Кутузова в главнокомандующие.


После отъезда государя из Москвы московская жизнь потекла прежним, обычным порядком, и течение этой жизни было так обычно, что трудно было вспомнить о бывших днях патриотического восторга и увлечения, и трудно было верить, что действительно Россия в опасности и что члены Английского клуба суть вместе с тем и сыны отечества, готовые для него на всякую жертву. Одно, что напоминало о бывшем во время пребывания государя в Москве общем восторженно патриотическом настроении, было требование пожертвований людьми и деньгами, которые, как скоро они были сделаны, облеклись в законную, официальную форму и казались неизбежны.
С приближением неприятеля к Москве взгляд москвичей на свое положение не только не делался серьезнее, но, напротив, еще легкомысленнее, как это всегда бывает с людьми, которые видят приближающуюся большую опасность. При приближении опасности всегда два голоса одинаково сильно говорят в душе человека: один весьма разумно говорит о том, чтобы человек обдумал самое свойство опасности и средства для избавления от нее; другой еще разумнее говорит, что слишком тяжело и мучительно думать об опасности, тогда как предвидеть все и спастись от общего хода дела не во власти человека, и потому лучше отвернуться от тяжелого, до тех пор пока оно не наступило, и думать о приятном. В одиночестве человек большею частью отдается первому голосу, в обществе, напротив, – второму. Так было и теперь с жителями Москвы. Давно так не веселились в Москве, как этот год.
Растопчинские афишки с изображением вверху питейного дома, целовальника и московского мещанина Карпушки Чигирина, который, быв в ратниках и выпив лишний крючок на тычке, услыхал, будто Бонапарт хочет идти на Москву, рассердился, разругал скверными словами всех французов, вышел из питейного дома и заговорил под орлом собравшемуся народу, читались и обсуживались наравне с последним буриме Василия Львовича Пушкина.
В клубе, в угловой комнате, собирались читать эти афиши, и некоторым нравилось, как Карпушка подтрунивал над французами, говоря, что они от капусты раздуются, от каши перелопаются, от щей задохнутся, что они все карлики и что их троих одна баба вилами закинет. Некоторые не одобряли этого тона и говорила, что это пошло и глупо. Рассказывали о том, что французов и даже всех иностранцев Растопчин выслал из Москвы, что между ними шпионы и агенты Наполеона; но рассказывали это преимущественно для того, чтобы при этом случае передать остроумные слова, сказанные Растопчиным при их отправлении. Иностранцев отправляли на барке в Нижний, и Растопчин сказал им: «Rentrez en vous meme, entrez dans la barque et n'en faites pas une barque ne Charon». [войдите сами в себя и в эту лодку и постарайтесь, чтобы эта лодка не сделалась для вас лодкой Харона.] Рассказывали, что уже выслали из Москвы все присутственные места, и тут же прибавляли шутку Шиншина, что за это одно Москва должна быть благодарна Наполеону. Рассказывали, что Мамонову его полк будет стоить восемьсот тысяч, что Безухов еще больше затратил на своих ратников, но что лучше всего в поступке Безухова то, что он сам оденется в мундир и поедет верхом перед полком и ничего не будет брать за места с тех, которые будут смотреть на него.
– Вы никому не делаете милости, – сказала Жюли Друбецкая, собирая и прижимая кучку нащипанной корпии тонкими пальцами, покрытыми кольцами.
Жюли собиралась на другой день уезжать из Москвы и делала прощальный вечер.
– Безухов est ridicule [смешон], но он так добр, так мил. Что за удовольствие быть так caustique [злоязычным]?
– Штраф! – сказал молодой человек в ополченском мундире, которого Жюли называла «mon chevalier» [мой рыцарь] и который с нею вместе ехал в Нижний.
В обществе Жюли, как и во многих обществах Москвы, было положено говорить только по русски, и те, которые ошибались, говоря французские слова, платили штраф в пользу комитета пожертвований.
– Другой штраф за галлицизм, – сказал русский писатель, бывший в гостиной. – «Удовольствие быть не по русски.
– Вы никому не делаете милости, – продолжала Жюли к ополченцу, не обращая внимания на замечание сочинителя. – За caustique виновата, – сказала она, – и плачу, но за удовольствие сказать вам правду я готова еще заплатить; за галлицизмы не отвечаю, – обратилась она к сочинителю: – у меня нет ни денег, ни времени, как у князя Голицына, взять учителя и учиться по русски. А вот и он, – сказала Жюли. – Quand on… [Когда.] Нет, нет, – обратилась она к ополченцу, – не поймаете. Когда говорят про солнце – видят его лучи, – сказала хозяйка, любезно улыбаясь Пьеру. – Мы только говорили о вас, – с свойственной светским женщинам свободой лжи сказала Жюли. – Мы говорили, что ваш полк, верно, будет лучше мамоновского.
– Ах, не говорите мне про мой полк, – отвечал Пьер, целуя руку хозяйке и садясь подле нее. – Он мне так надоел!
– Вы ведь, верно, сами будете командовать им? – сказала Жюли, хитро и насмешливо переглянувшись с ополченцем.
Ополченец в присутствии Пьера был уже не так caustique, и в лице его выразилось недоуменье к тому, что означала улыбка Жюли. Несмотря на свою рассеянность и добродушие, личность Пьера прекращала тотчас же всякие попытки на насмешку в его присутствии.
– Нет, – смеясь, отвечал Пьер, оглядывая свое большое, толстое тело. – В меня слишком легко попасть французам, да и я боюсь, что не влезу на лошадь…
В числе перебираемых лиц для предмета разговора общество Жюли попало на Ростовых.
– Очень, говорят, плохи дела их, – сказала Жюли. – И он так бестолков – сам граф. Разумовские хотели купить его дом и подмосковную, и все это тянется. Он дорожится.
– Нет, кажется, на днях состоится продажа, – сказал кто то. – Хотя теперь и безумно покупать что нибудь в Москве.
– Отчего? – сказала Жюли. – Неужели вы думаете, что есть опасность для Москвы?
– Отчего же вы едете?
– Я? Вот странно. Я еду, потому… ну потому, что все едут, и потом я не Иоанна д'Арк и не амазонка.
– Ну, да, да, дайте мне еще тряпочек.
– Ежели он сумеет повести дела, он может заплатить все долги, – продолжал ополченец про Ростова.
– Добрый старик, но очень pauvre sire [плох]. И зачем они живут тут так долго? Они давно хотели ехать в деревню. Натали, кажется, здорова теперь? – хитро улыбаясь, спросила Жюли у Пьера.
– Они ждут меньшого сына, – сказал Пьер. – Он поступил в казаки Оболенского и поехал в Белую Церковь. Там формируется полк. А теперь они перевели его в мой полк и ждут каждый день. Граф давно хотел ехать, но графиня ни за что не согласна выехать из Москвы, пока не приедет сын.
– Я их третьего дня видела у Архаровых. Натали опять похорошела и повеселела. Она пела один романс. Как все легко проходит у некоторых людей!
– Что проходит? – недовольно спросил Пьер. Жюли улыбнулась.
– Вы знаете, граф, что такие рыцари, как вы, бывают только в романах madame Suza.
– Какой рыцарь? Отчего? – краснея, спросил Пьер.
– Ну, полноте, милый граф, c'est la fable de tout Moscou. Je vous admire, ma parole d'honneur. [это вся Москва знает. Право, я вам удивляюсь.]
– Штраф! Штраф! – сказал ополченец.
– Ну, хорошо. Нельзя говорить, как скучно!
– Qu'est ce qui est la fable de tout Moscou? [Что знает вся Москва?] – вставая, сказал сердито Пьер.
– Полноте, граф. Вы знаете!
– Ничего не знаю, – сказал Пьер.
– Я знаю, что вы дружны были с Натали, и потому… Нет, я всегда дружнее с Верой. Cette chere Vera! [Эта милая Вера!]
– Non, madame, [Нет, сударыня.] – продолжал Пьер недовольным тоном. – Я вовсе не взял на себя роль рыцаря Ростовой, и я уже почти месяц не был у них. Но я не понимаю жестокость…
– Qui s'excuse – s'accuse, [Кто извиняется, тот обвиняет себя.] – улыбаясь и махая корпией, говорила Жюли и, чтобы за ней осталось последнее слово, сейчас же переменила разговор. – Каково, я нынче узнала: бедная Мари Волконская приехала вчера в Москву. Вы слышали, она потеряла отца?
– Неужели! Где она? Я бы очень желал увидать ее, – сказал Пьер.
– Я вчера провела с ней вечер. Она нынче или завтра утром едет в подмосковную с племянником.
– Ну что она, как? – сказал Пьер.