static Ref<Image> load_jpeg_image (const Ptr<IData> data) { jpeg_decompress_struct cinfo; jpeg_error_mgr jerr; Ref<Image> result_image; DataType data_type = DataType::BYTE; Shared<Buffer> buffer = data->buffer(); unsigned width, height; try { //memset (&cinfo, 0, sizeof (cinfo)); memset (&jerr, 0, sizeof (jerr)); cinfo.err = jpeg_std_error(&jerr); jpeg_create_decompress(&cinfo); jpeg_memory_src(&cinfo, buffer->begin(), buffer->size()); jpeg_read_header(&cinfo, TRUE); width = cinfo.image_width; height = cinfo.image_height; unsigned row_width = 0; PixelFormat pixel_format; if (cinfo.jpeg_color_space == JCS_GRAYSCALE) { row_width = width; pixel_format = PixelFormat::L; } else { row_width = 3 * width; pixel_format = PixelFormat::RGB; } result_image = new Image(Vec2u(width, height), pixel_format, data_type); ByteT *line = result_image->data(); jpeg_start_decompress(&cinfo); // read jpeg image while (cinfo.output_scanline < cinfo.output_height) { jpeg_read_scanlines(&cinfo, &line, 1); line += row_width; } jpeg_finish_decompress(&cinfo); jpeg_destroy_decompress(&cinfo); } catch (std::exception &e) { } return result_image; };
Shared<Buffer> Program::info_log() { GLint length; property(GL_INFO_LOG_LENGTH, &length); if (length > 0) { Shared<MutableBuffer> buffer = PackedBuffer::new_buffer(length); glGetProgramInfoLog(_handle, length, NULL, (GLchar *)buffer->begin()); return buffer; } else { return NULL; } }
bool Program::link() { glLinkProgram(_handle); GLint status; property(GL_LINK_STATUS, &status); glGetProgramiv(_handle, GL_LINK_STATUS, &status); if (status == 0) { // Something went wrong... Shared<Buffer> log = info_log(); LogBuffer buffer; buffer << "Error linking program:" << std::endl; buffer << StringT(log->begin(), log->end()) << std::endl; logger()->log(LOG_ERROR, buffer); } return status != 0; }
GLenum ShaderManager::compile(GLenum type, const Buffer * buffer) { GLuint shader = glCreateShader(type); const GLchar * source = (GLchar*)buffer->begin(); GLint length = (GLint)buffer->size(); glShaderSource(shader, 1, &source, &length); check_graphics_error(); glCompileShader(shader); check_graphics_error(); GLint log_length; glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &log_length); if (log_length > 0) { Shared<MutableBuffer> buffer = PackedBuffer::new_buffer(log_length); glGetShaderInfoLog(shader, (GLsizei)buffer->size(), (GLsizei*)&log_length, (GLchar*)buffer->begin()); LogBuffer log_buffer; log_buffer << "Error compiling shader:" << std::endl; log_buffer << buffer->begin() << std::endl; logger()->log(LOG_ERROR, log_buffer); } GLint status; glGetShaderiv(shader, GL_COMPILE_STATUS, &status); if (status == 0) { logger()->log(LOG_ERROR, "Shader compilation failed!"); glDeleteShader(shader); return 0; } check_graphics_error(); return shader; }
const char * read_bytes (unsigned length) { unsigned prev_offset = offset; offset += length; return (const char*)(buffer->begin() + prev_offset); }
static Ref<Image> load_png_image (const Ptr<IData> data) { // Image formatting details PixelFormat format = PixelFormat(0); DataType data_type = DataType(0); DataFile df(data); Ref<Image> result_image; Shared<Buffer> buffer = data->buffer(); // internally used by libpng png_structp png_reader = NULL; // user requested transforms png_infop png_info = NULL; png_byte **ppb_row_pointers = NULL; if (!png_check_sig((png_byte*)buffer->begin(), 8)) { logger()->log(LOG_ERROR, "Could not verify PNG image!"); return Ref<Image>(); } try { png_reader = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, png_error, NULL); DREAM_ASSERT(png_reader != NULL && "png_create_read_struct returned NULL!"); png_info = png_create_info_struct(png_reader); DREAM_ASSERT(png_info != NULL && "png_create_info_struct returned NULL!"); // We will use this function to read data from Data class png_set_read_fn (png_reader, (void *)&df, DataFile::png_read_data); // Read PNG header png_read_info (png_reader, png_info); // Interpret IMAGE header int bit_depth, color_type; png_uint_32 width, height; png_get_IHDR (png_reader, png_info, &width, &height, &bit_depth, &color_type, NULL, NULL, NULL); if (bit_depth < 8) { png_set_packing (png_reader); //png_set_expand(png_reader); } if (color_type == PNG_COLOR_TYPE_PALETTE) { png_set_expand(png_reader); } // after the transformations have been registered update png_info data png_read_update_info(png_reader, png_info); png_get_IHDR(png_reader, png_info, &width, &height, &bit_depth, &color_type, NULL, NULL, NULL); // Figure out image format if (color_type == PNG_COLOR_TYPE_RGB) { format = PixelFormat::RGB; } else if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) { format = PixelFormat::RGBA; } else if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA) { format = PixelFormat::LA; } else if (color_type == PNG_COLOR_TYPE_GRAY) { format = PixelFormat::L; } // Figure out bit depth if (bit_depth == 16) { // It is possible to convert to 8bpp using: png_set_strip_16 (png_reader); data_type = DataType::SHORT; } else if (bit_depth == 8) { data_type = DataType::BYTE; } else { std::stringstream s; s << "PNG: Bit depth of " << bit_depth << " not supported!" << std::endl; throw std::runtime_error(s.str()); } // row_bytes is the width x number of channels unsigned row_bytes = png_get_rowbytes(png_reader, png_info); // Allocate the image_data buffer. result_image = new Image(Vec2u(width, height), format, data_type); ByteT *image_bytes = result_image->data(); DREAM_ASSERT(image_bytes != NULL); //ByteT * image_data = (unsigned char *) malloc(rowbytes * height); ppb_row_pointers = (png_bytepp)malloc(height * sizeof(png_bytep)); for (unsigned i = 0; i < height; i++) ppb_row_pointers[i] = image_bytes + i * row_bytes; png_read_image(png_reader, ppb_row_pointers); png_read_end(png_reader, NULL); free(ppb_row_pointers); if (png_reader) png_destroy_read_struct(&png_reader, &png_info, NULL); } catch (std::exception &e) { logger()->log(LOG_ERROR, LogBuffer() << "PNG read error: " << e.what()); if (png_reader) png_destroy_read_struct(&png_reader, &png_info, NULL); png_reader = NULL; if (ppb_row_pointers) free(ppb_row_pointers); throw; } return result_image; }