Я пытаюсь прочитать изображение, используя собственные функции. С этой целью я попытался использовать этот код:
var result = new Bitmap((int)info.width,(int)info.height,PixelFormat.Format24bppRgb);
var data = result.LockBits(new Rectangle(0, 0, result.Width, result.Height), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);
bool success = ReadFullImage(data.Scan0, ref info, ref png);
result.UnlockBits(data);
if (!success)
return null;
else
{
return result;
}
где info
содержит высоту и ширину изображения, png
— это png_struct
, а ReadFullImage
является оболочкой вокруг png_read_image
. Однако я получал нарушение прав доступа (код исключения 0xc0000005).
После этого я изучил значения, которые содержит data
, и обнаружил следующее:
data {System.Drawing.Imaging.BitmapData} System.Drawing.Imaging.BitmapData
Height 1557 int
m_bmpdata {Microsoft.AGL.Drawing.AGL_BITMAPDATA} Microsoft.AGL.Drawing.AGL_BITMAPDATA
PixelFormat Format24bppRgb System.Drawing.Imaging.PixelFormat
Scan0 1638432 System.IntPtr
Stride 1512 int
Width 503 int
в чем, казалось бы, кроется проблема. Размер записываемой строки составляет 2012 байт, но доступно только 1512, и вскоре происходит попытка записи за пределы выделенной памяти.
Вопрос в том, почему размер строки составляет всего 1512=503*3+3, несмотря на то, что формат 24 бита на пиксель, и как можно выделить достаточно памяти и передать ее в растровое изображение?
В качестве альтернативы, можно ли читать png с libpng совместимым способом?
Обновление: ReadFullImage — это DllImport из
extern "C" void read_image_full( unsigned char * buffer,pngImageInfo* info,pngDataStructures* png)
{
png_bytepp row_pointers = new png_bytep[info->height];
for (unsigned int i = 0; i < info->height; ++i)
row_pointers[i] = buffer + i*info->rowbytes;
png_read_image(png->png_struct_field, row_pointers);
return true;
}
А байты строк извлекаются через png_get_rowbytes.