#include #include #include #include "ImageLoader.h" // Disable some file formats that we don't use. #define STBI_NO_PSD #define STBI_NO_PIC #define STBI_NO_GIF #define STBI_NO_HDR #define STBI_NO_PNM #define STB_IMAGE_IMPLEMENTATION #include "stb_image.h" #define STB_IMAGE_WRITE_IMPLEMENTATION #include "stb_image_write.h" #include #include #include #include namespace sp { bool ImageLoader::loadFromFile(const char *filename, Image& img) { FILE *fd = fopen(filename, "rb"); if (fd) { std::vector buf; fseek(fd, 0, SEEK_END); buf.resize(ftell(fd)); rewind(fd); fread(&buf[0], 1, buf.size(), fd); fclose(fd); // loaded into memory. now decode. if (decode((const char*)&buf[0], buf.size(), img) == false) { log("ImageLoader: could not load file '%s'. Reason: %s", filename, m_error); return false; } return true; } log("ImageLoader: could not open file '%s'. Reason: %s", filename, strerror(errno)); return false; } bool ImageLoader::loadFromMemory(const void *data, unsigned size, Image& img) { //std::vector buf; //buf.assign(((unsigned char*) data), ((unsigned char*) data) + size); return decode((const char*) data, size, img); } // TODO: Support more formats. bool ImageLoader::saveToFile(const Image& img, const char *filename) { std::string ext = file::getExtension(filename); std::vector encoded_data; if (ext == "png") { if (!encodePNG(img, encoded_data)) { log("ImageLoader: failed to save file '%s'. Reason: \n", filename, m_error); } } else { log("ImageLoader: Invalid file format\n"); return false; } if (encoded_data.size() > 0) { FILE *fd = fopen(filename, "wb"); if (fd) { fwrite(&encoded_data[0], 1, encoded_data.size(), fd); fclose(fd); } return true; } return false; } bool ImageLoader::decode(const char *data, unsigned int size, Image& img) { // width, height, num components. int w, h, n_comp; const stbi_uc *ptr = (const stbi_uc *) data; unsigned char *pixels = stbi_load_from_memory(ptr, size, &w, &h, &n_comp, 4); if (pixels) { unsigned int len = w * h * 4; img.create(w, h, pixels); stbi_image_free(pixels); return true; } m_error = stbi_failure_reason(); return false; } bool ImageLoader::encodePNG(const Image& img, std::vector& data) { int buf_len; unsigned char *raw = (unsigned char*) img.getPixels(); unsigned char *buf; buf = stbi_write_png_to_mem(raw, img.getStride(), img.getWidth(), img.getHeight(), img.getBpp() / 8, &buf_len); if (buf && buf_len > 0) { data.resize(buf_len); memcpy(&data[0], buf, buf_len); STBIW_FREE(buf); return true; } m_error = stbi_failure_reason(); return false; } } // namespace sp