Initial commit.

This commit is contained in:
hal8174 2024-04-23 10:14:24 +02:00
commit d3bb49b3f5
1073 changed files with 484757 additions and 0 deletions

View file

@ -0,0 +1,51 @@
## Copyright 2009-2021 Intel Corporation
## SPDX-License-Identifier: Apache-2.0
SET(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}" ${CMAKE_MODULE_PATH})
INCLUDE(CMakeDependentOption)
SET(ADDITIONAL_SOURCES)
## FIND_PACKAGE(OpenImageIO)
## MARK_AS_ADVANCED(
## OPENIMAGEIO_ROOT
## )
CMAKE_DEPENDENT_OPTION(EMBREE_TUTORIALS_OPENIMAGEIO "Enables BMP, GIF, PNG, TGA, TIFF image codecs." OFF "EMBREE_TUTORIALS AND OPENIMAGEIO_FOUND" OFF)
IF (EMBREE_TUTORIALS_OPENIMAGEIO)
ADD_DEFINITIONS(-DUSE_OPENIMAGEIO)
INCLUDE_DIRECTORIES(${OPENIMAGEIO_INCLUDE_DIRS})
SET(ADDITIONAL_LIBRARIES ${ADDITIONAL_LIBRARIES} ${OPENIMAGEIO_LIBRARIES})
SET(ADDITIONAL_SOURCES ${ADDITIONAL_SOURCES} oiio.cpp)
ENDIF (EMBREE_TUTORIALS_OPENIMAGEIO)
FIND_PACKAGE(JPEG)
CMAKE_DEPENDENT_OPTION(EMBREE_TUTORIALS_LIBJPEG "Enables JPEG image codec." OFF "EMBREE_TUTORIALS AND JPEG_FOUND" OFF)
IF (EMBREE_TUTORIALS_LIBJPEG)
ADD_DEFINITIONS(-DEMBREE_TUTORIALS_LIBJPEG)
INCLUDE_DIRECTORIES(${JPEG_INCLUDE_DIR})
SET(ADDITIONAL_LIBRARIES ${ADDITIONAL_LIBRARIES} ${JPEG_LIBRARIES})
SET(ADDITIONAL_SOURCES ${ADDITIONAL_SOURCES} jpeg.cpp)
ENDIF (EMBREE_TUTORIALS_LIBJPEG)
FIND_PACKAGE(PNG)
CMAKE_DEPENDENT_OPTION(EMBREE_TUTORIALS_LIBPNG "Enables PNG image codecs." OFF "EMBREE_TUTORIALS AND PNG_FOUND" OFF)
IF (EMBREE_TUTORIALS_LIBPNG)
ADD_DEFINITIONS(-DEMBREE_TUTORIALS_LIBPNG)
INCLUDE_DIRECTORIES(${PNG_INCLUDE_DIR})
SET(ADDITIONAL_LIBRARIES ${ADDITIONAL_LIBRARIES} ${PNG_LIBRARIES})
ENDIF (EMBREE_TUTORIALS_LIBPNG)
ADD_LIBRARY(image STATIC
image.cpp
pfm.cpp
ppm.cpp
tga.cpp
png.cpp
stb.cpp
exr.cpp
${ADDITIONAL_SOURCES}
)
TARGET_LINK_LIBRARIES(image sys math ${ADDITIONAL_LIBRARIES})
SET_PROPERTY(TARGET image PROPERTY FOLDER tutorials/common)
SET_PROPERTY(TARGET image APPEND PROPERTY COMPILE_FLAGS " ${FLAGS_LOWEST}")

View file

@ -0,0 +1,70 @@
// Copyright 2009-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "image.h"
#include <iostream>
#include <cstring>
#include <cstdio>
#define TINYEXR_USE_MINIZ 0
//#include "zlib.h"
//Or, if your project uses `stb_image[_write].h`, use their
//zlib implementation:
#define TINYEXR_USE_STB_ZLIB 1
#define TINYEXR_IMPLEMENTATION
#include "tinyexr.h"
namespace embree
{
/*! read PFM file from disk */
Ref<Image> loadEXR(const FileName& fileName)
{
float* rgba; // width * height * RGBA
int width;
int height;
const char* err = NULL; // or nullptr in C++11
int ret = LoadEXR(&rgba, &width, &height, fileName.str().c_str(), &err);
if (ret != TINYEXR_SUCCESS) {
if (err) {
std::cerr << "ERR: " << err;
FreeEXRErrorMessage(err);
}
THROW_RUNTIME_ERROR("Could not load image " + fileName.str())
}
/* create image and fill with data */
Ref<Image> img = new Image4f(width,height,fileName);
for (ssize_t y=0; y<height; y++) {
for (ssize_t x=0; x<width; x++) {
float* pix = rgba + (y * width + x) * 4;
img->set(x,y,Color4(pix[0],pix[1],pix[2],1.0f));
}
}
free(rgba);
return img;
}
/*! store PFM file to disk */
void storeEXR(const Ref<Image>& img, const FileName& fileName)
{
std::vector<Col3f> rgb(img->width * img->height);
for (size_t y=0; y<img->height; ++y) {
for (size_t x=0; x<img->width; ++x) {
Color4 c = img->get(x, y);
rgb[y * img->width + x] = Col3f(c.r, c.g, c.b);
}
}
const char* err = NULL;
int ret = SaveEXR((float*)rgb.data(), img->width, img->height, 3, 0, fileName.str().c_str(), &err);
if (ret != TINYEXR_SUCCESS) {
if (err) {
std::cerr << "ERR: " << err;
FreeEXRErrorMessage(err);
}
THROW_RUNTIME_ERROR("Could not save image " + fileName.str())
}
}
}

