J'utilise le FreeImage 3.15.4 library pour analyser les images PNG. Essentiellement, je tente de construire une structure de données simple composée d'une palette de toutes les couleurs ainsi que d'une version de tableau de l'image par pixel composée d'index dans la palette. Le FreeImage_GetBits
semble renvoyer un pointeur vers des données non valides et je ne sais pas pourquoi. Je suis capable de lire la largeur et la hauteur du fichier PNG correctement, mais les données pointées par FreeImage_GetBits
sont juste des données de vidage, et semblent être d'une taille impaire. Peu importe combien de fois je lance le programme, il meurt constamment au même endroit, quand iPix
dans le code ci-dessous est égal à 131740. J'obtiens une erreur C0000005 accédant aux bits [131740] dans l'appel std :: find. La taille d'image PNG réelle et rapportée est 524288.FreeImage: Les données de pixels accédées par FreeImage_GetBits ne sont pas correctes (données + taille)
En outre, j'ai essayé ce code avec des images plus petites que j'ai moi-même construites et elles fonctionnent bien. Le PNG que j'utilise est fourni à un tiers, et ne semble pas corrompu de toute façon (Photoshop l'ouvre, et DirectX peut le traiter et l'utiliser normalement)
Des idées?
est ici les déclarations de données:
struct Color
{
char b; // Blue
char g; // Green
char r; // Red
char a; // Alpha value
bool operator==(const Color& comp)
{
if (a == comp.a &&
r == comp.r &&
g == comp.g &&
b == comp.b)
return TRUE;
else
return FALSE;
}
};
typedef std::vector<Color> ColorPalette; // Array of colors forming a palette
Et voici le code qui fait l'indexation des couleurs:
// Read image data with FreeImage
unsigned int imageSize = FreeImage_GetWidth(hImage) * FreeImage_GetHeight(hImage);
unsigned char* pData = new unsigned char[imageSize];
// Access bits via FreeImage
FREE_IMAGE_FORMAT fif;
FIBITMAP* hImage;
fif = FreeImage_GetFIFFromFilename(fileEntry.name.c_str());
if(fif == FIF_UNKNOWN)
{
return false;
}
hImage = FreeImage_Load(fif, filename);
BYTE* pPixelData = NULL;
pPixelData = FreeImage_GetBits(hImage);
if (pPixelData == NULL)
{
return false;
}
Color* bits = (Color*)pPixelData;
ColorPalette palette;
for (unsigned int iPix = 0; iPix < imageSize; ++iPix)
{
ColorPalette::iterator it;
if((it = std::find(palette.begin(), palette.end(), bits[iPix])) == palette.end())
{
pData[iPix] = palette.size();
palette.push_back(bits[iPix]);
}
else
{
unsigned int index = it - palette.begin();
pData[iPix] = index;
}
}
Etes-vous sûr que le format des données de pixel brut correspond à la structure? Que faire si l'ordre des octets est différent? Que faire si le compilateur décide d'ajouter un remplissage à votre structure? –
En outre, si vous essayez d'accéder à 'bits [524288]' et le nombre d'entrées dans 'bits' est 524288, alors vous accédez hors limites que l'index supérieur devrait être 524287. –
Désolé, ce fut une faute de frappe. Il échoue à 'bits [131740]', en fait. Je vais devoir réexaminer les données, puisque 131740 est étrangement proche de 524288/4 (8bpp au lieu de 32bpp peut-être?). J'ai vérifié le format de données retourné par ma plus petite image de test et j'ai élaboré le code pour traiter ce format; il ne m'est pas venu à l'esprit que le format différerait entre les types de fichiers. Comment FreeImage décide-t-il du format dans lequel stocker les données internes? – 8bitcartridge