ИМХО, vector<vector< >>
подходит, если строки могут иметь различную длину, но на самом деле это больше не называется матрицей.(Необработанные данные образца OP формируют матрицу, сохраняемую построчно.)
Почему необходимо скопировать массив temp
в vector<>
?Это дублирует данные.Если срок службы может быть предоставлен, temp
может быть доступен напрямую.(В противном случае его можно скопировать в vector<uint8_t>
.)
AFAIK, упаковка компонентов в struct RGB
не предоставляется.Следовательно, reinterpret_cast<RGB*>()
не самый чистый способ доступа к байтам.
Итак, я хотел бы предложить решение, которое предотвращает все эти проблемы - class Image
, который работает какОболочка / средство доступа к необработанным данным в temp
:
#include <cstddef>
#include <cstdint>
struct RGB {
uint8_t red, green, blue;
RGB() { } // leaving contents uninitialized
RGB(uint8_t red, uint8_t green, uint8_t blue):
red(red), green(green), blue(blue)
{ }
};
class Image {
private:
const uint8_t *_pData;
public:
class Row {
private:
const uint8_t *_pData;
public:
Row(const uint8_t *pData): _pData(pData) { }
RGB operator[](size_t i) const
{
const uint8_t *pixel = _pData + 3 * i;
return RGB(pixel[0], pixel[1], pixel[2]);
}
};
Image(const uint8_t *pData): _pData(pData) { }
size_t height() const { return _pData[0]; }
size_t width() const { return _pData[1]; }
RGB get(size_t i, size_t j) const
{
const uint8_t *pixel = _pData + 2 + (i * _pData[1] + j) * 3;
return RGB(pixel[0], pixel[1], pixel[2]);
}
Row operator[](size_t i) const
{
return Row(_pData + 2 + i * _pData[1] * 3);
}
};
Доступ к RGB-tripel может быть выполнен с помощью Image::get()
, а также с более интуитивным Image::operator[]()
.
Пример кода:
#include <iomanip>
#include <iostream>
int main()
{
// data array representing image data - this would really be a bin fle
// header r, g, b r, g, b r, g, b footer
uint8_t temp[22] = { 0x02, 0x03, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0xef, 0x05,
0x0a, 0x01, 0x02, 0x0d, 0xfe, 0x00, 0x10, 0xff, 0xff, 0xef, 0xef };
// access via
Image img(temp);
std::cout << std::hex << std::setfill('0');
// via Image::get()
std::cout << "access with img.get(i, j):\n";
for (size_t i = 0, n = img.height(); i < n; ++i) {
for (size_t j = 0, m = img.width(); j < m; ++j) {
RGB rgb = img.get(i, j);
std::cout << " "
<< std::setw(2) << (unsigned)rgb.red << std::setw(0) << ' '
<< std::setw(2) << (unsigned)rgb.green << std::setw(0) << ' '
<< std::setw(2) << (unsigned)rgb.blue << std::setw(0);
}
std::cout << '\n';
}
// via Image::operator[]
std::cout << "access with img[i][j]:\n";
for (size_t i = 0, n = img.height(); i < n; ++i) {
for (size_t j = 0, m = img.width(); j < m; ++j) {
RGB rgb = img[i][j];
std::cout << " "
<< std::setw(2) << (unsigned)rgb.red << std::setw(0) << ' '
<< std::setw(2) << (unsigned)rgb.green << std::setw(0) << ' '
<< std::setw(2) << (unsigned)rgb.blue << std::setw(0);
}
std::cout << '\n';
}
return 0;
}
Выход:
access with img.get(i, j):
01 02 03 04 05 06 07 ef 05
0a 01 02 0d fe 00 10 ff ff
access with img[i][j]:
01 02 03 04 05 06 07 ef 05
0a 01 02 0d fe 00 10 ff ff
Живая демонстрация на coliru