View file

@ -0,0 +1,122 @@
// Copyright 2009-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "image.h"
#include "../../../common/sys/estring.h"
#include <map>
#include <iostream>
namespace embree
{
double compareImages(Ref<Image> image0, Ref<Image> image1)
{
/* compare image size */
const size_t width = image0->width;
const size_t height = image0->height;
if (image1->width != width) return inf;
if (image1->height != height) return inf;
/* compare both images */
double diff = 0.0;
for (size_t y=0; y<height; y++)
{
for (size_t x=0; x<width; x++)
{
const Color c0 = image0->get(x,y);
const Color c1 = image1->get(x,y);
diff += sqr(fabs(c0.r - c1.r))/3.0f;
diff += sqr(fabs(c0.g - c1.g))/3.0f;
diff += sqr(fabs(c0.b - c1.b))/3.0f;
}
}
return diff;
}
/*! loads an image from a file with auto-detection of format */
Ref<Image> loadImageFromDisk(const FileName& fileName)
{
std::string ext = toLowerCase(fileName.ext());
#ifdef EMBREE_TUTORIALS_LIBPNG
if (ext == "png" ) return loadPNG(fileName);
#endif
#ifdef EMBREE_TUTORIALS_LIBJPEG
if (ext == "jpg" ) return loadJPEG(fileName);
#endif
#ifdef USE_OPENIMAGEIO
if (ext == "bmp" ) return loadOIIO(fileName);
if (ext == "gif" ) return loadOIIO(fileName);
if (ext == "tga" ) return loadOIIO(fileName);
if (ext == "tif" ) return loadOIIO(fileName);
if (ext == "tiff") return loadOIIO(fileName);
if (ext == "png" ) return loadOIIO(fileName);
if (ext == "jpg" ) return loadOIIO(fileName);
#endif
if (ext == "bmp" ) return loadSTB(fileName);
if (ext == "png" ) return loadSTB(fileName);
if (ext == "jpg" ) return loadSTB(fileName);
if (ext == "exr" ) return loadEXR(fileName);
if (ext == "pfm" ) return loadPFM(fileName);
if (ext == "ppm" ) return loadPPM(fileName);
if (ext == "tga" ) return loadTGA(fileName);
THROW_RUNTIME_ERROR("image format " + ext + " not supported");
}
static std::map<std::string,Ref<Image> > image_cache;
/*! loads an image from a file with auto-detection of format */
Ref<Image> loadImage(const FileName& fileName, bool cache)
{
if (!cache)
return loadImageFromDisk(fileName);
if (image_cache.find(fileName) == image_cache.end())
image_cache[fileName] = loadImageFromDisk(fileName);
return image_cache[fileName];
}
/*! stores an image to file with auto-detection of format */
void storeImage(const Ref<Image>& img, const FileName& fileName)
{
std::string ext = toLowerCase(fileName.ext());
#ifdef EMBREE_TUTORIALS_LIBJPEG
if (ext == "jpg" ) { storeJPEG(img, fileName); return; }
#endif
#ifdef USE_OPENIMAGEIO
if (ext == "bmp" ) { storeOIIO(img, fileName); return; }
if (ext == "gif" ) { storeOIIO(img, fileName); return; }
if (ext == "tga" ) { storeOIIO(img, fileName); return; }
if (ext == "tif" ) { storeOIIO(img, fileName); return; }
if (ext == "tiff") { storeOIIO(img, fileName); return; }
if (ext == "png" ) { storeOIIO(img, fileName); return; }
if (ext == "jpg" ) { storeOIIO(img, fileName); return; }
#endif
if (ext == "bmp" ) { storeSTB(img, fileName); return; }
if (ext == "png" ) { storeSTB(img, fileName); return; }
if (ext == "jpg" ) { storeSTB(img, fileName); return; }
if (ext == "exr" ) { storeEXR(img, fileName); return; }
if (ext == "pfm" ) { storePFM(img, fileName); return; }
if (ext == "ppm" ) { storePPM(img, fileName); return; }
if (ext == "tga" ) { storeTga(img, fileName); return; }
THROW_RUNTIME_ERROR("image format " + ext + " not supported");
}
/*! template instantiations */
template class ImageT<Col3uc>;
template class ImageT<Col3f>;
}

View file

