Home > Software design >  Passing image to function as a char array in C and display with SFML
Passing image to function as a char array in C and display with SFML

Time:09-07

I'm aware there are similar posts already but I just couldn't find anything that solved my problem.

I have my image stored as a char array of hex numbers and I am trying to pass this to a function that loads that data from memory in order to read the data and display the image. When I write the array name directly into the code, the image displays as I need it to, but I want to be able to use different images without writing a function for each one.

I'm no expert with pointers and addresses so maybe this is where my mistake is but I've tried so many things and just can't figure it out. I'm working with the SFML graphics library so that's where some of the commands are from.

My image data array (in spritePNG.h):

#pragma once

const unsigned char spritePNG[] = {
    0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
    0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x64,
    0x08, 0x06, 0x00, 0x00, 0x00, 0x70, 0xe2, 0x95, 0x54, 0x00, 0x00, 0x00,
    0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b,
    0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x05, 0xc8, 0x69, 0x54,
    0x58, 0x74, 0x58, 0x4d, 0x4c, 0x3a, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x64,
    0x6f, 0x62, 0x65, 0x2e, 0x78, 0x6d, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, .... };

Header file for necessary function (IconSprite.h):

#pragma once

#include <SFML/Graphics.hpp>
#include <iostream>
#include <string>

using namespace std;
using namespace sf;

class IconSprite
{
private:
    Texture texture;
    Sprite sprite;

public:
    IconSprite(){}
    ~IconSprite(){}

    Sprite loadSpriteResource(const unsigned char image[], float scale);
    Sprite getSprite();
};

My function to load it from memory (in IconSprite.cpp):

#include "IconSprite.h"
#include "spritePNG.h"

Sprite IconSprite::loadSpriteResource(const unsigned char image[], float scale)
{
    // load sprite resource image into texture

    //if (!texture.loadFromMemory(spritePNG, sizeof(spritePNG)))
    /* when line above is used, it runs fine but then function is only 
    useful for displaying that one image */

    if (!texture.loadFromMemory(image, sizeof(image)))
    {
        cout << "Cannot locate sprite image file" << endl;
    }

    // set texture settings
    texture.setSmooth(true);
    sprite.setTexture(texture);


    // set scale and origin
    sprite.setScale(scale, scale);
    sprite.setOrigin(sprite.getLocalBounds().width / 2, sprite.getLocalBounds().height / 2);

    return sprite;
}

My main.cpp which calls the function:

int main()
{

    RenderWindow window(VideoMode(1280, 720), "Asteroids");
    window.setFramerateLimit(60);
    Vector2f windowSize = (Vector2f)window.getSize();

    IconSprite iconSprite;
    Sprite splashSprite = iconSprite.loadSpriteResource(splashPNG, 0.6f);
    Sprite sprite = iconSprite.loadSpriteResource(spritePNG, 0.6f);

    sprite.setPosition(windowSize.x / 2, windowSize.y / 2);
    splashSprite.setPosition(windowSize.x / 2, 100); ...

I haven't included the full main() function as this is the only section of it that is relevant and I don't want to make this question longer than it already is. splashPNG is another image that is stored in the same way as spritePNG.

Currently the images don't load at all and it gives me the following error:

Failed to load image from memory. Reason: Corrupt PNG

Each time I check if it is truly corrupt or not by writing the array name directly into the code and it displays perfectly which tells me it's not actually corrupt.

This has been really bugging me so any help at all is really appreciated!

CodePudding user response:

You can't pass arrays like that to function. What you're passing is only a pointer to the first element of the array. And the sizeof of a pointer is the size of the pointer itself, not what it actually points to.

All of this means that for the loadSpriteResource function the argument is really

const unsigned char* image

and that sizeof(image) will not give you the expected result.

Either use another container (std::array for example) or pass the size as an argument to the function.

Optionally you could use templates to pass a reference to the array with its exact size, but I still recommend using std::array.

  • Related