Расположение Pixel-данных в памяти? - PullRequest
1 голос
/ 12 мая 2009

Я пишу библиотеку C ++ для формата изображений, основанного на PNG. Одна остановка для меня заключается в том, что я не уверен, как мне следует размещать данные пикселей в памяти; Насколько я знаю, есть два практических подхода:

  1. Массив размера (ширина * высота); каждый пиксель может быть доступен с помощью массива [y * width + x].
  2. Массив размера (высоты), содержащий указатели на массивы размера (ширины).

Стандартная эталонная реализация для PNG (libpng) использует метод 2, описанный выше, в то время как я видел, как другие используют метод 1. Является ли один лучше другого, или каждый из них имеет свои плюсы и минусы, где компромисс должен быть достигнут? Кроме того, какой формат используют большинство систем графического отображения (возможно, для простоты использования вывода моей библиотеки в другие API)?

Ответы [ 4 ]

6 голосов
/ 13 мая 2009

с макушки головы:

  • Единственное, что заставило бы меня выбрать # 2, это то, что ваши требования к памяти немного смягчены. Если бы вы выбрали номер 1, система должна иметь возможность выделить height * width количество смежных памяти. Принимая во внимание, что в случае # 2 он может свободно выделять меньшие порции непрерывной памяти размером width (а может быть height) из свободных областей. (Когда вы учитываете каналы на пиксель, # 1 может не работать даже для изображений среднего размера.)
  • Кроме того, может быть немного лучше при замене строк (или столбцов), если это требуется для манипулирования изображениями (достаточно замены указателя).
  • Недостатком для # 2 является, конечно, дополнительный уровень косвенности, который проникает в каждый доступ и массив указателей, которые необходимо поддерживать. Но это вряд ли вопрос сегодняшней скорости процессора и памяти.
  • Вторым недостатком # 2 является то, что данные не обязательно находятся рядом друг с другом, что усложняет процессору загрузку нужных страниц памяти в кеш.
2 голосов
/ 13 мая 2009

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

Преимущество одного массива состоит в том, что ваши вычисления проще, то есть, чтобы перейти на одну строку вниз, вы делаете

pos += width;

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

1 голос
/ 13 мая 2009

Я подозреваю, что libpng делает это (стиль 2) по нескольким возможным причинам:

  1. Избегайте больших выделений (как уже упоминалось) и могут упростить обработку ОЧЕНЬ больших PNG, особенно в системах без ВМ
  2. (возможно), допускает чередованное декодирование с чередованием JPEG (если PNG это поддерживает)
  3. Легкость некоторых преобразований (вертикальное отражение) (маловероятно)
  4. Простота масштабирования (вставлять или удалять строки, не требуя полного второго буфера, или расширять / сужать строки) (маловероятно, но возможно)

Проблема с этим подходом (при условии, что каждая строка является выделением) является ОЧЕНЬ большим выделением / свободными издержками и, возможно, стимулирует фрагментацию памяти.

Если у вас нет веских причин, используйте стиль 1 (одиночное распределение) и, возможно, округлите до «хорошей» границы для используемой вами архитектуры (может быть 4, 8, 16 или, возможно, даже больше байтов). Обратите внимание, что многие библиотечные функции могут искать стиль 1 без отступов - подумайте, как вы будете использовать это и куда будете их передавать.

0 голосов
/ 13 мая 2009

Windows сама использует вариант метода 1. Каждая строка изображения дополняется кратным 4 байтам, и порядок цветов - B, G, R вместо более обычных R, G, B. Также первая строка буфера является нижней строкой изображения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...