@ -0,0 +1,205 @@
// Copyright 2009-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
#include "../../../common/sys/platform.h"
#include "../../../common/sys/ref.h"
#include "../../../common/sys/filename.h"
#include "../../../common/math/color.h"
#include <vector>
#include <string>
namespace embree
{
/* virtual interface to image */
class Image : public RefCount {
public:
Image (size_t width, size_t height, const std::string& name) : width(width), height(height), name(name) {}
virtual ~Image() {}
virtual Color4 get(size_t x, size_t y) const = 0;
virtual void set(size_t x, size_t y, const Color4& c) = 0;
void set(size_t x, size_t y, const Color& c) { set(x,y,Color4(c.r,c.g,c.b,1.0f)); }
void convertToRGBA8(unsigned char *dest)
{
for (size_t y=0;y<height;y++)
for (size_t x=0;x<width;x++)
{
size_t offset = 4 * (y * width + x);
Color4 c = get(x,y);
dest[offset+0] = (unsigned char)(c.r * 255.0f);
dest[offset+1] = (unsigned char)(c.g * 255.0f);
dest[offset+2] = (unsigned char)(c.b * 255.0f);
dest[offset+3] = (unsigned char)(c.a * 255.0f);
}
}
private:
Image (const Image& other) DELETED; // do not implement
Image& operator= (const Image& other) DELETED; // do not implement
public:
size_t width,height;
std::string name;
};
/* main image class templated over element type */
template<typename T>
class ImageT : public Image {
public:
/*! create empty image */
ImageT (size_t width = 0, size_t height = 0, const std::string& name = "")
: Image(width,height,name)
{
data = new T[width*height];
memset(data,0,width*height*sizeof(T));
}
/*! create image of constant color */
ImageT (size_t width, size_t height, const T& color, const std::string& name = "")
: Image(width,height,name)
{
data = new T[width*height];
for (size_t i=0; i<width*height; i++) data[i] = color;
}
/*! initialize image from color data */
ImageT (size_t width, size_t height, T* color, const bool copy = true, const std::string& name = "", const bool flip_y = false)
: Image(width,height,name)
{
if (copy)
{
data = new T[width*height];
if (flip_y)
{
const T* in = color + (height-1) * width;
T* out = data;
for (size_t y=0; y<height; y++)
{
for (size_t x=0; x<width; x++)
out[x] = in[x];
in -= width;
out += width;
}
}
else
{
for (size_t i=0; i<width*height; i++)
data[i] = color[i];
}
}
else
{
data = color;
}
}
/*! image destruction */
virtual ~ImageT() {
delete[] data; data = nullptr;
}
/*! returns pixel color */
__forceinline Color4 get(size_t x, size_t y) const {
return Color4(data[y*width+x]);
}
/*! sets pixel */
__forceinline void set(size_t x, size_t y, const Color4& c) {
c.set(data[y*width+x]);
}
/*! returns data pointer of image */
__forceinline void* ptr() {
return (void*)data;
}
/*! returns and forgets about data pointer of image */
__forceinline void* steal_ptr() {
T* ptr = data;
data = nullptr;
return (void*)ptr;
}
protected:
T* data;
};
/*! Shortcuts for common image types. */
typedef ImageT<Col3uc> Image3uc;
typedef ImageT<Col3f> Image3f;
typedef ImageT<Col4uc> Image4uc;
typedef ImageT<Col4f> Image4f;
/*! Generate a JPEG encoded image from a RGB8 buffer in memory. */
void encodeRGB8_to_JPEG(unsigned char *image, size_t width, size_t height, unsigned char **encoded, unsigned long *capacity);
/*! compare two images */
double compareImages(Ref<Image> image0, Ref<Image> image1);
/*! Loads image from file. Format is auto detected. */
Ref<Image> loadImage(const FileName& filename, bool cache = false);
/*! Loads image from JPEG file. */
Ref<Image> loadJPEG(const FileName& fileName);
/*! Loads image using OpenImageIO. */
Ref<Image> loadOIIO(const FileName& fileName);
/*! Loads image using stb_image. */
Ref<Image> loadSTB(const FileName& fileName);
/*! Loads image from EXR file. */
Ref<Image> loadEXR(const FileName& fileName);
/*! Loads image from PFM file. */
Ref<Image> loadPFM(const FileName& fileName);
/*! Loads image from PNG file. */
Ref<Image> loadPNG(const FileName& fileName);
/*! Loads image from PPM file. */
Ref<Image> loadPPM(const FileName& fileName);
/*! Loads image from TGA file. */
Ref<Image> loadTGA(const FileName& fileName);
/*! Loads image from TIFF file. */
//Ref<Image> loadTIFF(const FileName& fileName);
/*! Store image to file. Format is auto detected. */
void storeImage(const Ref<Image>& image, const FileName& filename);
/*! Store image to JPEG file. */
void storeJPEG(const Ref<Image>& img, const FileName& fileName);
/*! Store image to file using OpenImageIO. */
void storeOIIO(const Ref<Image>& img, const FileName& fileName);
/*! Store image to file using stb_image. */
void storeSTB(const Ref<Image>& img, const FileName& fileName);
/*! Store image to EXR file. */
void storeEXR(const Ref<Image>& img, const FileName& fileName);
/*! Store image to PFM file. */
void storePFM(const Ref<Image>& img, const FileName& fileName);
/*! Store image to PNG file. */
//void storePNG(const Ref<Image>& img, const FileName& fileName);
/*! Store image to PPM file. */
void storePPM(const Ref<Image>& img, const FileName& fileName);
/*! Store image to TGA file. */
void storeTga(const Ref<Image>& img, const FileName& fileName);
/*! Store image to TIFF file. */
//void storeTIFF(const Ref<Image>& img, const FileName& fileName);
}

View file

