bool ConvertPixels(byte* out, PixelFormat out_format, const byte* in, PixelFormat in_format, int pixel_count) { const FormatDesc* out_desc = GetDescription(out_format); const FormatDesc* in_desc = GetDescription(in_format); if (!out_desc || !in_desc) { return false; } const int out_size = GetPixelSize(out_format); const int in_size = GetPixelSize(in_format); for (int i = 0; i < pixel_count; ++i) { out[out_desc->r_shift] = in[in_desc->r_shift]; out[out_desc->g_shift] = in[in_desc->g_shift]; out[out_desc->b_shift] = in[in_desc->b_shift]; if (out_desc->has_alpha) { if (in_desc->has_alpha) { out[out_desc->a_shift] = in[in_desc->a_shift]; } else { out[out_desc->a_shift] = 255; } } in += in_size; out += out_size; } return true; }
OBSQTDisplay::OBSQTDisplay(QWidget *parent, Qt::WindowFlags flags) : QWidget(parent, flags) { setAttribute(Qt::WA_PaintOnScreen); setAttribute(Qt::WA_StaticContents); setAttribute(Qt::WA_NoSystemBackground); setAttribute(Qt::WA_OpaquePaintEvent); setAttribute(Qt::WA_DontCreateNativeAncestors); setAttribute(Qt::WA_NativeWindow); auto windowVisible = [this] (bool visible) { if (!visible) return; if (!display) { CreateDisplay(); } else { QSize size = GetPixelSize(this); obs_display_resize(display, size.width(), size.height()); } }; auto sizeChanged = [this] (QScreen*) { CreateDisplay(); QSize size = GetPixelSize(this); obs_display_resize(display, size.width(), size.height()); }; connect(windowHandle(), &QWindow::visibleChanged, windowVisible); connect(windowHandle(), &QWindow::screenChanged, sizeChanged); }
COR_EXPORT(Image*) CorConvertPalette( Image* image, PixelFormat palette_format) { // do we need to convert? if (!image || palette_format == PF_DONTCARE || image->getPaletteFormat() == palette_format) { return image; } // do we have invalid data? if (!IsPalettized(image->getFormat()) || !IsDirect(palette_format)) { delete image; return 0; } const int width = image->getWidth(); const int height = image->getHeight(); const PixelFormat format = image->getFormat(); const int palette_size = image->getPaletteSize(); // the palette indices don't change, so just make a copy const int image_size = width * height * GetPixelSize(format); byte* pixels = new byte[image_size]; std::memcpy(pixels, image->getPixels(), image_size); byte* new_palette = new byte[ palette_size * GetPixelSize(palette_format)]; if (!ConvertPixels(new_palette, palette_format, (byte*)image->getPalette(), image->getPaletteFormat(), palette_size)) { delete image; delete[] pixels; delete[] new_palette; return 0; } delete image; return new SimpleImage( width, height, format, pixels, new_palette, palette_size, palette_format); }
Size RichImage::GetPhysicalSize(const Value& data) const { Size sz = GetImageStringDots(data); if(sz.cx == 0 || sz.cy == 0) sz = 600 * GetPixelSize(data) / 96; return sz; }
Image* DirectConversion(Image* image, PixelFormat target_format) { COR_GUARD("DirectConversion()"); // assert isDirect(image->getFormat()) const int width = image->getWidth(); const int height = image->getHeight(); const PixelFormat source_format = image->getFormat(); const byte* in = (byte*)image->getPixels(); if (source_format == target_format) { return image; } const int target_size = GetPixelSize(target_format); byte* out_pixels = new byte[width * height * target_size]; if (!ConvertPixels(out_pixels, target_format, in, source_format, width * height)) { delete[] out_pixels; delete image; return 0; } delete image; return new SimpleImage(width, height, target_format, out_pixels); }
void GraphicString::Align(unsigned long mode, const AgmdMaths::Rectangle& rect) { ivec2 pSize = GetPixelSize(); /* if (mode & ALIGN_RIGHT) { m_Position.x = rect.Right() - pSize.x; } else if (mode & ALIGN_HCENTER) { m_Position.x = rect.Left() + (rect.Width() - pSize.x) / 2; } else { m_Position.x = rect.Left(); } if (mode & ALIGN_BOTTOM) { m_Position.y = rect.Bottom() - pSize.y; } else if (mode & ALIGN_VCENTER) { m_Position.y = rect.Top() + (rect.Height() - pSize.y) / 2; } else { m_Position.y = rect.Top(); }*/ }
Bitmap::Bitmap(vector<Byte> &&data, const Size &size) : m_data(std::move(data)), m_size(size) { if (m_data.size() != m_size.GetArea() * GetPixelSize()) { throw new invalid_argument("[Bitmap::Bitmap] Size mismatch"); } }
COGLTexture::COGLTexture(uint32 dwWidth, uint32 dwHeight, TextureUsage usage) : CTexture(dwWidth,dwHeight,usage), m_glInternalFmt(GL_RGBA) { // FIXME: If usage is AS_RENDER_TARGET, we need to create pbuffer instead of regular texture m_dwTextureFmt = TEXTURE_FMT_A8R8G8B8; // Always use 32bit to load texture glGenTextures( 1, &m_dwTextureName ); OPENGL_CHECK_ERRORS; // Make the width and height be the power of 2 uint32 w; for (w = 1; w < dwWidth; w <<= 1); m_dwCreatedTextureWidth = w; for (w = 1; w < dwHeight; w <<= 1); m_dwCreatedTextureHeight = w; if (dwWidth*dwHeight > 256*256) TRACE4("Large texture: (%d x %d), created as (%d x %d)", dwWidth, dwHeight,m_dwCreatedTextureWidth,m_dwCreatedTextureHeight); m_fYScale = (float)m_dwCreatedTextureHeight/(float)m_dwHeight; m_fXScale = (float)m_dwCreatedTextureWidth/(float)m_dwWidth; m_pTexture = malloc(m_dwCreatedTextureWidth * m_dwCreatedTextureHeight * GetPixelSize()); switch( options.textureQuality ) { case TXT_QUALITY_DEFAULT: if( options.colorQuality == TEXTURE_FMT_A4R4G4B4 ) m_glInternalFmt = GL_RGBA4; break; case TXT_QUALITY_32BIT: break; case TXT_QUALITY_16BIT: m_glInternalFmt = GL_RGBA4; break; }; #ifndef USE_GLES m_glFmt = GL_BGRA; m_glType = GL_UNSIGNED_INT_8_8_8_8_REV; #else m_glInternalFmt = m_glFmt = COGLGraphicsContext::Get()->IsSupportTextureFormatBGRA() ? GL_BGRA_EXT : GL_RGBA; m_glType = GL_UNSIGNED_BYTE; #endif LOG_TEXTURE(TRACE2("New texture: (%d, %d)", dwWidth, dwHeight)); // We create the OGL texture here and will use glTexSubImage2D to increase performance. glBindTexture(GL_TEXTURE_2D, m_dwTextureName); OPENGL_CHECK_ERRORS; glTexImage2D(GL_TEXTURE_2D, 0, m_glInternalFmt, m_dwCreatedTextureWidth, m_dwCreatedTextureHeight, 0, m_glFmt, m_glType, NULL); OPENGL_CHECK_ERRORS; }
STDMETHODIMP_( void ) CComRenderTarget::BeginDraw() { std::shared_ptr< CContext > context = GetContext(); context->MakeCurrent( context->GetDC() ); m_frameBuffer.Bind( GL2D_GL_FRAMEBUFFER_MODE_DRAW ); glDrawBuffer( GL_BACK ); context->Disable( GL_DEPTH_TEST ); GL2D_SIZE_U size = GetPixelSize(); context->Viewport( 0, 0, size.width, size.height ); context->Ortho( 0, 1, 0, 1, 0, 1 ); context->LoadIdentity(); }
COR_EXPORT(Image*) CorFlipImage( Image* image, int coordinate_axis) { COR_GUARD("CorFlipImage"); // if we don't have an image, don't flip. if (!image) { return 0; } COR_LOG("Doing the flip..."); const int width = image->getWidth(); const int height = image->getHeight(); byte* pixels = (byte*)image->getPixels(); const PixelFormat pixel_format = image->getFormat(); const int pixel_size = GetPixelSize(pixel_format); // flip about the X axis if (coordinate_axis & CA_X) { byte* row = new byte[width * pixel_size]; for (int h = 0; h < height / 2; ++h) { byte* top = pixels + h * width * pixel_size; byte* bot = pixels + (height - h - 1) * width * pixel_size; std::memcpy(row, top, width * pixel_size); std::memcpy(top, bot, width * pixel_size); std::memcpy(bot, row, width * pixel_size); } delete[] row; } // flip about the Y axis if (coordinate_axis & CA_Y) { for (int h = 0; h < height; ++h) { byte* row = pixels + h * width * pixel_size; for (int w = 0; w < width / 2; ++w) { byte* left = row + w * pixel_size; byte* right = row + (width - w - 1) * pixel_size; for (int b = 0; b < pixel_size; ++b) { std::swap(left[b], right[b]); } } } } return image; }
void OBSQTDisplay::resizeEvent(QResizeEvent *event) { QWidget::resizeEvent(event); CreateDisplay(); if (isVisible() && display) { QSize size = GetPixelSize(this); obs_display_resize(display, size.width(), size.height()); } emit DisplayResized(); }
void RichObject::InitSize(int cx, int cy, void *context) { Size sz; Size phsz = GetPixelSize(); if(cx || cy) sz = GetRatioSize(phsz, cx, cy); else sz = phsz; if(sz.cx > 2000 || sz.cy > 2000) sz = sz.cx > sz.cy ? GetRatioSize(phsz, 2000, 0) : GetRatioSize(phsz, 0, 2000); SetSize(sz); }
bool ScreenProjection::operator!=(const ScreenProjection& _Proj) const { if ( _Zoom != _Proj._Zoom || _Origin != _Proj._Origin || fabs(_Angle - _Proj._Angle) >= 0.5 ) { return true; } double offset; DistanceBearing(_PanLat, _PanLon, _Proj._PanLat, _Proj._PanLon, &offset, NULL); return (offset >= GetPixelSize()); }
Size RichObjectType::StdDefaultSize(const Value& data, Size maxsize, void * context) const { if(IsNull(data)) return Size(0, 0); Size psz = GetPhysicalSize(data, context); if((psz.cx | psz.cy) == 0) psz = 625 * GetPixelSize(data, context) / 100; Size sz; for(int i = 1; i < 10000; i++) { sz = psz / i; if(sz.cx <= maxsize.cx && sz.cy <= maxsize.cy) break; } return sz; }
bool COGLTexture::StartUpdate(DrawInfo *di) { if (m_pTexture == NULL) return false; di->dwHeight = (uint16_t)m_dwHeight; di->dwWidth = (uint16_t)m_dwWidth; di->dwCreatedHeight = m_dwCreatedTextureHeight; di->dwCreatedWidth = m_dwCreatedTextureWidth; di->lpSurface = m_pTexture; di->lPitch = GetPixelSize()*m_dwCreatedTextureWidth; return true; }
void OBSQTDisplay::CreateDisplay() { if (display/* || !windowHandle()->isExposed()*/) return; QSize size = GetPixelSize(this); gs_init_data info = {}; info.cx = size.width(); info.cy = size.height(); info.format = GS_RGBA; info.zsformat = GS_ZS_NONE; QTToGSWindow(winId(), info.window); display = obs_display_create(&info); emit DisplayCreated(this); }
COGLTexture::COGLTexture(uint32_t dwWidth, uint32_t dwHeight, TextureUsage usage) : CTexture(dwWidth,dwHeight,usage), m_glFmt(GL_RGBA) { // FIXME: If usage is AS_RENDER_TARGET, we need to create pbuffer instead of regular texture m_dwTextureFmt = TEXTURE_FMT_A8R8G8B8; // Always use 32bit to load texture glGenTextures( 1, &m_dwTextureName ); OPENGL_CHECK_ERRORS; // Make the width and height be the power of 2 uint32_t w; for (w = 1; w < dwWidth; w <<= 1); m_dwCreatedTextureWidth = w; for (w = 1; w < dwHeight; w <<= 1); m_dwCreatedTextureHeight = w; if (dwWidth*dwHeight > 256*256) TRACE4("Large texture: (%d x %d), created as (%d x %d)", dwWidth, dwHeight,m_dwCreatedTextureWidth,m_dwCreatedTextureHeight); m_fYScale = (float)m_dwCreatedTextureHeight/(float)m_dwHeight; m_fXScale = (float)m_dwCreatedTextureWidth/(float)m_dwWidth; m_pTexture = malloc(m_dwCreatedTextureWidth * m_dwCreatedTextureHeight * GetPixelSize()); switch( options.textureQuality ) { case TXT_QUALITY_DEFAULT: if( options.colorQuality == TEXTURE_FMT_A4R4G4B4 ) m_glFmt = GL_RGBA4; break; case TXT_QUALITY_32BIT: break; case TXT_QUALITY_16BIT: m_glFmt = GL_RGBA4; break; }; LOG_TEXTURE(TRACE2("New texture: (%d, %d)", dwWidth, dwHeight)); glBindTexture(GL_TEXTURE_2D, m_dwTextureName); glTexImage2D(GL_TEXTURE_2D, 0, m_glFmt, m_dwCreatedTextureWidth, m_dwCreatedTextureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_pTexture); }
void DisplayerImpl::DrawDanmakuItem(DanmakuRef item, time_t current, DanmakuConfig* config) { if (!mHasBackend) return; if (!mInRendering) return; if (mNeedRecreateBitmap) { config->BitmapValidFlag++; mNeedRecreateBitmap = false; } if (item.Get() == nullptr) return; auto rect = item->GetRectAtTime(mOuter, current); weak_ptr<Renderable> r = item->GetRenderable(); shared_ptr<Renderable> renderable = r.lock(); if (renderable == nullptr) return; if (!renderable->HasBitmap(config)) { renderable->BuildBitmap(mOuter, config); } auto bitmap = renderable->GetBitmap(); if (bitmap == nullptr) return; float left = std::roundf(rect.left); float top = std::roundf(rect.top); D2D1_SIZE_U size = bitmap->GetPixelSize(); D2D1_RECT_F dest = D2D1::RectF( left, top, left + size.width, top + size.height ); mDeviceContext->DrawBitmap(bitmap.Get(), dest, config->CompositionOpacity, D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR); }
Image* ExpandPalette(Image* image) { COR_GUARD("ExpandPalette()"); // assert isPalettized(image->getFormat()) const int width = image->getWidth(); const int height = image->getHeight(); const byte* in = (byte*)image->getPixels(); const PixelFormat palette_format = image->getPaletteFormat(); const int pixel_size = GetPixelSize(palette_format); const byte* palette = (byte*)image->getPalette(); byte* pixels = new byte[width * height * pixel_size]; byte* out = pixels; for (int i = 0; i < width * height; ++i) { std::memcpy(out, palette + (*in) * pixel_size, pixel_size); out += pixel_size; ++in; } delete image; return new SimpleImage(width, height, palette_format, pixels); }
bool wxFontBase::operator==(const wxFont& font) const { // either it is the same font, i.e. they share the same common data or they // have different ref datas but still describe the same font return IsSameAs(font) || ( IsOk() == font.IsOk() && GetPointSize() == font.GetPointSize() && // in wxGTK1 GetPixelSize() calls GetInternalFont() which uses // operator==() resulting in infinite recursion so we can't use it // in that port #if !defined(__WXGTK__) || defined(__WXGTK20__) GetPixelSize() == font.GetPixelSize() && #endif GetFamily() == font.GetFamily() && GetStyle() == font.GetStyle() && GetWeight() == font.GetWeight() && GetUnderlined() == font.GetUnderlined() && GetFaceName().IsSameAs(font.GetFaceName(), false) && GetEncoding() == font.GetEncoding() ); }
void VideoEngine::DrawLine(float x1, float y1, float x2, float y2, float width, const Color &color) { GLfloat vert_coords[] = { x1, y1, x2, y2 }; EnableBlending(); DisableTexture2D(); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // Normal blending glPushAttrib(GL_LINE_WIDTH); float pixel_width, pixel_height; GetPixelSize(pixel_width, pixel_height); glLineWidth(width * pixel_height); EnableVertexArray(); DisableColorArray(); DisableTextureCoordArray(); glColor4fv((GLfloat *)color.GetColors()); glVertexPointer(2, GL_FLOAT, 0, vert_coords); glDrawArrays(GL_LINES, 0, 2); glPopAttrib(); // GL_LINE_WIDTH }
void plDynamicTextMap::Swap( plDynamicTextMap *other ) { // We only do this if the two are the same size, color depth, etc if( other->GetWidth() != GetWidth() || other->GetHeight() != GetHeight() || other->GetPixelSize() != GetPixelSize() ) return; // Swap image pointers void *ptr = other->fImage; other->fImage = fImage; fImage = ptr; // Invalidate both device refs (don't risk swapping THOSE) if( GetDeviceRef() != nil ) GetDeviceRef()->SetDirty( true ); if( other->GetDeviceRef() != nil ) other->GetDeviceRef()->SetDirty( true ); // Swap DTMap info SWAP_ME( bool, fHasAlpha, other->fHasAlpha ); SWAP_ME( bool, fShadowed, other->fShadowed ); SWAP_ME( Justify, fJustify, other->fJustify ); SWAP_ME( char *, fFontFace, other->fFontFace ); SWAP_ME( uint16_t, fFontSize, other->fFontSize ); SWAP_ME( uint8_t, fFontFlags, other->fFontFlags ); SWAP_ME( bool, fFontAntiAliasRGB, other->fFontAntiAliasRGB ); SWAP_ME( hsColorRGBA, fFontColor, other->fFontColor ); SWAP_ME( bool, fFontBlockRGB, other->fFontBlockRGB ); SWAP_ME( bool, fFontBlockRGB, other->fFontBlockRGB ); SWAP_ME( bool, fFontBlockRGB, other->fFontBlockRGB ); SWAP_ME( bool, fFontBlockRGB, other->fFontBlockRGB ); SWAP_ME( plFont *, fCurrFont, other->fCurrFont ); SWAP_ME( uint32_t *, fInitBuffer, other->fInitBuffer ); }
//------------------------------------------------------------------------------ void CGUIWgtParticle2D::RefreshSelf() { CGUIWidget::RefreshSelf(); m_aOffsetMatrix.setTrans( CGUIVector3( GetPixelSize().GetWidth() * m_aParticleOffset.x, GetPixelSize().GetHeight() * m_aParticleOffset.y, 0.0f )); }
// There are reasons to create this function. D3D will only create surface of width and height // as 2's pow, for example, N64's 20x14 image, D3D will create a 32x16 surface. // When we using such a surface as D3D texture, and the U and V address is for the D3D surface // width and height. It is still OK if the U and V addr value is less than the real image within // the D3D surface. But we will have problems if the U and V addr value is larger than it, or even // large then 1.0. // In such a case, we need to scale the image to the D3D surface dimension, to ease the U/V addr // limition void CTexture::ScaleImageToSurface(bool scaleS, bool scaleT) { uint8 g_ucTempBuffer[1024*1024*4]; if( scaleS==false && scaleT==false) return; // If the image is not scaled, call this function to scale the real image to // the D3D given dimension uint32 width = scaleS ? m_dwWidth : m_dwCreatedTextureWidth; uint32 height = scaleT ? m_dwHeight : m_dwCreatedTextureHeight; uint32 xDst, yDst; uint32 xSrc, ySrc; DrawInfo di; if (!StartUpdate(&di)) { return; } int pixSize = GetPixelSize(); // Copy across from the temp buffer to the surface switch (pixSize) { case 4: { memcpy((uint8*)g_ucTempBuffer, (uint8*)(di.lpSurface), m_dwHeight*m_dwCreatedTextureWidth*4); uint32 * pDst; uint32 * pSrc; for (yDst = 0; yDst < m_dwCreatedTextureHeight; yDst++) { // ySrc ranges from 0..m_dwHeight // I'd rather do this but sometimes very narrow (i.e. 1 pixel) // surfaces are created which results in /0... //ySrc = (yDst * (m_dwHeight-1)) / (d3dTextureHeight-1); ySrc = (uint32)((yDst * height) / m_dwCreatedTextureHeight+0.49f); pSrc = (uint32*)((uint8*)g_ucTempBuffer + (ySrc * m_dwCreatedTextureWidth * 4)); pDst = (uint32*)((uint8*)di.lpSurface + (yDst * di.lPitch)); for (xDst = 0; xDst < m_dwCreatedTextureWidth; xDst++) { xSrc = (uint32)((xDst * width) / m_dwCreatedTextureWidth+0.49f); pDst[xDst] = pSrc[xSrc]; } } } break; case 2: { memcpy((uint8*)g_ucTempBuffer, (uint8*)(di.lpSurface), m_dwHeight*m_dwCreatedTextureWidth*2); uint16 * pDst; uint16 * pSrc; for (yDst = 0; yDst < m_dwCreatedTextureHeight; yDst++) { // ySrc ranges from 0..m_dwHeight ySrc = (yDst * height) / m_dwCreatedTextureHeight; pSrc = (uint16*)((uint8*)g_ucTempBuffer + (ySrc * m_dwCreatedTextureWidth * 2)); pDst = (uint16*)((uint8*)di.lpSurface + (yDst * di.lPitch)); for (xDst = 0; xDst < m_dwCreatedTextureWidth; xDst++) { xSrc = (xDst * width) / m_dwCreatedTextureWidth; pDst[xDst] = pSrc[xSrc]; } } } break; } EndUpdate(&di); if( scaleS ) m_bScaledS = true; if( scaleT ) m_bScaledT = true; }
bool DecodePNG ( Image& aImage, size_t aBufferSize, const void* aBuffer ) { if ( png_sig_cmp ( static_cast<uint8_t*> ( const_cast<void*> ( aBuffer ) ), 0, 8 ) != 0 ) { return false; } try { png_structp png_ptr = png_create_read_struct ( PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr ); if ( png_ptr == nullptr ) { throw std::runtime_error ( "png_create_read_struct failed." ); } png_infop info_ptr = png_create_info_struct ( png_ptr ); if ( info_ptr == nullptr ) { throw std::runtime_error ( "png_create_info_struct failed." ); } if ( setjmp ( png_jmpbuf ( png_ptr ) ) ) { throw std::runtime_error ( "Error during init_io." ); } png_read_memory_struct read_memory_struct = {static_cast<const uint8_t*> ( aBuffer ), static_cast<const uint8_t*> ( aBuffer ) + 8, static_cast<png_size_t> ( aBufferSize * sizeof ( uint8_t ) ) }; png_set_read_fn ( png_ptr, &read_memory_struct, png_read_memory_data ); png_set_sig_bytes ( png_ptr, 8 ); png_read_info ( png_ptr, info_ptr ); uint32_t width = png_get_image_width ( png_ptr, info_ptr ); uint32_t height = png_get_image_height ( png_ptr, info_ptr ); png_byte color_type = png_get_color_type ( png_ptr, info_ptr ); png_byte bit_depth = png_get_bit_depth ( png_ptr, info_ptr ); Image::ImageFormat format; Image::ImageType type; if ( ( color_type == PNG_COLOR_TYPE_RGB ) || ( color_type == PNG_COLOR_TYPE_RGBA ) ) { format = ( color_type == PNG_COLOR_TYPE_RGB ) ? Image::ImageFormat::RGB : Image::ImageFormat::RGBA; type = ( bit_depth == 8 ) ? Image::ImageType::UNSIGNED_BYTE : Image::ImageType::UNSIGNED_SHORT; } else { throw std::runtime_error ( "PNG image color type not supported...yet" ); } /*int number_of_passes =*/ png_set_interlace_handling ( png_ptr ); png_read_update_info ( png_ptr, info_ptr ); /* read file */ if ( setjmp ( png_jmpbuf ( png_ptr ) ) ) { throw std::runtime_error ( "Error during read_image." ); } // -------------------------------------- png_size_t rowbytes = png_get_rowbytes ( png_ptr, info_ptr ); std::vector<uint8_t*> row_pointers ( sizeof ( png_bytep ) * height ); std::vector<uint8_t> pixels ( width * height * GetPixelSize ( format, type ) ); for ( png_uint_32 y = 0; y < height; ++y ) { row_pointers[y] = pixels.data() + ( rowbytes * y ); } // -------------------------------------- png_read_image ( png_ptr, row_pointers.data() ); png_destroy_read_struct ( &png_ptr, &info_ptr, ( png_infopp ) nullptr ); aImage.Initialize ( width, height, format, type, pixels.data() ); } catch ( std::runtime_error& e ) { std::cout << e.what() << std::endl; return false; } return true; }
Size RichObjectType::GetPixelSize(const Value& data, void *context) const { return GetPixelSize(data); }
bool SplitPicture::StartSplit() { //清空文件列表 save_paths_.clear(); //打开源图片 boost::filesystem::ifstream _src_bmp(picture_name_, std::ios_base::in | std::ios_base::binary);//源图片 if(!_src_bmp) { std::cout<<"open file \""<<picture_name_<<"\" failed!"; return false; } const BMFH _file_header_ = GetBMFH(picture_name_.string().c_str()); const BMIH _info_header_ = GetBMIH(picture_name_.string().c_str()); if(_info_header_.biBitCount != 24) { return false; } //分割图片 const unsigned char _piexl_size = GetPixelSize(_info_header_.biBitCount);//一个像素的大小 const std::string _dest_path = AssignPath();//获取分割图片要保存的路径名 const size_t _src_width = _info_header_.biWidth;//源图宽度(单位:像素) /*const */size_t _src_width_size = _src_width * _piexl_size;//源图宽度(单位:字节) int _BytePaddingPerRow = 4 - (_src_width_size)%4; if(_BytePaddingPerRow == 4) { _BytePaddingPerRow = 0; } _src_width_size += _BytePaddingPerRow; const size_t _src_height = _info_header_.biHeight;//源图高度(单位:像素) //const size_t _src_height_size = _src_height * _piexl_size;//源图高度(单位:字节) const size_t _per_width = _src_width / row_;//分割图平均宽度(单位:像素) const size_t _per_height = _src_height / column_;//分割图平均高度(单位:像素) char* _read_data = new char[std::max(_per_width, (_src_width - _per_width * (row_ - 1))) * _piexl_size]; for(unsigned short r = 0; r < row_; ++r) { for(unsigned short c = 0; c < column_; ++c) { std::stringstream _ss; //生成新的图像文件名称 _ss << _dest_path << "_" << column_ - c << "_" << r + 1 << ".bmp"; Path _save_path(_ss.str()); boost::filesystem::ofstream _dest_bmp(_save_path, std::ios_base::out | std::ios_base::binary);//输出图像文件 //const size_t _src_y = c * _per_height; const size_t _dest_width = r == (row_ - 1) ? (_src_width - _per_width * r) : _per_width; const size_t _dest_width_size = _piexl_size * _dest_width; const size_t _dest_height = c == (column_ - 1) ? (_src_height - _per_height * c) : _per_height; //更新文件头并写入 int BytePaddingPerRow = 4 - (_dest_width_size)%4; if(BytePaddingPerRow == 4) { BytePaddingPerRow = 0; } byte _zero_data[3] = {0}; size_t dActualBytesPerRow = _dest_width_size + BytePaddingPerRow; size_t dTotalPixelBytes = _dest_height * dActualBytesPerRow; //size_t dPaletteSize = 0; //if( _info_header_.biBitCount == 1 || _info_header_.biBitCount == 4 || _info_header_.biBitCount == 8 ) //{ // dPaletteSize = IntPow(2, _info_header_.biBitCount) * 4; //} // leave some room for 16-bit masks //if( _info_header_.biBitCount == 16 ) //{ dPaletteSize = 3*4; } size_t dTotalFileSize = 14 + 40 + dTotalPixelBytes;// + dPaletteSize; // write the file header BMFH _new_file_header; _new_file_header.bfSize = dTotalFileSize; _new_file_header.bfReserved1 = 0; _new_file_header.bfReserved2 = 0; _new_file_header.bfOffBits = 14 + 40;// + dPaletteSize; BMIH _new_info_header = _info_header_; _new_info_header.biSize = 40; _new_info_header.biWidth = _dest_width; _new_info_header.biHeight = _dest_height; _new_info_header.biSizeImage = (ebmpDWORD) dTotalPixelBytes; WtireBmpHeader(_dest_bmp, _new_file_header, _new_info_header); const size_t _read_size = _dest_width * _piexl_size;//新图片每行的大小 const size_t _seek_data = _src_width_size - _read_size; const size_t _moved_data = _file_header_.bfOffBits + c * _per_height * _src_width_size + r * _per_width * _piexl_size; _src_bmp.seekg(_moved_data, std::ios_base::beg); _dest_bmp.seekp(_new_file_header.bfOffBits, std::ios_base::beg); #if(SHOW_TIME_PASSED) boost::posix_time::ptime _start_time = boost::posix_time::microsec_clock::universal_time(); #endif//SHOW_TIME_PASSED for(size_t i = 0; i < _dest_height; ++i) { _src_bmp.read(_read_data, _read_size); _dest_bmp.write(_read_data, _read_size); _dest_bmp.write((char*)_zero_data, BytePaddingPerRow); _src_bmp.seekg(_seek_data, std::ios_base::cur); } //if(_zero_data) delete[] _zero_data; _dest_bmp.close(); _ss.str(""); _ss<<column_ - c << "," << r + 1; save_paths_.insert(FileNameMap::value_type(_ss.str(), _save_path)); #if(SHOW_TIME_PASSED) boost::posix_time::ptime _end_time = boost::posix_time::microsec_clock::universal_time(); boost::posix_time::time_duration _elp_time = _end_time - _start_time; std::cout<<_elp_time.total_milliseconds()<<"ms\n"; #endif//SHOW_TIME_PASSED } } delete[] _read_data; return true; }
//------------------------------------------------------------------------------ void CGUIWgtParticle2D::SetParticleOffset( const CGUIVector2& rOffset) { m_aParticleOffset = rOffset; m_aOffsetMatrix.setTrans( CGUIVector3( GetPixelSize().GetWidth() * m_aParticleOffset.x, GetPixelSize().GetHeight() * m_aParticleOffset.y, 0.0f )); }
/* `从NVIDIA网站上下载, 做了一些修改让它也可以读取非压缩的DDS格式, 例如HDR浮点数格式贴图.` */ DDS_IMAGE_DATA* loadDDSTextureFile( const char *filename ) { DDS_IMAGE_DATA *pDDSImageData = NULL; DDSURFACEDESC2 ddsd; char filecode[4]; FILE *pFile = NULL; int factor = 1; int bufferSize = 0; // `打开档案` pFile = fopen( filename, "rb" ); if( pFile == NULL ) { #ifdef _DEBUG printf( "loadDDSTextureFile couldn't find, or failed to load \"%s\"\n", filename ); #endif return NULL; } // `确认它是个DDS档` fread( filecode, 1, 4, pFile ); if( strncmp( filecode, "DDS ", 4 ) != 0 ) { printf( "The file \"%s\" doesn't appear to be a valid .dds file!\n", filename ); fclose( pFile ); return NULL; } // `获得图形格式` fread( &ddsd, sizeof(ddsd), 1, pFile ); pDDSImageData = (DDS_IMAGE_DATA*) malloc(sizeof(DDS_IMAGE_DATA)); memset( pDDSImageData, 0, sizeof(DDS_IMAGE_DATA) ); memcpy(&pDDSImageData->ddsd, &ddsd, sizeof(DDSURFACEDESC2)); pDDSImageData->bBlock = false; // // This .dds loader supports the loading of compressed formats DXT1, DXT3 and DXT5. // switch( ddsd.ddpfPixelFormat.dwFourCC ) { case FOURCC_DXT1: // `DXT1压缩比为8:1` pDDSImageData->format = D3DFMT_DXT1; factor = 2; pDDSImageData->bBlock = true; break; case FOURCC_DXT3: // `DXT3压缩比为4:1` pDDSImageData->format = D3DFMT_DXT3; factor = 4; pDDSImageData->bBlock = true; break; case FOURCC_DXT5: // `DXT5压缩比为4:1` pDDSImageData->format = D3DFMT_DXT5; factor = 4; pDDSImageData->bBlock = true; break; default: // `DDS也可以存储其它非压缩格式` if ( ddsd.ddpfPixelFormat.dwFlags & DDPF_FOURCC ) { pDDSImageData->format = ddsd.ddpfPixelFormat.dwFourCC; if ( ddsd.ddpfPixelFormat.dwRGBBitCount ) { pDDSImageData->PixelSize = ddsd.ddpfPixelFormat.dwRGBBitCount/8; } else { pDDSImageData->PixelSize = GetPixelSize((D3DFORMAT)ddsd.ddpfPixelFormat.dwFourCC); } } break; } pDDSImageData->cubeMap = (ddsd.ddsCaps.dwCaps & DDSCAPS_COMPLEX) && (ddsd.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP); // // `预估图片占用内存的大小` // if( ddsd.dwLinearSize == 0 ) { int current_pos = ftell(pFile); fseek(pFile, 0, SEEK_END); int end_pos = ftell(pFile); fseek(pFile, current_pos, SEEK_SET); bufferSize = end_pos - current_pos; } else { if( ddsd.dwMipMapCount > 1 ) bufferSize = ddsd.dwLinearSize * factor; else bufferSize = ddsd.dwLinearSize; } pDDSImageData->pixels = (unsigned char*)malloc(bufferSize * sizeof(unsigned char)); fread( pDDSImageData->pixels, 1, bufferSize, pFile ); // Close the file fclose( pFile ); pDDSImageData->width = ddsd.dwWidth; pDDSImageData->height = ddsd.dwHeight; pDDSImageData->depth = ddsd.dwDepth; pDDSImageData->BufferSize = bufferSize; pDDSImageData->numMipMaps = ddsd.dwMipMapCount==0 ? 1 : ddsd.dwMipMapCount; return pDDSImageData; }