void RawImage::loadBMP(FILE *file) throw(ImageException) { // Read the header data. unsigned char file_header[14]; unsigned char info_header[40]; if (fread(file_header, sizeof(unsigned char), 14, file) < 14) throw ImageException("Invalid or missing texture data."); if (fread(info_header, sizeof(unsigned char), 40, file) < 40) throw ImageException("Invalid or missing texture data."); // TODO: inspect the header data and return suitable errors for unsupported formats. _type = GL_BGR; _bytesPerPixel = 3; _width = (unsigned int)info_header[4] | (unsigned int)info_header[5] << 8 | (unsigned int)info_header[6] << 16 | (unsigned int)info_header[7] << 24; _height = (unsigned int)info_header[8] | (unsigned int)info_header[9] << 8 | (unsigned int)info_header[10] << 16 | (unsigned int)info_header[11] << 24; // Read the texture data. unsigned int numBytes = _width * _height * _bytesPerPixel; _pixels = new unsigned char[numBytes]; if (fread(_pixels, sizeof(unsigned char), numBytes, file) < numBytes) throw ImageException("Invalid or missing texture data."); // Note that the data from the file is in BGR order. }
void RawImage::tgaLoadRLECompressed(FILE *file, unsigned int numPixels, unsigned int bytesPerPixel, unsigned char *pixels) throw(ImageException) { const int MAX_BYTES_PER_PIXEL = 4; int pixelCount; bool isEncoded; unsigned int pixelsRead = 0; unsigned char pixel[MAX_BYTES_PER_PIXEL]; while (pixelsRead < numPixels) { pixelCount = fgetc(file); if (pixelCount == EOF) throw ImageException("Missing or invalid TGA image data."); isEncoded = pixelCount > 127; pixelCount = (pixelCount & 0x7F) + 1; if (isEncoded) { if (fread(pixel, sizeof(unsigned char), bytesPerPixel, file) < bytesPerPixel) throw ImageException("Missing or invalid TGA image data."); for (int i = 0; i < pixelCount; ++i) { memcpy(pixels, pixel, bytesPerPixel); pixels += bytesPerPixel; } } else { unsigned int numBytes = pixelCount * bytesPerPixel; if (fread(pixels, sizeof(unsigned char), numBytes, file) < numBytes) throw ImageException("Missing or invalid TGA image data."); pixels += numBytes; } pixelsRead += pixelCount; } }
////////////////////////////////////////////////////////////////////////////// // // // Nombre funcion: saveToFile // // Descripcion: crea una imagen, en escala de grises o en color dependiendo // // del tipo, a partir de una leida. // // Parametros de entrada: una cadena con el nombre del nuevo fichero. // // Devuelve: void // // // ////////////////////////////////////////////////////////////////////////////// void Image::saveToFile(string nombre) throw(ImageException) { fstream file; file.open(nombre.c_str(), ios::out); /** Si no se ha abierto el fichero, se muestra mensaje de error */ if(!file.is_open()){ throw ImageException("Error: apertura de fichero fallida"); } /** Dependiendo del tipo que sea se pone un numero magico u otro */ if(_type == 0){ file << "P5\n"; } else if(_type == 1){ file << "P6\n"; } else{ throw ImageException("Error: imagen no cargada previamente"); } file << _width << ' ' << _heigth << endl; file << 255 << endl; /** Escritura en binario de la imagen */ if(_type == 0){ file.write((char *) _data, _width*_heigth*sizeof(unsigned char)); } else{ file.write((char *) _data, _width*_heigth*3*sizeof(unsigned char)); } file.close(); }
/** \brief fill an image with the values of a given frame * \param index : index of the frame * \param frame : image which will be filled * \throw ImageException : invalid frame dimensions * \throw ImageException : index out of bound */ inline void getFrame(unsigned int index, Image<T>& frame){ if(frame.width() != imageWidth || frame.height() != imageHeight || frame.nbChannel() != imageNbChannel) throw ImageException("Invalid frame dimensions", "Image3D::setFrame"); if(index >= imageDepth) throw ImageException("index out of bound", "Image3D::setFrame"); std::copy(frames[index], frames[index]+frame.size(), frame.begin()); }
void RawImage::loadPPM(FILE* file) throw(ImageException) { int fileType = 0; fscanf(file, "P%d", &fileType); if (fileType != 3 && fileType != 6) throw ImageException("Unsupported PPM subformat."); _type = GL_RGB; _bytesPerPixel = 3; _width = ppmGetNextInt(file); _height = ppmGetNextInt(file); int maxValue = ppmGetNextInt(file); unsigned int numBytes = _width * _height * _bytesPerPixel; _pixels = new unsigned char[numBytes]; if (fileType == 3) { for (int row = _height - 1; row >= 0; --row) { long start = row * _width * _bytesPerPixel; long end = start + _width * _bytesPerPixel; for (long i = start; i < end; ++i) _pixels[i] = ppmGetNextInt(file) * 255 / maxValue; } } else { int ch = fgetc(file); if (ch != ' ' && ch != '\t' && ch != '\n' && ch != '\r') ungetc(ch, file); if (fread(_pixels, sizeof(unsigned char), numBytes, file) < numBytes) throw ImageException("Invalid or missing texture data."); } }
//////////////////////////////////////////////////////////////////////////////// // // // Nombre funcion: loadFromFile // // Descripcion: carga una imagen desde un fichero, comprobando si es en escala// // de grises o en color. // // Parametros de entrada: una cadena con el nombre del fichero. // // Devuelve: void // // // //////////////////////////////////////////////////////////////////////////////// void Image::loadFromFile(string nombre) throw(ImageException) { fstream file; string numMag; int auxGris; char garbage; file.open(nombre.c_str(), ios::in); /** Si no se ha abierto el fichero, se muestra mensaje de error */ if(!file.is_open()){ throw ImageException("Error en loadFromFile(nombre): apertura de fichero fallida"); } /** Se lee la parte en modo texto */ file >> numMag; file >> _width; file >> _height; file >> auxGris; /** Se desecha la posible basura que pueda haber */ file.read(&garbage, sizeof(char)); while(garbage != '\n'){ file.read(&garbage, sizeof(char)); } if(numMag == "P5"){ _type = GREY; } else if(numMag == "P6"){ _type = COLOR; } else{ throw ImageException("Error en loadFromFile(nombre): tipo de imagen no soportado"); } /** Se lee la parte en modo binario */ /** Se comprueba que no tuviese valor previo el array */ if(_data != NULL){ delete[] _data; _data = NULL; } /** Reserva de la memoria del array y lectura de imagen */ _data = new unsigned char[_width*_height*_type]; file.read((char *) _data, _width*_height*_type*sizeof(unsigned char)); file.close(); }
/** Operador de asignación. Asigna a todos los pixels el mismo valor */ Image & Image::operator=(unsigned char v) throw(ImageException) { if(_data == NULL){ throw ImageException("Error en operator=(v): imagen no cargada previamente"); } if(_type == -1){ throw ImageException("Error en operator=(v): imagen no cargada previamente"); } memset(_data, v, _width*_height*_type*sizeof(unsigned char)); return *this; }
void RawImage::loadJPG(FILE* file) throw(ImageException) { jpeg_decompress_struct cinfo; jpeg_error_mgr jerr; cinfo.err = jpeg_std_error(&jerr); jpeg_create_decompress(&cinfo); try { jpeg_stdio_src(&cinfo, file); if (jpeg_read_header(&cinfo, TRUE) != JPEG_HEADER_OK) throw ImageException("Error reading JPEG header."); // Set decompression parameters in cinfo here. (optional) if (!jpeg_start_decompress(&cinfo)) throw ImageException("Error reading JPEG data."); _bytesPerPixel = sizeof(JSAMPLE) * cinfo.output_components; switch (cinfo.output_components) { case 1: _type = GL_ALPHA; break; case 3: _type = GL_RGB; break; case 4: _type = GL_RGBA; break; } _width = cinfo.output_width; _height = cinfo.output_height; _pixels = new unsigned char[_bytesPerPixel * _width * _height]; unsigned char *p; while (cinfo.output_scanline < cinfo.output_height) { p = _pixels + (sizeof(JSAMPLE) * _bytesPerPixel * _width * (_height - cinfo.output_scanline - 1)); jpeg_read_scanlines(&cinfo, &p, 1); } if (!jpeg_finish_decompress(&cinfo)) throw ImageException("Error reading JPEG data."); jpeg_destroy_decompress(&cinfo); } catch (ImageException& e) { jpeg_destroy_decompress(&cinfo); throw e; } }
/** Copy the pixels from the pixbuf without padding. * * @throw ImageException if image does not have 8 bits per sample. */ void ImagePixbuf::unpack() { guint8 *pixels; int bitsPerSample, channels, stridePacked, strideUnpacked; // Get info from pixbuf pixels = pixbuf->get_pixels(); stridePacked = pixbuf->get_rowstride(); channels = pixbuf->get_n_channels(); bitsPerSample = pixbuf->get_bits_per_sample(); // Verify if (bitsPerSample != 8) { throw ImageException("[Image] Does not have 8 bits per sample."); } // Initialize the data strideUnpacked = getWidth() * channels; data = new GLchar[getHeight()*strideUnpacked]; for (int i=0; i<getHeight(); ++i) { for (int j=0; j<strideUnpacked; ++j) { data[i*strideUnpacked+j] = pixels[i*stridePacked+j]; } } }
void Image3D<T>::buildImageFromBuffer(const size_t width, const size_t height, const size_t depth, const size_t nbChannel, T* buffer, const bool copy) { if (size()) { throw ImageException("buildImageFromImage","Image already allocated"); } imageWidth = width; imageHeight = height; imageDepth = depth; imageNbChannel = nbChannel; imageSize = imageWidth*imageHeight*imageDepth*imageNbChannel; if (copy) { if(data){ delete[] data; data = 0; } data = new T[size()*sizeof(T)]; std::copy(buffer,buffer+size(),data); } else { if(data){ delete[] data; } data = buffer; } initRowsAndFrames(); begin_ = data; end_ = data+imageSize; }
ImageBuffer::ImageBuffer (const string &filename) : _filename (filename), _data (NULL), _length (0) { // Open file std::ifstream ifs (filename.c_str(), std::ios::in | std::ios::binary); if (ifs.fail ()) throw ImageException ("Couldn't open file", filename); // Get file length ifs.seekg (0, std::ios::end); _length = ifs.tellg (); ifs.seekg (0, std::ios::beg); try { // Allocate memory for holding file data _data = new GLubyte[_length]; // Read whole file data ifs.read (reinterpret_cast<char *> (_data), _length); ifs.close (); } catch (...) { delete [] _data; throw; } }
bool Importer::Load(const System::string& filename) { std::wstring file(filename.Data()); std::transform(file.begin(), file.end(), file.begin(), ::towlower); if (file.rfind(L".png") != std::wstring::npos) { PngImporter importer; importer.Load(filename); std::swap(impl_image, importer.impl_image); return true; } else if (file.rfind(L".jpeg") != std::wstring::npos || file.rfind(L".jpg") != std::wstring::npos) { JpgImporter importer; importer.Load(filename); std::swap(impl_image, importer.impl_image); return true; } else { auto default_file_name = System::Environment::Instance()->GetTextureFolder() + L"default.png"; PngImporter importer; if (importer.Load(default_file_name)) { std::swap(impl_image, importer.impl_image); return true; } else { throw ImageException(L"Unsupported file format"); } } }
/** \brief get component value of the asked pixel (with bounds checking). * \param x width position of the pixel * \param y height position of the pixel * \param z depth position of the pixel * \param channel component number * \return a value of the component */ inline virtual T & at(const unsigned int x, const unsigned int y, const unsigned int z, const unsigned int channel) { if (channel>=imageNbChannel) { std::ostringstream o("Operator("); o << x << "," << y << "," << z << "," << channel <<") " ; throw ImageException(o.str(), "Invalid range"); } return (at(x,y,z)[channel]); }
/** Operador de asignación */ Image & Image::operator=(const Image &I) throw(ImageException) { int t; if(_data != NULL){ delete[] _data; _data = NULL; } _width = I._width; _heigth = I._heigth; _type = I._type; if(_type == 0){ t = 1; } else if(_type == 1){ t = 3; } else{ throw ImageException("Error: imagen no cargada previamente"); } if(_data == NULL){ _data = new unsigned char[_width*_heigth*t]; } memcpy(_data, I._data, _width*_heigth*t*sizeof(unsigned char)); return *this; }
/** \brief get pointer on the asked pixel (with bounds checking). * This function is the same than the operator() but checks if indices are valid. * \param x width position of the pixel * \param y height position of the pixel * \param z depth position of the pixel * \return a buffer with the pixel */ inline virtual T * at(const unsigned int x, const unsigned int y, const unsigned int z) const { if (x>=imageWidth || y>=imageHeight || z>=imageDepth ) { std::ostringstream o("Operator("); o << x << "," << y << "," << z << ") " ; throw ImageException(o.str(), "Invalid range"); } return (*this)(x,y,z);//(rows[y]+x*nbChannel()); }
////////////////////////////////////////////////////////////////////////////// // // // Nombre funcion: saveToFile // // Descripcion: crea una imagen, en escala de grises o en color dependiendo // // del tipo, a partir de una leida. // // Parametros de entrada: una cadena con el nombre del nuevo fichero. // // Devuelve: void // // // ////////////////////////////////////////////////////////////////////////////// void Image::saveToFile(string nombre) throw(ImageException) { fstream file; file.open(nombre.c_str(), ios::out); // Si no se ha abierto el fichero, se muestra mensaje de error if(!file.is_open()){ throw ImageException("Error en apertura de fichero"); } // Dependiendo del tipo que sea se pone un numero magico u otro if(_type == 0){ file << "P5\n"; } else{ file << "P6\n"; } file << _width << ' ' << _heigth << endl; file << _gris << endl; // Escritura en binario de la imagen if(_type == 0){ file.write((char *) _data, _width*_heigth*sizeof(unsigned char)); } else{ file.write((char *) _data, _width*_heigth*3*sizeof(unsigned char)); } file.close(); }
/** Accede al elemento x,y de una imagen y modificarlo. Permite hacer cosas como * Image I(100,100,0,10); * I(10,10) = 19; * cout << I(10,10) */ unsigned char & Image::operator()(unsigned int x, unsigned int y, unsigned int c) throw(ImageException) { if((x >= (unsigned int) _width) || (y >= (unsigned int) _heigth)){ throw ImageException("Error: las coordenadas estan fuera de rango"); } else{ if((_type == 0) && (c != 0)){ throw ImageException("Error: el tipo y la capa no coinciden"); } else if((_type == 0) && (c == 0)){ return(_data[y*_width+x]); } else{ return(_data[((y*_width+x)*3)+c]); } } }
template<class Type> SOWAIterator<Type>::SOWAIterator(const Image<Type>* image, ConstantTemplate<Type>* tLinkC, ConstantTemplate<Type>* tLinkS) : OWAIterator<Type>(image, tLinkC) { this->m_tLinkS = tLinkS; if( this->m_tLinkS->width() != this->m_tLinkC->width() || this->m_tLinkS->height() != this->m_tLinkC->height() ) { throw ImageException("SOWAIterator::SOWAIterator [The linked templates must be the same dimensions]"); } }
void RawImage::tgaLoadUncompressed(FILE *file, unsigned int numPixels, unsigned int bytesPerPixel, unsigned char *pixels) throw(ImageException) { unsigned int numBytes = numPixels * bytesPerPixel; if (fread(pixels, sizeof(unsigned char), numBytes, file) < numBytes) throw ImageException("Missing or invalid TGA image data."); }
void RawImage::loadTIFF(const char* filename) throw(ImageException) { TIFF* tiff = TIFFOpen(filename, "rb"); if (!tiff) throw ImageException("Unable to open TIFF file."); _type = GL_RGBA; _bytesPerPixel = 4; TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &_width); TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &_height); size_t numPixels = _width * _height; _pixels = new unsigned char[_bytesPerPixel * numPixels]; bool readOK = TIFFReadRGBAImage(tiff, _width, _height, (uint32*)_pixels, 0); TIFFClose(tiff); if (!readOK) throw ImageException("Error reading TIFF data."); }
GrayImage* Importer::LoadGray(const System::string& filename) { Load(filename); if (impl_image->m_components != 1) throw ImageException((filename + L" is not an RGB image").Data()); GrayImage* gray_image = new GrayImage; std::swap(gray_image->impl_image, impl_image); return gray_image; }
RGBImage* Importer::LoadRGB(const System::string& filename) { Load(filename); if (impl_image->m_components != 3) throw ImageException((filename + L" is not an RGB image").Data()); RGBImage* rgb_image = new RGBImage; std::swap(rgb_image->impl_image, impl_image); return rgb_image; }
RawImage::RawImage(const char *path) throw(ImageException) : _type(GL_RGB), _texId(0), _bytesPerPixel(0), _width(0), _height(0), _pixels(NULL) { const char *filename = basename(const_cast<char *>(path)); if (filename == NULL) throw ImageException("Invalid image filename: %s does not name a file.", filename); const char *ext = strrchr(filename, '.'); if (ext == NULL) throw ImageException("Unknown image format."); FILE *file = fopen(path, "rb"); if (file == NULL) throw ImageException("File not found: %s.", filename); try { if (strcasecmp(ext, ".bmp") == 0) { loadBMP(file); } else if (strcasecmp(ext, ".tga") == 0) { loadTGA(file); } else if (strcasecmp(ext, ".ppm") == 0) { loadPPM(file); } else if (strcasecmp(ext, ".jpg") == 0 || strcasecmp(ext, ".jpeg") == 0) { loadJPG(file); } else if (strcasecmp(ext, ".png") == 0) { loadPNG(file); } else if (strcasecmp(ext, ".tif") == 0 || strcasecmp(ext, ".tiff") == 0) { loadTIFF(path); } else { throw ImageException("Unknown image format: %s", ext); } fclose(file); } catch (ImageException& ex) { fclose(file); if (_pixels != NULL) delete _pixels; throw ex; } }
/** Crea una imagen a partir de otra */ Image::Image(const Image & I) { if(I._data == NULL){ throw ImageException("Error en Image(I): imagen no cargada previamente"); } _width = I._width; _height = I._height; _type = I._type; if(_type != -1){ _data = new unsigned char[_width*_height*_type]; memcpy(_data, I._data, _width*_height*_type*sizeof(unsigned char)); } else{ throw ImageException("Error en Image(I): imagen no cargada previamente"); } }
Image(const int width, const int height, const int linesize, const int64_t pts, const uint8_t* const data) : width_(width), height_(height), linesize_(linesize), pts_(pts) { data_ = (uint8_t*) malloc(linesize_ * height_); if (!data) throw ImageException("Can not allocate image."); memcpy(data_, data, linesize_ * height_); }
/** Operador de asignación. Asigna a todos los pixels el mismo valor */ Image & Image::operator=(unsigned char v) throw(ImageException) { int t; if(_data == NULL){ throw ImageException("Error: imagen no cargada previamente"); } if(_type == 0){ t = 1; } else if(_type == 1){ t = 3; } else{ throw ImageException("Error: imagen no cargada previamente"); } memset(_data, v, _width*_heigth*t*sizeof(unsigned char)); return *this; }
void RawImage::loadTGA(FILE *file) throw(ImageException) { unsigned char header[18]; fread(header, sizeof(unsigned char), 18, file); if (header[1] != 0) // The colormap byte. throw ImageException("Colormap TGA files aren't supported."); _width = header[0xC] + header[0xD] * 256; _height = header[0xE] + header[0xF] * 256; unsigned int bitDepth = header[0x10]; /* make sure we are loading a supported bit-depth */ if (bitDepth != 32 && bitDepth != 24 && bitDepth != 8) throw ImageException("TGA files with a bit depth of %d aren't supported.", bitDepth); unsigned int numPixels = _width * _height; _bytesPerPixel = bitDepth / 8; _pixels = new unsigned char[numPixels * _bytesPerPixel]; switch (header[2]) { // The image type byte case 2: // TrueColor, uncompressed case 3: // Monochrome, uncompressed tgaLoadUncompressed(file, numPixels, _bytesPerPixel, _pixels); break; case 10: // TrueColor, RLE compressed case 11: // Monochrome, RLE compressed tgaLoadRLECompressed(file, numPixels, _bytesPerPixel, _pixels); break; // Unsupported image types. default: throw ImageException("Unknown TGA image type (type code: %d).", header[2]); } if (bitDepth == 32) _type = GL_BGRA; else if (bitDepth == 24) _type = GL_BGR; else _type = GL_ALPHA; }
/** Crea una imagen con un tamaño y tipo indicado y con un valor por defecto */ Image::Image(int w, int h, int type, unsigned char c) { _width = w; _height = h; _type = type; if((_type == GREY) || (_type == COLOR)){ _data = new unsigned char[_width*_height*_type]; memset(_data, c, _width*_height*_type*sizeof(unsigned char)); } else{ throw ImageException("Error en Image(w,h,type,c): imagen no cargada previamente"); } }
/** Crea una imagen a partir de otra */ Image::Image(const Image & I) { if(I._data == NULL){ throw ImageException("Error: imagen no cargada previamente"); } _width = I._width; _heigth = I._heigth; _type = I._type; if(_type == 0){ _data = new unsigned char[_width*_heigth]; memcpy(_data, I._data, _width*_heigth*sizeof(unsigned char)); } else if(_type == 1){ _data = new unsigned char[_width*_heigth*3]; memcpy(_data, I._data, _width*_heigth*3*sizeof(unsigned char)); } else{ throw ImageException("Error: imagen no cargada previamente"); } }
template<class Type> typename ConvolutionIterator<Type>::value_type SOWAIterator<Type>::operator*() { if(this->m_tLinkS == NULL) { throw ImageException("SOWAIterator::operator* [A template must be linked in order to dereference]"); } int xMin = this->m_imageX - this->m_templateNegOffsetX; int xMax = this->m_imageX + this->m_templatePosOffsetX; int yMin = this->m_imageY - this->m_templateNegOffsetY; //int yMax = this->m_imageY + this->m_templatePosOffsetY; this->clearData(this->m_data); this->clearData(this->m_temData); int yLoop = yMin; int xLoop = xMin; int temSize = this->m_tLinkC->size(); typename ConvolutionIterator<Type>::data_iterator data_i = this->m_data->begin(); typename ConvolutionIterator<Type>::data_iterator temData_i = this->m_temData->begin(); for(int i = 0; i < temSize; i++) { try { *(data_i++) = this->m_tLinkS->operator()(i) + this->m_image->getPixel(xLoop++, yLoop); } catch(ImageException&) { continue; } *(temData_i++) = this->m_tLinkC->operator()(i); if(xLoop > xMax) { xLoop = xMin; yLoop++; } } sort(this->m_data->begin(), this->m_data->end()); Type sum = Type(0); data_i = this->m_data->begin(); temData_i = this->m_temData->begin(); typename ConvolutionIterator<Type>::data_iterator data_e = this->m_data->end(); while(data_i != data_e) { sum += (*(data_i++)) * (*(temData_i++)); } return sum; }