@ -0,0 +1,192 @@
// Copyright 2009-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#ifdef EMBREE_TUTORIALS_LIBJPEG
#include "image.h"
#include "jpeglib.h"
namespace embree
{
void compress(struct jpeg_compress_struct *cinfo, unsigned char *image)
{
/*! Start compression. */
jpeg_start_compress(cinfo, TRUE);
/*! Pointer to and size of a scanline in the image. */
JSAMPROW scanline[1]; size_t bytes = cinfo->image_width * cinfo->input_components;
/*! Here we use the library state variable 'next_scanline' as the loop index. */
while (cinfo->next_scanline < cinfo->image_height) {
scanline[0] = &image[cinfo->next_scanline * bytes];
jpeg_write_scanlines(cinfo, scanline, 1);
}
/*! Finish compression. */
jpeg_finish_compress(cinfo);
}
unsigned char *decompress(struct jpeg_decompress_struct *cinfo)
{
/*! Start decompression. */
jpeg_start_decompress(cinfo);
/*! Bytes per row in the scanline buffer. */
size_t bytes = cinfo->output_width * cinfo->output_components;
/*! Allocate scratch space for a single scanline. */
JSAMPARRAY scanline = (*cinfo->mem->alloc_sarray)((j_common_ptr) cinfo, JPOOL_IMAGE, bytes, 1);
/*! Allocate storage for the decompressed image. */
unsigned char* image = new unsigned char[cinfo->output_height * bytes];
/*! Here we use the library state variable 'output_scanline' as the loop index. */
while (cinfo->output_scanline < cinfo->output_height) {
jpeg_read_scanlines(cinfo, scanline, 1);
for (size_t i=0; i<bytes; i++)
image[(cinfo->output_scanline - 1) * bytes + i] = scanline[0][i];
}
/*! Finish decompression. */
jpeg_finish_decompress(cinfo);
return(image);
}
void encodeRGB8_to_JPEG(unsigned char *image, size_t width, size_t height, unsigned char **encoded, unsigned long *capacity)
{
#if JPEG_LIB_VERSION >= 80
/*! Compression parameters and scratch space pointers (allocated by the library). */
struct jpeg_compress_struct cinfo;
/*! The library error handler. */
struct jpeg_error_mgr jerror; cinfo.err = jpeg_std_error(&jerror);
/*! Initialize the JPEG compression object. */
jpeg_create_compress(&cinfo);
/*! Specify the incoming image resolution, color space, and color space components. */
cinfo.image_width = width; cinfo.image_height = height; cinfo.in_color_space = JCS_RGB; cinfo.input_components = 3;
/*! Fill in a sensible set of defaults. */
jpeg_set_defaults(&cinfo);
/*! Set the image quality. */
jpeg_set_quality(&cinfo, 90, TRUE);
/*! Specify the data source. */
jpeg_mem_dest(&cinfo, encoded, capacity);
/*! Compress and write the image into the target buffer. */
compress(&cinfo, image);
/*! At this point 'jerror.num_warnings' could be checked for corrupt-data warnings. */
jpeg_destroy_compress(&cinfo);
#else // JPEG_LIB_VERSION
THROW_RUNTIME_ERROR("JPEG encoding into a memory buffer requires LibJPEG 8a or higher");
#endif // JPEG_LIB_VERSION
}
Ref<Image> loadJPEG(const FileName &filename)
{
/*! Open the source JPEG file. */
FILE *file = fopen(filename.c_str(), "rb"); if (!file) THROW_RUNTIME_ERROR("Unable to open \"" + filename.str() + "\".");
/*! Decompression parameters and scratch space pointers allocated by the library. */
struct jpeg_decompress_struct cinfo;
/*! The library error handler. */
struct jpeg_error_mgr jerror; cinfo.err = jpeg_std_error(&jerror);
/*! Initialize the JPEG decompression object. */
jpeg_create_decompress(&cinfo);
/*! Specify the data source. */
jpeg_stdio_src(&cinfo, file);
/*! Read file parameters with jpeg_read_header(). */
jpeg_read_header(&cinfo, TRUE);
/*! Specify the color space and color space components of the decompressed image. */
cinfo.out_color_space = JCS_RGB; cinfo.output_components = 3;
/*! Decompress the image into an output buffer and get the image dimensions. */
unsigned char *rgb = decompress(&cinfo); size_t width = cinfo.output_width; size_t height = cinfo.output_height;
/*! Allocate the Embree image. */
Ref<Image> image = new Image4uc(width, height, filename);
/*! Convert the image from unsigned char RGB to unsigned char RGBA. */
for (size_t y=0, i=0 ; y < height ; y++) {
for (size_t x=0 ; x < width ; x++) {
const float r = (float) rgb[i++] / 255.0f;
const float g = (float) rgb[i++] / 255.0f;
const float b = (float) rgb[i++] / 255.0f;
image->set(x, y, Color4(r,g,b,1.0f));
}
}
/*! Clean up. */
jpeg_destroy_decompress(&cinfo);
delete[] rgb;
fclose(file);
return(image);
}
void storeJPEG(const Ref<Image> &image, const FileName &filename)
{
/*! Open the target JPEG file. */
FILE *file = fopen(filename.c_str(), "wb"); if (!file) THROW_RUNTIME_ERROR("Unable to open \"" + filename.str() + "\".");
/*! Compression parameters and scratch space pointers (allocated by the library). */
struct jpeg_compress_struct cinfo;
/*! The library error handler. */
struct jpeg_error_mgr jerror; cinfo.err = jpeg_std_error(&jerror);
/*! Initialize the JPEG compression object. */
jpeg_create_compress(&cinfo);
/*! Specify the incoming image resolution, color space, and color space components. */
cinfo.image_width = image->width; cinfo.image_height = image->height; cinfo.in_color_space = JCS_RGB; cinfo.input_components = 3;
/*! Fill in a sensible set of defaults. */
jpeg_set_defaults(&cinfo);
/*! Specify the data source. */
jpeg_stdio_dest(&cinfo, file);
/*! Allocate storage for the uncompressed packed image. */
unsigned char* rgb = new unsigned char [3 * image->height * image->width];
/*! Convert the image to unsigned char RGB. */
for (size_t y=0, i=0 ; y < image->height ; y++) {
for (size_t x=0 ; x < image->width ; x++) {
const Color4 pixel = image->get(x, y);
rgb[i++] = (unsigned char)(clamp(pixel.r) * 255.0f);
rgb[i++] = (unsigned char)(clamp(pixel.g) * 255.0f);
rgb[i++] = (unsigned char)(clamp(pixel.b) * 255.0f);
}
}
/*! Compress and write the image into the target file. */
compress(&cinfo, rgb);
/*! At this point 'jerror.num_warnings' could be checked for corrupt-data warnings. */
jpeg_destroy_compress(&cinfo);
delete [] rgb;
fclose(file);
}
}
#endif // EMBREE_TUTORIALS_LIBJPEG

