MTS_NAMESPACE_BEGIN /* ==================================================================== */ /* ImageBlock */ /* ==================================================================== */ ImageBlock::ImageBlock(const Vector2i &maxBlockSize, int borderSize, bool supportWeights, bool supportAlpha, bool supportSnapshot, bool supportStatistics) : border(borderSize), maxBlockSize(maxBlockSize), alpha(NULL), weights(NULL), variances(NULL), nSamples(NULL), pixelSnapshot(NULL), weightSnapshot(NULL), alphaSnapshot(NULL), extra(0) { int maxArraySize = (maxBlockSize.x + 2*border) *(maxBlockSize.y + 2*border); pixels = (Spectrum *) allocAligned(sizeof(Spectrum)*maxArraySize); if (supportAlpha) alpha = (Float *) allocAligned(sizeof(Float)*maxArraySize); if (supportWeights) weights = (Float *) allocAligned(sizeof(Float)*maxArraySize); if (supportSnapshot) { pixelSnapshot = (Spectrum *) allocAligned(sizeof(Spectrum)*(2*border+1)*(2*border+1)); alphaSnapshot = (Float*) allocAligned(sizeof(Float)*(2*border+1)*(2*border+1)); weightSnapshot = (Float *) allocAligned(sizeof(Float)*(2*border+1)*(2*border+1)); } if (supportStatistics) { variances = (Spectrum *) allocAligned(sizeof(Spectrum)*maxArraySize); nSamples = (uint32_t *) allocAligned(sizeof(uint32_t)*maxArraySize); } }
void Bitmap::loadTGA(Stream *stream) { int headerSize = stream->readUChar(); if (stream->readUChar() != 0) Log(EError, "Invalid TGA format -- only raw (non-RLE encoded) RGB is supported for now"); if (stream->readUChar() != 2) Log(EError, "Invalid TGA format -- only raw (non-RLE encoded) RGB is supported for now"); stream->setPos(8); int x1 = stream->readShort(); int y1 = stream->readShort(); int x2 = stream->readShort(); int y2 = stream->readShort(); m_width = x2-x1; m_height = y2-y1; Log(EInfo, "Reading a %ix%i TGA file", m_width, m_height); stream->setPos(16); m_bpp = stream->readUChar(); if (m_bpp != 24 && m_bpp != 32) Log(EError, "Invalid TGA format -- only 24 or 32 bpp images are supported for now"); m_gamma = -1; int channels = m_bpp / 8; m_size = m_width * m_height * channels; m_data = static_cast<uint8_t *>(allocAligned(m_size)); stream->setPos(18 + headerSize); stream->read(m_data, m_size); /* Convert BGR to RGB */ for (size_t i=0; i<m_size; i += channels) { uint8_t tmp = m_data[i]; m_data[i] = m_data[i+2]; m_data[i+2] = tmp; } }
void Bitmap::loadEXR(Stream *stream) { EXRIStream istr(stream); Imf::RgbaInputFile file(istr); /* Determine dimensions and allocate space */ Imath::Box2i dw = file.dataWindow(); m_width = dw.max.x - dw.min.x + 1; m_height = dw.max.y - dw.min.y + 1; m_size = m_width * m_height * 16; m_bpp = 4*4*8; m_gamma = 1.0f; m_data = static_cast<uint8_t *>(allocAligned(m_size)); Imf::Rgba *rgba = new Imf::Rgba[m_width*m_height]; Log(ETrace, "Reading a %ix%i EXR file", m_width, m_height); /* Convert to 32-bit floating point per channel */ file.setFrameBuffer(rgba, 1, m_width); file.readPixels(dw.min.y, dw.max.y); float *m_buffer = getFloatData(); for (int i=0; i<m_width*m_height; i++) { *m_buffer = (float) rgba[i].r; m_buffer++; *m_buffer = (float) rgba[i].g; m_buffer++; *m_buffer = (float) rgba[i].b; m_buffer++; *m_buffer = (float) rgba[i].a; m_buffer++; } delete[] rgba; }
// Allocates a char array of given size from the pool, and optionally copies a given string to it. // If the allocation request cannot be accommodated, this function will throw <code>std::bad_alloc</code>. // If exceptions are disabled by defining CLAS_NO_EXCEPTIONS, this function // will call rapidxml::parse_error_handler() function. // \param source String to initialize the allocated memory with, or 0 to not initialize it. // \param size Number of characters to allocate, or zero to calculate it automatically from source string length; if size is 0, source string must be specified and null terminated. // \return Pointer to allocated char array. This pointer will never be NULL. Ch *allocStr( const Ch *source = 0, std::size_t size = 0 ) { assert( source || size ); // Either source or size (or both) must be specified if ( size == 0 ) size = internal::Measure( source ) + 1; Ch *result = static_cast<Ch *>( allocAligned( size * sizeof( Ch ) ) ); if ( source ) for ( std::size_t i = 0; i < size; ++i ) result[ i ] = source[ i ]; return result; }
Bitmap::Bitmap(int width, int height, int bpp) : m_width(width), m_height(height), m_bpp(bpp), m_data(NULL) { AssertEx(m_bpp == 1 || m_bpp == 8 || m_bpp == 16 || m_bpp == 24 || m_bpp == 32 || m_bpp == 96 || m_bpp == 128, "Invalid number of bits per pixel"); AssertEx(width > 0 && height > 0, "Invalid bitmap size"); if (bpp == 96 || bpp == 128) m_gamma = 1.0f; else m_gamma = -1.0f; // sRGB // 1-bit masks are stored in a packed format. m_size = (size_t) std::ceil(((double) m_width * m_height * m_bpp) / 8.0); m_data = static_cast<uint8_t *>(allocAligned(m_size)); }
/* Isotropic/anisotropic EWA mip-map texture map class based on PBRT */ MIPMap::MIPMap(int width, int height, Spectrum *pixels, EFilterType filterType, EWrapMode wrapMode, Float maxAnisotropy) : m_width(width), m_height(height), m_filterType(filterType), m_wrapMode(wrapMode), m_maxAnisotropy(maxAnisotropy) { Spectrum *texture = pixels; if (filterType != ENone && (!isPow2(width) || !isPow2(height))) { m_width = (int) roundToPow2((uint32_t) width); m_height = (int) roundToPow2((uint32_t) height); /* The texture needs to be up-sampled */ Spectrum *texture1 = new Spectrum[m_width*height]; /* Re-sample into the X direction */ ResampleWeight *weights = resampleWeights(width, m_width); for (int y=0; y<height; y++) { for (int x=0; x<m_width; x++) { texture1[x+m_width*y] = Spectrum(0.0f); for (int j=0; j<4; j++) { int pos = weights[x].firstTexel + j; if (pos < 0 || pos >= height) { if (wrapMode == ERepeat) pos = modulo(pos, width); else if (wrapMode == EClamp) pos = clamp(pos, 0, width-1); } if (pos >= 0 && pos < width) texture1[x+m_width*y] += pixels[pos+y*width] * weights[x].weight[j]; } } } delete[] weights; delete[] pixels; /* Re-sample into the Y direction */ texture = new Spectrum[m_width*m_height]; weights = resampleWeights(height, m_height); memset(texture, 0, sizeof(Spectrum)*m_width*m_height); for (int x=0; x<m_width; x++) { for (int y=0; y<m_height; y++) { for (int j=0; j<4; j++) { int pos = weights[y].firstTexel + j; if (pos < 0 || pos >= height) { if (wrapMode == ERepeat) pos = modulo(pos, height); else if (wrapMode == EClamp) pos = clamp(pos, 0, height-1); } if (pos >= 0 && pos < height) texture[x+m_width*y] += texture1[x+pos*m_width] * weights[y].weight[j]; } } } for (int y=0; y<m_height; y++) for (int x=0; x<m_width; x++) texture[x+m_width*y].clampNegative(); delete[] weights; delete[] texture1; } if (m_filterType != ENone) m_levels = 1 + log2i((uint32_t) std::max(width, height)); else m_levels = 1; m_pyramid = new Spectrum*[m_levels]; m_pyramid[0] = texture; m_levelWidth = new int[m_levels]; m_levelHeight= new int[m_levels]; m_levelWidth[0] = m_width; m_levelHeight[0] = m_height; /* Generate the mip-map hierarchy */ for (int i=1; i<m_levels; i++) { m_levelWidth[i] = std::max(1, m_levelWidth[i-1]/2); m_levelHeight[i] = std::max(1, m_levelHeight[i-1]/2); m_pyramid[i] = new Spectrum[m_levelWidth[i] * m_levelHeight[i]]; for (int y = 0; y < m_levelHeight[i]; y++) { for (int x = 0; x < m_levelWidth[i]; x++) { m_pyramid[i][x+y*m_levelWidth[i]] = ( getTexel(i-1, 2*x, 2*y) + getTexel(i-1, 2*x+1, 2*y) + getTexel(i-1, 2*x, 2*y+1) + getTexel(i-1, 2*x+1, 2*y+1)) * 0.25f; } } } if (m_filterType == EEWA) { m_weightLut = static_cast<Float *>(allocAligned(sizeof(Float)*MIPMAP_LUTSIZE)); for (int i=0; i<MIPMAP_LUTSIZE; ++i) { Float pos = (Float) i / (Float) (MIPMAP_LUTSIZE-1); m_weightLut[i] = std::exp(-2.0f * pos) - std::exp(-2.0f); } } }
void* Allocator_sys::alloc( size_t _size ) { return allocAligned( _size, EX_DEFAULT_ALIGNMENT ); }