View file

@ -0,0 +1,76 @@
// Copyright 2009-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#ifdef USE_OPENIMAGEIO
#include "image.h"
#include <iostream>
#include <vector>
/*! include OpenImageIO headers */
#include <OpenImageIO/imageio.h>
OIIO_NAMESPACE_USING
namespace embree
{
Ref<Image> loadOIIO(const FileName& fileName)
{
std::unique_ptr<ImageInput> in(ImageInput::open(fileName.str().c_str()));
if (!in)
THROW_RUNTIME_ERROR("error opening file " + fileName.str());
const ImageSpec& spec = in->spec();
size_t width = spec.width;
size_t height = spec.height;
size_t channels = spec.nchannels;
std::vector<unsigned char> pixels(width*height*channels);
in->read_image(TypeDesc::UINT8, pixels.data());
in->close();
Image* out = new Image4uc(width, height, fileName);
const float rcpMaxColor = 1.f/255.f;
for (size_t y = 0; y < height; y++)
{
for (size_t x = 0; x < width; x++)
{
float r = (channels > 0) ? (float(pixels[(y*width+x)*channels+0]) * rcpMaxColor) : 0.f;
float g = (channels > 1) ? (float(pixels[(y*width+x)*channels+1]) * rcpMaxColor) : r;
float b = (channels > 2) ? (float(pixels[(y*width+x)*channels+2]) * rcpMaxColor) : ((channels == 1) ? r : 0.f);
float a = (channels > 3) ? (float(pixels[(y*width+x)*channels+3]) * rcpMaxColor) : 1.f;
out->set(x, height-y-1, Color4(r,g,b,a)); // flip image
}
}
return out;
}
void storeOIIO(const Ref<Image>& img, const FileName& fileName)
{
std::unique_ptr<ImageOutput> out(ImageOutput::create(fileName.c_str()));
if (!out) THROW_RUNTIME_ERROR("unsupported output file format " + fileName.str());
std::vector<unsigned char> pixels(img->width*img->height*3);
const float maxColor = 255.f;
for (size_t y = 0; y < img->height; y++)
{
for (size_t x = 0; x < img->width; x++)
{
Color4 c = img->get(x, y);
pixels[(y*img->width+x)*3+0] = (unsigned char)(clamp(c.r) * maxColor);
pixels[(y*img->width+x)*3+1] = (unsigned char)(clamp(c.g) * maxColor);
pixels[(y*img->width+x)*3+2] = (unsigned char)(clamp(c.b) * maxColor);
}
}
ImageSpec spec(int(img->width), int(img->height), 3, TypeDesc::UINT8);
if (!out->open(fileName.c_str(), spec))
{
THROW_RUNTIME_ERROR("error opening file " + fileName.str());
}
out->write_image(TypeDesc::UINT8, pixels.data());
out->close();
}
}
#endif // USE_OPENIMAGEIO

View file

@ -0,0 +1,90 @@
// Copyright 2009-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "image.h"
#include <iostream>
#include <cstring>
#include <cstdio>
namespace embree
{
static void skipSpacesAndComments(std::fstream& file)
{
while (true)
{
if (isspace(file.peek())) {
file.ignore();
} else if (file.peek() == '#') {
std::string line; std::getline(file,line);
} else break;
}
}
/*! read PFM file from disk */
Ref<Image> loadPFM(const FileName& fileName)
{
/* open file for reading */
std::fstream file;
file.exceptions (std::fstream::failbit | std::fstream::badbit);
file.open (fileName.c_str(), std::fstream::in | std::fstream::binary);
/* read file type */
char cty[2]; file.read(cty,2);
skipSpacesAndComments(file);
std::string type(cty,2);
/* read width, height, and maximum color value */
int width; file >> width;
skipSpacesAndComments(file);
int height; file >> height;
skipSpacesAndComments(file);
float maxColor; file >> maxColor;
if (maxColor > 0) THROW_RUNTIME_ERROR("Big endian PFM files not supported");
float rcpMaxColor = -1.0f/float(maxColor);
file.ignore(); // skip space or return
/* create image and fill with data */
Ref<Image> img = new Image4f(width,height,fileName);
/* image in binary format 16 bit */
if (type == "PF")
{
float rgb[3];
for (ssize_t y=height-1; y>=0; y--) {
for (ssize_t x=0; x<width; x++) {
file.read((char*)rgb,sizeof(rgb));
img->set(x,y,Color4(rgb[0]*rcpMaxColor,rgb[1]*rcpMaxColor,rgb[2]*rcpMaxColor,1.0f));
}
}
}
/* invalid magic value */
else {
THROW_RUNTIME_ERROR("Invalid magic value in PFM file");
}
return img;
}
/*! store PFM file to disk */
void storePFM(const Ref<Image>& img, const FileName& fileName)
{
/* open file for writing */
std::fstream file;
file.exceptions (std::fstream::failbit | std::fstream::badbit);
file.open (fileName.c_str(), std::fstream::out | std::fstream::binary);
/* write file header */
file << "PF" << std::endl;
file << img->width << " " << img->height << std::endl;
file << -1.0f << std::endl;
/* write image */
for (ssize_t y=img->height-1; y>=0; y--) {
for (ssize_t x=0; x<(ssize_t)img->width; x++) {
const Color4 c = img->get(x,y);
file.write((char*)&c,3*sizeof(float));
}
}
}
}

View file

@ -0,0 +1,135 @@
// Copyright 2009-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#ifdef EMBREE_TUTORIALS_LIBPNG
#include "image.h"
#include <iostream>
#include <cstring>
#include <cstdio>
#include <png.h>
namespace embree
{
struct AutoCloseFile
{
FILE* file;
AutoCloseFile (FILE* file) : file(file) {}
~AutoCloseFile () { if (file) fclose(file); }
};
/*! read PNG file from disk */
Ref<Image> loadPNG(const FileName& fileName)
{
size_t width, height;
//header for testing if it is a png
png_byte header[8];
//open file as binary
FILE* fp = fopen(fileName.c_str(), "rb");
if (!fp) THROW_RUNTIME_ERROR("cannot open file "+fileName.str());
//ON_SCOPE_EXIT(fclose(fp));
AutoCloseFile close_file(fp);
//read the header
if (fread(header, 1, 8, fp) != 8)
THROW_RUNTIME_ERROR("invalid PNG file "+fileName.str());
//test if png
int is_png = !png_sig_cmp(header, 0, 8);
if (!is_png)
THROW_RUNTIME_ERROR("invalid PNG file "+fileName.str());
//create png struct
png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
if (!png_ptr) THROW_RUNTIME_ERROR("invalid PNG file "+fileName.str());
ON_SCOPE_EXIT(png_destroy_read_struct(&png_ptr, (png_infopp) nullptr, (png_infopp) nullptr));
//create png info struct
png_infop info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr)
THROW_RUNTIME_ERROR("invalid PNG file "+fileName.str());
//create png info struct
png_infop end_info = png_create_info_struct(png_ptr);
if (!end_info)
THROW_RUNTIME_ERROR("invalid PNG file "+fileName.str());
//png error stuff, not sure libpng man suggests this.
//if (setjmp(png_jmpbuf(png_ptr))) {
/// return (TEXTURE_LOAD_ERROR);
//}
//init png reading
png_init_io(png_ptr, fp);
//let libpng know you already read the first 8 bytes
png_set_sig_bytes(png_ptr, 8);
// read all the info up to the image data
png_read_info(png_ptr, info_ptr);
//variables to pass to get info
int bit_depth, color_type;
png_uint_32 twidth, theight;
// get info about png
png_get_IHDR(png_ptr, info_ptr, &twidth, &theight, &bit_depth, &color_type,
nullptr, nullptr, nullptr);
//update width and height based on png info
width = twidth;
height = theight;
Ref<Image> img = new Image4uc(width,height,fileName);
// Update the png info struct.
png_read_update_info(png_ptr, info_ptr);
// Row size in bytes.
int rowbytes = png_get_rowbytes(png_ptr, info_ptr);
// Allocate the image_data as a big block, to be given to opengl
std::vector<png_byte> data(rowbytes * height);
// row_pointers is for pointing to image_data for reading the png with libpng
std::vector<png_bytep> row_pointers(height);
// set the individual row_pointers to point at the correct offsets of image_data
for (size_t i = 0; i < height; ++i)
row_pointers[i] = (unsigned char*) &data[i * rowbytes];
// read the png into image_data through row_pointers
png_read_image(png_ptr, row_pointers.data());
if (color_type == PNG_COLOR_TYPE_RGB && bit_depth == 8)
{
for (size_t y=0;y<height;y++)
for (size_t x=0;x<width;x++)
{
unsigned char* texel = data.data() + (y * width + x) * 3;
Color4 c( (float)texel[0] * 1.0f/255.0f, (float)texel[1] * 1.0f/255.0f, (float)texel[2] * 1.0f/255.0f, 0.0f );
img.ptr->set(x,y,c);
}
}
else if (color_type == PNG_COLOR_TYPE_RGBA && bit_depth == 8)
{
for (size_t y=0;y<height;y++)
for (size_t x=0;x<width;x++)
{
unsigned char *texel = data.data() + (y * width + x) * 4;
Color4 c( (float)texel[0] * 1.0f/255.0f, (float)texel[1] * 1.0f/255.0f, (float)texel[2] * 1.0f/255.0f, (float)texel[3] * 1.0f/255.0f );
img.ptr->set(x,y,c);
}
}
else
THROW_RUNTIME_ERROR("invalid color type in PNG file "+fileName.str());
return img;
}
}
#endif

View file

@ -0,0 +1,117 @@
// Copyright 2009-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "image.h"
#include <iostream>
#include <cstring>
#include <cstdio>
#include <fstream>
namespace embree
{
static void skipSpacesAndComments(std::fstream& file)
{
while (true)
{
if (isspace(file.peek())) {
file.ignore();
} else if (file.peek() == '#') {
std::string line; std::getline(file,line);
} else break;
}
}
/*! read PPM file from disk */
Ref<Image> loadPPM(const FileName& fileName)
{
/* open file for reading */
std::fstream file;
file.exceptions (std::fstream::failbit | std::fstream::badbit);
file.open (fileName.c_str(), std::fstream::in | std::fstream::binary);
/* read file type */
char cty[2]; file.read(cty,2);
skipSpacesAndComments(file);
std::string type(cty,2);
/* read width, height, and maximum color value */
int width; file >> width;
skipSpacesAndComments(file);
int height; file >> height;
skipSpacesAndComments(file);
int maxColor; file >> maxColor;
if (maxColor <= 0) THROW_RUNTIME_ERROR("Invalid maxColor value in PPM file");
float rcpMaxColor = 1.0f/float(maxColor);
file.ignore(); // skip space or return
/* create image and fill with data */
Ref<Image> img = new Image4uc(width,height,fileName);
/* image in text format */
if (type == "P3")
{
int r, g, b;
for (ssize_t y=0; y<height; y++) {
for (ssize_t x=0; x<width; x++) {
file >> r; file >> g; file >> b;
img->set(x,y,Color4(float(r)*rcpMaxColor,float(g)*rcpMaxColor,float(b)*rcpMaxColor,1.0f));
}
}
}
/* image in binary format 8 bit */
else if (type == "P6" && maxColor <= 255)
{
unsigned char rgb[3];
for (ssize_t y=0; y<height; y++) {
for (ssize_t x=0; x<width; x++) {
file.read((char*)rgb,sizeof(rgb));
img->set(x,y,Color4(float(rgb[0])*rcpMaxColor,float(rgb[1])*rcpMaxColor,float(rgb[2])*rcpMaxColor,1.0f));
}
}
}
/* image in binary format 16 bit */
else if (type == "P6" && maxColor <= 65535)
{
unsigned short rgb[3];
for (ssize_t y=0; y<height; y++) {
for (ssize_t x=0; x<width; x++) {
file.read((char*)rgb,sizeof(rgb));
img->set(x,y,Color4(float(rgb[0])*rcpMaxColor,float(rgb[1])*rcpMaxColor,float(rgb[2])*rcpMaxColor,1.0f));
}
}
}
/* invalid magic value */
else {
THROW_RUNTIME_ERROR("Invalid magic value in PPM file");
}
return img;
}
/*! store PPM file to disk */
void storePPM(const Ref<Image>& img, const FileName& fileName)
{
/* open file for writing */
std::fstream file;
file.exceptions (std::fstream::failbit | std::fstream::badbit);
file.open (fileName.c_str(), std::fstream::out | std::fstream::binary);
/* write file header */
file << "P6" << std::endl;
file << img->width << " " << img->height << std::endl;
file << 255 << std::endl;
/* write image */
for (size_t y=0; y<img->height; y++) {
for (size_t x=0; x<img->width; x++) {
const Color4 c = img->get(x,y);
file << (unsigned char)(clamp(c.r)*255.0f);
file << (unsigned char)(clamp(c.g)*255.0f);
file << (unsigned char)(clamp(c.b)*255.0f);
}
}
}
}

View file

@ -0,0 +1,72 @@
// Copyright 2009-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "image.h"
#include "../../../common/sys/estring.h"
#include <iostream>
#include <vector>
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb_image_write.h"
namespace embree
{
Ref<Image> loadSTB(const FileName& fileName)
{
int width, height, channels;
unsigned char *pixels = stbi_load(fileName.str().c_str(), &width, &height, &channels, 0);
if(pixels == nullptr) {
THROW_RUNTIME_ERROR("Could not load " + fileName.str());
}
Image* out = new Image4uc(width, height, fileName);
const float rcpMaxColor = 1.f/255.f;
for (size_t y = 0; y < height; y++)
{
for (size_t x = 0; x < width; x++)
{
float r = (channels > 0) ? (float(pixels[(y*width+x)*channels+0]) * rcpMaxColor) : 0.f;
float g = (channels > 1) ? (float(pixels[(y*width+x)*channels+1]) * rcpMaxColor) : r;
float b = (channels > 2) ? (float(pixels[(y*width+x)*channels+2]) * rcpMaxColor) : ((channels == 1) ? r : 0.f);
float a = (channels > 3) ? (float(pixels[(y*width+x)*channels+3]) * rcpMaxColor) : 1.f;
out->set(x, y, Color4(r,g,b,a));
}
}
stbi_image_free(pixels);
return out;
}
void storeSTB(const Ref<Image>& img, const FileName& fileName)
{
std::string ext = toLowerCase(fileName.ext());
if (ext != "bmp" && ext != "png" && ext != "jpg") {
THROW_RUNTIME_ERROR("Could not store image")
return;
}
int width = int(img->width);
int height = int(img->height);
int channels = 3;
std::vector<unsigned char> pixels(width*height*channels);
const float maxColor = 255.f;
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
Color4 c = img->get(x, y);
pixels[(y*img->width+x)*channels+0] = (unsigned char)(clamp(c.r) * maxColor);
pixels[(y*img->width+x)*channels+1] = (unsigned char)(clamp(c.g) * maxColor);
pixels[(y*img->width+x)*channels+2] = (unsigned char)(clamp(c.b) * maxColor);
}
}
if (ext == "bmp" ) { stbi_write_bmp(fileName.str().c_str(), width, height, channels, pixels.data()); return; }
if (ext == "png" ) { stbi_write_png(fileName.str().c_str(), width, height, channels, pixels.data(), width * channels); return; }
if (ext == "jpg" ) { stbi_write_jpg(fileName.str().c_str(), width, height, channels, pixels.data(), 100); return; }
}
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,95 @@
// Copyright 2009-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "image.h"
#include <fstream>
namespace embree
{
inline void fwrite_uchar (unsigned char v, std::fstream& file) { file.write((const char*)&v,sizeof(v)); }
inline void fwrite_ushort(unsigned short v, std::fstream& file) { file.write((const char*)&v,sizeof(v)); }
void storeTga(const Ref<Image>& img, const FileName& fileName)
{
/* open file for reading */
std::fstream file;
file.exceptions (std::fstream::failbit | std::fstream::badbit);
file.open (fileName.c_str(), std::fstream::out | std::fstream::binary);
fwrite_uchar(0x00, file);
fwrite_uchar(0x00, file);
fwrite_uchar(0x02, file);
fwrite_ushort(0x0000, file);
fwrite_ushort(0x0000, file);
fwrite_uchar(0x00, file);
fwrite_ushort(0x0000, file);
fwrite_ushort(0x0000, file);
fwrite_ushort((unsigned short)img->width , file);
fwrite_ushort((unsigned short)img->height, file);
fwrite_uchar(0x18, file);
fwrite_uchar(0x20, file);
for (size_t y=0; y<img->height; y++) {
for (size_t x=0; x<img->width; x++) {
Color c = img->get(x,y);
fwrite_uchar((unsigned char)(clamp(c.b)*255.0f), file);
fwrite_uchar((unsigned char)(clamp(c.g)*255.0f), file);
fwrite_uchar((unsigned char)(clamp(c.r)*255.0f), file);
}
}
}
inline unsigned char fread_uchar (std::fstream& file) { unsigned char v; file.read((char*)&v,sizeof(v)); return v; }
inline unsigned short fread_ushort(std::fstream& file) { unsigned short v; file.read((char*)&v,sizeof(v)); return v; }
/*! read TGA file from disk */
Ref<Image> loadTGA(const FileName& fileName)
{
/* open file for reading */
std::fstream file;
file.exceptions (std::fstream::failbit | std::fstream::badbit);
file.open (fileName.c_str(), std::fstream::in | std::fstream::binary);
unsigned char idlength = fread_uchar(file);
if (idlength != 0) THROW_RUNTIME_ERROR("unsupported TGA file");
unsigned char colormaptype = fread_uchar(file);
if (colormaptype != 0) THROW_RUNTIME_ERROR("unsupported TGA file");
unsigned char datatype = fread_uchar(file);
if (datatype != 2) THROW_RUNTIME_ERROR("unsupported TGA file");
unsigned short cmo = fread_ushort(file);
unsigned short cml = fread_ushort(file);
unsigned char cmd = fread_uchar(file);
unsigned short xorg = fread_ushort(file);
unsigned short yorg = fread_ushort(file);
if (cmo != 0 || cml != 0 || cmd != 0 || xorg != 0 || yorg != 0)
THROW_RUNTIME_ERROR("unsupported TGA file");
unsigned short width = fread_ushort(file);
unsigned short height = fread_ushort(file);
unsigned char bits = fread_uchar(file);
if (bits != 3*8) THROW_RUNTIME_ERROR("unsupported TGA file bits per pixel");
unsigned char desc = fread_uchar(file);
if (desc != 0x20) THROW_RUNTIME_ERROR("unsupported TGA file");
/* create image and fill with data */
Ref<Image> img = new Image4f(width,height,fileName);
/* load image data */
for (size_t y=0; y<height; y++) {
for (size_t x=0; x<width; x++) {
const unsigned char b = fread_uchar(file);
const unsigned char g = fread_uchar(file);
const unsigned char r = fread_uchar(file);
img->set(x,y,Color4(r/255.0f,g/255.0f,b/255.0f,1.0f));
}
}
return img;
}
}

File diff suppressed because it is too large Load diff