mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-10 18:51:21 +03:00
0023272: Image comparison algorithm
A new class Image_Diff for comparison of images and a draw-command "diffimage", which compares 2 images. Image_PixMap redesigned to provide interface for low-level image operations. New Image_AlienPixMap class now intended for Save/Load functionality. Aspect_PixMap class dropped. Xw_PixMap and WNT_PixMap classes now do not inherit from Aspect_PixMap and deprecated. ToPixMap methods now retrieve Image_PixMap as argument. Conflicts: src/ViewerTest/ViewerTest.cxx Remarks applied Fix compilation (correct merging error) Eliminated Aspect <-> Image cyclic dependency Fixed GIF dump in case of BGR32 image format
This commit is contained in:
parent
567148d8f4
commit
692613e554
@ -348,10 +348,6 @@ is
|
|||||||
deferred class Window;
|
deferred class Window;
|
||||||
---Purpose: Defines a window.
|
---Purpose: Defines a window.
|
||||||
---Category: Classes
|
---Category: Classes
|
||||||
|
|
||||||
deferred class PixMap;
|
|
||||||
---Purpose: Defines a pixmap(bitmap)
|
|
||||||
---Category: Classes
|
|
||||||
|
|
||||||
deferred class GraphicDevice;
|
deferred class GraphicDevice;
|
||||||
---Purpose: Defines a physical graphic device allowing to
|
---Purpose: Defines a physical graphic device allowing to
|
||||||
|
@ -1,92 +0,0 @@
|
|||||||
-- Created on: 1999-10-14
|
|
||||||
-- Created by: VKH
|
|
||||||
-- Copyright (c) 1999 Matra Datavision
|
|
||||||
-- Copyright (c) 1999-2012 OPEN CASCADE SAS
|
|
||||||
--
|
|
||||||
-- The content of this file is subject to the Open CASCADE Technology Public
|
|
||||||
-- License Version 6.5 (the "License"). You may not use the content of this file
|
|
||||||
-- except in compliance with the License. Please obtain a copy of the License
|
|
||||||
-- at http://www.opencascade.org and read it completely before using this file.
|
|
||||||
--
|
|
||||||
-- The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
|
|
||||||
-- main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
|
|
||||||
--
|
|
||||||
-- The Original Code and all software distributed under the License is
|
|
||||||
-- distributed on an "AS IS" basis, without warranty of any kind, and the
|
|
||||||
-- Initial Developer hereby disclaims all such warranties, including without
|
|
||||||
-- limitation, any warranties of merchantability, fitness for a particular
|
|
||||||
-- purpose or non-infringement. Please see the License for the specific terms
|
|
||||||
-- and conditions governing the rights and limitations under the License.
|
|
||||||
|
|
||||||
-- Updated: GG IMP100701 Add the "depth" field and method
|
|
||||||
-- to the pixmap object.
|
|
||||||
|
|
||||||
|
|
||||||
deferred class PixMap from Aspect
|
|
||||||
inherits
|
|
||||||
TShared from MMgt
|
|
||||||
---Purpose: This class allows the definition of a pixmap(bitmap)
|
|
||||||
|
|
||||||
uses
|
|
||||||
Handle from Aspect,
|
|
||||||
Color from Quantity
|
|
||||||
|
|
||||||
raises
|
|
||||||
PixmapDefinitionError from Aspect,
|
|
||||||
PixmapError from Aspect
|
|
||||||
is
|
|
||||||
Initialize ( aWidth, anHeight : Integer from Standard;
|
|
||||||
aDepth : Integer from Standard );
|
|
||||||
---Level: Public
|
|
||||||
---Purpose: Initializes the datas of a pixmap with a pixel size
|
|
||||||
-- <aWidth>,<anHeight> and depth.
|
|
||||||
|
|
||||||
Destroy ( me : mutable )
|
|
||||||
raises PixmapError from Aspect is deferred;
|
|
||||||
---Level: Advanced
|
|
||||||
---Purpose: Destroy the pixmap
|
|
||||||
---Category: Methods to modify the class definition
|
|
||||||
|
|
||||||
Dump ( me ; aFilename : CString from Standard;
|
|
||||||
aGammaValue: Real from Standard = 1.0 )
|
|
||||||
returns Boolean
|
|
||||||
raises PixmapError from Aspect is deferred;
|
|
||||||
---Level: Advanced
|
|
||||||
---Purpose:
|
|
||||||
-- Dumps the Bitmap to an image file with
|
|
||||||
-- an optional gamma correction value
|
|
||||||
-- and returns TRUE if the dump occurs normaly.
|
|
||||||
---Trigger: Raises if pixmap is not defined properly
|
|
||||||
|
|
||||||
PixelColor ( me : in;
|
|
||||||
theX, theY : in Integer from Standard )
|
|
||||||
returns Color from Quantity is deferred;
|
|
||||||
---Purpose:
|
|
||||||
-- Returns the pixel color.
|
|
||||||
|
|
||||||
----------------------------
|
|
||||||
-- Category: Inquire methods
|
|
||||||
----------------------------
|
|
||||||
|
|
||||||
PixmapID ( me ) returns Handle from Aspect
|
|
||||||
is deferred;
|
|
||||||
---Level: Advanced
|
|
||||||
---Purpose: Returns the ID of the just created pixmap
|
|
||||||
---Category: Inquire methods
|
|
||||||
|
|
||||||
Size ( me ; aWidth, anHeight : out Integer from Standard )
|
|
||||||
is static;
|
|
||||||
---Level: Public
|
|
||||||
---Purpose: Returns the allocated pixmap's size in PIXEL
|
|
||||||
---Category: Inquire methods
|
|
||||||
|
|
||||||
Depth ( me ) returns Integer from Standard
|
|
||||||
is static;
|
|
||||||
---Level: Public
|
|
||||||
---Purpose: Returns the allocated pixmap's depth (planes number)
|
|
||||||
---Category: Inquire methods
|
|
||||||
fields
|
|
||||||
myWidth : Integer from Standard is protected;
|
|
||||||
myHeight : Integer from Standard is protected;
|
|
||||||
myDepth : Integer from Standard is protected;
|
|
||||||
end PixMap;
|
|
@ -1,52 +0,0 @@
|
|||||||
// Created on: 1999-10-14
|
|
||||||
// Created by: VKH
|
|
||||||
// Copyright (c) 1999 Matra Datavision
|
|
||||||
// Copyright (c) 1999-2012 OPEN CASCADE SAS
|
|
||||||
//
|
|
||||||
// The content of this file is subject to the Open CASCADE Technology Public
|
|
||||||
// License Version 6.5 (the "License"). You may not use the content of this file
|
|
||||||
// except in compliance with the License. Please obtain a copy of the License
|
|
||||||
// at http://www.opencascade.org and read it completely before using this file.
|
|
||||||
//
|
|
||||||
// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
|
|
||||||
// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
|
|
||||||
//
|
|
||||||
// The Original Code and all software distributed under the License is
|
|
||||||
// distributed on an "AS IS" basis, without warranty of any kind, and the
|
|
||||||
// Initial Developer hereby disclaims all such warranties, including without
|
|
||||||
// limitation, any warranties of merchantability, fitness for a particular
|
|
||||||
// purpose or non-infringement. Please see the License for the specific terms
|
|
||||||
// and conditions governing the rights and limitations under the License.
|
|
||||||
|
|
||||||
|
|
||||||
// Updated GG IMP100701 Add the "depth" field and method
|
|
||||||
// to the pixmap object.
|
|
||||||
|
|
||||||
|
|
||||||
//-Version
|
|
||||||
|
|
||||||
#include <Aspect_PixMap.ixx>
|
|
||||||
|
|
||||||
//-Constructor
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
Aspect_PixMap::Aspect_PixMap ( const Standard_Integer aWidth,
|
|
||||||
const Standard_Integer anHeight,
|
|
||||||
const Standard_Integer aDepth )
|
|
||||||
{
|
|
||||||
myWidth = aWidth;
|
|
||||||
myHeight = anHeight;
|
|
||||||
myDepth = aDepth;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
void Aspect_PixMap::Size ( Standard_Integer &aWidth,
|
|
||||||
Standard_Integer &anHeight ) const {
|
|
||||||
aWidth = myWidth;
|
|
||||||
anHeight = myHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
Standard_Integer Aspect_PixMap::Depth () const {
|
|
||||||
return myDepth;
|
|
||||||
}
|
|
||||||
|
|
@ -42,7 +42,6 @@ uses
|
|||||||
TypeOfResize from Aspect,
|
TypeOfResize from Aspect,
|
||||||
FillMethod from Aspect,
|
FillMethod from Aspect,
|
||||||
Handle from Aspect,
|
Handle from Aspect,
|
||||||
PixMap from Aspect,
|
|
||||||
Ratio from Quantity,
|
Ratio from Quantity,
|
||||||
Parameter from Quantity,
|
Parameter from Quantity,
|
||||||
NameOfColor from Quantity,
|
NameOfColor from Quantity,
|
||||||
@ -208,12 +207,6 @@ is
|
|||||||
-- or the area is out of the Window.
|
-- or the area is out of the Window.
|
||||||
raises WindowError from Aspect is deferred;
|
raises WindowError from Aspect is deferred;
|
||||||
|
|
||||||
ToPixMap ( me )
|
|
||||||
returns PixMap from Aspect
|
|
||||||
---Level : Public
|
|
||||||
---Purpose : dump the full contents of the window to a pixmap.
|
|
||||||
is deferred;
|
|
||||||
|
|
||||||
Load ( me ; aFilename : CString from Standard) returns Boolean
|
Load ( me ; aFilename : CString from Standard) returns Boolean
|
||||||
---Level: Advanced
|
---Level: Advanced
|
||||||
---Purpose: Loads the XWD file to this Window.
|
---Purpose: Loads the XWD file to this Window.
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
#include <Draw_Interpretor.hxx>
|
#include <Draw_Interpretor.hxx>
|
||||||
#include <Draw_Appli.hxx>
|
#include <Draw_Appli.hxx>
|
||||||
#include <TCollection_AsciiString.hxx>
|
#include <TCollection_AsciiString.hxx>
|
||||||
#include <Image_PixMap.hxx>
|
#include <Image_AlienPixMap.hxx>
|
||||||
|
|
||||||
extern Draw_Interpretor theCommands;
|
extern Draw_Interpretor theCommands;
|
||||||
extern Standard_Boolean Draw_VirtualWindows;
|
extern Standard_Boolean Draw_VirtualWindows;
|
||||||
@ -717,39 +717,44 @@ Standard_Boolean Draw_Window::Save (const char* theFileName) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// find the image
|
XVisualInfo aVInfo;
|
||||||
XImage* pximage = XGetImage (Draw_WindowDisplay, GetDrawable(),
|
if (XMatchVisualInfo (Draw_WindowDisplay, Draw_WindowScreen, 32, TrueColor, &aVInfo) == 0
|
||||||
0, 0, winAttr.width, winAttr.height,
|
&& XMatchVisualInfo (Draw_WindowDisplay, Draw_WindowScreen, 24, TrueColor, &aVInfo) == 0)
|
||||||
AllPlanes, ZPixmap);
|
|
||||||
if (pximage == NULL)
|
|
||||||
{
|
{
|
||||||
|
std::cerr << "24-bit TrueColor visual is not supported by server!\n";
|
||||||
return Standard_False;
|
return Standard_False;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (winAttr.visual->c_class == TrueColor)
|
Image_AlienPixMap anImage;
|
||||||
|
bool isBigEndian = Image_PixMap::IsBigEndianHost();
|
||||||
|
const Standard_Size aSizeRowBytes = Standard_Size(winAttr.width) * 4;
|
||||||
|
if (!anImage.InitTrash (isBigEndian ? Image_PixMap::ImgRGB32 : Image_PixMap::ImgBGR32,
|
||||||
|
Standard_Size(winAttr.width), Standard_Size(winAttr.height), aSizeRowBytes))
|
||||||
{
|
{
|
||||||
Standard_Byte* aDataPtr = (Standard_Byte* )pximage->data;
|
|
||||||
Handle(Image_PixMap) anImagePixMap = new Image_PixMap (aDataPtr,
|
|
||||||
pximage->width, pximage->height,
|
|
||||||
pximage->bytes_per_line,
|
|
||||||
pximage->bits_per_pixel,
|
|
||||||
Standard_True);
|
|
||||||
// destroy the image
|
|
||||||
XDestroyImage (pximage);
|
|
||||||
|
|
||||||
// save the image
|
|
||||||
return anImagePixMap->Dump (theFileName);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::cerr << "Visual Type not supported!";
|
|
||||||
// destroy the image
|
|
||||||
XDestroyImage (pximage);
|
|
||||||
return Standard_False;
|
return Standard_False;
|
||||||
}
|
}
|
||||||
|
anImage.SetTopDown (true);
|
||||||
|
|
||||||
|
XImage* anXImage = XCreateImage (Draw_WindowDisplay, aVInfo.visual,
|
||||||
|
32, ZPixmap, 0, (char* )anImage.ChangeData(), winAttr.width, winAttr.height, 32, int(aSizeRowBytes));
|
||||||
|
anXImage->bitmap_bit_order = anXImage->byte_order = (isBigEndian ? MSBFirst : LSBFirst);
|
||||||
|
if (XGetSubImage (Draw_WindowDisplay, GetDrawable(),
|
||||||
|
0, 0, winAttr.width, winAttr.height,
|
||||||
|
AllPlanes, ZPixmap, anXImage, 0, 0) == NULL)
|
||||||
|
{
|
||||||
|
anXImage->data = NULL;
|
||||||
|
XDestroyImage (anXImage);
|
||||||
|
return Standard_False;
|
||||||
|
}
|
||||||
|
|
||||||
|
// destroy the image
|
||||||
|
anXImage->data = NULL;
|
||||||
|
XDestroyImage (anXImage);
|
||||||
|
|
||||||
|
// save the image
|
||||||
|
return anImage.Save (theFileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
//function : ProcessEvent
|
//function : ProcessEvent
|
||||||
//purpose :
|
//purpose :
|
||||||
@ -1700,63 +1705,44 @@ void DrawWindow::Clear()
|
|||||||
/*--------------------------------------------------------*\
|
/*--------------------------------------------------------*\
|
||||||
| SaveBitmap
|
| SaveBitmap
|
||||||
\*--------------------------------------------------------*/
|
\*--------------------------------------------------------*/
|
||||||
static Standard_Boolean SaveBitmap (HBITMAP theHBitmap,
|
static Standard_Boolean SaveBitmap (HBITMAP theHBitmap,
|
||||||
const char* theFileName)
|
const char* theFileName)
|
||||||
{
|
{
|
||||||
// Copy data from HBITMAP
|
|
||||||
BITMAP aBitmap;
|
|
||||||
|
|
||||||
// Get informations about the bitmap
|
// Get informations about the bitmap
|
||||||
GetObject (theHBitmap, sizeof(BITMAP), (LPSTR )&aBitmap);
|
BITMAP aBitmap;
|
||||||
Standard_Integer aWidth = aBitmap.bmWidth;
|
if (GetObject (theHBitmap, sizeof(BITMAP), (LPSTR )&aBitmap) == 0)
|
||||||
Standard_Integer aHeight = aBitmap.bmHeight;
|
{
|
||||||
|
return Standard_False;
|
||||||
|
}
|
||||||
|
|
||||||
|
Image_AlienPixMap anImage;
|
||||||
|
const Standard_Size aSizeRowBytes = Standard_Size(aBitmap.bmWidth) * 4;
|
||||||
|
if (!anImage.InitTrash (Image_PixMap::ImgBGR32, Standard_Size(aBitmap.bmWidth), Standard_Size(aBitmap.bmHeight), aSizeRowBytes))
|
||||||
|
{
|
||||||
|
return Standard_False;
|
||||||
|
}
|
||||||
|
anImage.SetTopDown (false);
|
||||||
|
|
||||||
// Setup image data
|
// Setup image data
|
||||||
BITMAPINFOHEADER aBitmapInfo;
|
BITMAPINFOHEADER aBitmapInfo;
|
||||||
memset (&aBitmapInfo, 0, sizeof(BITMAPINFOHEADER));
|
memset (&aBitmapInfo, 0, sizeof(BITMAPINFOHEADER));
|
||||||
aBitmapInfo.biSize = sizeof(BITMAPINFOHEADER);
|
aBitmapInfo.biSize = sizeof(BITMAPINFOHEADER);
|
||||||
aBitmapInfo.biWidth = aWidth;
|
aBitmapInfo.biWidth = aBitmap.bmWidth;
|
||||||
aBitmapInfo.biHeight = aHeight; // positive means bottom-up!
|
aBitmapInfo.biHeight = aBitmap.bmHeight; // positive means bottom-up!
|
||||||
aBitmapInfo.biPlanes = 1;
|
aBitmapInfo.biPlanes = 1;
|
||||||
aBitmapInfo.biBitCount = 32;
|
aBitmapInfo.biBitCount = 32; // use 32bit for automatic word-alignment per row
|
||||||
aBitmapInfo.biCompression = BI_RGB;
|
aBitmapInfo.biCompression = BI_RGB;
|
||||||
|
|
||||||
Standard_Integer aBytesPerLine = aWidth * 4;
|
|
||||||
Standard_Byte* aDataPtr = new Standard_Byte[aBytesPerLine * aHeight];
|
|
||||||
|
|
||||||
// Copy the pixels
|
// Copy the pixels
|
||||||
HDC aDC = GetDC (NULL);
|
HDC aDC = GetDC (NULL);
|
||||||
Standard_Boolean isSuccess
|
Standard_Boolean isSuccess = GetDIBits (aDC, theHBitmap,
|
||||||
= GetDIBits (aDC, // handle to DC
|
0, // first scan line to set
|
||||||
theHBitmap, // handle to bitmap
|
aBitmap.bmHeight, // number of scan lines to copy
|
||||||
0, // first scan line to set
|
anImage.ChangeData(), // array for bitmap bits
|
||||||
aHeight, // number of scan lines to copy
|
(LPBITMAPINFO )&aBitmapInfo, // bitmap data info
|
||||||
aDataPtr, // array for bitmap bits
|
DIB_RGB_COLORS) != 0;
|
||||||
(LPBITMAPINFO )&aBitmapInfo, // bitmap data info
|
|
||||||
DIB_RGB_COLORS // RGB
|
|
||||||
) != 0;
|
|
||||||
|
|
||||||
if (isSuccess)
|
|
||||||
{
|
|
||||||
Handle(Image_PixMap) anImagePixMap = new Image_PixMap (aDataPtr,
|
|
||||||
aWidth, aHeight,
|
|
||||||
aBytesPerLine,
|
|
||||||
aBitmapInfo.biBitCount,
|
|
||||||
Standard_False); // bottom-up!
|
|
||||||
|
|
||||||
// Release dump memory here
|
|
||||||
delete[] aDataPtr;
|
|
||||||
|
|
||||||
// save the image
|
|
||||||
anImagePixMap->Dump (theFileName);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Release dump memory
|
|
||||||
delete[] aDataPtr;
|
|
||||||
}
|
|
||||||
ReleaseDC (NULL, aDC);
|
ReleaseDC (NULL, aDC);
|
||||||
return isSuccess;
|
return isSuccess && anImage.Save (theFileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*--------------------------------------------------------*\
|
/*--------------------------------------------------------*\
|
||||||
|
@ -53,3 +53,4 @@ Graphic3d_AspectText3d.cxx
|
|||||||
Graphic3d_WNTGraphicDevice.cxx
|
Graphic3d_WNTGraphicDevice.cxx
|
||||||
Graphic3d_NameOfFont.hxx
|
Graphic3d_NameOfFont.hxx
|
||||||
Graphic3d_PtrFrameBuffer.hxx
|
Graphic3d_PtrFrameBuffer.hxx
|
||||||
|
Graphic3d_BufferType.hxx
|
||||||
|
@ -329,6 +329,7 @@ is
|
|||||||
---------------------------
|
---------------------------
|
||||||
|
|
||||||
imported PrimitiveArray;
|
imported PrimitiveArray;
|
||||||
|
imported BufferType;
|
||||||
|
|
||||||
imported CBitFields20;
|
imported CBitFields20;
|
||||||
---Purpose: Defines the C structure
|
---Purpose: Defines the C structure
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 1999-2012 OPEN CASCADE SAS
|
// Copyright (c) 2012 OPEN CASCADE SAS
|
||||||
//
|
//
|
||||||
// The content of this file is subject to the Open CASCADE Technology Public
|
// The content of this file is subject to the Open CASCADE Technology Public
|
||||||
// License Version 6.5 (the "License"). You may not use the content of this file
|
// License Version 6.5 (the "License"). You may not use the content of this file
|
||||||
@ -15,15 +15,15 @@
|
|||||||
// purpose or non-infringement. Please see the License for the specific terms
|
// purpose or non-infringement. Please see the License for the specific terms
|
||||||
// and conditions governing the rights and limitations under the License.
|
// and conditions governing the rights and limitations under the License.
|
||||||
|
|
||||||
#ifndef _Image_HPrivateImage_HeaderFile
|
#ifndef _Graphic3d_BufferType_H__
|
||||||
#define _Image_HPrivateImage_HeaderFile
|
#define _Graphic3d_BufferType_H__
|
||||||
|
|
||||||
#include <NCollection_Handle.hxx>
|
//! Define buffers available for dump
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
Graphic3d_BT_RGB, //!< color buffer without alpha component
|
||||||
|
Graphic3d_BT_RGBA, //!< color buffer
|
||||||
|
Graphic3d_BT_Depth //!< depth buffer
|
||||||
|
} Graphic3d_BufferType;
|
||||||
|
|
||||||
// This typedef shadows the private image storage class
|
#endif // _Graphic3d_BufferType_H__
|
||||||
// Currently FreeImagePlus is used
|
|
||||||
|
|
||||||
class fipImage;
|
|
||||||
typedef NCollection_Handle<fipImage> Image_HPrivateImage;
|
|
||||||
|
|
||||||
#endif /*_Image_HPrivateImage_HeaderFile*/
|
|
@ -71,6 +71,7 @@ uses
|
|||||||
PlaneAngle from Quantity,
|
PlaneAngle from Quantity,
|
||||||
|
|
||||||
AlienImage from AlienImage,
|
AlienImage from AlienImage,
|
||||||
|
PixMap from Image,
|
||||||
|
|
||||||
Array1OfEdge from Aspect,
|
Array1OfEdge from Aspect,
|
||||||
CLayer2d from Aspect,
|
CLayer2d from Aspect,
|
||||||
@ -93,7 +94,7 @@ uses
|
|||||||
CPlane from Graphic3d,
|
CPlane from Graphic3d,
|
||||||
CStructure from Graphic3d,
|
CStructure from Graphic3d,
|
||||||
CView from Graphic3d,
|
CView from Graphic3d,
|
||||||
CRawBufferData from Image,
|
BufferType from Graphic3d,
|
||||||
Structure from Graphic3d,
|
Structure from Graphic3d,
|
||||||
TextPath from Graphic3d,
|
TextPath from Graphic3d,
|
||||||
TypeOfComposition from Graphic3d,
|
TypeOfComposition from Graphic3d,
|
||||||
@ -1008,8 +1009,9 @@ is
|
|||||||
---Purpose: Change offscreen FBO viewport.
|
---Purpose: Change offscreen FBO viewport.
|
||||||
|
|
||||||
BufferDump( me : mutable;
|
BufferDump( me : mutable;
|
||||||
view : CView from Graphic3d;
|
theCView : CView from Graphic3d;
|
||||||
buffer : in out CRawBufferData from Image )
|
theImage : in out PixMap from Image;
|
||||||
|
theBufferType : BufferType from Graphic3d )
|
||||||
returns Boolean from Standard
|
returns Boolean from Standard
|
||||||
is deferred;
|
is deferred;
|
||||||
---Purpose: Dump active rendering buffer into specified memory buffer.
|
---Purpose: Dump active rendering buffer into specified memory buffer.
|
||||||
|
@ -6,5 +6,11 @@ Image_PixelAddress.cxx
|
|||||||
Image_PixelAddress.hxx
|
Image_PixelAddress.hxx
|
||||||
Image.edl
|
Image.edl
|
||||||
Image_CMPLRS.edl
|
Image_CMPLRS.edl
|
||||||
Image_CRawBufferData.hxx
|
Image_PixMap.hxx
|
||||||
Image_HPrivateImage.hxx
|
Image_PixMap.cxx
|
||||||
|
Image_PixMapData.hxx
|
||||||
|
Image_Color.hxx
|
||||||
|
Image_AlienPixMap.hxx
|
||||||
|
Image_AlienPixMap.cxx
|
||||||
|
Image_Diff.hxx
|
||||||
|
Image_Diff.cxx
|
||||||
|
@ -88,18 +88,16 @@ is
|
|||||||
IndexPixel from Aspect,
|
IndexPixel from Aspect,
|
||||||
IndexPixelMapHasher );
|
IndexPixelMapHasher );
|
||||||
|
|
||||||
class PixMap;
|
|
||||||
---Purpose: Aspect_PixMap implementation.
|
|
||||||
|
|
||||||
-----------------------------
|
-----------------------------
|
||||||
---Category: Imported types:
|
---Category: Imported types:
|
||||||
-----------------------------
|
-----------------------------
|
||||||
|
|
||||||
imported PixelAddress;
|
imported PixelAddress;
|
||||||
|
imported PixMap;
|
||||||
imported HPrivateImage;
|
imported AlienPixMap;
|
||||||
|
imported PixMap_Handle;
|
||||||
imported CRawBufferData;
|
imported AlienPixMap_Handle;
|
||||||
|
imported Diff;
|
||||||
|
|
||||||
-----------------------------
|
-----------------------------
|
||||||
---Category: The Enumerations
|
---Category: The Enumerations
|
||||||
@ -132,12 +130,7 @@ is
|
|||||||
---Purpose: Type of dithering method.
|
---Purpose: Type of dithering method.
|
||||||
|
|
||||||
enumeration TypeOfImage is TOI_ColorImage,
|
enumeration TypeOfImage is TOI_ColorImage,
|
||||||
TOI_PseudoColorImage,
|
TOI_PseudoColorImage
|
||||||
TOI_RGB,
|
|
||||||
TOI_RGBA,
|
|
||||||
TOI_RGBF,
|
|
||||||
TOI_RGBAF,
|
|
||||||
TOI_FLOAT
|
|
||||||
end TypeOfImage ;
|
end TypeOfImage ;
|
||||||
|
|
||||||
Zoom ( aImage : mutable Image from Image ;
|
Zoom ( aImage : mutable Image from Image ;
|
||||||
|
516
src/Image/Image_AlienPixMap.cxx
Normal file
516
src/Image/Image_AlienPixMap.cxx
Normal file
@ -0,0 +1,516 @@
|
|||||||
|
// Created on: 2010-09-16
|
||||||
|
// Created by: KGV
|
||||||
|
// Copyright (c) 2010-2012 OPEN CASCADE SAS
|
||||||
|
//
|
||||||
|
// The content of this file is subject to the Open CASCADE Technology Public
|
||||||
|
// License Version 6.5 (the "License"). You may not use the content of this file
|
||||||
|
// except in compliance with the License. Please obtain a copy of the License
|
||||||
|
// at http://www.opencascade.org and read it completely before using this file.
|
||||||
|
//
|
||||||
|
// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
|
||||||
|
// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
|
||||||
|
//
|
||||||
|
// The Original Code and all software distributed under the License is
|
||||||
|
// distributed on an "AS IS" basis, without warranty of any kind, and the
|
||||||
|
// Initial Developer hereby disclaims all such warranties, including without
|
||||||
|
// limitation, any warranties of merchantability, fitness for a particular
|
||||||
|
// purpose or non-infringement. Please see the License for the specific terms
|
||||||
|
// and conditions governing the rights and limitations under the License.
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_FREEIMAGE
|
||||||
|
#include <FreeImage.h>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma comment( lib, "FreeImage.lib" )
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <Image_AlienPixMap.hxx>
|
||||||
|
#include <gp.hxx>
|
||||||
|
#include <TCollection_AsciiString.hxx>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
#ifdef HAVE_FREEIMAGE
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
static Image_PixMap::ImgFormat convertFromFreeFormat (FREE_IMAGE_TYPE theFormatFI,
|
||||||
|
FREE_IMAGE_COLOR_TYPE theColorTypeFI,
|
||||||
|
unsigned theBitsPerPixel)
|
||||||
|
{
|
||||||
|
switch (theFormatFI)
|
||||||
|
{
|
||||||
|
case FIT_RGBF: return Image_PixMap::ImgRGBF;
|
||||||
|
case FIT_RGBAF: return Image_PixMap::ImgRGBAF;
|
||||||
|
case FIT_FLOAT: return Image_PixMap::ImgGrayF;
|
||||||
|
case FIT_BITMAP:
|
||||||
|
{
|
||||||
|
switch (theColorTypeFI)
|
||||||
|
{
|
||||||
|
case FIC_MINISBLACK:
|
||||||
|
{
|
||||||
|
return Image_PixMap::ImgGray;
|
||||||
|
}
|
||||||
|
case FIC_RGB:
|
||||||
|
{
|
||||||
|
if (Image_PixMap::IsBigEndianHost())
|
||||||
|
{
|
||||||
|
return (theBitsPerPixel == 32) ? Image_PixMap::ImgRGB32 : Image_PixMap::ImgRGB;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return (theBitsPerPixel == 32) ? Image_PixMap::ImgBGR32 : Image_PixMap::ImgBGR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case FIC_RGBALPHA:
|
||||||
|
{
|
||||||
|
return Image_PixMap::IsBigEndianHost() ? Image_PixMap::ImgRGBA : Image_PixMap::ImgBGRA;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return Image_PixMap::ImgUNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return Image_PixMap::ImgUNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static FREE_IMAGE_TYPE convertToFreeFormat (Image_PixMap::ImgFormat theFormat)
|
||||||
|
{
|
||||||
|
switch (theFormat)
|
||||||
|
{
|
||||||
|
case Image_PixMap::ImgGrayF:
|
||||||
|
return FIT_FLOAT;
|
||||||
|
case Image_PixMap::ImgRGBAF:
|
||||||
|
return FIT_RGBAF;
|
||||||
|
case Image_PixMap::ImgRGBF:
|
||||||
|
return FIT_RGBF;
|
||||||
|
case Image_PixMap::ImgRGBA:
|
||||||
|
case Image_PixMap::ImgBGRA:
|
||||||
|
case Image_PixMap::ImgRGB32:
|
||||||
|
case Image_PixMap::ImgBGR32:
|
||||||
|
case Image_PixMap::ImgRGB:
|
||||||
|
case Image_PixMap::ImgBGR:
|
||||||
|
case Image_PixMap::ImgGray:
|
||||||
|
return FIT_BITMAP;
|
||||||
|
default:
|
||||||
|
return FIT_UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
IMPLEMENT_STANDARD_HANDLE (Image_AlienPixMap, Image_PixMap)
|
||||||
|
IMPLEMENT_STANDARD_RTTIEXT(Image_AlienPixMap, Image_PixMap)
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : Image_AlienPixMap
|
||||||
|
// purpose :
|
||||||
|
// =======================================================================
|
||||||
|
Image_AlienPixMap::Image_AlienPixMap()
|
||||||
|
: myLibImage (NULL)
|
||||||
|
{
|
||||||
|
SetTopDown (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : ~Image_AlienPixMap
|
||||||
|
// purpose :
|
||||||
|
// =======================================================================
|
||||||
|
Image_AlienPixMap::~Image_AlienPixMap()
|
||||||
|
{
|
||||||
|
Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : InitWrapper
|
||||||
|
// purpose :
|
||||||
|
// =======================================================================
|
||||||
|
bool Image_AlienPixMap::InitWrapper (ImgFormat thePixelFormat,
|
||||||
|
Standard_Byte* theDataPtr,
|
||||||
|
const Standard_Size theSizeX,
|
||||||
|
const Standard_Size theSizeY,
|
||||||
|
const Standard_Size theSizeRowBytes)
|
||||||
|
{
|
||||||
|
Clear();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : InitTrash
|
||||||
|
// purpose :
|
||||||
|
// =======================================================================
|
||||||
|
bool Image_AlienPixMap::InitTrash (ImgFormat thePixelFormat,
|
||||||
|
const Standard_Size theSizeX,
|
||||||
|
const Standard_Size theSizeY,
|
||||||
|
const Standard_Size theSizeRowBytes)
|
||||||
|
{
|
||||||
|
Clear();
|
||||||
|
#ifdef HAVE_FREEIMAGE
|
||||||
|
FREE_IMAGE_TYPE aFormatFI = convertToFreeFormat (thePixelFormat);
|
||||||
|
int aBitsPerPixel = (int )Image_PixMap::SizePixelBytes (thePixelFormat) * 8;
|
||||||
|
if (aFormatFI == FIT_UNKNOWN)
|
||||||
|
{
|
||||||
|
aFormatFI = FIT_BITMAP;
|
||||||
|
aBitsPerPixel = 24;
|
||||||
|
}
|
||||||
|
|
||||||
|
FIBITMAP* anImage = FreeImage_AllocateT (aFormatFI, (int )theSizeX, (int )theSizeY, aBitsPerPixel);
|
||||||
|
Image_PixMap::ImgFormat aFormat = convertFromFreeFormat (FreeImage_GetImageType (anImage),
|
||||||
|
FreeImage_GetColorType (anImage),
|
||||||
|
FreeImage_GetBPP (anImage));
|
||||||
|
if (thePixelFormat == Image_PixMap::ImgBGR32
|
||||||
|
|| thePixelFormat == Image_PixMap::ImgRGB32)
|
||||||
|
{
|
||||||
|
//FreeImage_SetTransparent (anImage, FALSE);
|
||||||
|
aFormat = (aFormat == Image_PixMap::ImgBGRA) ? Image_PixMap::ImgBGR32 : Image_PixMap::ImgRGB32;
|
||||||
|
}
|
||||||
|
|
||||||
|
Image_PixMap::InitWrapper (aFormat, FreeImage_GetBits (anImage),
|
||||||
|
FreeImage_GetWidth (anImage), FreeImage_GetHeight (anImage), FreeImage_GetPitch (anImage));
|
||||||
|
SetTopDown (false);
|
||||||
|
|
||||||
|
// assign image after wrapper initialization (virtual Clear() called inside)
|
||||||
|
myLibImage = anImage;
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
|
return Image_PixMap::InitTrash (thePixelFormat, theSizeX, theSizeY, theSizeRowBytes);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : Clear
|
||||||
|
// purpose :
|
||||||
|
// =======================================================================
|
||||||
|
bool Image_AlienPixMap::InitCopy (const Image_PixMap& theCopy)
|
||||||
|
{
|
||||||
|
if (&theCopy == this)
|
||||||
|
{
|
||||||
|
// self-copying disallowed
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!InitTrash (theCopy.Format(), theCopy.SizeX(), theCopy.SizeY(), theCopy.SizeRowBytes()))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (myImgFormat == theCopy.Format())
|
||||||
|
{
|
||||||
|
if (myData.mySizeRowBytes == theCopy.SizeRowBytes()
|
||||||
|
&& myData.myTopToDown == theCopy.TopDownInc())
|
||||||
|
{
|
||||||
|
// copy with one call
|
||||||
|
memcpy (myData.myDataPtr, theCopy.Data(), theCopy.SizeBytes());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy row-by-row
|
||||||
|
const Standard_Size aRowSizeBytes = (myData.mySizeRowBytes > theCopy.SizeRowBytes())
|
||||||
|
? theCopy.SizeRowBytes() : myData.mySizeRowBytes;
|
||||||
|
for (Standard_Size aRow = 0; aRow < myData.mySizeY; ++aRow)
|
||||||
|
{
|
||||||
|
memcpy (ChangeRow (aRow), theCopy.Row (aRow), aRowSizeBytes);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// pixel format conversion required
|
||||||
|
Clear();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : Clear
|
||||||
|
// purpose :
|
||||||
|
// =======================================================================
|
||||||
|
void Image_AlienPixMap::Clear (ImgFormat thePixelFormat)
|
||||||
|
{
|
||||||
|
Image_PixMap::Clear (thePixelFormat);
|
||||||
|
#ifdef HAVE_FREEIMAGE
|
||||||
|
if (myLibImage != NULL)
|
||||||
|
{
|
||||||
|
FreeImage_Unload (myLibImage);
|
||||||
|
myLibImage = NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : Load
|
||||||
|
// purpose :
|
||||||
|
// =======================================================================
|
||||||
|
bool Image_AlienPixMap::Load (const TCollection_AsciiString& theImagePath)
|
||||||
|
{
|
||||||
|
Clear();
|
||||||
|
#ifdef HAVE_FREEIMAGE
|
||||||
|
|
||||||
|
FREE_IMAGE_FORMAT aFIF = FreeImage_GetFileType (theImagePath.ToCString(), 0);
|
||||||
|
if (aFIF == FIF_UNKNOWN)
|
||||||
|
{
|
||||||
|
// no signature? try to guess the file format from the file extension
|
||||||
|
aFIF = FreeImage_GetFIFFromFilename (theImagePath.ToCString());
|
||||||
|
}
|
||||||
|
if ((aFIF == FIF_UNKNOWN) || !FreeImage_FIFSupportsReading (aFIF))
|
||||||
|
{
|
||||||
|
// unsupported image format
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int aLoadFlags = 0;
|
||||||
|
if (aFIF == FIF_GIF)
|
||||||
|
{
|
||||||
|
// 'Play' the GIF to generate each frame (as 32bpp) instead of returning raw frame data when loading
|
||||||
|
aLoadFlags = GIF_PLAYBACK;
|
||||||
|
}
|
||||||
|
else if (aFIF == FIF_ICO)
|
||||||
|
{
|
||||||
|
// convert to 32bpp and create an alpha channel from the AND-mask when loading
|
||||||
|
aLoadFlags = ICO_MAKEALPHA;
|
||||||
|
}
|
||||||
|
|
||||||
|
FIBITMAP* anImage = FreeImage_Load (aFIF, theImagePath.ToCString(), aLoadFlags);
|
||||||
|
if (anImage == NULL)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Image_PixMap::ImgFormat aFormat = convertFromFreeFormat (FreeImage_GetImageType (anImage),
|
||||||
|
FreeImage_GetColorType (anImage),
|
||||||
|
FreeImage_GetBPP (anImage));
|
||||||
|
if (aFormat == Image_PixMap::ImgUNKNOWN)
|
||||||
|
{
|
||||||
|
//anImage = FreeImage_ConvertTo24Bits (anImage);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Image_PixMap::InitWrapper (aFormat, FreeImage_GetBits (anImage),
|
||||||
|
FreeImage_GetWidth (anImage), FreeImage_GetHeight (anImage), FreeImage_GetPitch (anImage));
|
||||||
|
SetTopDown (false);
|
||||||
|
|
||||||
|
// assign image after wrapper initialization (virtual Clear() called inside)
|
||||||
|
myLibImage = anImage;
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : savePPM
|
||||||
|
// purpose :
|
||||||
|
// =======================================================================
|
||||||
|
bool Image_AlienPixMap::savePPM (const TCollection_AsciiString& theFileName) const
|
||||||
|
{
|
||||||
|
if (IsEmpty())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open file
|
||||||
|
FILE* aFile = fopen (theFileName.ToCString(), "wb");
|
||||||
|
if (aFile == NULL)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write header
|
||||||
|
fprintf (aFile, "P6\n%d %d\n255\n", (int )SizeX(), (int )SizeY());
|
||||||
|
fprintf (aFile, "# Image stored by OpenCASCADE framework in linear RGB colorspace\n");
|
||||||
|
|
||||||
|
// Write pixel data
|
||||||
|
Quantity_Color aColor;
|
||||||
|
Quantity_Parameter aDummy;
|
||||||
|
Standard_Byte aByte;
|
||||||
|
for (Standard_Size aRow = 0; aRow < SizeY(); ++aRow)
|
||||||
|
{
|
||||||
|
for (Standard_Size aCol = 0; aCol < SizeY(); ++aCol)
|
||||||
|
{
|
||||||
|
// extremely SLOW but universal (implemented for all supported pixel formats)
|
||||||
|
aColor = PixelColor (aCol, aRow, aDummy);
|
||||||
|
aByte = Standard_Byte(aColor.Red() * 255.0); fwrite (&aByte, 1, 1, aFile);
|
||||||
|
aByte = Standard_Byte(aColor.Green() * 255.0); fwrite (&aByte, 1, 1, aFile);
|
||||||
|
aByte = Standard_Byte(aColor.Blue() * 255.0); fwrite (&aByte, 1, 1, aFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close file
|
||||||
|
fclose (aFile);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : Save
|
||||||
|
// purpose :
|
||||||
|
// =======================================================================
|
||||||
|
bool Image_AlienPixMap::Save (const TCollection_AsciiString& theFileName)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_FREEIMAGE
|
||||||
|
if (myLibImage == NULL)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
FREE_IMAGE_FORMAT anImageFormat = FreeImage_GetFIFFromFilename (theFileName.ToCString());
|
||||||
|
if (anImageFormat == FIF_UNKNOWN)
|
||||||
|
{
|
||||||
|
std::cerr << "Image_PixMap, image format doesn't supported!\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsTopDown())
|
||||||
|
{
|
||||||
|
FreeImage_FlipVertical (myLibImage);
|
||||||
|
SetTopDown (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// FreeImage doesn't provide flexible format convertion API
|
||||||
|
// so we should perform multiple convertions in some cases!
|
||||||
|
Standard_Boolean isCopied = Standard_False;
|
||||||
|
FIBITMAP* anImageToDump = myLibImage;
|
||||||
|
switch (anImageFormat)
|
||||||
|
{
|
||||||
|
case FIF_PNG:
|
||||||
|
case FIF_BMP:
|
||||||
|
{
|
||||||
|
if (Format() == Image_PixMap::ImgBGR32
|
||||||
|
|| Format() == Image_PixMap::ImgRGB32)
|
||||||
|
{
|
||||||
|
// stupid FreeImage treats reserved byte as alpha if some bytes not set to 0xFF
|
||||||
|
Image_PixMapData<Image_ColorRGB32>& aData = Image_PixMap::EditData<Image_ColorRGB32>();
|
||||||
|
for (Standard_Size aRow = 0; aRow < SizeY(); ++aRow)
|
||||||
|
{
|
||||||
|
for (Standard_Size aCol = 0; aCol < SizeX(); ++aCol)
|
||||||
|
{
|
||||||
|
aData.ChangeValue (aRow, aCol).a_() = 0xFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (FreeImage_GetImageType (myLibImage) != FIT_BITMAP)
|
||||||
|
{
|
||||||
|
anImageToDump = FreeImage_ConvertToType (myLibImage, FIT_BITMAP);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FIF_GIF:
|
||||||
|
{
|
||||||
|
FIBITMAP* aTmpBitmap = myLibImage;
|
||||||
|
if (FreeImage_GetImageType (myLibImage) != FIT_BITMAP)
|
||||||
|
{
|
||||||
|
aTmpBitmap = FreeImage_ConvertToType (myLibImage, FIT_BITMAP);
|
||||||
|
if (aTmpBitmap == NULL)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FreeImage_GetBPP (aTmpBitmap) != 24)
|
||||||
|
{
|
||||||
|
FIBITMAP* aTmpBitmap24 = FreeImage_ConvertTo24Bits (aTmpBitmap);
|
||||||
|
if (aTmpBitmap != myLibImage)
|
||||||
|
{
|
||||||
|
FreeImage_Unload (aTmpBitmap);
|
||||||
|
}
|
||||||
|
if (aTmpBitmap24 == NULL)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
aTmpBitmap = aTmpBitmap24;
|
||||||
|
}
|
||||||
|
|
||||||
|
// need convertion to image with pallete (requires 24bit bitmap)
|
||||||
|
anImageToDump = FreeImage_ColorQuantize (aTmpBitmap, FIQ_NNQUANT);
|
||||||
|
if (aTmpBitmap != myLibImage)
|
||||||
|
{
|
||||||
|
FreeImage_Unload (aTmpBitmap);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FIF_EXR:
|
||||||
|
{
|
||||||
|
if (Format() == Image_PixMap::ImgGray)
|
||||||
|
{
|
||||||
|
anImageToDump = FreeImage_ConvertToType (myLibImage, FIT_FLOAT);
|
||||||
|
}
|
||||||
|
else if (Format() == Image_PixMap::ImgRGBA
|
||||||
|
|| Format() == Image_PixMap::ImgBGRA)
|
||||||
|
{
|
||||||
|
anImageToDump = FreeImage_ConvertToType (myLibImage, FIT_RGBAF);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FREE_IMAGE_TYPE aImgTypeFI = FreeImage_GetImageType (myLibImage);
|
||||||
|
if (aImgTypeFI != FIT_RGBF
|
||||||
|
&& aImgTypeFI != FIT_RGBAF
|
||||||
|
&& aImgTypeFI != FIT_FLOAT)
|
||||||
|
{
|
||||||
|
anImageToDump = FreeImage_ConvertToType (myLibImage, FIT_RGBF);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
if (FreeImage_GetImageType (myLibImage) != FIT_BITMAP)
|
||||||
|
{
|
||||||
|
anImageToDump = FreeImage_ConvertToType (myLibImage, FIT_BITMAP);
|
||||||
|
if (anImageToDump == NULL)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FreeImage_GetBPP (anImageToDump) != 24)
|
||||||
|
{
|
||||||
|
FIBITMAP* aTmpBitmap24 = FreeImage_ConvertTo24Bits (anImageToDump);
|
||||||
|
if (anImageToDump != myLibImage)
|
||||||
|
{
|
||||||
|
FreeImage_Unload (anImageToDump);
|
||||||
|
}
|
||||||
|
if (aTmpBitmap24 == NULL)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
anImageToDump = aTmpBitmap24;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (anImageToDump == NULL)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isSaved = (FreeImage_Save (anImageFormat, anImageToDump, theFileName.ToCString()) != FALSE);
|
||||||
|
if (anImageToDump != myLibImage)
|
||||||
|
{
|
||||||
|
FreeImage_Unload (anImageToDump);
|
||||||
|
}
|
||||||
|
return isSaved;
|
||||||
|
#else
|
||||||
|
const Standard_Integer aLen = theFileName.Length();
|
||||||
|
if ((aLen >= 4) && (theFileName.Value (aLen - 3) == '.')
|
||||||
|
&& TCollection_AsciiString::ISSIMILAR (theFileName.SubString (aLen - 2, aLen), "ppm"))
|
||||||
|
{
|
||||||
|
return savePPM (theFileName);
|
||||||
|
}
|
||||||
|
std::cerr << "Image_PixMap, no image library available! Image saved in PPM format.\n";
|
||||||
|
return savePPM (theFileName);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : AdjustGamma
|
||||||
|
// purpose :
|
||||||
|
// =======================================================================
|
||||||
|
Standard_EXPORT bool Image_AlienPixMap::AdjustGamma (const Standard_Real theGammaCorr)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_FREEIMAGE
|
||||||
|
return FreeImage_AdjustGamma (myLibImage, theGammaCorr) != FALSE;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
96
src/Image/Image_AlienPixMap.hxx
Normal file
96
src/Image/Image_AlienPixMap.hxx
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
// Created on: 2012-07-18
|
||||||
|
// Created by: Kirill GAVRILOV
|
||||||
|
// Copyright (c) 2012 OPEN CASCADE SAS
|
||||||
|
//
|
||||||
|
// The content of this file is subject to the Open CASCADE Technology Public
|
||||||
|
// License Version 6.5 (the "License"). You may not use the content of this file
|
||||||
|
// except in compliance with the License. Please obtain a copy of the License
|
||||||
|
// at http://www.opencascade.org and read it completely before using this file.
|
||||||
|
//
|
||||||
|
// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
|
||||||
|
// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
|
||||||
|
//
|
||||||
|
// The Original Code and all software distributed under the License is
|
||||||
|
// distributed on an "AS IS" basis, without warranty of any kind, and the
|
||||||
|
// Initial Developer hereby disclaims all such warranties, including without
|
||||||
|
// limitation, any warranties of merchantability, fitness for a particular
|
||||||
|
// purpose or non-infringement. Please see the License for the specific terms
|
||||||
|
// and conditions governing the rights and limitations under the License.
|
||||||
|
|
||||||
|
#ifndef _Image_AlienPixMap_H__
|
||||||
|
#define _Image_AlienPixMap_H__
|
||||||
|
|
||||||
|
#include <Image_PixMap.hxx>
|
||||||
|
#include <Image_TypeOfImage.hxx>
|
||||||
|
|
||||||
|
class TCollection_AsciiString;
|
||||||
|
struct FIBITMAP;
|
||||||
|
|
||||||
|
//! Image class that support file reading/writing operations using auxiliary image library.
|
||||||
|
//! Notice that supported images format could be limited.
|
||||||
|
class Image_AlienPixMap : public Image_PixMap
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//! Empty constructor.
|
||||||
|
Standard_EXPORT Image_AlienPixMap();
|
||||||
|
|
||||||
|
//! Destructor
|
||||||
|
Standard_EXPORT virtual ~Image_AlienPixMap();
|
||||||
|
|
||||||
|
//! Read image data from file.
|
||||||
|
Standard_EXPORT bool Load (const TCollection_AsciiString& theFileName);
|
||||||
|
|
||||||
|
//! Write image data to file using file extension to determine compression format.
|
||||||
|
Standard_EXPORT bool Save (const TCollection_AsciiString& theFileName);
|
||||||
|
|
||||||
|
//! Initialize image plane with required dimensions.
|
||||||
|
//! thePixelFormat - if specified pixel format doesn't supported by image library
|
||||||
|
//! than nearest supported will be used instead!
|
||||||
|
//! theSizeRowBytes - may be ignored by this class and required alignemnt will be used instead!
|
||||||
|
Standard_EXPORT virtual bool InitTrash (ImgFormat thePixelFormat,
|
||||||
|
const Standard_Size theSizeX,
|
||||||
|
const Standard_Size theSizeY,
|
||||||
|
const Standard_Size theSizeRowBytes = 0);
|
||||||
|
|
||||||
|
//! Initialize by copying data.
|
||||||
|
Standard_EXPORT virtual bool InitCopy (const Image_PixMap& theCopy);
|
||||||
|
|
||||||
|
//! Method correctly deallocate internal buffer.
|
||||||
|
Standard_EXPORT virtual void Clear (ImgFormat thePixelFormat = ImgGray);
|
||||||
|
|
||||||
|
//! Performs gamma correction on image.
|
||||||
|
//! theGamma - gamma value to use; a value of 1.0 leaves the image alone
|
||||||
|
Standard_EXPORT bool AdjustGamma (const Standard_Real theGammaCorr);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
FIBITMAP* myLibImage;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
//! Copying allowed only within Handles
|
||||||
|
Image_AlienPixMap (const Image_AlienPixMap& );
|
||||||
|
Image_AlienPixMap& operator= (const Image_AlienPixMap& );
|
||||||
|
|
||||||
|
//! Wrapper initialization is disallowed for this class (will return false in any case)!
|
||||||
|
//! Use only copying and allocation initializers.
|
||||||
|
Standard_EXPORT virtual bool InitWrapper (ImgFormat thePixelFormat,
|
||||||
|
Standard_Byte* theDataPtr,
|
||||||
|
const Standard_Size theSizeX,
|
||||||
|
const Standard_Size theSizeY,
|
||||||
|
const Standard_Size theSizeRowBytes);
|
||||||
|
|
||||||
|
//! Built-in PPM export
|
||||||
|
Standard_EXPORT bool savePPM (const TCollection_AsciiString& theFileName) const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
DEFINE_STANDARD_RTTI(Image_AlienPixMap) // Type definition
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
DEFINE_STANDARD_HANDLE(Image_AlienPixMap, Image_PixMap)
|
||||||
|
|
||||||
|
#endif // _Image_AlienPixMap_H__
|
@ -1,30 +0,0 @@
|
|||||||
// Copyright (c) 1999-2012 OPEN CASCADE SAS
|
|
||||||
//
|
|
||||||
// The content of this file is subject to the Open CASCADE Technology Public
|
|
||||||
// License Version 6.5 (the "License"). You may not use the content of this file
|
|
||||||
// except in compliance with the License. Please obtain a copy of the License
|
|
||||||
// at http://www.opencascade.org and read it completely before using this file.
|
|
||||||
//
|
|
||||||
// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
|
|
||||||
// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
|
|
||||||
//
|
|
||||||
// The Original Code and all software distributed under the License is
|
|
||||||
// distributed on an "AS IS" basis, without warranty of any kind, and the
|
|
||||||
// Initial Developer hereby disclaims all such warranties, including without
|
|
||||||
// limitation, any warranties of merchantability, fitness for a particular
|
|
||||||
// purpose or non-infringement. Please see the License for the specific terms
|
|
||||||
// and conditions governing the rights and limitations under the License.
|
|
||||||
|
|
||||||
#ifndef _Image_CRawBufferData_HeaderFile
|
|
||||||
#define _Image_CRawBufferData_HeaderFile
|
|
||||||
|
|
||||||
#include <InterfaceGraphic_RawBufferData.hxx>
|
|
||||||
|
|
||||||
typedef TRawBufferData Image_CRawBufferData;
|
|
||||||
|
|
||||||
#if defined(__cplusplus) || defined(c_plusplus)
|
|
||||||
#include <Standard_Type.hxx>
|
|
||||||
const Handle(Standard_Type)& TYPE(Image_CRawBufferData);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /*_Image_CRawBufferData_HeaderFile*/
|
|
543
src/Image/Image_Color.hxx
Normal file
543
src/Image/Image_Color.hxx
Normal file
@ -0,0 +1,543 @@
|
|||||||
|
// Created on: 2012-07-18
|
||||||
|
// Created by: Kirill GAVRILOV
|
||||||
|
// Copyright (c) 2012 OPEN CASCADE SAS
|
||||||
|
//
|
||||||
|
// The content of this file is subject to the Open CASCADE Technology Public
|
||||||
|
// License Version 6.5 (the "License"). You may not use the content of this file
|
||||||
|
// except in compliance with the License. Please obtain a copy of the License
|
||||||
|
// at http://www.opencascade.org and read it completely before using this file.
|
||||||
|
//
|
||||||
|
// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
|
||||||
|
// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
|
||||||
|
//
|
||||||
|
// The Original Code and all software distributed under the License is
|
||||||
|
// distributed on an "AS IS" basis, without warranty of any kind, and the
|
||||||
|
// Initial Developer hereby disclaims all such warranties, including without
|
||||||
|
// limitation, any warranties of merchantability, fitness for a particular
|
||||||
|
// purpose or non-infringement. Please see the License for the specific terms
|
||||||
|
// and conditions governing the rights and limitations under the License.
|
||||||
|
|
||||||
|
#ifndef _Image_Color_H__
|
||||||
|
#define _Image_Color_H__
|
||||||
|
|
||||||
|
#include <Standard.hxx>
|
||||||
|
|
||||||
|
//! POD structure for packed RGB color value (3 bytes)
|
||||||
|
struct Image_ColorRGB
|
||||||
|
{
|
||||||
|
|
||||||
|
//! Returns the number of components.
|
||||||
|
static Standard_Integer Length()
|
||||||
|
{
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
public: // access methods
|
||||||
|
|
||||||
|
//! Alias to 1st component (red intensity).
|
||||||
|
Standard_Byte r() const { return v[0]; }
|
||||||
|
|
||||||
|
//! Alias to 2nd component (green intensity).
|
||||||
|
Standard_Byte g() const { return v[1]; }
|
||||||
|
|
||||||
|
//! Alias to 3rd component (blue intensity).
|
||||||
|
Standard_Byte b() const { return v[2]; }
|
||||||
|
|
||||||
|
//! Alias to 1st component (red intensity).
|
||||||
|
Standard_Byte& r() { return v[0]; }
|
||||||
|
|
||||||
|
//! Alias to 2nd component (green intensity).
|
||||||
|
Standard_Byte& g() { return v[1]; }
|
||||||
|
|
||||||
|
//! Alias to 3rd component (blue intensity).
|
||||||
|
Standard_Byte& b() { return v[2]; }
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Standard_Byte v[3];
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
//! POD structure for packed RGB color value (4 bytes with extra byte for alignment)
|
||||||
|
struct Image_ColorRGB32
|
||||||
|
{
|
||||||
|
|
||||||
|
//! Returns the number of components.
|
||||||
|
static Standard_Integer Length()
|
||||||
|
{
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Alias to 1st component (red intensity).
|
||||||
|
Standard_Byte r() const { return v[0]; }
|
||||||
|
|
||||||
|
//! Alias to 2nd component (green intensity).
|
||||||
|
Standard_Byte g() const { return v[1]; }
|
||||||
|
|
||||||
|
//! Alias to 3rd component (blue intensity).
|
||||||
|
Standard_Byte b() const { return v[2]; }
|
||||||
|
|
||||||
|
//! Alias to 4th component (dummy).
|
||||||
|
Standard_Byte a_() const { return v[3]; }
|
||||||
|
|
||||||
|
//! Alias to 1st component (red intensity).
|
||||||
|
Standard_Byte& r() { return v[0]; }
|
||||||
|
|
||||||
|
//! Alias to 2nd component (green intensity).
|
||||||
|
Standard_Byte& g() { return v[1]; }
|
||||||
|
|
||||||
|
//! Alias to 3rd component (blue intensity).
|
||||||
|
Standard_Byte& b() { return v[2]; }
|
||||||
|
|
||||||
|
//! Alias to 4th component (dummy).
|
||||||
|
Standard_Byte& a_() { return v[3]; }
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Standard_Byte v[4];
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
//! POD structure for packed RGBA color value (4 bytes)
|
||||||
|
struct Image_ColorRGBA
|
||||||
|
{
|
||||||
|
|
||||||
|
//! Returns the number of components.
|
||||||
|
static Standard_Integer Length()
|
||||||
|
{
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Alias to 1st component (red intensity).
|
||||||
|
Standard_Byte r() const { return v[0]; }
|
||||||
|
|
||||||
|
//! Alias to 2nd component (green intensity).
|
||||||
|
Standard_Byte g() const { return v[1]; }
|
||||||
|
|
||||||
|
//! Alias to 3rd component (blue intensity).
|
||||||
|
Standard_Byte b() const { return v[2]; }
|
||||||
|
|
||||||
|
//! Alias to 4th component (alpha value).
|
||||||
|
Standard_Byte a() const { return v[3]; }
|
||||||
|
|
||||||
|
//! Alias to 1st component (red intensity).
|
||||||
|
Standard_Byte& r() { return v[0]; }
|
||||||
|
|
||||||
|
//! Alias to 2nd component (green intensity).
|
||||||
|
Standard_Byte& g() { return v[1]; }
|
||||||
|
|
||||||
|
//! Alias to 3rd component (blue intensity).
|
||||||
|
Standard_Byte& b() { return v[2]; }
|
||||||
|
|
||||||
|
//! Alias to 4th component (alpha value).
|
||||||
|
Standard_Byte& a() { return v[3]; }
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Standard_Byte v[4];
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
//! POD structure for packed BGR color value (3 bytes)
|
||||||
|
struct Image_ColorBGR
|
||||||
|
{
|
||||||
|
|
||||||
|
//! Returns the number of components.
|
||||||
|
static Standard_Integer Length()
|
||||||
|
{
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Alias to 3rd component (red intensity).
|
||||||
|
Standard_Byte r() const { return v[2]; }
|
||||||
|
|
||||||
|
//! Alias to 2nd component (green intensity).
|
||||||
|
Standard_Byte g() const { return v[1]; }
|
||||||
|
|
||||||
|
//! Alias to 1st component (blue intensity).
|
||||||
|
Standard_Byte b() const { return v[0]; }
|
||||||
|
|
||||||
|
//! Alias to 3rd component (red intensity).
|
||||||
|
Standard_Byte& r() { return v[2]; }
|
||||||
|
|
||||||
|
//! Alias to 2nd component (green intensity).
|
||||||
|
Standard_Byte& g() { return v[1]; }
|
||||||
|
|
||||||
|
//! Alias to 1st component (blue intensity).
|
||||||
|
Standard_Byte& b() { return v[0]; }
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Standard_Byte v[3];
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
//! POD structure for packed BGR color value (4 bytes with extra byte for alignment)
|
||||||
|
struct Image_ColorBGR32
|
||||||
|
{
|
||||||
|
|
||||||
|
//! Returns the number of components.
|
||||||
|
static Standard_Integer Length()
|
||||||
|
{
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Alias to 3rd component (red intensity).
|
||||||
|
Standard_Byte r() const { return v[2]; }
|
||||||
|
|
||||||
|
//! Alias to 2nd component (green intensity).
|
||||||
|
Standard_Byte g() const { return v[1]; }
|
||||||
|
|
||||||
|
//! Alias to 1st component (blue intensity).
|
||||||
|
Standard_Byte b() const { return v[0]; }
|
||||||
|
|
||||||
|
//! Alias to 4th component (dummy).
|
||||||
|
Standard_Byte a_() const { return v[3]; }
|
||||||
|
|
||||||
|
//! Alias to 3rd component (red intensity).
|
||||||
|
Standard_Byte& r() { return v[2]; }
|
||||||
|
|
||||||
|
//! Alias to 2nd component (green intensity).
|
||||||
|
Standard_Byte& g() { return v[1]; }
|
||||||
|
|
||||||
|
//! Alias to 1st component (blue intensity).
|
||||||
|
Standard_Byte& b() { return v[0]; }
|
||||||
|
|
||||||
|
//! Alias to 4th component (dummy).
|
||||||
|
Standard_Byte& a_() { return v[3]; }
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Standard_Byte v[4];
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
//! POD structure for packed BGRA color value (4 bytes)
|
||||||
|
struct Image_ColorBGRA
|
||||||
|
{
|
||||||
|
|
||||||
|
//! Returns the number of components.
|
||||||
|
static Standard_Integer Length()
|
||||||
|
{
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Alias to 3rd component (red intensity).
|
||||||
|
Standard_Byte r() const { return v[2]; }
|
||||||
|
|
||||||
|
//! Alias to 2nd component (green intensity).
|
||||||
|
Standard_Byte g() const { return v[1]; }
|
||||||
|
|
||||||
|
//! Alias to 1st component (blue intensity).
|
||||||
|
Standard_Byte b() const { return v[0]; }
|
||||||
|
|
||||||
|
//! Alias to 4th component (alpha value).
|
||||||
|
Standard_Byte a() const { return v[3]; }
|
||||||
|
|
||||||
|
//! Alias to 3rd component (red intensity).
|
||||||
|
Standard_Byte& r() { return v[2]; }
|
||||||
|
|
||||||
|
//! Alias to 2nd component (green intensity).
|
||||||
|
Standard_Byte& g() { return v[1]; }
|
||||||
|
|
||||||
|
//! Alias to 1st component (blue intensity).
|
||||||
|
Standard_Byte& b() { return v[0]; }
|
||||||
|
|
||||||
|
//! Alias to 4th component (alpha value).
|
||||||
|
Standard_Byte& a() { return v[3]; }
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Standard_Byte v[4];
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
//! POD structure for packed float RGB color value (3 floats)
|
||||||
|
struct Image_ColorRGBF
|
||||||
|
{
|
||||||
|
|
||||||
|
//! Returns the number of components.
|
||||||
|
static Standard_Integer Length()
|
||||||
|
{
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Alias to 1st component (red intensity).
|
||||||
|
Standard_ShortReal r() const { return v[0]; }
|
||||||
|
|
||||||
|
//! Alias to 2nd component (green intensity).
|
||||||
|
Standard_ShortReal g() const { return v[1]; }
|
||||||
|
|
||||||
|
//! Alias to 3rd component (blue intensity).
|
||||||
|
Standard_ShortReal b() const { return v[2]; }
|
||||||
|
|
||||||
|
//! Alias to 1st component (red intensity).
|
||||||
|
Standard_ShortReal& r() { return v[0]; }
|
||||||
|
|
||||||
|
//! Alias to 2nd component (green intensity).
|
||||||
|
Standard_ShortReal& g() { return v[1]; }
|
||||||
|
|
||||||
|
//! Alias to 3rd component (blue intensity).
|
||||||
|
Standard_ShortReal& b() { return v[2]; }
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Standard_ShortReal v[3];
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
//! POD structure for packed BGR float color value (3 floats)
|
||||||
|
struct Image_ColorBGRF
|
||||||
|
{
|
||||||
|
|
||||||
|
//! Returns the number of components.
|
||||||
|
static Standard_Integer Length()
|
||||||
|
{
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Alias to 3rd component (red intensity).
|
||||||
|
Standard_ShortReal r() const { return v[2]; }
|
||||||
|
|
||||||
|
//! Alias to 2nd component (green intensity).
|
||||||
|
Standard_ShortReal g() const { return v[1]; }
|
||||||
|
|
||||||
|
//! Alias to 1st component (blue intensity).
|
||||||
|
Standard_ShortReal b() const { return v[0]; }
|
||||||
|
|
||||||
|
//! Alias to 3rd component (red intensity).
|
||||||
|
Standard_ShortReal& r() { return v[2]; }
|
||||||
|
|
||||||
|
//! Alias to 2nd component (green intensity).
|
||||||
|
Standard_ShortReal& g() { return v[1]; }
|
||||||
|
|
||||||
|
//! Alias to 1st component (blue intensity).
|
||||||
|
Standard_ShortReal& b() { return v[0]; }
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Standard_ShortReal v[3];
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
//! POD structure for packed RGBA color value (4 floats)
|
||||||
|
struct Image_ColorRGBAF
|
||||||
|
{
|
||||||
|
|
||||||
|
//! Returns the number of components.
|
||||||
|
static Standard_Integer Length()
|
||||||
|
{
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Alias to 1st component (red intensity).
|
||||||
|
Standard_ShortReal r() const { return v[0]; }
|
||||||
|
|
||||||
|
//! Alias to 2nd component (green intensity).
|
||||||
|
Standard_ShortReal g() const { return v[1]; }
|
||||||
|
|
||||||
|
//! Alias to 3rd component (blue intensity).
|
||||||
|
Standard_ShortReal b() const { return v[2]; }
|
||||||
|
|
||||||
|
//! Alias to 4th component (alpha value).
|
||||||
|
Standard_ShortReal a() const { return v[3]; }
|
||||||
|
|
||||||
|
//! Alias to 1st component (red intensity).
|
||||||
|
Standard_ShortReal& r() { return v[0]; }
|
||||||
|
|
||||||
|
//! Alias to 2nd component (green intensity).
|
||||||
|
Standard_ShortReal& g() { return v[1]; }
|
||||||
|
|
||||||
|
//! Alias to 3rd component (blue intensity).
|
||||||
|
Standard_ShortReal& b() { return v[2]; }
|
||||||
|
|
||||||
|
//! Alias to 4th component (alpha value).
|
||||||
|
Standard_ShortReal& a() { return v[3]; }
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Standard_ShortReal v[4];
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
//! POD structure for packed float BGRA color value (4 floats)
|
||||||
|
struct Image_ColorBGRAF
|
||||||
|
{
|
||||||
|
|
||||||
|
//! Returns the number of components.
|
||||||
|
static Standard_Integer Length()
|
||||||
|
{
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Alias to 3rd component (red intensity).
|
||||||
|
Standard_ShortReal r() const { return v[2]; }
|
||||||
|
|
||||||
|
//! Alias to 2nd component (green intensity).
|
||||||
|
Standard_ShortReal g() const { return v[1]; }
|
||||||
|
|
||||||
|
//! Alias to 1st component (blue intensity).
|
||||||
|
Standard_ShortReal b() const { return v[0]; }
|
||||||
|
|
||||||
|
//! Alias to 4th component (alpha value).
|
||||||
|
Standard_ShortReal a() const { return v[3]; }
|
||||||
|
|
||||||
|
//! Alias to 3rd component (red intensity).
|
||||||
|
Standard_ShortReal& r() { return v[2]; }
|
||||||
|
|
||||||
|
//! Alias to 2nd component (green intensity).
|
||||||
|
Standard_ShortReal& g() { return v[1]; }
|
||||||
|
|
||||||
|
//! Alias to 1st component (blue intensity).
|
||||||
|
Standard_ShortReal& b() { return v[0]; }
|
||||||
|
|
||||||
|
//! Alias to 4th component (alpha value).
|
||||||
|
Standard_ShortReal& a() { return v[3]; }
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Standard_ShortReal v[4];
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Addition operator
|
||||||
|
template<typename ColorType_t>
|
||||||
|
inline ColorType_t Image_ColorSumm3 (const ColorType_t& theA, const ColorType_t& theB)
|
||||||
|
{
|
||||||
|
ColorType_t aRes = { theA.v[0] + theB.v[0],
|
||||||
|
theA.v[1] + theB.v[1],
|
||||||
|
theA.v[2] + theB.v[2] };
|
||||||
|
return aRes;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Image_ColorRGB operator+ (const Image_ColorRGB& theA, const Image_ColorRGB& theB)
|
||||||
|
{
|
||||||
|
return Image_ColorSumm3 (theA, theB);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Image_ColorBGR operator+ (const Image_ColorBGR& theA, const Image_ColorBGR& theB)
|
||||||
|
{
|
||||||
|
return Image_ColorSumm3 (theA, theB);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Image_ColorRGBF operator+ (const Image_ColorRGBF& theA, const Image_ColorRGBF& theB)
|
||||||
|
{
|
||||||
|
return Image_ColorSumm3 (theA, theB);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Image_ColorBGRF operator+ (const Image_ColorBGRF& theA, const Image_ColorBGRF& theB)
|
||||||
|
{
|
||||||
|
return Image_ColorSumm3 (theA, theB);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ColorType_t>
|
||||||
|
inline ColorType_t Image_ColorSumm4 (const ColorType_t& theA, const ColorType_t& theB)
|
||||||
|
{
|
||||||
|
ColorType_t aRes = { theA.v[0] + theB.v[0],
|
||||||
|
theA.v[1] + theB.v[1],
|
||||||
|
theA.v[2] + theB.v[2],
|
||||||
|
theA.v[3] + theB.v[3] };
|
||||||
|
return aRes;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Image_ColorRGBA operator+ (const Image_ColorRGBA& theA, const Image_ColorRGBA& theB)
|
||||||
|
{
|
||||||
|
return Image_ColorSumm4 (theA, theB);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Image_ColorBGRA operator+ (const Image_ColorBGRA& theA, const Image_ColorBGRA& theB)
|
||||||
|
{
|
||||||
|
return Image_ColorSumm4 (theA, theB);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Image_ColorRGB32 operator+ (const Image_ColorRGB32& theA, const Image_ColorRGB32& theB)
|
||||||
|
{
|
||||||
|
return Image_ColorSumm4 (theA, theB);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Image_ColorBGR32 operator+ (const Image_ColorBGR32& theA, const Image_ColorBGR32& theB)
|
||||||
|
{
|
||||||
|
return Image_ColorSumm4 (theA, theB);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Image_ColorRGBAF operator+ (const Image_ColorRGBAF& theA, const Image_ColorRGBAF& theB)
|
||||||
|
{
|
||||||
|
return Image_ColorSumm4 (theA, theB);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Image_ColorBGRAF operator+ (const Image_ColorBGRAF& theA, const Image_ColorBGRAF& theB)
|
||||||
|
{
|
||||||
|
return Image_ColorSumm4 (theA, theB);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Subtraction operator
|
||||||
|
template<typename ColorType_t>
|
||||||
|
inline ColorType_t Image_ColorSub3 (const ColorType_t& theA, const ColorType_t& theB)
|
||||||
|
{
|
||||||
|
ColorType_t aRes = { theA.v[0] - theB.v[0],
|
||||||
|
theA.v[1] - theB.v[1],
|
||||||
|
theA.v[2] - theB.v[2] };
|
||||||
|
return aRes;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Image_ColorRGB operator- (const Image_ColorRGB& theA, const Image_ColorRGB& theB)
|
||||||
|
{
|
||||||
|
return Image_ColorSub3 (theA, theB);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Image_ColorBGR operator- (const Image_ColorBGR& theA, const Image_ColorBGR& theB)
|
||||||
|
{
|
||||||
|
return Image_ColorSub3 (theA, theB);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Image_ColorRGBF operator- (const Image_ColorRGBF& theA, const Image_ColorRGBF& theB)
|
||||||
|
{
|
||||||
|
return Image_ColorSub3 (theA, theB);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Image_ColorBGRF operator- (const Image_ColorBGRF& theA, const Image_ColorBGRF& theB)
|
||||||
|
{
|
||||||
|
return Image_ColorSub3 (theA, theB);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ColorType_t>
|
||||||
|
inline ColorType_t Image_ColorSub4 (const ColorType_t& theA, const ColorType_t& theB)
|
||||||
|
{
|
||||||
|
ColorType_t aRes = { theA.v[0] - theB.v[0],
|
||||||
|
theA.v[1] - theB.v[1],
|
||||||
|
theA.v[2] - theB.v[2],
|
||||||
|
theA.v[3] - theB.v[3] };
|
||||||
|
return aRes;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Image_ColorRGBA operator- (const Image_ColorRGBA& theA, const Image_ColorRGBA& theB)
|
||||||
|
{
|
||||||
|
return Image_ColorSub4 (theA, theB);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Image_ColorBGRA operator- (const Image_ColorBGRA& theA, const Image_ColorBGRA& theB)
|
||||||
|
{
|
||||||
|
return Image_ColorSub4 (theA, theB);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Image_ColorRGB32 operator- (const Image_ColorRGB32& theA, const Image_ColorRGB32& theB)
|
||||||
|
{
|
||||||
|
return Image_ColorSub4 (theA, theB);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Image_ColorBGR32 operator- (const Image_ColorBGR32& theA, const Image_ColorBGR32& theB)
|
||||||
|
{
|
||||||
|
return Image_ColorSub4 (theA, theB);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Image_ColorRGBAF operator- (const Image_ColorRGBAF& theA, const Image_ColorRGBAF& theB)
|
||||||
|
{
|
||||||
|
return Image_ColorSub4 (theA, theB);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Image_ColorBGRAF operator- (const Image_ColorBGRAF& theA, const Image_ColorBGRAF& theB)
|
||||||
|
{
|
||||||
|
return Image_ColorSub4 (theA, theB);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // _Image_Color_H__
|
526
src/Image/Image_Diff.cxx
Normal file
526
src/Image/Image_Diff.cxx
Normal file
@ -0,0 +1,526 @@
|
|||||||
|
// Created on: 2012-07-10
|
||||||
|
// Created by: VRO
|
||||||
|
// Copyright (c) 2012 OPEN CASCADE SAS
|
||||||
|
//
|
||||||
|
// The content of this file is subject to the Open CASCADE Technology Public
|
||||||
|
// License Version 6.5 (the "License"). You may not use the content of this file
|
||||||
|
// except in compliance with the License. Please obtain a copy of the License
|
||||||
|
// at http://www.opencascade.org and read it completely before using this file.
|
||||||
|
//
|
||||||
|
// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
|
||||||
|
// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
|
||||||
|
//
|
||||||
|
// The Original Code and all software distributed under the License is
|
||||||
|
// distributed on an "AS IS" basis, without warranty of any kind, and the
|
||||||
|
// Initial Developer hereby disclaims all such warranties, including without
|
||||||
|
// limitation, any warranties of merchantability, fitness for a particular
|
||||||
|
// purpose or non-infringement. Please see the License for the specific terms
|
||||||
|
// and conditions governing the rights and limitations under the License.
|
||||||
|
|
||||||
|
#include <Image_Diff.hxx>
|
||||||
|
#include <Image_AlienPixMap.hxx>
|
||||||
|
|
||||||
|
#include <TColStd_MapIteratorOfMapOfInteger.hxx>
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
|
IMPLEMENT_STANDARD_HANDLE (Image_Diff, Standard_Transient)
|
||||||
|
IMPLEMENT_STANDARD_RTTIEXT(Image_Diff, Standard_Transient)
|
||||||
|
|
||||||
|
//! Dot squared for difference of two colors
|
||||||
|
inline Standard_Integer dotSquared (const Image_ColorRGB& theColor)
|
||||||
|
{
|
||||||
|
// explicitly convert to integer
|
||||||
|
const Standard_Integer r = theColor.r();
|
||||||
|
const Standard_Integer g = theColor.g();
|
||||||
|
const Standard_Integer b = theColor.b();
|
||||||
|
return r * r + g * g + b * b;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @return true if pixel is black
|
||||||
|
inline bool isBlack (const Image_ColorRGB& theColor)
|
||||||
|
{
|
||||||
|
return theColor.r() == 0
|
||||||
|
&& theColor.g() == 0
|
||||||
|
&& theColor.b() == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Converts a pixel position (row, column) to one integer value
|
||||||
|
inline Standard_Size pixel2Int (const Standard_Size aRow,
|
||||||
|
const Standard_Size aCol)
|
||||||
|
{
|
||||||
|
return aCol + (aRow << 15);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Converts an integer value to pixel coordinates (row, column)
|
||||||
|
inline void int2Pixel (const Standard_Size theValue,
|
||||||
|
Standard_Size& theRow,
|
||||||
|
Standard_Size& theCol)
|
||||||
|
{
|
||||||
|
theRow = (theValue >> 15);
|
||||||
|
theCol = theValue - (theRow << 15);
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
static const Standard_Size NEIGHBOR_PIXELS_NB = 8;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
Standard_Integer row_inc;
|
||||||
|
Standard_Integer col_inc;
|
||||||
|
|
||||||
|
inline Standard_Size pixel2Int (const Standard_Size theRowCenter,
|
||||||
|
const Standard_Size theColCenter) const
|
||||||
|
{
|
||||||
|
return ::pixel2Int (theRowCenter + Standard_Size(row_inc),
|
||||||
|
theColCenter + Standard_Size(col_inc));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool isBlack (const Image_PixMapData<Image_ColorRGB>& theData,
|
||||||
|
const Standard_Size theRowCenter,
|
||||||
|
const Standard_Size theColCenter) const
|
||||||
|
{
|
||||||
|
return ::isBlack (theData.Value (theRowCenter + Standard_Size(row_inc),
|
||||||
|
theColCenter + Standard_Size(col_inc)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static const NEIGHBOR_PIXELS[NEIGHBOR_PIXELS_NB] =
|
||||||
|
{
|
||||||
|
{-1, -1}, {-1, 0}, {-1, 1},
|
||||||
|
{ 0, -1}, { 0, 1},
|
||||||
|
{ 1, -1}, { 1, 0}, { 1, 1}
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool isSupportedFormat (const Image_PixMap::ImgFormat theFormat)
|
||||||
|
{
|
||||||
|
return theFormat == Image_PixMap::ImgRGB
|
||||||
|
|| theFormat == Image_PixMap::ImgBGR
|
||||||
|
|| theFormat == Image_PixMap::ImgRGB32
|
||||||
|
|| theFormat == Image_PixMap::ImgBGR32
|
||||||
|
|| theFormat == Image_PixMap::ImgRGBA
|
||||||
|
|| theFormat == Image_PixMap::ImgBGRA;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : Image_Diff
|
||||||
|
// purpose :
|
||||||
|
// =======================================================================
|
||||||
|
Image_Diff::Image_Diff()
|
||||||
|
: myColorTolerance (0.0),
|
||||||
|
myIsBorderFilterOn (Standard_False)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : ~Image_Diff
|
||||||
|
// purpose :
|
||||||
|
// =======================================================================
|
||||||
|
Image_Diff::~Image_Diff()
|
||||||
|
{
|
||||||
|
releaseGroupsOfDiffPixels();
|
||||||
|
}
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : Init
|
||||||
|
// purpose :
|
||||||
|
// =======================================================================
|
||||||
|
Standard_Boolean Image_Diff::Init (const Handle(Image_PixMap)& theImageRef,
|
||||||
|
const Handle(Image_PixMap)& theImageNew,
|
||||||
|
const Standard_Boolean theToBlackWhite)
|
||||||
|
{
|
||||||
|
myImageRef.Nullify();
|
||||||
|
myImageNew.Nullify();
|
||||||
|
myDiffPixels.Clear();
|
||||||
|
releaseGroupsOfDiffPixels();
|
||||||
|
if (theImageRef.IsNull() || theImageNew.IsNull()
|
||||||
|
|| theImageRef->IsEmpty() || theImageNew->IsEmpty()
|
||||||
|
|| theImageRef->SizeX() != theImageNew->SizeX()
|
||||||
|
|| theImageRef->SizeY() != theImageNew->SizeY()
|
||||||
|
|| theImageRef->Format() != theImageNew->Format())
|
||||||
|
{
|
||||||
|
std::cerr << "Images has different format or dimensions\n";
|
||||||
|
return Standard_False;
|
||||||
|
}
|
||||||
|
else if (!isSupportedFormat (theImageRef->Format()))
|
||||||
|
{
|
||||||
|
std::cerr << "Images has unsupported pixel format\n";
|
||||||
|
return Standard_False;
|
||||||
|
}
|
||||||
|
else if (theImageRef->SizeX() >= 0xFFFF
|
||||||
|
|| theImageRef->SizeY() >= 0xFFFF)
|
||||||
|
{
|
||||||
|
std::cerr << "Image too large\n";
|
||||||
|
return Standard_False;
|
||||||
|
}
|
||||||
|
|
||||||
|
myImageRef = theImageRef;
|
||||||
|
myImageNew = theImageNew;
|
||||||
|
|
||||||
|
if (theToBlackWhite)
|
||||||
|
{
|
||||||
|
// Convert the images to white/black
|
||||||
|
const Image_ColorRGB aWhite = {{255, 255, 255}};
|
||||||
|
Image_PixMapData<Image_ColorRGB>& aDataRef = myImageRef->EditData<Image_ColorRGB>();
|
||||||
|
Image_PixMapData<Image_ColorRGB>& aDataNew = myImageNew->EditData<Image_ColorRGB>();
|
||||||
|
for (Standard_Size aRow = 0; aRow < aDataRef.SizeY(); ++aRow)
|
||||||
|
{
|
||||||
|
for (Standard_Size aCol = 0; aCol < aDataRef.SizeY(); ++aCol)
|
||||||
|
{
|
||||||
|
Image_ColorRGB& aPixel1 = aDataRef.ChangeValue (aRow, aCol);
|
||||||
|
Image_ColorRGB& aPixel2 = aDataNew.ChangeValue (aRow, aCol);
|
||||||
|
if (!isBlack (aPixel1))
|
||||||
|
{
|
||||||
|
aPixel1 = aWhite;
|
||||||
|
}
|
||||||
|
if (!isBlack (aPixel2))
|
||||||
|
{
|
||||||
|
aPixel2 = aWhite;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Standard_True;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : Init
|
||||||
|
// purpose :
|
||||||
|
// =======================================================================
|
||||||
|
Standard_Boolean Image_Diff::Init (const TCollection_AsciiString& theImgPathRef,
|
||||||
|
const TCollection_AsciiString& theImgPathNew,
|
||||||
|
const Standard_Boolean theToBlackWhite)
|
||||||
|
{
|
||||||
|
Handle(Image_AlienPixMap) anImgRef = new Image_AlienPixMap();
|
||||||
|
Handle(Image_AlienPixMap) anImgNew = new Image_AlienPixMap();
|
||||||
|
if (!anImgRef->Load (theImgPathRef)
|
||||||
|
|| !anImgNew->Load (theImgPathNew))
|
||||||
|
{
|
||||||
|
std::cerr << "Failed to load image(s) file(s)\n";
|
||||||
|
return Standard_False;
|
||||||
|
}
|
||||||
|
return Init (anImgRef, anImgNew, theToBlackWhite);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : SetColorTolerance
|
||||||
|
// purpose :
|
||||||
|
// =======================================================================
|
||||||
|
void Image_Diff::SetColorTolerance (const Standard_Real theTolerance)
|
||||||
|
{
|
||||||
|
myColorTolerance = theTolerance;
|
||||||
|
}
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : ColorTolerance
|
||||||
|
// purpose :
|
||||||
|
// =======================================================================
|
||||||
|
Standard_Real Image_Diff::ColorTolerance() const
|
||||||
|
{
|
||||||
|
return myColorTolerance;
|
||||||
|
}
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : SetBorderFilterOn
|
||||||
|
// purpose :
|
||||||
|
// =======================================================================
|
||||||
|
void Image_Diff::SetBorderFilterOn (const Standard_Boolean theToIgnore)
|
||||||
|
{
|
||||||
|
myIsBorderFilterOn = theToIgnore;
|
||||||
|
}
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : IsBorderFilterOn
|
||||||
|
// purpose :
|
||||||
|
// =======================================================================
|
||||||
|
Standard_Boolean Image_Diff::IsBorderFilterOn() const
|
||||||
|
{
|
||||||
|
return myIsBorderFilterOn;
|
||||||
|
}
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : Compare
|
||||||
|
// purpose :
|
||||||
|
// =======================================================================
|
||||||
|
Standard_Integer Image_Diff::Compare()
|
||||||
|
{
|
||||||
|
// Number of different pixels (by color)
|
||||||
|
Standard_Integer aNbDiffColors = 0;
|
||||||
|
myDiffPixels.Clear();
|
||||||
|
|
||||||
|
if (myImageRef.IsNull() || myImageNew.IsNull())
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tolerance of comparison operation for color
|
||||||
|
// Maximum difference between colors (white - black) = 100%
|
||||||
|
Image_ColorRGB aDiff = {{255, 255, 255}};
|
||||||
|
const Standard_Integer aMaxDiffColor = dotSquared (aDiff);
|
||||||
|
const Standard_Integer aDiffThreshold = Standard_Integer(Standard_Real(aMaxDiffColor) * myColorTolerance);
|
||||||
|
|
||||||
|
// we don't care about RGB/BGR/RGBA/BGRA/RGB32/BGR32 differences
|
||||||
|
// because we just compute summ of r g b components
|
||||||
|
const Image_PixMapData<Image_ColorRGB>& aDataRef = myImageRef->ReadData<Image_ColorRGB>();
|
||||||
|
const Image_PixMapData<Image_ColorRGB>& aDataNew = myImageNew->ReadData<Image_ColorRGB>();
|
||||||
|
|
||||||
|
// compare colors of each pixel
|
||||||
|
for (Standard_Size aRow = 0; aRow < myImageRef->SizeY(); ++aRow)
|
||||||
|
{
|
||||||
|
for (Standard_Size aCol = 0; aCol < myImageRef->SizeX(); ++aCol)
|
||||||
|
{
|
||||||
|
aDiff = aDataNew.Value (aRow, aCol) - aDataRef.Value (aRow, aCol);
|
||||||
|
if (dotSquared (aDiff) > aDiffThreshold)
|
||||||
|
{
|
||||||
|
const Standard_Size aValue = pixel2Int (aRow, aCol);
|
||||||
|
myDiffPixels.Append (aValue);
|
||||||
|
++aNbDiffColors;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// take into account a border effect
|
||||||
|
if (myIsBorderFilterOn && myDiffPixels.Length() > 0)
|
||||||
|
{
|
||||||
|
aNbDiffColors = ignoreBorderEffect();
|
||||||
|
}
|
||||||
|
|
||||||
|
return aNbDiffColors;
|
||||||
|
}
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : SaveDiffImage
|
||||||
|
// purpose :
|
||||||
|
// =======================================================================
|
||||||
|
Standard_Boolean Image_Diff::SaveDiffImage (Image_PixMap& theDiffImage) const
|
||||||
|
{
|
||||||
|
if (myImageRef.IsNull() || myImageNew.IsNull())
|
||||||
|
{
|
||||||
|
return Standard_False;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (theDiffImage.IsEmpty()
|
||||||
|
|| theDiffImage.SizeX() != myImageRef->SizeX()
|
||||||
|
|| theDiffImage.SizeY() != myImageRef->SizeY()
|
||||||
|
|| !isSupportedFormat (theDiffImage.Format()))
|
||||||
|
{
|
||||||
|
if (!theDiffImage.InitTrash (Image_PixMap::ImgRGB, myImageRef->SizeX(), myImageRef->SizeY()))
|
||||||
|
{
|
||||||
|
return Standard_False;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Standard_Size aRow, aCol;
|
||||||
|
const Image_ColorRGB aWhite = {{255, 255, 255}};
|
||||||
|
Image_PixMapData<Image_ColorRGB>& aDataOut = theDiffImage.EditData<Image_ColorRGB>();
|
||||||
|
|
||||||
|
// initialize black image for dump
|
||||||
|
memset (theDiffImage.ChangeData(), 0, theDiffImage.SizeBytes());
|
||||||
|
if (myGroupsOfDiffPixels.IsEmpty())
|
||||||
|
{
|
||||||
|
if (myIsBorderFilterOn)
|
||||||
|
{
|
||||||
|
return Standard_True;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Standard_Integer aPixelId = 0; aPixelId < myDiffPixels.Length(); ++aPixelId)
|
||||||
|
{
|
||||||
|
const Standard_Size aValue = myDiffPixels.Value (aPixelId);
|
||||||
|
int2Pixel (aValue, aRow, aCol);
|
||||||
|
aDataOut.ChangeValue (aRow, aCol) = aWhite;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Standard_True;
|
||||||
|
}
|
||||||
|
|
||||||
|
Standard_Integer aGroupId = 1;
|
||||||
|
for (ListOfMapOfInteger::Iterator aGrIter (myGroupsOfDiffPixels); aGrIter.More(); aGrIter.Next(), ++aGroupId)
|
||||||
|
{
|
||||||
|
if (myLinearGroups.Contains (aGroupId))
|
||||||
|
{
|
||||||
|
continue; // skip linear groups
|
||||||
|
}
|
||||||
|
|
||||||
|
const TColStd_MapOfInteger* aGroup = aGrIter.Value();
|
||||||
|
for (TColStd_MapIteratorOfMapOfInteger aPixelIter(*aGroup);
|
||||||
|
aPixelIter.More(); aPixelIter.Next())
|
||||||
|
{
|
||||||
|
int2Pixel (aPixelIter.Key(), aRow, aCol);
|
||||||
|
aDataOut.ChangeValue (aRow, aCol) = aWhite;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Standard_True;
|
||||||
|
}
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : SaveDiffImage
|
||||||
|
// purpose :
|
||||||
|
// =======================================================================
|
||||||
|
Standard_Boolean Image_Diff::SaveDiffImage (const TCollection_AsciiString& theDiffPath) const
|
||||||
|
{
|
||||||
|
if (myImageRef.IsNull() || myImageNew.IsNull() || theDiffPath.IsEmpty())
|
||||||
|
{
|
||||||
|
return Standard_False;
|
||||||
|
}
|
||||||
|
|
||||||
|
Image_AlienPixMap aDiff;
|
||||||
|
if (!aDiff.InitTrash (Image_PixMap::ImgRGB, myImageRef->SizeX(), myImageRef->SizeY())
|
||||||
|
|| !SaveDiffImage (aDiff))
|
||||||
|
{
|
||||||
|
return Standard_False;
|
||||||
|
}
|
||||||
|
|
||||||
|
// save image
|
||||||
|
return aDiff.Save (theDiffPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : ignoreBorderEffect
|
||||||
|
// purpose :
|
||||||
|
// =======================================================================
|
||||||
|
Standard_Integer Image_Diff::ignoreBorderEffect()
|
||||||
|
{
|
||||||
|
if (myImageRef.IsNull() || myImageNew.IsNull())
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Image_PixMapData<Image_ColorRGB>& aDataRef = myImageRef->ReadData<Image_ColorRGB>();
|
||||||
|
|
||||||
|
// allocate groups of different pixels
|
||||||
|
releaseGroupsOfDiffPixels();
|
||||||
|
|
||||||
|
// Find a different area (a set of close to each other pixels which colors differ in both images).
|
||||||
|
// It filters alone pixels with different color.
|
||||||
|
Standard_Size aRow1, aCol1, aRow2, aCol2;
|
||||||
|
Standard_Integer aLen1 = (myDiffPixels.Length() > 0) ? (myDiffPixels.Length() - 1) : 0;
|
||||||
|
for (Standard_Integer aPixelId1 = 0; aPixelId1 < aLen1; ++aPixelId1)
|
||||||
|
{
|
||||||
|
const Standard_Size aValue1 = myDiffPixels.Value (aPixelId1);
|
||||||
|
int2Pixel (aValue1, aRow1, aCol1);
|
||||||
|
|
||||||
|
// Check other pixels in the list looking for a neighbour of this one
|
||||||
|
for (Standard_Integer aPixelId2 = aPixelId1 + 1; aPixelId2 < myDiffPixels.Length(); ++aPixelId2)
|
||||||
|
{
|
||||||
|
const Standard_Size aValue2 = myDiffPixels.Value (aPixelId2);
|
||||||
|
int2Pixel (aValue2, aRow2, aCol2);
|
||||||
|
if (std::abs (ptrdiff_t (aCol1 - aCol2)) <= 1 &&
|
||||||
|
std::abs (ptrdiff_t (aRow1 - aRow2)) <= 1)
|
||||||
|
{
|
||||||
|
// A neighbour is found. Create a new group and add both pixels.
|
||||||
|
if (myGroupsOfDiffPixels.IsEmpty())
|
||||||
|
{
|
||||||
|
TColStd_MapOfInteger* aGroup = new TColStd_MapOfInteger();
|
||||||
|
aGroup->Add (aValue1);
|
||||||
|
aGroup->Add (aValue2);
|
||||||
|
myGroupsOfDiffPixels.Append (aGroup);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Find a group the pixels belong to.
|
||||||
|
Standard_Boolean isFound = Standard_False;
|
||||||
|
for (ListOfMapOfInteger::Iterator aGrIter (myGroupsOfDiffPixels); aGrIter.More(); aGrIter.Next())
|
||||||
|
{
|
||||||
|
TColStd_MapOfInteger*& aGroup = aGrIter.ChangeValue();
|
||||||
|
if (aGroup->Contains (aValue1))
|
||||||
|
{
|
||||||
|
aGroup->Add (aValue2);
|
||||||
|
isFound = Standard_True;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isFound)
|
||||||
|
{
|
||||||
|
// Create a new group
|
||||||
|
TColStd_MapOfInteger* aGroup = new TColStd_MapOfInteger();
|
||||||
|
aGroup->Add (aValue1);
|
||||||
|
aGroup->Add (aValue2);
|
||||||
|
myGroupsOfDiffPixels.Append (aGroup);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// filter linear groups which represent border of a solid shape
|
||||||
|
Standard_Integer aGroupId = 1;
|
||||||
|
for (ListOfMapOfInteger::Iterator aGrIter (myGroupsOfDiffPixels); aGrIter.More(); aGrIter.Next(), ++aGroupId)
|
||||||
|
{
|
||||||
|
Standard_Integer aNeighboursNb = 0;
|
||||||
|
Standard_Boolean isLine = Standard_True;
|
||||||
|
const TColStd_MapOfInteger* aGroup = aGrIter.Value();
|
||||||
|
for (TColStd_MapIteratorOfMapOfInteger aPixelIter (*aGroup); aPixelIter.More(); aPixelIter.Next())
|
||||||
|
{
|
||||||
|
int2Pixel (aPixelIter.Key(), aRow1, aCol1);
|
||||||
|
aNeighboursNb = 0;
|
||||||
|
|
||||||
|
// pixels of a line have only 1 or 2 neighbour pixels inside the same group
|
||||||
|
// check all neighbour pixels on presence in the group
|
||||||
|
for (Standard_Size aNgbrIter = 0; aNgbrIter < NEIGHBOR_PIXELS_NB; ++aNgbrIter)
|
||||||
|
{
|
||||||
|
if (aGroup->Contains (NEIGHBOR_PIXELS[aNgbrIter].pixel2Int (aRow1, aCol1)))
|
||||||
|
{
|
||||||
|
++aNeighboursNb;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aNeighboursNb > 2)
|
||||||
|
{
|
||||||
|
isLine = Standard_False;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} // for pixels inside group...
|
||||||
|
|
||||||
|
if (isLine)
|
||||||
|
{
|
||||||
|
// Test a pixel of the linear group on belonging to a solid shape.
|
||||||
|
// Consider neighbour pixels of the last pixel of the linear group in the 1st image.
|
||||||
|
// If the pixel has greater than 1 not black neighbour pixel, it is a border of a shape.
|
||||||
|
// Otherwise, it may be a topological edge, for example.
|
||||||
|
aNeighboursNb = 0;
|
||||||
|
for (Standard_Size aNgbrIter = 0; aNgbrIter < NEIGHBOR_PIXELS_NB; ++aNgbrIter)
|
||||||
|
{
|
||||||
|
if (!NEIGHBOR_PIXELS[aNgbrIter].isBlack (aDataRef, aRow1, aCol1))
|
||||||
|
{
|
||||||
|
++aNeighboursNb;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aNeighboursNb > 1)
|
||||||
|
{
|
||||||
|
myLinearGroups.Add (aGroupId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // for groups...
|
||||||
|
|
||||||
|
// number of different groups of pixels (except linear groups)
|
||||||
|
Standard_Integer aNbDiffColors = 0;
|
||||||
|
aGroupId = 1;
|
||||||
|
for (ListOfMapOfInteger::Iterator aGrIter (myGroupsOfDiffPixels); aGrIter.More(); aGrIter.Next(), ++aGroupId)
|
||||||
|
{
|
||||||
|
if (!myLinearGroups.Contains (aGroupId))
|
||||||
|
++aNbDiffColors;
|
||||||
|
}
|
||||||
|
|
||||||
|
return aNbDiffColors;
|
||||||
|
}
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : releaseGroupsOfDiffPixels
|
||||||
|
// purpose :
|
||||||
|
// =======================================================================
|
||||||
|
void Image_Diff::releaseGroupsOfDiffPixels()
|
||||||
|
{
|
||||||
|
for (ListOfMapOfInteger::Iterator aGrIter (myGroupsOfDiffPixels); aGrIter.More(); aGrIter.Next())
|
||||||
|
{
|
||||||
|
TColStd_MapOfInteger*& aGroup = aGrIter.ChangeValue();
|
||||||
|
delete aGroup;
|
||||||
|
}
|
||||||
|
myGroupsOfDiffPixels.Clear();
|
||||||
|
myLinearGroups.Clear();
|
||||||
|
}
|
135
src/Image/Image_Diff.hxx
Normal file
135
src/Image/Image_Diff.hxx
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
// Created on: 2012-07-10
|
||||||
|
// Created by: VRO
|
||||||
|
// Copyright (c) 2012 OPEN CASCADE SAS
|
||||||
|
//
|
||||||
|
// The content of this file is subject to the Open CASCADE Technology Public
|
||||||
|
// License Version 6.5 (the "License"). You may not use the content of this file
|
||||||
|
// except in compliance with the License. Please obtain a copy of the License
|
||||||
|
// at http://www.opencascade.org and read it completely before using this file.
|
||||||
|
//
|
||||||
|
// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
|
||||||
|
// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
|
||||||
|
//
|
||||||
|
// The Original Code and all software distributed under the License is
|
||||||
|
// distributed on an "AS IS" basis, without warranty of any kind, and the
|
||||||
|
// Initial Developer hereby disclaims all such warranties, including without
|
||||||
|
// limitation, any warranties of merchantability, fitness for a particular
|
||||||
|
// purpose or non-infringement. Please see the License for the specific terms
|
||||||
|
// and conditions governing the rights and limitations under the License.
|
||||||
|
|
||||||
|
#ifndef _Image_Diff_H__
|
||||||
|
#define _Image_Diff_H__
|
||||||
|
|
||||||
|
#include <Image_PixMap.hxx>
|
||||||
|
#include <TCollection_AsciiString.hxx>
|
||||||
|
#include <TColStd_MapOfInteger.hxx>
|
||||||
|
#include <NCollection_List.hxx>
|
||||||
|
#include <NCollection_Vector.hxx>
|
||||||
|
|
||||||
|
//! This class compares two images pixel-by-pixel.
|
||||||
|
//! It uses the following methods to ignore the difference between images:
|
||||||
|
//! - Black/White comparison. It makes the images 2-colored before the comparison.
|
||||||
|
//! - Equality with tolerance. Colors of two pixels are considered the same if the
|
||||||
|
//! differnce of their color is less than a tolerance.
|
||||||
|
//! - Border filter. The algorithm ignores alone independent pixels,
|
||||||
|
//! which are different on both images, ignores the "border effect" -
|
||||||
|
//! the difference caused by triangles located at angle about 0 or 90 degrees to the user.
|
||||||
|
//!
|
||||||
|
//! Border filter ignores a difference in implementation of
|
||||||
|
//! anti-aliasing and other effects on boundary of a shape.
|
||||||
|
//! The triangles of a boundary zone are usually located so that their normals point aside the user
|
||||||
|
//! (about 90 degree between the normal and the direction to the user's eye).
|
||||||
|
//! Deflection of the light for such a triangle depends on implementation of the video driver.
|
||||||
|
//! In order to skip this difference the following algorithm is used:
|
||||||
|
//! a) "Different" pixels are groupped and checked on "one-pixel width line".
|
||||||
|
//! indeed, the pixels may represent not a line, but any curve.
|
||||||
|
//! But the width of this curve should be not more than a pixel.
|
||||||
|
//! This group of pixels become a candidate to be ignored because of boundary effect.
|
||||||
|
//! b) The group of pixels is checked on belonging to a "shape".
|
||||||
|
//! Neighbour pixels are checked from the reference image.
|
||||||
|
//! This test confirms a fact that the group of pixels belongs to a shape and
|
||||||
|
//! represent a boundary of the shape.
|
||||||
|
//! In this case the whole group of pixels is ignored (considered as same).
|
||||||
|
//! Otherwise, the group of pixels may represent a geometrical curve in the viewer 3D
|
||||||
|
//! and should be considered as "different".
|
||||||
|
class Image_Diff : public Standard_Transient
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//! An empty constructor. Init() should be called for initialization.
|
||||||
|
Standard_EXPORT Image_Diff();
|
||||||
|
|
||||||
|
//! Desctructor.
|
||||||
|
Standard_EXPORT virtual ~Image_Diff();
|
||||||
|
|
||||||
|
//! Initialize algorithm by two images.
|
||||||
|
//! @return false if images has different or unsupported pixel format.
|
||||||
|
Standard_EXPORT Standard_Boolean Init (const Handle(Image_PixMap)& theImageRef,
|
||||||
|
const Handle(Image_PixMap)& theImageNew,
|
||||||
|
const Standard_Boolean theToBlackWhite = Standard_False);
|
||||||
|
|
||||||
|
//! Initialize algorithm by two images (will be loaded from files).
|
||||||
|
//! @return false if images couldn't be opened or their format is unsupported.
|
||||||
|
Standard_EXPORT Standard_Boolean Init (const TCollection_AsciiString& theImgPathRef,
|
||||||
|
const TCollection_AsciiString& theImgPathNew,
|
||||||
|
const Standard_Boolean theToBlackWhite = Standard_False);
|
||||||
|
|
||||||
|
//! Color tolerance for equality check. Should be within range 0..1:
|
||||||
|
//! Corresponds to a difference between white and black colors (maximum difference).
|
||||||
|
//! By default, the tolerance is equal to 0 thus equality check will return false for any different colors.
|
||||||
|
Standard_EXPORT void SetColorTolerance (const Standard_Real theTolerance);
|
||||||
|
|
||||||
|
//! Color tolerance for equality check.
|
||||||
|
Standard_EXPORT Standard_Real ColorTolerance() const;
|
||||||
|
|
||||||
|
//! Sets taking into account (ignoring) a "border effect" on comparison of images.
|
||||||
|
//! The border effect is caused by a border of shaded shapes in the viewer 3d.
|
||||||
|
//! Triangles of this area are located at about 0 or 90 degrees to the user.
|
||||||
|
//! Therefore, they deflect light differently according to implementation of a video card driver.
|
||||||
|
//! This flag allows to detect such a "border" area and skip it from comparison of images.
|
||||||
|
//! Filter turned OFF by default.
|
||||||
|
Standard_EXPORT void SetBorderFilterOn (const Standard_Boolean theToIgnore);
|
||||||
|
|
||||||
|
//! Returns a flag of taking into account (ignoring) a border effect in comparison of images.
|
||||||
|
Standard_EXPORT Standard_Boolean IsBorderFilterOn() const;
|
||||||
|
|
||||||
|
//! Compares two images. It returns a number of different pixels (or groups of pixels).
|
||||||
|
//! It returns -1 if algorithm not initialized before.
|
||||||
|
Standard_EXPORT Standard_Integer Compare();
|
||||||
|
|
||||||
|
//! Saves a difference between two images as white pixels on black backgroud.
|
||||||
|
Standard_EXPORT Standard_Boolean SaveDiffImage (Image_PixMap& theDiffImage) const;
|
||||||
|
|
||||||
|
//! Saves a difference between two images as white pixels on black backgroud.
|
||||||
|
Standard_EXPORT Standard_Boolean SaveDiffImage (const TCollection_AsciiString& theDiffPath) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
//! Perform border filter algorithm.
|
||||||
|
Standard_EXPORT Standard_Integer ignoreBorderEffect();
|
||||||
|
|
||||||
|
//! Release dynamically allocated memory.
|
||||||
|
Standard_EXPORT void releaseGroupsOfDiffPixels();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
typedef NCollection_List<TColStd_MapOfInteger* > ListOfMapOfInteger;
|
||||||
|
|
||||||
|
Handle(Image_PixMap) myImageRef; //!< reference image to compare (from)
|
||||||
|
Handle(Image_PixMap) myImageNew; //!< new image to compare (to)
|
||||||
|
Standard_Real myColorTolerance; //!< tolerance for equality check (0..1, 0 - any not equal, 1 - opposite colors)
|
||||||
|
Standard_Boolean myIsBorderFilterOn; //!< perform algorithm with border effect filter
|
||||||
|
ListOfMapOfInteger myGroupsOfDiffPixels;
|
||||||
|
NCollection_Vector<Standard_Size> myDiffPixels; //!< different pixels (position packed into integer)
|
||||||
|
TColStd_MapOfInteger myLinearGroups;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
DEFINE_STANDARD_RTTI(Image_Diff) // Type definition
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
DEFINE_STANDARD_HANDLE(Image_Diff, Standard_Transient)
|
||||||
|
|
||||||
|
#endif // _Image_Diff_H__
|
@ -1,147 +0,0 @@
|
|||||||
-- Created on: 2010-09-16
|
|
||||||
-- Created by: KGV
|
|
||||||
-- Copyright (c) 2010-2012 OPEN CASCADE SAS
|
|
||||||
--
|
|
||||||
-- The content of this file is subject to the Open CASCADE Technology Public
|
|
||||||
-- License Version 6.5 (the "License"). You may not use the content of this file
|
|
||||||
-- except in compliance with the License. Please obtain a copy of the License
|
|
||||||
-- at http://www.opencascade.org and read it completely before using this file.
|
|
||||||
--
|
|
||||||
-- The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
|
|
||||||
-- main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
|
|
||||||
--
|
|
||||||
-- The Original Code and all software distributed under the License is
|
|
||||||
-- distributed on an "AS IS" basis, without warranty of any kind, and the
|
|
||||||
-- Initial Developer hereby disclaims all such warranties, including without
|
|
||||||
-- limitation, any warranties of merchantability, fitness for a particular
|
|
||||||
-- purpose or non-infringement. Please see the License for the specific terms
|
|
||||||
-- and conditions governing the rights and limitations under the License.
|
|
||||||
|
|
||||||
|
|
||||||
class PixMap from Image
|
|
||||||
|
|
||||||
---Version:
|
|
||||||
|
|
||||||
---Purpose: This class defines a system-independent bitmap
|
|
||||||
|
|
||||||
---Keywords: Bitmap, Pixmap
|
|
||||||
|
|
||||||
inherits
|
|
||||||
PixMap from Aspect
|
|
||||||
|
|
||||||
uses
|
|
||||||
Handle from Aspect,
|
|
||||||
TypeOfImage from Image,
|
|
||||||
HPrivateImage from Image,
|
|
||||||
CRawBufferData from Image,
|
|
||||||
Color from Quantity,
|
|
||||||
Parameter from Quantity
|
|
||||||
|
|
||||||
raises
|
|
||||||
PixmapDefinitionError from Aspect,
|
|
||||||
PixmapError from Aspect
|
|
||||||
|
|
||||||
is
|
|
||||||
|
|
||||||
Create ( theWidth, theHeight : Integer from Standard;
|
|
||||||
theType : TypeOfImage from Image )
|
|
||||||
returns mutable PixMap from Image
|
|
||||||
raises PixmapDefinitionError from Aspect;
|
|
||||||
---Level: Public
|
|
||||||
---Purpose:
|
|
||||||
-- Allocate the bitmap with requested dimensions.
|
|
||||||
-- Allowed image types:
|
|
||||||
-- - Image_TOI_RGB (color image, 1 byte per component);
|
|
||||||
-- - Image_TOI_RGBA (color image with alpha channel);
|
|
||||||
-- - Image_TOI_RGBF (color image, 1 float per component);
|
|
||||||
-- - Image_TOI_RGBAF (color image with alpha channel);
|
|
||||||
-- - Image_TOI_FLOAT (grey image, 1 float per pixel).
|
|
||||||
|
|
||||||
Create ( theDataPtr : PByte from Standard;
|
|
||||||
theWidth, theHeight : Integer from Standard;
|
|
||||||
thePitch : Integer from Standard;
|
|
||||||
theBitsPerPixel : Integer from Standard;
|
|
||||||
theIsTopDown : Boolean from Standard )
|
|
||||||
returns mutable PixMap from Image
|
|
||||||
raises PixmapDefinitionError from Aspect;
|
|
||||||
---Level: Public
|
|
||||||
---Purpose:
|
|
||||||
-- Create a bitmap by copying an existing buffer.
|
|
||||||
|
|
||||||
---------------------------------------------------
|
|
||||||
-- Category: Methods to modify the class definition
|
|
||||||
---------------------------------------------------
|
|
||||||
|
|
||||||
Destroy ( me : mutable )
|
|
||||||
---Level: Advanced
|
|
||||||
---Purpose:
|
|
||||||
-- Destroies the Bitmap
|
|
||||||
---C++: alias ~
|
|
||||||
---Trigger: Raises if Bitmap is not defined properly
|
|
||||||
raises PixmapError from Aspect is virtual;
|
|
||||||
|
|
||||||
Dump ( me;
|
|
||||||
theFilename : CString from Standard;
|
|
||||||
theGammaCorr : Real from Standard = 1.0 )
|
|
||||||
returns Boolean from Standard
|
|
||||||
---Level: Advanced
|
|
||||||
---Purpose:
|
|
||||||
-- Dumps the Bitmap to an image file with
|
|
||||||
-- an optional gamma correction value
|
|
||||||
-- and returns TRUE if the dump occurs normaly.
|
|
||||||
raises PixmapError from Aspect is virtual;
|
|
||||||
|
|
||||||
----------------------------
|
|
||||||
-- Category: Inquire methods
|
|
||||||
----------------------------
|
|
||||||
|
|
||||||
PixmapID ( me ) returns Handle from Aspect is virtual;
|
|
||||||
---Level: Advanced
|
|
||||||
---Purpose:
|
|
||||||
-- Returns NULL handle
|
|
||||||
---Category: Inquire methods
|
|
||||||
|
|
||||||
----------------------------
|
|
||||||
-- Category: Access methods
|
|
||||||
----------------------------
|
|
||||||
|
|
||||||
AccessBuffer ( me : in;
|
|
||||||
theBufferInfo : in out CRawBufferData from Image )
|
|
||||||
is static;
|
|
||||||
---Purpose:
|
|
||||||
-- Fill the structure for low-level access to the bitmap data.
|
|
||||||
-- It is up to you to interpret these bytes correctly!
|
|
||||||
-- Important notice: image stored upside-down in the memory,
|
|
||||||
-- first image row is an last scanline in
|
|
||||||
-- the memory buffer.
|
|
||||||
-- If image was created with type Image_TOI_FLOAT buffer
|
|
||||||
-- format will be set to TDepthComponent. You can override
|
|
||||||
-- this field with another one-channel buffer format because
|
|
||||||
-- it useless for bitmap definition.
|
|
||||||
|
|
||||||
PixelColor ( me : in;
|
|
||||||
theX, theY : in Integer from Standard )
|
|
||||||
returns Color from Quantity
|
|
||||||
is virtual;
|
|
||||||
---Purpose:
|
|
||||||
-- Returns the pixel color. This function is relatively slow,
|
|
||||||
-- use AccessBuffer() instead for stream operations.
|
|
||||||
-- Note that this function convert input theY coordinate
|
|
||||||
-- to count off from top of an image (while in memory it stored
|
|
||||||
-- upside-down).
|
|
||||||
|
|
||||||
PixelColor ( me : in;
|
|
||||||
theX, theY : in Integer from Standard;
|
|
||||||
theAlpha : out Parameter from Quantity )
|
|
||||||
returns Color from Quantity;
|
|
||||||
---Purpose:
|
|
||||||
-- Returns the pixel color. This function is relatively slow,
|
|
||||||
-- use AccessBuffer() instead for stream operations.
|
|
||||||
-- theAlpha argument is set to color intensity (0 - transparent, 1 - opaque)
|
|
||||||
-- Note that this function convert input theY coordinate
|
|
||||||
-- to count off from top of an image (while in memory it stored
|
|
||||||
-- upside-down).
|
|
||||||
|
|
||||||
fields
|
|
||||||
myImage : HPrivateImage from Image is protected;
|
|
||||||
end PixMap;
|
|
@ -1,6 +1,6 @@
|
|||||||
// Created on: 2010-09-16
|
// Created on: 2012-07-18
|
||||||
// Created by: KGV
|
// Created by: Kirill GAVRILOV
|
||||||
// Copyright (c) 2010-2012 OPEN CASCADE SAS
|
// Copyright (c) 2012 OPEN CASCADE SAS
|
||||||
//
|
//
|
||||||
// The content of this file is subject to the Open CASCADE Technology Public
|
// The content of this file is subject to the Open CASCADE Technology Public
|
||||||
// License Version 6.5 (the "License"). You may not use the content of this file
|
// License Version 6.5 (the "License"). You may not use the content of this file
|
||||||
@ -17,414 +17,209 @@
|
|||||||
// purpose or non-infringement. Please see the License for the specific terms
|
// purpose or non-infringement. Please see the License for the specific terms
|
||||||
// and conditions governing the rights and limitations under the License.
|
// and conditions governing the rights and limitations under the License.
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#include <Image_PixMap.hxx>
|
||||||
# include <config.h>
|
|
||||||
|
#ifndef _MSC_VER
|
||||||
|
#include <mm_malloc.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_FREEIMAGE
|
template<typename TypePtr>
|
||||||
#include <FreeImagePlus.h>
|
inline TypePtr MemAllocAligned (const Standard_Size& theBytesCount,
|
||||||
#include <Image_PixMap.ixx>
|
const Standard_Size& theAlign = 16)
|
||||||
/* OCC22216 NOTE: linker dependency can be switched off by undefining macro */
|
{
|
||||||
#ifdef _MSC_VER
|
#if defined(_MSC_VER)
|
||||||
#pragma comment( lib, "FreeImage.lib" )
|
return (TypePtr )_aligned_malloc (theBytesCount, theAlign);
|
||||||
#pragma comment( lib, "FreeImagePlus.lib" )
|
|
||||||
#endif
|
|
||||||
#else
|
#else
|
||||||
#include <Image_PixMap.ixx>
|
return (TypePtr ) _mm_malloc (theBytesCount, theAlign);
|
||||||
#include <fstream>
|
|
||||||
|
|
||||||
#if (defined(BYTE_ORDER) && BYTE_ORDER==BIG_ENDIAN) || \
|
|
||||||
(defined(__BYTE_ORDER) && __BYTE_ORDER==__BIG_ENDIAN) || \
|
|
||||||
defined(__BIG_ENDIAN__)
|
|
||||||
#define THE_BIGENDIAN
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// dummy class which can only dump to PPM format
|
|
||||||
class fipImage
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
typedef struct tagRGBQuad {
|
|
||||||
#ifndef THE_BIGENDIAN
|
|
||||||
Standard_Byte rgbBlue;
|
|
||||||
Standard_Byte rgbGreen;
|
|
||||||
Standard_Byte rgbRed;
|
|
||||||
#else
|
|
||||||
Standard_Byte rgbRed;
|
|
||||||
Standard_Byte rgbGreen;
|
|
||||||
Standard_Byte rgbBlue;
|
|
||||||
#endif
|
|
||||||
Standard_Byte rgbReserved;
|
|
||||||
} RGBQuad_t;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
fipImage()
|
|
||||||
: myDataPtr(NULL),
|
|
||||||
mySizeX(0),
|
|
||||||
mySizeY(0),
|
|
||||||
myBytesPerLine(0),
|
|
||||||
myBytesPerPixel(3)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
fipImage (const Standard_Integer theSizeX, const Standard_Integer theSizeY,
|
|
||||||
const Standard_Integer theBytesPerLine = 0, const Standard_Integer theBytesPerPixel = 3)
|
|
||||||
: myDataPtr(NULL),
|
|
||||||
mySizeX (theSizeX),
|
|
||||||
mySizeY (theSizeY),
|
|
||||||
myBytesPerLine (theBytesPerLine),
|
|
||||||
myBytesPerPixel (theBytesPerPixel)
|
|
||||||
{
|
|
||||||
if (myBytesPerLine == 0)
|
|
||||||
{
|
|
||||||
myBytesPerLine = mySizeX * myBytesPerPixel;
|
|
||||||
}
|
|
||||||
myDataPtr = new Standard_Byte[myBytesPerLine * mySizeY];
|
|
||||||
}
|
|
||||||
|
|
||||||
~fipImage()
|
|
||||||
{
|
|
||||||
delete[] myDataPtr;
|
|
||||||
}
|
|
||||||
|
|
||||||
Standard_Integer getHeight() const
|
|
||||||
{
|
|
||||||
return mySizeY;
|
|
||||||
}
|
|
||||||
|
|
||||||
Standard_Integer getWidth() const
|
|
||||||
{
|
|
||||||
return mySizeX;
|
|
||||||
}
|
|
||||||
|
|
||||||
Standard_Integer getBytesPerPixel() const
|
|
||||||
{
|
|
||||||
return myBytesPerPixel;
|
|
||||||
}
|
|
||||||
|
|
||||||
Standard_Integer getBytesPerLine() const
|
|
||||||
{
|
|
||||||
return myBytesPerLine;
|
|
||||||
}
|
|
||||||
|
|
||||||
Standard_Byte* getData() const
|
|
||||||
{
|
|
||||||
return myDataPtr;
|
|
||||||
}
|
|
||||||
|
|
||||||
Standard_Byte* getScanLine (const Standard_Integer theRow) const
|
|
||||||
{
|
|
||||||
return &myDataPtr[theRow * myBytesPerLine];
|
|
||||||
}
|
|
||||||
|
|
||||||
Quantity_Color getPixelColor (const Standard_Integer theCol,
|
|
||||||
const Standard_Integer theRow,
|
|
||||||
Quantity_Parameter& theAlpha) const
|
|
||||||
{
|
|
||||||
RGBQuad_t* aPixel = (RGBQuad_t* )&getScanLine (theRow)[theCol * myBytesPerPixel];
|
|
||||||
theAlpha = (myBytesPerPixel > 3) ? (Standard_Real (aPixel->rgbReserved) / 255.0) : 1.0;
|
|
||||||
return Quantity_Color (Standard_Real (aPixel->rgbRed) / 255.0,
|
|
||||||
Standard_Real (aPixel->rgbGreen) / 255.0,
|
|
||||||
Standard_Real (aPixel->rgbBlue) / 255.0,
|
|
||||||
Quantity_TOC_RGB);
|
|
||||||
}
|
|
||||||
|
|
||||||
Standard_Boolean savePPM (const Standard_CString theFileName) const
|
|
||||||
{
|
|
||||||
// Open file
|
|
||||||
FILE* pFile = fopen (theFileName, "wb");
|
|
||||||
if (pFile == NULL)
|
|
||||||
{
|
|
||||||
return Standard_False;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write header
|
|
||||||
fprintf (pFile, "P6\n%d %d\n255\n", mySizeX, mySizeY);
|
|
||||||
|
|
||||||
// Write pixel data
|
|
||||||
Standard_Byte* aScanLine;
|
|
||||||
RGBQuad_t* aPixel;
|
|
||||||
// image stored upside-down
|
|
||||||
for (Standard_Integer aRow = mySizeY - 1; aRow >= 0; --aRow)
|
|
||||||
{
|
|
||||||
aScanLine = getScanLine (aRow);
|
|
||||||
for (Standard_Integer aCol = 0; aCol < mySizeX; ++aCol)
|
|
||||||
{
|
|
||||||
aPixel = (RGBQuad_t* )&aScanLine[aCol * myBytesPerPixel];
|
|
||||||
fwrite (&aPixel->rgbRed, 1, 1, pFile);
|
|
||||||
fwrite (&aPixel->rgbGreen, 1, 1, pFile);
|
|
||||||
fwrite (&aPixel->rgbBlue, 1, 1, pFile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close file
|
|
||||||
fclose (pFile);
|
|
||||||
return Standard_True;
|
|
||||||
}
|
|
||||||
|
|
||||||
Standard_Integer getMaxRowAligmentBytes() const
|
|
||||||
{
|
|
||||||
Standard_Integer aDeltaBytes = myBytesPerLine - myBytesPerPixel * mySizeX;
|
|
||||||
for (Standard_Integer anAligment = 16; anAligment > 1; anAligment /= 2)
|
|
||||||
{
|
|
||||||
if (isRowAlignedTo (anAligment, aDeltaBytes))
|
|
||||||
{
|
|
||||||
return anAligment;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
Standard_Boolean isRowAlignedTo (const Standard_Integer theAligmentBytes,
|
|
||||||
const Standard_Integer theDeltaBytes) const
|
|
||||||
{
|
|
||||||
return (theDeltaBytes < theAligmentBytes) &&
|
|
||||||
((myBytesPerLine % theAligmentBytes) == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
Standard_Byte* myDataPtr;
|
|
||||||
Standard_Integer mySizeX;
|
|
||||||
Standard_Integer mySizeY;
|
|
||||||
Standard_Integer myBytesPerLine;
|
|
||||||
Standard_Integer myBytesPerPixel;
|
|
||||||
|
|
||||||
};
|
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#include <gp.hxx>
|
inline void MemFreeAligned (void* thePtrAligned)
|
||||||
#include <TCollection_AsciiString.hxx>
|
|
||||||
|
|
||||||
//=======================================================================
|
|
||||||
//function : Image_PixMap
|
|
||||||
//purpose :
|
|
||||||
//=======================================================================
|
|
||||||
Image_PixMap::Image_PixMap (const Standard_Integer theWidth,
|
|
||||||
const Standard_Integer theHeight,
|
|
||||||
const Image_TypeOfImage theType)
|
|
||||||
: Aspect_PixMap (theWidth, theHeight, 1),
|
|
||||||
myImage()
|
|
||||||
{
|
{
|
||||||
#ifdef HAVE_FREEIMAGE
|
#if defined(_MSC_VER)
|
||||||
FREE_IMAGE_TYPE aFIType = FIT_UNKNOWN;
|
_aligned_free (thePtrAligned);
|
||||||
int aBitsPerPixel = 0;
|
|
||||||
switch (theType)
|
|
||||||
{
|
|
||||||
case Image_TOI_RGBA:
|
|
||||||
aFIType = FIT_BITMAP;
|
|
||||||
aBitsPerPixel = 32;
|
|
||||||
break;
|
|
||||||
case Image_TOI_RGBF:
|
|
||||||
aFIType = FIT_RGBF;
|
|
||||||
aBitsPerPixel = 96;
|
|
||||||
break;
|
|
||||||
case Image_TOI_RGBAF:
|
|
||||||
aFIType = FIT_RGBAF;
|
|
||||||
aBitsPerPixel = 128;
|
|
||||||
break;
|
|
||||||
case Image_TOI_FLOAT:
|
|
||||||
aFIType = FIT_FLOAT;
|
|
||||||
aBitsPerPixel = 32;
|
|
||||||
break;
|
|
||||||
case Image_TOI_RGB:
|
|
||||||
default:
|
|
||||||
aFIType = FIT_BITMAP;
|
|
||||||
aBitsPerPixel = 24;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
myImage = new fipImage (aFIType, theWidth, theHeight, aBitsPerPixel);
|
|
||||||
#else
|
#else
|
||||||
Standard_Integer aBytesPerPixel = 0;
|
_mm_free (thePtrAligned);
|
||||||
switch (theType)
|
|
||||||
{
|
|
||||||
case Image_TOI_RGBAF:
|
|
||||||
std::cerr << "Float formats not supported\n";
|
|
||||||
case Image_TOI_RGBA:
|
|
||||||
aBytesPerPixel = 4;
|
|
||||||
break;
|
|
||||||
case Image_TOI_RGBF:
|
|
||||||
case Image_TOI_FLOAT:
|
|
||||||
std::cerr << "Float formats not supported\n";
|
|
||||||
case Image_TOI_RGB:
|
|
||||||
default:
|
|
||||||
aBytesPerPixel = 3;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
myImage = new fipImage (theWidth, theHeight, 0, aBytesPerPixel);
|
|
||||||
//
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//=======================================================================
|
IMPLEMENT_STANDARD_HANDLE (Image_PixMap, Standard_Transient)
|
||||||
//function : Image_PixMap
|
IMPLEMENT_STANDARD_RTTIEXT(Image_PixMap, Standard_Transient)
|
||||||
//purpose :
|
|
||||||
//=======================================================================
|
|
||||||
Image_PixMap::Image_PixMap (const Standard_PByte theDataPtr,
|
|
||||||
const Standard_Integer theWidth, const Standard_Integer theHeight,
|
|
||||||
const Standard_Integer thePitch, const Standard_Integer theBitsPerPixel,
|
|
||||||
const Standard_Boolean theIsTopDown)
|
|
||||||
: Aspect_PixMap (theWidth, theHeight, 1),
|
|
||||||
myImage (new fipImage())
|
|
||||||
{
|
|
||||||
#ifdef HAVE_FREEIMAGE
|
|
||||||
*myImage = FreeImage_ConvertFromRawBits (theDataPtr,
|
|
||||||
theWidth, theHeight,
|
|
||||||
thePitch, theBitsPerPixel,
|
|
||||||
0, 0, 0,
|
|
||||||
theIsTopDown);
|
|
||||||
if (theBitsPerPixel != 24)
|
|
||||||
{
|
|
||||||
myImage->convertTo24Bits();
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
myImage = new fipImage (theWidth, theHeight, thePitch, theBitsPerPixel / 8);
|
|
||||||
Standard_Integer aRowStart = !theIsTopDown ? 0 : (theHeight - 1);
|
|
||||||
Standard_Integer aRowDelta = !theIsTopDown ? 1 : -1;
|
|
||||||
for (Standard_Integer aRowFrom (aRowStart), aRowTo (0);
|
|
||||||
aRowFrom >= 0 && aRowFrom < theHeight;
|
|
||||||
aRowFrom += aRowDelta, ++aRowTo)
|
|
||||||
{
|
|
||||||
memcpy (myImage->getScanLine (aRowTo),
|
|
||||||
&theDataPtr[aRowFrom * thePitch],
|
|
||||||
myImage->getBytesPerLine());
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
//=======================================================================
|
|
||||||
//function : Destroy
|
|
||||||
//purpose :
|
|
||||||
//=======================================================================
|
|
||||||
void Image_PixMap::Destroy()
|
|
||||||
{
|
|
||||||
myImage = Image_HPrivateImage();
|
|
||||||
}
|
|
||||||
|
|
||||||
//=======================================================================
|
|
||||||
//function : Dump
|
|
||||||
//purpose :
|
|
||||||
//=======================================================================
|
|
||||||
Standard_Boolean Image_PixMap::Dump (const Standard_CString theFilename,
|
|
||||||
const Standard_Real theGammaCorr) const
|
|
||||||
{
|
|
||||||
#ifdef HAVE_FREEIMAGE
|
|
||||||
FREE_IMAGE_FORMAT anImageFormat = FreeImage_GetFIFFromFilename (theFilename);
|
|
||||||
if (anImageFormat == FIF_UNKNOWN)
|
|
||||||
{
|
|
||||||
std::cerr << "Image_PixMap, image format doesn't supported!\n";
|
|
||||||
return Standard_False;
|
|
||||||
}
|
|
||||||
|
|
||||||
Standard_Boolean isCopied = Standard_False;
|
|
||||||
Image_HPrivateImage anImageToDump = myImage;
|
|
||||||
if (Abs (theGammaCorr - 1.0) > gp::Resolution())
|
|
||||||
{
|
|
||||||
if (!isCopied)
|
|
||||||
{
|
|
||||||
isCopied = Standard_True;
|
|
||||||
anImageToDump = new fipImage (*myImage);
|
|
||||||
}
|
|
||||||
anImageToDump->adjustGamma (theGammaCorr);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (anImageFormat)
|
|
||||||
{
|
|
||||||
case FIF_GIF:
|
|
||||||
if (!isCopied)
|
|
||||||
{
|
|
||||||
isCopied = Standard_True;
|
|
||||||
anImageToDump = new fipImage (*myImage);
|
|
||||||
}
|
|
||||||
// need convertion to image with pallete
|
|
||||||
anImageToDump->colorQuantize (FIQ_NNQUANT);
|
|
||||||
break;
|
|
||||||
case FIF_EXR:
|
|
||||||
if (myImage->getImageType() == FIT_BITMAP)
|
|
||||||
{
|
|
||||||
if (!isCopied)
|
|
||||||
{
|
|
||||||
isCopied = Standard_True;
|
|
||||||
anImageToDump = new fipImage (*myImage);
|
|
||||||
}
|
|
||||||
anImageToDump->convertToType (FIT_RGBF);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
if (myImage->getImageType() != FIT_BITMAP)
|
|
||||||
{
|
|
||||||
if (!isCopied)
|
|
||||||
{
|
|
||||||
isCopied = Standard_True;
|
|
||||||
anImageToDump = new fipImage (*myImage);
|
|
||||||
}
|
|
||||||
anImageToDump->convertToType (FIT_BITMAP);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return anImageToDump->save (theFilename);
|
|
||||||
#else
|
|
||||||
return myImage->savePPM (theFilename);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
Aspect_Handle Image_PixMap::PixmapID() const
|
|
||||||
{
|
|
||||||
return Aspect_Handle();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Image_PixMap::AccessBuffer (Image_CRawBufferData& theBuffer) const
|
|
||||||
{
|
|
||||||
theBuffer.widthPx = myImage->getWidth();
|
|
||||||
theBuffer.heightPx = myImage->getHeight();
|
|
||||||
#ifdef HAVE_FREEIMAGE
|
|
||||||
theBuffer.rowAligmentBytes = 4; // 32 bits according to FreeImage documentation
|
|
||||||
switch (myImage->getImageType())
|
|
||||||
{
|
|
||||||
case FIT_FLOAT:
|
|
||||||
theBuffer.format = TDepthComponent;
|
|
||||||
theBuffer.type = TFloat;
|
|
||||||
break;
|
|
||||||
case FIT_RGBF:
|
|
||||||
theBuffer.format = TRGB;
|
|
||||||
theBuffer.type = TFloat;
|
|
||||||
break;
|
|
||||||
case FIT_RGBAF:
|
|
||||||
theBuffer.format = TRGBA;
|
|
||||||
theBuffer.type = TFloat;
|
|
||||||
break;
|
|
||||||
case FIT_BITMAP:
|
|
||||||
default:
|
|
||||||
#if defined(FREEIMAGE_BIGENDIAN)
|
|
||||||
theBuffer.format = (myImage->getColorType() == FIC_RGBALPHA) ? TRGBA : TRGB;
|
|
||||||
#else
|
|
||||||
theBuffer.format = (myImage->getColorType() == FIC_RGBALPHA) ? TBGRA : TBGR;
|
|
||||||
#endif
|
|
||||||
theBuffer.type = TUByte;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
theBuffer.dataPtr = myImage->accessPixels();
|
|
||||||
#else
|
|
||||||
theBuffer.rowAligmentBytes = myImage->getMaxRowAligmentBytes();
|
|
||||||
theBuffer.format = (myImage->getBytesPerPixel() == 4) ? TBGRA : TBGR;
|
|
||||||
theBuffer.type = TUByte;
|
|
||||||
theBuffer.dataPtr = myImage->getData();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
// function : PixelColor
|
// function : Image_PixMap
|
||||||
// purpose :
|
// purpose :
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
Quantity_Color Image_PixMap::PixelColor (const Standard_Integer theX,
|
Image_PixMap::Image_PixMap()
|
||||||
const Standard_Integer theY) const
|
: myImgFormat (Image_PixMap::ImgGray),
|
||||||
|
myIsOwnPointer (true)
|
||||||
{
|
{
|
||||||
Quantity_Parameter aDummy;
|
memset (&myData, 0, sizeof(myData));
|
||||||
return PixelColor (theX, theY, aDummy);
|
myData.mySizeBPP = 1;
|
||||||
|
myData.myTopToDown = 1;
|
||||||
|
setFormat (Image_PixMap::ImgGray);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : ~Image_PixMap
|
||||||
|
// purpose :
|
||||||
|
// =======================================================================
|
||||||
|
Image_PixMap::~Image_PixMap()
|
||||||
|
{
|
||||||
|
Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
Standard_Size Image_PixMap::SizePixelBytes (const Image_PixMap::ImgFormat thePixelFormat)
|
||||||
|
{
|
||||||
|
switch (thePixelFormat)
|
||||||
|
{
|
||||||
|
case ImgGrayF:
|
||||||
|
return sizeof(float);
|
||||||
|
case ImgRGBAF:
|
||||||
|
case ImgBGRAF:
|
||||||
|
return sizeof(float) * 4;
|
||||||
|
case ImgRGBF:
|
||||||
|
case ImgBGRF:
|
||||||
|
return sizeof(float) * 3;
|
||||||
|
case ImgRGBA:
|
||||||
|
case ImgBGRA:
|
||||||
|
return 4;
|
||||||
|
case ImgRGB32:
|
||||||
|
case ImgBGR32:
|
||||||
|
return 4;
|
||||||
|
case ImgRGB:
|
||||||
|
case ImgBGR:
|
||||||
|
return 3;
|
||||||
|
case ImgGray:
|
||||||
|
default:
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : setFormat
|
||||||
|
// purpose :
|
||||||
|
// =======================================================================
|
||||||
|
void Image_PixMap::setFormat (Image_PixMap::ImgFormat thePixelFormat)
|
||||||
|
{
|
||||||
|
myImgFormat = thePixelFormat;
|
||||||
|
myData.mySizeBPP = SizePixelBytes (myImgFormat);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : setTopDown
|
||||||
|
// purpose :
|
||||||
|
// =======================================================================
|
||||||
|
void Image_PixMap::setTopDown()
|
||||||
|
{
|
||||||
|
myData.myTopRowPtr = ((myData.myTopToDown == 1 || myData.myDataPtr == NULL)
|
||||||
|
? myData.myDataPtr : (myData.myDataPtr + myData.mySizeRowBytes * (myData.mySizeY - 1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : InitWrapper
|
||||||
|
// purpose :
|
||||||
|
// =======================================================================
|
||||||
|
bool Image_PixMap::InitWrapper (Image_PixMap::ImgFormat thePixelFormat,
|
||||||
|
Standard_Byte* theDataPtr,
|
||||||
|
const Standard_Size theSizeX,
|
||||||
|
const Standard_Size theSizeY,
|
||||||
|
const Standard_Size theSizeRowBytes)
|
||||||
|
{
|
||||||
|
Clear (thePixelFormat);
|
||||||
|
if ((theSizeX == 0) || (theSizeY == 0) || (theDataPtr == NULL))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
myData.mySizeX = theSizeX;
|
||||||
|
myData.mySizeY = theSizeY;
|
||||||
|
myData.mySizeRowBytes = (theSizeRowBytes != 0) ? theSizeRowBytes : (theSizeX * myData.mySizeBPP);
|
||||||
|
myData.myDataPtr = theDataPtr;
|
||||||
|
myIsOwnPointer = false;
|
||||||
|
setTopDown();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : InitTrash
|
||||||
|
// purpose :
|
||||||
|
// =======================================================================
|
||||||
|
bool Image_PixMap::InitTrash (Image_PixMap::ImgFormat thePixelFormat,
|
||||||
|
const Standard_Size theSizeX,
|
||||||
|
const Standard_Size theSizeY,
|
||||||
|
const Standard_Size theSizeRowBytes)
|
||||||
|
{
|
||||||
|
Clear (thePixelFormat);
|
||||||
|
if ((theSizeX == 0) || (theSizeY == 0))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
myData.mySizeX = theSizeX;
|
||||||
|
myData.mySizeY = theSizeY;
|
||||||
|
myData.mySizeRowBytes = myData.mySizeX * myData.mySizeBPP;
|
||||||
|
if (theSizeRowBytes > myData.mySizeRowBytes)
|
||||||
|
{
|
||||||
|
// use argument only if it greater
|
||||||
|
myData.mySizeRowBytes = theSizeRowBytes;
|
||||||
|
}
|
||||||
|
myData.myDataPtr = MemAllocAligned<Standard_Byte*> (SizeBytes());
|
||||||
|
myIsOwnPointer = true;
|
||||||
|
setTopDown();
|
||||||
|
return myData.myDataPtr != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : InitZero
|
||||||
|
// purpose :
|
||||||
|
// =======================================================================
|
||||||
|
bool Image_PixMap::InitZero (Image_PixMap::ImgFormat thePixelFormat,
|
||||||
|
const Standard_Size theSizeX,
|
||||||
|
const Standard_Size theSizeY,
|
||||||
|
const Standard_Size theSizeRowBytes,
|
||||||
|
const Standard_Byte theValue)
|
||||||
|
{
|
||||||
|
if (!InitTrash (thePixelFormat, theSizeX, theSizeY, theSizeRowBytes))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
memset (myData.myDataPtr, (int )theValue, SizeBytes());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : InitCopy
|
||||||
|
// purpose :
|
||||||
|
// =======================================================================
|
||||||
|
bool Image_PixMap::InitCopy (const Image_PixMap& theCopy)
|
||||||
|
{
|
||||||
|
if (&theCopy == this)
|
||||||
|
{
|
||||||
|
// self-copying disallowed
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (InitTrash (theCopy.myImgFormat, theCopy.myData.mySizeX, theCopy.myData.mySizeY, theCopy.myData.mySizeRowBytes))
|
||||||
|
{
|
||||||
|
memcpy (myData.myDataPtr, theCopy.myData.myDataPtr, theCopy.SizeBytes());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : Clear
|
||||||
|
// purpose :
|
||||||
|
// =======================================================================
|
||||||
|
void Image_PixMap::Clear (Image_PixMap::ImgFormat thePixelFormat)
|
||||||
|
{
|
||||||
|
if (myIsOwnPointer && (myData.myDataPtr != NULL))
|
||||||
|
{
|
||||||
|
MemFreeAligned (myData.myDataPtr);
|
||||||
|
}
|
||||||
|
myData.myDataPtr = myData.myTopRowPtr = NULL;
|
||||||
|
myIsOwnPointer = true;
|
||||||
|
myData.mySizeX = myData.mySizeY = myData.mySizeRowBytes = 0;
|
||||||
|
setFormat (thePixelFormat);
|
||||||
|
myData.myTopToDown = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
@ -435,64 +230,130 @@ Quantity_Color Image_PixMap::PixelColor (const Standard_Integer theX,
|
|||||||
const Standard_Integer theY,
|
const Standard_Integer theY,
|
||||||
Quantity_Parameter& theAlpha) const
|
Quantity_Parameter& theAlpha) const
|
||||||
{
|
{
|
||||||
Standard_Integer aScanlineId = myImage->getHeight() - theY - 1;
|
if (IsEmpty() ||
|
||||||
if (theX < 0 || (unsigned int )theX >= (unsigned int )myImage->getWidth() ||
|
theX < 0 || (Standard_Size )theX >= myData.mySizeX ||
|
||||||
theY < 0 || (unsigned int )theY >= (unsigned int )myImage->getHeight())
|
theY < 0 || (Standard_Size )theY >= myData.mySizeY)
|
||||||
{
|
{
|
||||||
theAlpha = 0.0; // transparent
|
theAlpha = 0.0; // transparent
|
||||||
return Quantity_Color (0.0, 0.0, 0.0, Quantity_TOC_RGB);
|
return Quantity_Color (0.0, 0.0, 0.0, Quantity_TOC_RGB);
|
||||||
}
|
}
|
||||||
#ifdef HAVE_FREEIMAGE
|
|
||||||
else if (myImage->getImageType() == FIT_BITMAP)
|
switch (myImgFormat)
|
||||||
{
|
{
|
||||||
RGBQUAD aValue; memset (&aValue, 0, sizeof(aValue));
|
case ImgGrayF:
|
||||||
myImage->getPixelColor (theX, aScanlineId, &aValue);
|
|
||||||
theAlpha = (myImage->getColorType() == FIC_RGBALPHA) ? (Standard_Real (aValue.rgbReserved) / 255.0) : 1.0;
|
|
||||||
return Quantity_Color (Standard_Real (aValue.rgbRed) / 255.0,
|
|
||||||
Standard_Real (aValue.rgbGreen) / 255.0,
|
|
||||||
Standard_Real (aValue.rgbBlue) / 255.0,
|
|
||||||
Quantity_TOC_RGB);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
switch (myImage->getImageType())
|
|
||||||
{
|
{
|
||||||
case FIT_FLOAT:
|
const Standard_ShortReal& aPixel = Value<Standard_ShortReal> (theY, theX);
|
||||||
{
|
theAlpha = 1.0; // opaque
|
||||||
float* aScanLine = (float* )myImage->getScanLine (aScanlineId);
|
return Quantity_Color (Quantity_Parameter (Standard_Real (aPixel)),
|
||||||
Quantity_Parameter aValue = Quantity_Parameter (aScanLine[theX]);
|
Quantity_Parameter (Standard_Real (aPixel)),
|
||||||
theAlpha = 1.0; // opaque
|
Quantity_Parameter (Standard_Real (aPixel)),
|
||||||
return Quantity_Color (aValue, aValue, aValue, Quantity_TOC_RGB);
|
Quantity_TOC_RGB);
|
||||||
}
|
break;
|
||||||
case FIT_RGBF:
|
}
|
||||||
{
|
case ImgRGBAF:
|
||||||
FIRGBF* aScanLine = (FIRGBF* )myImage->getScanLine (aScanlineId);
|
{
|
||||||
FIRGBF* aPixel = &aScanLine[theX];
|
const Image_ColorRGBAF& aPixel = Value<Image_ColorRGBAF> (theY, theX);
|
||||||
theAlpha = 1.0; // opaque
|
theAlpha = aPixel.a();
|
||||||
return Quantity_Color (Quantity_Parameter (aPixel->red),
|
return Quantity_Color (Quantity_Parameter (aPixel.r()),
|
||||||
Quantity_Parameter (aPixel->green),
|
Quantity_Parameter (aPixel.g()),
|
||||||
Quantity_Parameter (aPixel->blue),
|
Quantity_Parameter (aPixel.b()),
|
||||||
Quantity_TOC_RGB);
|
Quantity_TOC_RGB);
|
||||||
}
|
}
|
||||||
case FIT_RGBAF:
|
case ImgBGRAF:
|
||||||
{
|
{
|
||||||
FIRGBAF* aScanLine = (FIRGBAF* )myImage->getScanLine (aScanlineId);
|
const Image_ColorBGRAF& aPixel = Value<Image_ColorBGRAF> (theY, theX);
|
||||||
FIRGBAF* aPixel = &aScanLine[theX];
|
theAlpha = aPixel.a();
|
||||||
theAlpha = aPixel->alpha;
|
return Quantity_Color (Quantity_Parameter (aPixel.r()),
|
||||||
return Quantity_Color (Quantity_Parameter (aPixel->red),
|
Quantity_Parameter (aPixel.g()),
|
||||||
Quantity_Parameter (aPixel->green),
|
Quantity_Parameter (aPixel.b()),
|
||||||
Quantity_Parameter (aPixel->blue),
|
Quantity_TOC_RGB);
|
||||||
Quantity_TOC_RGB);
|
}
|
||||||
}
|
case ImgRGBF:
|
||||||
default:
|
{
|
||||||
{
|
const Image_ColorRGBF& aPixel = Value<Image_ColorRGBF> (theY, theX);
|
||||||
// not supported image type
|
theAlpha = 1.0; // opaque
|
||||||
theAlpha = 0.0; // transparent
|
return Quantity_Color (Quantity_Parameter (aPixel.r()),
|
||||||
return Quantity_Color (0.0, 0.0, 0.0, Quantity_TOC_RGB);
|
Quantity_Parameter (aPixel.g()),
|
||||||
}
|
Quantity_Parameter (aPixel.b()),
|
||||||
|
Quantity_TOC_RGB);
|
||||||
|
}
|
||||||
|
case ImgBGRF:
|
||||||
|
{
|
||||||
|
const Image_ColorBGRF& aPixel = Value<Image_ColorBGRF> (theY, theX);
|
||||||
|
theAlpha = 1.0; // opaque
|
||||||
|
return Quantity_Color (Quantity_Parameter (aPixel.r()),
|
||||||
|
Quantity_Parameter (aPixel.g()),
|
||||||
|
Quantity_Parameter (aPixel.b()),
|
||||||
|
Quantity_TOC_RGB);
|
||||||
|
}
|
||||||
|
case ImgRGBA:
|
||||||
|
{
|
||||||
|
const Image_ColorRGBA& aPixel = Value<Image_ColorRGBA> (theY, theX);
|
||||||
|
theAlpha = Standard_Real (aPixel.a()) / 255.0;
|
||||||
|
return Quantity_Color (Quantity_Parameter (Standard_Real (aPixel.r()) / 255.0),
|
||||||
|
Quantity_Parameter (Standard_Real (aPixel.g()) / 255.0),
|
||||||
|
Quantity_Parameter (Standard_Real (aPixel.b()) / 255.0),
|
||||||
|
Quantity_TOC_RGB);
|
||||||
|
}
|
||||||
|
case ImgBGRA:
|
||||||
|
{
|
||||||
|
const Image_ColorBGRA& aPixel = Value<Image_ColorBGRA> (theY, theX);
|
||||||
|
theAlpha = Standard_Real (aPixel.a()) / 255.0;
|
||||||
|
return Quantity_Color (Quantity_Parameter (Standard_Real (aPixel.r()) / 255.0),
|
||||||
|
Quantity_Parameter (Standard_Real (aPixel.g()) / 255.0),
|
||||||
|
Quantity_Parameter (Standard_Real (aPixel.b()) / 255.0),
|
||||||
|
Quantity_TOC_RGB);
|
||||||
|
}
|
||||||
|
case ImgRGB32:
|
||||||
|
{
|
||||||
|
const Image_ColorRGB32& aPixel = Value<Image_ColorRGB32> (theY, theX);
|
||||||
|
theAlpha = 1.0; // opaque
|
||||||
|
return Quantity_Color (Quantity_Parameter (Standard_Real (aPixel.r()) / 255.0),
|
||||||
|
Quantity_Parameter (Standard_Real (aPixel.g()) / 255.0),
|
||||||
|
Quantity_Parameter (Standard_Real (aPixel.b()) / 255.0),
|
||||||
|
Quantity_TOC_RGB);
|
||||||
|
}
|
||||||
|
case ImgBGR32:
|
||||||
|
{
|
||||||
|
const Image_ColorBGR32& aPixel = Value<Image_ColorBGR32> (theY, theX);
|
||||||
|
theAlpha = 1.0; // opaque
|
||||||
|
return Quantity_Color (Quantity_Parameter (Standard_Real (aPixel.r()) / 255.0),
|
||||||
|
Quantity_Parameter (Standard_Real (aPixel.g()) / 255.0),
|
||||||
|
Quantity_Parameter (Standard_Real (aPixel.b()) / 255.0),
|
||||||
|
Quantity_TOC_RGB);
|
||||||
|
}
|
||||||
|
case ImgRGB:
|
||||||
|
{
|
||||||
|
const Image_ColorRGB& aPixel = Value<Image_ColorRGB> (theY, theX);
|
||||||
|
theAlpha = 1.0; // opaque
|
||||||
|
return Quantity_Color (Quantity_Parameter (Standard_Real (aPixel.r()) / 255.0),
|
||||||
|
Quantity_Parameter (Standard_Real (aPixel.g()) / 255.0),
|
||||||
|
Quantity_Parameter (Standard_Real (aPixel.b()) / 255.0),
|
||||||
|
Quantity_TOC_RGB);
|
||||||
|
}
|
||||||
|
case ImgBGR:
|
||||||
|
{
|
||||||
|
const Image_ColorBGR& aPixel = Value<Image_ColorBGR> (theY, theX);
|
||||||
|
theAlpha = 1.0; // opaque
|
||||||
|
return Quantity_Color (Quantity_Parameter (Standard_Real (aPixel.r()) / 255.0),
|
||||||
|
Quantity_Parameter (Standard_Real (aPixel.g()) / 255.0),
|
||||||
|
Quantity_Parameter (Standard_Real (aPixel.b()) / 255.0),
|
||||||
|
Quantity_TOC_RGB);
|
||||||
|
}
|
||||||
|
case ImgGray:
|
||||||
|
{
|
||||||
|
const Standard_Byte& aPixel = Value<Standard_Byte> (theY, theX);
|
||||||
|
theAlpha = 1.0; // opaque
|
||||||
|
return Quantity_Color (Quantity_Parameter (Standard_Real (aPixel) / 255.0),
|
||||||
|
Quantity_Parameter (Standard_Real (aPixel) / 255.0),
|
||||||
|
Quantity_Parameter (Standard_Real (aPixel) / 255.0),
|
||||||
|
Quantity_TOC_RGB);
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
// not supported image type
|
||||||
|
theAlpha = 0.0; // transparent
|
||||||
|
return Quantity_Color (0.0, 0.0, 0.0, Quantity_TOC_RGB);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
return myImage->getPixelColor (theX, aScanlineId, theAlpha);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
294
src/Image/Image_PixMap.hxx
Normal file
294
src/Image/Image_PixMap.hxx
Normal file
@ -0,0 +1,294 @@
|
|||||||
|
// Created on: 2012-07-18
|
||||||
|
// Created by: Kirill GAVRILOV
|
||||||
|
// Copyright (c) 2012 OPEN CASCADE SAS
|
||||||
|
//
|
||||||
|
// The content of this file is subject to the Open CASCADE Technology Public
|
||||||
|
// License Version 6.5 (the "License"). You may not use the content of this file
|
||||||
|
// except in compliance with the License. Please obtain a copy of the License
|
||||||
|
// at http://www.opencascade.org and read it completely before using this file.
|
||||||
|
//
|
||||||
|
// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
|
||||||
|
// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
|
||||||
|
//
|
||||||
|
// The Original Code and all software distributed under the License is
|
||||||
|
// distributed on an "AS IS" basis, without warranty of any kind, and the
|
||||||
|
// Initial Developer hereby disclaims all such warranties, including without
|
||||||
|
// limitation, any warranties of merchantability, fitness for a particular
|
||||||
|
// purpose or non-infringement. Please see the License for the specific terms
|
||||||
|
// and conditions governing the rights and limitations under the License.
|
||||||
|
|
||||||
|
#ifndef _Image_PixMap_H__
|
||||||
|
#define _Image_PixMap_H__
|
||||||
|
|
||||||
|
#include <Image_PixMapData.hxx>
|
||||||
|
#include <Standard_Transient.hxx>
|
||||||
|
#include <Quantity_Color.hxx>
|
||||||
|
|
||||||
|
//! Class represents packed image plane.
|
||||||
|
class Image_PixMap : public Standard_Transient
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//! This enumeration define packed image plane formats
|
||||||
|
typedef enum tagFormat {
|
||||||
|
ImgUNKNOWN = 0, //!< unsupported or unknown format
|
||||||
|
ImgGray = 1, //!< 1 byte per pixel
|
||||||
|
ImgRGB, //!< 3 bytes packed RGB image plane
|
||||||
|
ImgBGR, //!< same as RGB but with different components order
|
||||||
|
ImgRGB32, //!< 4 bytes packed RGB image plane (1 extra byte for alignment, may have undefined value)
|
||||||
|
ImgBGR32, //!< same as RGB but with different components order
|
||||||
|
ImgRGBA, //!< 4 bytes packed RGBA image plane
|
||||||
|
ImgBGRA, //!< same as RGBA but with different components order
|
||||||
|
ImgGrayF, //!< 1 float (4-bytes) per pixel (1-component plane)
|
||||||
|
ImgRGBF, //!< 3 floats (12-bytes) RGB image plane
|
||||||
|
ImgBGRF, //!< same as RGBF but with different components order
|
||||||
|
ImgRGBAF, //!< 4 floats (16-bytes) RGBA image plane
|
||||||
|
ImgBGRAF, //!< same as RGBAF but with different components order
|
||||||
|
} ImgFormat;
|
||||||
|
|
||||||
|
//! Determine Big-Endian at runtime
|
||||||
|
static inline bool IsBigEndianHost()
|
||||||
|
{
|
||||||
|
union { int myInt; char myChar[sizeof(int)]; } aUnion;
|
||||||
|
aUnion.myInt = 1;
|
||||||
|
return !aUnion.myChar[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
public: // high-level API
|
||||||
|
|
||||||
|
inline ImgFormat Format() const
|
||||||
|
{
|
||||||
|
return myImgFormat;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @return image width in pixels
|
||||||
|
inline Standard_Size Width() const
|
||||||
|
{
|
||||||
|
return myData.mySizeX;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @return image height in pixels
|
||||||
|
inline Standard_Size Height() const
|
||||||
|
{
|
||||||
|
return myData.mySizeY;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @return image width in pixels
|
||||||
|
inline Standard_Size SizeX() const
|
||||||
|
{
|
||||||
|
return myData.mySizeX;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @return image height in pixels
|
||||||
|
inline Standard_Size SizeY() const
|
||||||
|
{
|
||||||
|
return myData.mySizeY;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @return width / height.
|
||||||
|
inline Standard_Real Ratio() const
|
||||||
|
{
|
||||||
|
return (myData.mySizeY > 0) ? (Standard_Real(myData.mySizeX) / Standard_Real(myData.mySizeY)) : 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @return true if data is NULL.
|
||||||
|
bool IsEmpty() const
|
||||||
|
{
|
||||||
|
return myData.myDataPtr == NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Empty constructor. Initialize the NULL image plane.
|
||||||
|
Standard_EXPORT Image_PixMap();
|
||||||
|
|
||||||
|
//! Destructor
|
||||||
|
Standard_EXPORT virtual ~Image_PixMap();
|
||||||
|
|
||||||
|
//! Returns the pixel color. This function is relatively slow.
|
||||||
|
//! @param theX - column index from left
|
||||||
|
//! @param theY - row index from top
|
||||||
|
//! @return the pixel color
|
||||||
|
inline Quantity_Color PixelColor (const Standard_Integer theX,
|
||||||
|
const Standard_Integer theY) const
|
||||||
|
{
|
||||||
|
Quantity_Parameter aDummy;
|
||||||
|
return PixelColor (theX, theY, aDummy);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Returns the pixel color. This function is relatively slow.
|
||||||
|
//! theAlpha argument is set to color intensity (0 - transparent, 1 - opaque)
|
||||||
|
Standard_EXPORT Quantity_Color PixelColor (const Standard_Integer theX,
|
||||||
|
const Standard_Integer theY,
|
||||||
|
Quantity_Parameter& theAlpha) const;
|
||||||
|
|
||||||
|
//! Initialize image plane as wrapper over alien data.
|
||||||
|
//! Data will not be copied! Notice that caller should ensure
|
||||||
|
//! that data pointer will not be released during this wrapper lifetime.
|
||||||
|
//! You may call InitCopy() to perform data copying.
|
||||||
|
Standard_EXPORT virtual bool InitWrapper (ImgFormat thePixelFormat,
|
||||||
|
Standard_Byte* theDataPtr,
|
||||||
|
const Standard_Size theSizeX,
|
||||||
|
const Standard_Size theSizeY,
|
||||||
|
const Standard_Size theSizeRowBytes = 0);
|
||||||
|
|
||||||
|
//! Initialize image plane with required dimensions.
|
||||||
|
//! Memory will be left uninitialized (performance trick).
|
||||||
|
Standard_EXPORT virtual bool InitTrash (ImgFormat thePixelFormat,
|
||||||
|
const Standard_Size theSizeX,
|
||||||
|
const Standard_Size theSizeY,
|
||||||
|
const Standard_Size theSizeRowBytes = 0);
|
||||||
|
|
||||||
|
//! Initialize by copying data.
|
||||||
|
//! If you want to copy alien data you should create wrapper using InitWrapper() before.
|
||||||
|
Standard_EXPORT virtual bool InitCopy (const Image_PixMap& theCopy);
|
||||||
|
|
||||||
|
//! Initialize image plane with required dimensions.
|
||||||
|
//! Buffer will be zeroed (black color for most formats).
|
||||||
|
Standard_EXPORT bool InitZero (ImgFormat thePixelFormat,
|
||||||
|
const Standard_Size theSizeX,
|
||||||
|
const Standard_Size theSizeY,
|
||||||
|
const Standard_Size theSizeRowBytes = 0,
|
||||||
|
const Standard_Byte theValue = 0);
|
||||||
|
|
||||||
|
//! Method correctly deallocate internal buffer.
|
||||||
|
Standard_EXPORT virtual void Clear (ImgFormat thePixelFormat = ImgGray);
|
||||||
|
|
||||||
|
public: // low-level API for batch-processing (pixels reading / comparison / modification)
|
||||||
|
|
||||||
|
//! Returns true if image data stored from Top to the Down (default).
|
||||||
|
//! Some external APIs can return bottom-up data instead
|
||||||
|
//! (topmost scanlines starts from the bottom in memory).
|
||||||
|
//! Notice that access methods within this class automatically
|
||||||
|
//! convert input row-index to apply this flag!
|
||||||
|
//! You should use this flag only if interconnect with alien APIs and buffers.
|
||||||
|
//! @return true if image data is top-down.
|
||||||
|
inline bool IsTopDown() const
|
||||||
|
{
|
||||||
|
return myData.myTopToDown == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Setup scanlines order in memory - top-down or bottom-up.
|
||||||
|
//! Drawers should explicitly specify this value if current state IsTopDown() was ignored!
|
||||||
|
//! @param theIsTopDown - top-down flag.
|
||||||
|
inline void SetTopDown (bool theIsTopDown)
|
||||||
|
{
|
||||||
|
myData.myTopToDown = (theIsTopDown ? 1 : Standard_Size(-1));
|
||||||
|
setTopDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Returns +1 if scanlines ordered in Top->Down order in memory and -1 otherwise.
|
||||||
|
//! @return scanline increment for Top->Down iteration
|
||||||
|
inline Standard_Size TopDownInc() const
|
||||||
|
{
|
||||||
|
return myData.myTopToDown;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @return data pointer for low-level operations (copying entire buffer, parsing with extra tools etc.).
|
||||||
|
inline const Standard_Byte* Data() const
|
||||||
|
{
|
||||||
|
return myData.myDataPtr;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @return data pointer for low-level operations (copying entire buffer, parsing with extra tools etc.).
|
||||||
|
inline Standard_Byte* ChangeData()
|
||||||
|
{
|
||||||
|
return myData.myDataPtr;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @return data pointer to requested row (first column).
|
||||||
|
inline const Standard_Byte* Row (const Standard_Size theRow) const
|
||||||
|
{
|
||||||
|
return myData.Row (theRow);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @return data pointer to requested row (first column).
|
||||||
|
inline Standard_Byte* ChangeRow (const Standard_Size theRow)
|
||||||
|
{
|
||||||
|
return myData.ChangeRow (theRow);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @return bytes reserved for one pixel (may include extra bytes for alignment).
|
||||||
|
inline Standard_Size SizePixelBytes() const
|
||||||
|
{
|
||||||
|
return myData.mySizeBPP;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @return bytes reserved for one pixel (may include extra bytes for alignment).
|
||||||
|
static Standard_Size SizePixelBytes (const Image_PixMap::ImgFormat thePixelFormat);
|
||||||
|
|
||||||
|
//! @return bytes reserved per row.
|
||||||
|
//! Could be larger than needed to store packed row (extra bytes for alignment etc.).
|
||||||
|
inline Standard_Size SizeRowBytes() const
|
||||||
|
{
|
||||||
|
return myData.mySizeRowBytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @return the extra bytes in the row.
|
||||||
|
inline Standard_Size RowExtraBytes() const
|
||||||
|
{
|
||||||
|
return myData.mySizeRowBytes - myData.mySizeX * myData.mySizeBPP;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Compute the maximal row alignment for current row size.
|
||||||
|
//! @return maximal row alignment in bytes (up to 16 bytes).
|
||||||
|
inline Standard_Size MaxRowAligmentBytes() const
|
||||||
|
{
|
||||||
|
return myData.MaxRowAligmentBytes();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Standard_Size SizeBytes() const
|
||||||
|
{
|
||||||
|
return myData.SizeBytes();
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Access image buffer for write/read operations with specified color type.
|
||||||
|
template <typename ColorType_t>
|
||||||
|
inline Image_PixMapData<ColorType_t>& EditData()
|
||||||
|
{
|
||||||
|
return *(Image_PixMapData<ColorType_t>* )&myData;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Access image buffer for read operations with specified color type.
|
||||||
|
template <typename ColorType_t>
|
||||||
|
inline const Image_PixMapData<ColorType_t>& ReadData() const
|
||||||
|
{
|
||||||
|
return *(Image_PixMapData<ColorType_t>* )&myData;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Access image pixel with specified color type.
|
||||||
|
template <typename ColorType_t>
|
||||||
|
inline const ColorType_t& Value (const Standard_Size theRow,
|
||||||
|
const Standard_Size theCol) const
|
||||||
|
{
|
||||||
|
return ((Image_PixMapData<ColorType_t>* )&myData)->Value (theRow, theCol);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
//! Setup pixel format
|
||||||
|
Standard_EXPORT void setFormat (ImgFormat thePixelFormat);
|
||||||
|
|
||||||
|
//! Auxiliary method to setup myTopRowPtr
|
||||||
|
Standard_EXPORT void setTopDown();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
Image_PixMapData<Standard_Byte> myData;
|
||||||
|
ImgFormat myImgFormat; //!< pixel format
|
||||||
|
bool myIsOwnPointer; //!< if data was allocated by this class - flag is true
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
//! Copying allowed only within Handles
|
||||||
|
Image_PixMap (const Image_PixMap& );
|
||||||
|
Image_PixMap& operator= (const Image_PixMap& );
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
DEFINE_STANDARD_RTTI(Image_PixMap) // Type definition
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
DEFINE_STANDARD_HANDLE(Image_PixMap, Standard_Transient)
|
||||||
|
|
||||||
|
#endif // _Image_PixMap_H__
|
113
src/Image/Image_PixMapData.hxx
Normal file
113
src/Image/Image_PixMapData.hxx
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
// Created on: 2012-07-18
|
||||||
|
// Created by: Kirill GAVRILOV
|
||||||
|
// Copyright (c) 2012 OPEN CASCADE SAS
|
||||||
|
//
|
||||||
|
// The content of this file is subject to the Open CASCADE Technology Public
|
||||||
|
// License Version 6.5 (the "License"). You may not use the content of this file
|
||||||
|
// except in compliance with the License. Please obtain a copy of the License
|
||||||
|
// at http://www.opencascade.org and read it completely before using this file.
|
||||||
|
//
|
||||||
|
// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
|
||||||
|
// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
|
||||||
|
//
|
||||||
|
// The Original Code and all software distributed under the License is
|
||||||
|
// distributed on an "AS IS" basis, without warranty of any kind, and the
|
||||||
|
// Initial Developer hereby disclaims all such warranties, including without
|
||||||
|
// limitation, any warranties of merchantability, fitness for a particular
|
||||||
|
// purpose or non-infringement. Please see the License for the specific terms
|
||||||
|
// and conditions governing the rights and limitations under the License.
|
||||||
|
|
||||||
|
#ifndef _Image_PixMapData_H__
|
||||||
|
#define _Image_PixMapData_H__
|
||||||
|
|
||||||
|
#include <Image_Color.hxx>
|
||||||
|
|
||||||
|
//! POD template structure to access image buffer
|
||||||
|
template<typename ColorType_t>
|
||||||
|
struct Image_PixMapData
|
||||||
|
{
|
||||||
|
|
||||||
|
//! @return data pointer for low-level operations (copying entire buffer, parsing with extra tools etc.).
|
||||||
|
inline const ColorType_t* Data() const
|
||||||
|
{
|
||||||
|
return (const ColorType_t* )myDataPtr;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @return data pointer for low-level operations (copying entire buffer, parsing with extra tools etc.).
|
||||||
|
inline ColorType_t* ChangeData()
|
||||||
|
{
|
||||||
|
return (ColorType_t* )myDataPtr;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @return data pointer to requested row (first column).
|
||||||
|
inline const ColorType_t* Row (const Standard_Size theRow) const
|
||||||
|
{
|
||||||
|
return (ColorType_t* )(myTopRowPtr + mySizeRowBytes * theRow * myTopToDown);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @return data pointer to requested row (first column).
|
||||||
|
inline ColorType_t* ChangeRow (const Standard_Size theRow)
|
||||||
|
{
|
||||||
|
return (ColorType_t* )(myTopRowPtr + mySizeRowBytes * theRow * myTopToDown);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @return data pointer to requested position.
|
||||||
|
inline const ColorType_t& Value (const Standard_Size theRow,
|
||||||
|
const Standard_Size theCol) const
|
||||||
|
{
|
||||||
|
return *(const ColorType_t* )(myTopRowPtr + mySizeRowBytes * theRow * myTopToDown + mySizeBPP * theCol);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @return data pointer to requested position.
|
||||||
|
inline ColorType_t& ChangeValue (const Standard_Size theRow,
|
||||||
|
const Standard_Size theCol)
|
||||||
|
{
|
||||||
|
return *(ColorType_t* )(myTopRowPtr + mySizeRowBytes * theRow * myTopToDown + mySizeBPP * theCol);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Compute the maximal row alignment for current row size.
|
||||||
|
//! @return maximal row alignment in bytes (up to 16 bytes).
|
||||||
|
inline Standard_Size MaxRowAligmentBytes() const
|
||||||
|
{
|
||||||
|
Standard_Size anAlignment = 2;
|
||||||
|
for (; anAlignment <= 16; anAlignment <<= 1)
|
||||||
|
{
|
||||||
|
if ((mySizeRowBytes % anAlignment) != 0 || (Standard_Size(myDataPtr) % anAlignment) != 0)
|
||||||
|
{
|
||||||
|
return (anAlignment >> 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return anAlignment;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @return bytes allocated for the whole image plane.
|
||||||
|
inline Standard_Size SizeBytes() const
|
||||||
|
{
|
||||||
|
return mySizeRowBytes * mySizeY;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @return image width in pixels
|
||||||
|
inline Standard_Size SizeX() const
|
||||||
|
{
|
||||||
|
return mySizeX;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @return image height in pixels
|
||||||
|
inline Standard_Size SizeY() const
|
||||||
|
{
|
||||||
|
return mySizeY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Standard_Byte* myDataPtr; //!< pointer to the data
|
||||||
|
Standard_Byte* myTopRowPtr; //!< pointer to the topmost row (depending on scanlines order in memory)
|
||||||
|
Standard_Size mySizeBPP; //!< bytes per pixel
|
||||||
|
Standard_Size mySizeX; //!< width in pixels
|
||||||
|
Standard_Size mySizeY; //!< height in pixels
|
||||||
|
Standard_Size mySizeRowBytes; //!< number of bytes per line (in most cases equal to 3 * sizeX)
|
||||||
|
Standard_Size myTopToDown; //!< image scanlines direction in memory from Top to the Down
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // _Image_PixMapData_H__
|
@ -11,7 +11,6 @@ InterfaceGraphic_wntio.hxx
|
|||||||
InterfaceGraphic_cPrintf.cxx
|
InterfaceGraphic_cPrintf.cxx
|
||||||
InterfaceGraphic_Palette.c
|
InterfaceGraphic_Palette.c
|
||||||
InterfaceGraphic_PrimitiveArray.hxx
|
InterfaceGraphic_PrimitiveArray.hxx
|
||||||
InterfaceGraphic_RawBufferData.hxx
|
|
||||||
InterfaceGraphic_telem.hxx
|
InterfaceGraphic_telem.hxx
|
||||||
InterfaceGraphic_degeneration.hxx
|
InterfaceGraphic_degeneration.hxx
|
||||||
InterfaceGraphic_tgl_all.hxx
|
InterfaceGraphic_tgl_all.hxx
|
||||||
|
@ -1,54 +0,0 @@
|
|||||||
// Copyright (c) 1991-1999 Matra Datavision
|
|
||||||
// Copyright (c) 1999-2012 OPEN CASCADE SAS
|
|
||||||
//
|
|
||||||
// The content of this file is subject to the Open CASCADE Technology Public
|
|
||||||
// License Version 6.5 (the "License"). You may not use the content of this file
|
|
||||||
// except in compliance with the License. Please obtain a copy of the License
|
|
||||||
// at http://www.opencascade.org and read it completely before using this file.
|
|
||||||
//
|
|
||||||
// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
|
|
||||||
// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
|
|
||||||
//
|
|
||||||
// The Original Code and all software distributed under the License is
|
|
||||||
// distributed on an "AS IS" basis, without warranty of any kind, and the
|
|
||||||
// Initial Developer hereby disclaims all such warranties, including without
|
|
||||||
// limitation, any warranties of merchantability, fitness for a particular
|
|
||||||
// purpose or non-infringement. Please see the License for the specific terms
|
|
||||||
// and conditions governing the rights and limitations under the License.
|
|
||||||
|
|
||||||
#ifndef INTERFACEGRAPHIC_RawBufferData_H
|
|
||||||
#define INTERFACEGRAPHIC_RawBufferData_H
|
|
||||||
|
|
||||||
#include <Standard.hxx>
|
|
||||||
|
|
||||||
// Most items are from GLenum, but values not equal!
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
TRGB,
|
|
||||||
TBGR,
|
|
||||||
TRGBA,
|
|
||||||
TBGRA,
|
|
||||||
TDepthComponent,
|
|
||||||
TRed,
|
|
||||||
TGreen,
|
|
||||||
TBlue,
|
|
||||||
TAlpha,
|
|
||||||
} TRawBufferDataFormat;
|
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
TUByte,
|
|
||||||
TFloat,
|
|
||||||
} TRawBufferDataType;
|
|
||||||
|
|
||||||
struct TRawBufferData
|
|
||||||
{
|
|
||||||
Standard_Integer widthPx;
|
|
||||||
Standard_Integer heightPx;
|
|
||||||
Standard_Integer rowAligmentBytes;
|
|
||||||
TRawBufferDataFormat format;
|
|
||||||
TRawBufferDataType type;
|
|
||||||
Standard_Address dataPtr;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* INTERFACEGRAPHIC_RawBufferData_H */
|
|
@ -32,7 +32,6 @@
|
|||||||
#include <Quantity_PlaneAngle.hxx>
|
#include <Quantity_PlaneAngle.hxx>
|
||||||
#include <Quantity_NameOfColor.hxx>
|
#include <Quantity_NameOfColor.hxx>
|
||||||
#include <Handle_AlienImage_AlienImage.hxx>
|
#include <Handle_AlienImage_AlienImage.hxx>
|
||||||
#include <Image_CRawBufferData.hxx>
|
|
||||||
|
|
||||||
#include <Aspect_Display.hxx>
|
#include <Aspect_Display.hxx>
|
||||||
#include <Aspect_GradientFillMethod.hxx>
|
#include <Aspect_GradientFillMethod.hxx>
|
||||||
@ -69,6 +68,7 @@
|
|||||||
#include <Graphic3d_Array2OfVertex.hxx>
|
#include <Graphic3d_Array2OfVertex.hxx>
|
||||||
#include <Graphic3d_Array2OfVertexN.hxx>
|
#include <Graphic3d_Array2OfVertexN.hxx>
|
||||||
#include <Graphic3d_Array2OfVertexNT.hxx>
|
#include <Graphic3d_Array2OfVertexNT.hxx>
|
||||||
|
#include <Graphic3d_BufferType.hxx>
|
||||||
#include <NCollection_DataMap.hxx>
|
#include <NCollection_DataMap.hxx>
|
||||||
|
|
||||||
class TColStd_Array1OfInteger;
|
class TColStd_Array1OfInteger;
|
||||||
@ -82,6 +82,7 @@ class Graphic3d_Vertex;
|
|||||||
class Aspect_Array1OfEdge;
|
class Aspect_Array1OfEdge;
|
||||||
class TCollection_ExtendedString;
|
class TCollection_ExtendedString;
|
||||||
class AlienImage_AlienImage;
|
class AlienImage_AlienImage;
|
||||||
|
class Image_PixMap;
|
||||||
class TColStd_HArray1OfReal;
|
class TColStd_HArray1OfReal;
|
||||||
class Handle(OpenGl_View);
|
class Handle(OpenGl_View);
|
||||||
class Handle(OpenGl_Workspace);
|
class Handle(OpenGl_Workspace);
|
||||||
@ -262,7 +263,9 @@ public:
|
|||||||
//! Remove offscreen FBO <br>
|
//! Remove offscreen FBO <br>
|
||||||
Standard_EXPORT void FBORelease (const Graphic3d_CView& view, Graphic3d_PtrFrameBuffer& fboPtr);
|
Standard_EXPORT void FBORelease (const Graphic3d_CView& view, Graphic3d_PtrFrameBuffer& fboPtr);
|
||||||
//! Dump active rendering buffer into specified memory buffer. <br>
|
//! Dump active rendering buffer into specified memory buffer. <br>
|
||||||
Standard_EXPORT Standard_Boolean BufferDump (const Graphic3d_CView& view, Image_CRawBufferData& buffer);
|
Standard_EXPORT Standard_Boolean BufferDump (const Graphic3d_CView& theCView,
|
||||||
|
Image_PixMap& theImage,
|
||||||
|
const Graphic3d_BufferType& theBufferType);
|
||||||
Standard_EXPORT void SetGLLightEnabled (const Graphic3d_CView& view,const Standard_Boolean isEnabled) const;
|
Standard_EXPORT void SetGLLightEnabled (const Graphic3d_CView& view,const Standard_Boolean isEnabled) const;
|
||||||
Standard_EXPORT Standard_Boolean IsGLLightEnabled (const Graphic3d_CView& view) const;
|
Standard_EXPORT Standard_Boolean IsGLLightEnabled (const Graphic3d_CView& view) const;
|
||||||
//! Clear visualization data in graphical driver and stop <br>
|
//! Clear visualization data in graphical driver and stop <br>
|
||||||
|
@ -284,72 +284,88 @@ void OpenGl_GraphicDriver::FBOChangeViewport (const Graphic3d_CView& ,
|
|||||||
aFrameBuffer->ChangeViewport (theWidth, theHeight);
|
aFrameBuffer->ChangeViewport (theWidth, theHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
// OpenGL 1.2 stuff
|
inline bool getDataFormat (const Image_PixMap& theData,
|
||||||
#ifndef GL_BGR
|
GLenum& thePixelFormat,
|
||||||
#define GL_BGR 0x80E0
|
GLenum& theDataType)
|
||||||
#endif
|
|
||||||
#ifndef GL_BGRA
|
|
||||||
#define GL_BGRA 0x80E1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static inline GLenum TFormatToGLEnum (const TRawBufferDataFormat theTFormat)
|
|
||||||
{
|
{
|
||||||
switch (theTFormat)
|
thePixelFormat = GL_RGB;
|
||||||
|
theDataType = GL_UNSIGNED_BYTE;
|
||||||
|
switch (theData.Format())
|
||||||
{
|
{
|
||||||
case TRGB: return GL_RGB;
|
case Image_PixMap::ImgGray:
|
||||||
case TBGR: return GL_BGR;
|
thePixelFormat = GL_DEPTH_COMPONENT;
|
||||||
case TRGBA: return GL_RGBA;
|
theDataType = GL_UNSIGNED_BYTE;
|
||||||
case TBGRA: return GL_BGRA;
|
return true;
|
||||||
case TDepthComponent: return GL_DEPTH_COMPONENT;
|
case Image_PixMap::ImgRGB:
|
||||||
case TRed: return GL_RED;
|
thePixelFormat = GL_RGB;
|
||||||
case TGreen: return GL_GREEN;
|
theDataType = GL_UNSIGNED_BYTE;
|
||||||
case TBlue: return GL_BLUE;
|
return true;
|
||||||
case TAlpha: return GL_ALPHA;
|
case Image_PixMap::ImgBGR:
|
||||||
default: return 0;
|
thePixelFormat = GL_BGR;
|
||||||
|
theDataType = GL_UNSIGNED_BYTE;
|
||||||
|
return true;
|
||||||
|
case Image_PixMap::ImgRGBA:
|
||||||
|
case Image_PixMap::ImgRGB32:
|
||||||
|
thePixelFormat = GL_RGBA;
|
||||||
|
theDataType = GL_UNSIGNED_BYTE;
|
||||||
|
return true;
|
||||||
|
case Image_PixMap::ImgBGRA:
|
||||||
|
case Image_PixMap::ImgBGR32:
|
||||||
|
thePixelFormat = GL_BGRA;
|
||||||
|
theDataType = GL_UNSIGNED_BYTE;
|
||||||
|
return true;
|
||||||
|
case Image_PixMap::ImgGrayF:
|
||||||
|
thePixelFormat = GL_DEPTH_COMPONENT;
|
||||||
|
theDataType = GL_FLOAT;
|
||||||
|
return true;
|
||||||
|
case Image_PixMap::ImgRGBF:
|
||||||
|
thePixelFormat = GL_RGB;
|
||||||
|
theDataType = GL_FLOAT;
|
||||||
|
return true;
|
||||||
|
case Image_PixMap::ImgBGRF:
|
||||||
|
thePixelFormat = GL_BGR;
|
||||||
|
theDataType = GL_FLOAT;
|
||||||
|
return true;
|
||||||
|
case Image_PixMap::ImgRGBAF:
|
||||||
|
thePixelFormat = GL_RGBA;
|
||||||
|
theDataType = GL_FLOAT;
|
||||||
|
return true;
|
||||||
|
case Image_PixMap::ImgBGRAF:
|
||||||
|
thePixelFormat = GL_BGRA;
|
||||||
|
theDataType = GL_FLOAT;
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline GLenum TTypeToGLEnum (const TRawBufferDataType theTType)
|
Standard_Boolean OpenGl_GraphicDriver::BufferDump (const Graphic3d_CView& theCView,
|
||||||
|
Image_PixMap& theImage,
|
||||||
|
const Graphic3d_BufferType& theBufferType)
|
||||||
{
|
{
|
||||||
switch (theTType)
|
const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView;
|
||||||
{
|
return (aCView != NULL) && aCView->WS->BufferDump ((OpenGl_FrameBuffer* )theCView.ptrFBO, theImage, theBufferType);
|
||||||
case TUByte: return GL_UNSIGNED_BYTE;
|
|
||||||
case TFloat: return GL_FLOAT;
|
|
||||||
default: return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Standard_Boolean OpenGl_GraphicDriver::BufferDump (const Graphic3d_CView& ACView, Image_CRawBufferData& theBuffer)
|
|
||||||
{
|
|
||||||
const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
|
|
||||||
if (aCView)
|
|
||||||
return aCView->WS->BufferDump((OpenGl_FrameBuffer *)ACView.ptrFBO,theBuffer);
|
|
||||||
return Standard_False;
|
return Standard_False;
|
||||||
}
|
}
|
||||||
|
|
||||||
Standard_Boolean OpenGl_Workspace::BufferDump (OpenGl_FrameBuffer *theFBOPtr, Image_CRawBufferData& theBuffer)
|
Standard_Boolean OpenGl_Workspace::BufferDump (OpenGl_FrameBuffer* theFBOPtr,
|
||||||
|
Image_PixMap& theImage,
|
||||||
|
const Graphic3d_BufferType& theBufferType)
|
||||||
{
|
{
|
||||||
GLenum aFormat = TFormatToGLEnum (theBuffer.format);
|
GLenum aFormat, aType;
|
||||||
GLenum aType = TTypeToGLEnum (theBuffer.type);
|
if (theImage.IsEmpty()
|
||||||
|
|| !getDataFormat (theImage, aFormat, aType)
|
||||||
// safe checks
|
|| ((theBufferType == Graphic3d_BT_Depth) && (aFormat != GL_DEPTH_COMPONENT))
|
||||||
if (aFormat == 0 || aType == 0 ||
|
|| !Activate())
|
||||||
theBuffer.widthPx == 0 || theBuffer.heightPx == 0 ||
|
|
||||||
theBuffer.dataPtr == NULL)
|
|
||||||
{
|
{
|
||||||
return Standard_False;
|
return Standard_False;
|
||||||
}
|
}
|
||||||
|
|
||||||
// activate OpenGL context
|
|
||||||
if (!Activate())
|
|
||||||
return Standard_False;
|
|
||||||
|
|
||||||
// bind FBO if used
|
// bind FBO if used
|
||||||
OpenGl_FrameBuffer* aFrameBuffer = theFBOPtr;
|
|
||||||
GLint aReadBufferPrev = GL_BACK;
|
GLint aReadBufferPrev = GL_BACK;
|
||||||
if (aFrameBuffer != NULL && aFrameBuffer->IsValid())
|
if (theFBOPtr != NULL && theFBOPtr->IsValid())
|
||||||
{
|
{
|
||||||
aFrameBuffer->BindBuffer (GetGlContext());
|
theFBOPtr->BindBuffer (GetGlContext());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -361,19 +377,30 @@ Standard_Boolean OpenGl_Workspace::BufferDump (OpenGl_FrameBuffer *theFBOPtr, Im
|
|||||||
|
|
||||||
GLint anAlignBack = 1;
|
GLint anAlignBack = 1;
|
||||||
glGetIntegerv (GL_PACK_ALIGNMENT, &anAlignBack);
|
glGetIntegerv (GL_PACK_ALIGNMENT, &anAlignBack);
|
||||||
if (theBuffer.rowAligmentBytes == 0)
|
GLint anExtraBytes = (GLint )theImage.RowExtraBytes();
|
||||||
{
|
GLint anAligment = Min (GLint(theImage.MaxRowAligmentBytes()), 8); // limit to 8 bytes for OpenGL
|
||||||
theBuffer.rowAligmentBytes = 1;
|
glPixelStorei (GL_PACK_ALIGNMENT, anAligment);
|
||||||
}
|
|
||||||
glPixelStorei (GL_PACK_ALIGNMENT, theBuffer.rowAligmentBytes);
|
if (anExtraBytes >= anAligment)
|
||||||
|
{
|
||||||
|
// copy row by row
|
||||||
|
for (Standard_Size aRow = 0; aRow < theImage.SizeY(); ++aRow)
|
||||||
|
{
|
||||||
|
glReadPixels (0, GLint(aRow), GLsizei (theImage.SizeX()), 1, aFormat, aType, theImage.ChangeRow (aRow));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// read pixels
|
||||||
|
glReadPixels (0, 0, GLsizei (theImage.SizeX()), GLsizei (theImage.SizeY()), aFormat, aType, theImage.ChangeData());
|
||||||
|
theImage.SetTopDown (false); // image bottom-up in OpenGL
|
||||||
|
}
|
||||||
|
|
||||||
// read pixels
|
|
||||||
glReadPixels (0, 0, theBuffer.widthPx, theBuffer.heightPx, aFormat, aType, (GLvoid* )theBuffer.dataPtr);
|
|
||||||
glPixelStorei (GL_PACK_ALIGNMENT, anAlignBack);
|
glPixelStorei (GL_PACK_ALIGNMENT, anAlignBack);
|
||||||
|
|
||||||
if (aFrameBuffer != NULL && aFrameBuffer->IsValid())
|
if (theFBOPtr != NULL && theFBOPtr->IsValid())
|
||||||
{
|
{
|
||||||
aFrameBuffer->UnbindBuffer (GetGlContext());
|
theFBOPtr->UnbindBuffer (GetGlContext());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
#include <Aspect_Handle.hxx>
|
#include <Aspect_Handle.hxx>
|
||||||
#include <Aspect_PrintAlgo.hxx>
|
#include <Aspect_PrintAlgo.hxx>
|
||||||
#include <Graphic3d_PtrFrameBuffer.hxx>
|
#include <Graphic3d_PtrFrameBuffer.hxx>
|
||||||
#include <Image_CRawBufferData.hxx>
|
#include <Graphic3d_BufferType.hxx>
|
||||||
|
|
||||||
#include <InterfaceGraphic_Graphic3d.hxx>
|
#include <InterfaceGraphic_Graphic3d.hxx>
|
||||||
#include <InterfaceGraphic_Visual3d.hxx>
|
#include <InterfaceGraphic_Visual3d.hxx>
|
||||||
@ -53,6 +53,7 @@ class OpenGl_AspectMarker;
|
|||||||
class OpenGl_AspectText;
|
class OpenGl_AspectText;
|
||||||
class OpenGl_FrameBuffer;
|
class OpenGl_FrameBuffer;
|
||||||
class OpenGl_Structure;
|
class OpenGl_Structure;
|
||||||
|
class Image_PixMap;
|
||||||
|
|
||||||
//! Reprepsents window with GL context.
|
//! Reprepsents window with GL context.
|
||||||
//! Provides methods to render primitives and maintan GL state.
|
//! Provides methods to render primitives and maintan GL state.
|
||||||
@ -127,7 +128,9 @@ public:
|
|||||||
|
|
||||||
Graphic3d_PtrFrameBuffer FBOCreate (const Standard_Integer theWidth, const Standard_Integer theHeight);
|
Graphic3d_PtrFrameBuffer FBOCreate (const Standard_Integer theWidth, const Standard_Integer theHeight);
|
||||||
void FBORelease (Graphic3d_PtrFrameBuffer theFBOPtr);
|
void FBORelease (Graphic3d_PtrFrameBuffer theFBOPtr);
|
||||||
Standard_Boolean BufferDump (OpenGl_FrameBuffer *theFBOPtr, Image_CRawBufferData& theBuffer);
|
Standard_Boolean BufferDump (OpenGl_FrameBuffer* theFBOPtr,
|
||||||
|
Image_PixMap& theImage,
|
||||||
|
const Graphic3d_BufferType& theBufferType);
|
||||||
|
|
||||||
void UseTransparency (const Standard_Boolean theFlag);
|
void UseTransparency (const Standard_Boolean theFlag);
|
||||||
Standard_Boolean& UseZBuffer() { return myUseZBuffer; }
|
Standard_Boolean& UseZBuffer() { return myUseZBuffer; }
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
#include <QADraw.hxx>
|
#include <QADraw.hxx>
|
||||||
#include <QADraw_DataMapOfAsciiStringOfAddress.hxx>
|
#include <QADraw_DataMapOfAsciiStringOfAddress.hxx>
|
||||||
#include <Draw_Interpretor.hxx>
|
#include <Draw_Interpretor.hxx>
|
||||||
#include <Image_PixMap.hxx>
|
#include <Image_AlienPixMap.hxx>
|
||||||
#include <V3d_View.hxx>
|
#include <V3d_View.hxx>
|
||||||
#include <ViewerTest.hxx>
|
#include <ViewerTest.hxx>
|
||||||
#include <ViewerTest_EventManager.hxx>
|
#include <ViewerTest_EventManager.hxx>
|
||||||
@ -426,19 +426,18 @@ static Standard_Integer QAvzfit(Draw_Interpretor& di, Standard_Integer /*argc*/,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle(TColStd_HSequenceOfReal) GetColorOfPixel (const Handle(Aspect_PixMap) theImage,
|
Handle(TColStd_HSequenceOfReal) GetColorOfPixel (const Image_PixMap& theImage,
|
||||||
const Standard_Integer theCoordinateX,
|
const Standard_Integer theCoordinateX,
|
||||||
const Standard_Integer theCoordinateY,
|
const Standard_Integer theCoordinateY,
|
||||||
const Standard_Integer theRadius)
|
const Standard_Integer theRadius)
|
||||||
{
|
{
|
||||||
Handle(TColStd_HSequenceOfReal) aSeq = new TColStd_HSequenceOfReal();
|
Handle(TColStd_HSequenceOfReal) aSeq = new TColStd_HSequenceOfReal();
|
||||||
if (theImage.IsNull()) {
|
if (theImage.IsEmpty()) {
|
||||||
std::cerr << "The image is null.\n";
|
std::cerr << "The image is null.\n";
|
||||||
return aSeq;
|
return aSeq;
|
||||||
}
|
}
|
||||||
Standard_Integer aWidth = 0;
|
Standard_Integer aWidth = (Standard_Integer )theImage.SizeX();
|
||||||
Standard_Integer anHeight = 0;
|
Standard_Integer anHeight = (Standard_Integer )theImage.SizeY();
|
||||||
theImage->Size (aWidth, anHeight);
|
|
||||||
|
|
||||||
Quantity_Color aColorTmp;
|
Quantity_Color aColorTmp;
|
||||||
for (Standard_Integer anXIter = theCoordinateX - theRadius;
|
for (Standard_Integer anXIter = theCoordinateX - theRadius;
|
||||||
@ -456,7 +455,7 @@ Handle(TColStd_HSequenceOfReal) GetColorOfPixel (const Handle(Aspect_PixMap) the
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// Image_PixMap stores image upside-down in memory!
|
// Image_PixMap stores image upside-down in memory!
|
||||||
aColorTmp = theImage->PixelColor (anXIter, anYIter);
|
aColorTmp = theImage.PixelColor (anXIter, anYIter);
|
||||||
aSeq->Append (aColorTmp.Red());
|
aSeq->Append (aColorTmp.Red());
|
||||||
aSeq->Append (aColorTmp.Green());
|
aSeq->Append (aColorTmp.Green());
|
||||||
aSeq->Append (aColorTmp.Blue());
|
aSeq->Append (aColorTmp.Blue());
|
||||||
@ -482,8 +481,8 @@ static Standard_Integer QAAISGetPixelColor (Draw_Interpretor& di, Standard_Integ
|
|||||||
Standard_Integer QAAISXWindowSize_X = 0;
|
Standard_Integer QAAISXWindowSize_X = 0;
|
||||||
Standard_Integer QAAISXWindowSize_Y = 0;
|
Standard_Integer QAAISXWindowSize_Y = 0;
|
||||||
QAAISWindow->Size(QAAISXWindowSize_X, QAAISXWindowSize_Y);
|
QAAISWindow->Size(QAAISXWindowSize_X, QAAISXWindowSize_Y);
|
||||||
Standard_ShortReal QAAISCoordinateX = atoi (argv [1]);
|
Standard_ShortReal QAAISCoordinateX = atof (argv [1]);
|
||||||
Standard_ShortReal QAAISCoordinateY = atoi (argv [2]);
|
Standard_ShortReal QAAISCoordinateY = atof (argv [2]);
|
||||||
|
|
||||||
Standard_ShortReal QAAISColorRED_V = 0;
|
Standard_ShortReal QAAISColorRED_V = 0;
|
||||||
Standard_ShortReal QAAISColorGRN_V = 0;
|
Standard_ShortReal QAAISColorGRN_V = 0;
|
||||||
@ -504,9 +503,9 @@ static Standard_Integer QAAISGetPixelColor (Draw_Interpretor& di, Standard_Integ
|
|||||||
aRadius=0;
|
aRadius=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle(TColStd_HSequenceOfReal) aSeq = GetColorOfPixel (QAAISView->ToPixMap (QAAISXWindowSize_X, QAAISXWindowSize_Y, Image_TOI_RGB),
|
Image_PixMap anImage;
|
||||||
QAAISCoordinateX, QAAISCoordinateY,
|
QAAISView->ToPixMap (anImage, QAAISXWindowSize_X, QAAISXWindowSize_Y);
|
||||||
aRadius);
|
Handle(TColStd_HSequenceOfReal) aSeq = GetColorOfPixel (anImage, QAAISCoordinateX, QAAISCoordinateY, aRadius);
|
||||||
cout << "Length = " << aSeq->Length() << endl;
|
cout << "Length = " << aSeq->Length() << endl;
|
||||||
|
|
||||||
Standard_Boolean IsNotEqual = Standard_True;
|
Standard_Boolean IsNotEqual = Standard_True;
|
||||||
@ -696,6 +695,7 @@ static Standard_Integer QAAISGetViewCharac (Draw_Interpretor& di, Standard_Integ
|
|||||||
di << "Proj on X : " << QAAISViewProjX << "; on Y: " << QAAISViewProjY << "; on Z: " << QAAISViewProjZ << "\n";
|
di << "Proj on X : " << QAAISViewProjX << "; on Y: " << QAAISViewProjY << "; on Z: " << QAAISViewProjZ << "\n";
|
||||||
di << "Up on X : " << QAAISViewUpX << "; on Y: " << QAAISViewUpY << "; on Z: " << QAAISViewUpZ << "\n";
|
di << "Up on X : " << QAAISViewUpX << "; on Y: " << QAAISViewUpY << "; on Z: " << QAAISViewUpZ << "\n";
|
||||||
di << "At on X : " << QAAISViewAtX << "; on Y: " << QAAISViewAtY << "; on Z: " << QAAISViewAtZ << "\n";
|
di << "At on X : " << QAAISViewAtX << "; on Y: " << QAAISViewAtY << "; on Z: " << QAAISViewAtZ << "\n";
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Standard_Integer QAAISSetViewCharac (Draw_Interpretor& di, Standard_Integer argc, const char ** argv)
|
static Standard_Integer QAAISSetViewCharac (Draw_Interpretor& di, Standard_Integer argc, const char ** argv)
|
||||||
@ -737,7 +737,7 @@ static Standard_Integer QAAISGetColorCoord (Draw_Interpretor& di, Standard_Integ
|
|||||||
di << "Usage : " << argv[0] << " [3d|2d]" << "\n";
|
di << "Usage : " << argv[0] << " [3d|2d]" << "\n";
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
Handle (Aspect_Window) QAAISWindow;
|
Handle(Xw_Window) QAAISWindow;
|
||||||
|
|
||||||
Standard_Boolean is3d = 1;
|
Standard_Boolean is3d = 1;
|
||||||
|
|
||||||
@ -748,7 +748,7 @@ static Standard_Integer QAAISGetColorCoord (Draw_Interpretor& di, Standard_Integ
|
|||||||
di << "You must initialize AISViewer before this command." << "\n";
|
di << "You must initialize AISViewer before this command." << "\n";
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
QAAISWindow = QAAIS_MainView -> V3d_View::Window ();
|
QAAISWindow = Handle(Xw_Window)::DownCast (QAAIS_MainView->V3d_View::Window());
|
||||||
is3d = 1;
|
is3d = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -758,7 +758,7 @@ static Standard_Integer QAAISGetColorCoord (Draw_Interpretor& di, Standard_Integ
|
|||||||
di << "You must initialize AIS 2D Viewer before this command." << "\n";
|
di << "You must initialize AIS 2D Viewer before this command." << "\n";
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
QAAISWindow = V->Driver()->Window();
|
QAAISWindow = Handle(Xw_Window)::DownCast (V->Driver()->Window());
|
||||||
is3d = 0;
|
is3d = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -795,19 +795,20 @@ static Standard_Integer QAAISGetColorCoord (Draw_Interpretor& di, Standard_Integ
|
|||||||
const char **argvvv = (const char **) bufff;
|
const char **argvvv = (const char **) bufff;
|
||||||
while ( is3d ? ViewerMainLoop (argccc, argvvv) : ViewerMainLoop2d (argccc, argvvv)) {
|
while ( is3d ? ViewerMainLoop (argccc, argvvv) : ViewerMainLoop2d (argccc, argvvv)) {
|
||||||
Handle(TColStd_HSequenceOfReal) aSeq;
|
Handle(TColStd_HSequenceOfReal) aSeq;
|
||||||
|
Image_PixMap anImage;
|
||||||
if(is3d)
|
if(is3d)
|
||||||
{
|
{
|
||||||
ViewerTest::GetMousePosition (QAAIS_MousePoint_X, QAAIS_MousePoint_Y);
|
ViewerTest::GetMousePosition (QAAIS_MousePoint_X, QAAIS_MousePoint_Y);
|
||||||
Handle (V3d_View) QAAIS_MainView = ViewerTest::CurrentView();
|
Handle (V3d_View) QAAIS_MainView = ViewerTest::CurrentView();
|
||||||
aSeq = GetColorOfPixel (QAAIS_MainView->ToPixMap (QAAIS_WindowSize_X, QAAIS_WindowSize_Y, Image_TOI_RGB),
|
QAAIS_MainView->ToPixMap (anImage, QAAIS_WindowSize_X, QAAIS_WindowSize_Y);
|
||||||
QAAIS_MousePoint_X, QAAIS_MousePoint_Y, 0);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Viewer2dTest::GetMousePosition (QAAIS_MousePoint_X, QAAIS_MousePoint_Y);
|
Viewer2dTest::GetMousePosition (QAAIS_MousePoint_X, QAAIS_MousePoint_Y);
|
||||||
aSeq = GetColorOfPixel (QAAISWindow->ToPixMap(),
|
QAAISWindow->ToPixMap (anImage);
|
||||||
QAAIS_MousePoint_X, QAAIS_MousePoint_Y, 0);
|
|
||||||
}
|
}
|
||||||
|
aSeq = GetColorOfPixel (anImage, QAAIS_MousePoint_X, QAAIS_MousePoint_Y, 0);
|
||||||
|
|
||||||
QAAIS_ColorRED = aSeq->Value(1);
|
QAAIS_ColorRED = aSeq->Value(1);
|
||||||
QAAIS_ColorGRN = aSeq->Value(2);
|
QAAIS_ColorGRN = aSeq->Value(2);
|
||||||
QAAIS_ColorBLU = aSeq->Value(3);
|
QAAIS_ColorBLU = aSeq->Value(3);
|
||||||
@ -869,8 +870,13 @@ static int QAAISGetPixelColor2d (Draw_Interpretor& di, Standard_Integer argc, co
|
|||||||
di << "You must initialize AIS 2D Viewer before this command." << "\n";
|
di << "You must initialize AIS 2D Viewer before this command." << "\n";
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get Color
|
// Get Color
|
||||||
Handle(Aspect_Window) QAAISWindow = V->Driver()->Window();
|
#if (defined(_WIN32) || defined(__WIN32__))
|
||||||
|
Handle(WNT_Window) QAAISWindow = Handle(WNT_Window)::DownCast (V->Driver()->Window());
|
||||||
|
#else
|
||||||
|
Handle(Xw_Window) QAAISWindow = Handle(Xw_Window )::DownCast (V->Driver()->Window());
|
||||||
|
#endif
|
||||||
|
|
||||||
Standard_ShortReal aCoordinateX = atoi(argv[1]);
|
Standard_ShortReal aCoordinateX = atoi(argv[1]);
|
||||||
Standard_ShortReal aCoordinateY = atoi(argv[2]);
|
Standard_ShortReal aCoordinateY = atoi(argv[2]);
|
||||||
@ -895,9 +901,9 @@ static int QAAISGetPixelColor2d (Draw_Interpretor& di, Standard_Integer argc, co
|
|||||||
aRadius=0;
|
aRadius=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle(TColStd_HSequenceOfReal) aSeq = GetColorOfPixel (QAAISWindow->ToPixMap(),
|
Image_PixMap anImage;
|
||||||
aCoordinateX, aCoordinateY,
|
QAAISWindow->ToPixMap (anImage);
|
||||||
aRadius);
|
Handle(TColStd_HSequenceOfReal) aSeq = GetColorOfPixel (anImage, aCoordinateX, aCoordinateY, aRadius);
|
||||||
|
|
||||||
Standard_Boolean IsNotEqual = Standard_True;
|
Standard_Boolean IsNotEqual = Standard_True;
|
||||||
Standard_Integer i;
|
Standard_Integer i;
|
||||||
@ -1041,7 +1047,7 @@ static int V2dPan (Draw_Interpretor& di, int argc, const char ** argv)
|
|||||||
di << "use 'v2dinit' command before " << argv[0] << "\n";
|
di << "use 'v2dinit' command before " << argv[0] << "\n";
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
Viewer2dTest::CurrentView()->Pan(atof(argv[1]), atof(argv[2]));
|
Viewer2dTest::CurrentView()->Pan(atoi(argv[1]), atoi(argv[2]));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1242,6 +1248,7 @@ static int QA2dGetIndexes (Draw_Interpretor& di, int /*argc*/, const char ** arg
|
|||||||
di << "Available font indexes are " << aFontMin << " - " << aFontMax << "\n";
|
di << "Available font indexes are " << aFontMin << " - " << aFontMax << "\n";
|
||||||
aWindowDriver->ColorBoundIndexs(aColorMin, aColorMax);
|
aWindowDriver->ColorBoundIndexs(aColorMin, aColorMax);
|
||||||
di << "Available color indexes are " << aColorMin << " - " << aColorMax << "\n";
|
di << "Available color indexes are " << aColorMin << " - " << aColorMax << "\n";
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if ! defined(WNT)
|
#if ! defined(WNT)
|
||||||
|
@ -125,7 +125,7 @@ uses
|
|||||||
Plotter from Graphic3d,
|
Plotter from Graphic3d,
|
||||||
Window from Aspect,
|
Window from Aspect,
|
||||||
PixMap from Image,
|
PixMap from Image,
|
||||||
TypeOfImage from Image,
|
BufferType from Graphic3d,
|
||||||
Background from Aspect,
|
Background from Aspect,
|
||||||
GradientBackground from Aspect,
|
GradientBackground from Aspect,
|
||||||
PlotterDriver from PlotMgt,
|
PlotterDriver from PlotMgt,
|
||||||
@ -1590,8 +1590,8 @@ is
|
|||||||
---Purpose: dump the view
|
---Purpose: dump the view
|
||||||
|
|
||||||
Dump ( me: mutable;
|
Dump ( me: mutable;
|
||||||
theFile: CString from Standard;
|
theFile : CString from Standard;
|
||||||
theBufferType : TypeOfImage from Image = Image_TOI_RGB )
|
theBufferType : BufferType from Graphic3d = Graphic3d_BT_RGB )
|
||||||
returns Boolean from Standard;
|
returns Boolean from Standard;
|
||||||
---Level: Public
|
---Level: Public
|
||||||
---Purpose: dump the full contents of the view at the same
|
---Purpose: dump the full contents of the view at the same
|
||||||
@ -1600,9 +1600,9 @@ is
|
|||||||
-- Returns FALSE when the dump has failed
|
-- Returns FALSE when the dump has failed
|
||||||
|
|
||||||
Dump ( me: mutable;
|
Dump ( me: mutable;
|
||||||
theFile : CString from Standard;
|
theFile : CString from Standard;
|
||||||
theFormat : FormatOfSheetPaper from Aspect;
|
theFormat : FormatOfSheetPaper from Aspect;
|
||||||
theBufferType : TypeOfImage from Image = Image_TOI_RGB )
|
theBufferType : BufferType from Graphic3d = Graphic3d_BT_RGB )
|
||||||
returns Boolean from Standard;
|
returns Boolean from Standard;
|
||||||
---Level: Public
|
---Level: Public
|
||||||
---Purpose: dump the full contents of the view with a
|
---Purpose: dump the full contents of the view with a
|
||||||
@ -1653,16 +1653,18 @@ is
|
|||||||
-- Warning: Works only under Windows.
|
-- Warning: Works only under Windows.
|
||||||
|
|
||||||
ToPixMap ( me : mutable;
|
ToPixMap ( me : mutable;
|
||||||
|
theImage : in out PixMap from Image;
|
||||||
theWidth : Integer from Standard;
|
theWidth : Integer from Standard;
|
||||||
theHeight : Integer from Standard;
|
theHeight : Integer from Standard;
|
||||||
theBufferType : TypeOfImage from Image = Image_TOI_RGB;
|
theBufferType : BufferType from Graphic3d = Graphic3d_BT_RGB;
|
||||||
theForceCentered : Boolean from Standard = Standard_True )
|
theForceCentered : Boolean from Standard = Standard_True )
|
||||||
returns PixMap from Image;
|
returns Boolean from Standard;
|
||||||
---Level : Public
|
---Level : Public
|
||||||
---Purpose : dump the full contents of the view
|
---Purpose : dump the full contents of the view
|
||||||
-- to a pixmap of pixel size <theWidth>*<theHeight> and
|
-- to a pixmap of pixel size <theWidth>*<theHeight> and
|
||||||
-- buffer type <theBufferType>. If <theForceCentered> is true
|
-- buffer type <theBufferType>. If <theForceCentered> is true
|
||||||
-- view scene will be centered.
|
-- view scene will be centered.
|
||||||
|
-- Pixmap will be automatically (re)allocated when needed.
|
||||||
|
|
||||||
SetProjModel( me : mutable;
|
SetProjModel( me : mutable;
|
||||||
amOdel: TypeOfProjectionModel from V3d = V3d_TPM_SCREEN )
|
amOdel: TypeOfProjectionModel from V3d = V3d_TPM_SCREEN )
|
||||||
|
@ -158,7 +158,7 @@ To solve the problem (for lack of a better solution) I make 2 passes.
|
|||||||
#include <Graphic3d_MapIteratorOfMapOfStructure.hxx>
|
#include <Graphic3d_MapIteratorOfMapOfStructure.hxx>
|
||||||
#include <Graphic3d_MapOfStructure.hxx>
|
#include <Graphic3d_MapOfStructure.hxx>
|
||||||
#include <Graphic3d_TextureEnv.hxx>
|
#include <Graphic3d_TextureEnv.hxx>
|
||||||
#include <Image_PixMap.hxx>
|
#include <Image_AlienPixMap.hxx>
|
||||||
#include <V3d.hxx>
|
#include <V3d.hxx>
|
||||||
#include <V3d_View.ixx>
|
#include <V3d_View.ixx>
|
||||||
#include <Viewer_BadValue.hxx>
|
#include <Viewer_BadValue.hxx>
|
||||||
@ -3482,22 +3482,20 @@ void V3d_View::ScreenCopy (const Handle(PlotMgt_PlotterDriver)& aPlotterDriver,
|
|||||||
#include <Visual3d_Layer.hxx>
|
#include <Visual3d_Layer.hxx>
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
Standard_Boolean V3d_View::Dump (const Standard_CString theFile,
|
Standard_Boolean V3d_View::Dump (const Standard_CString theFile,
|
||||||
const Image_TypeOfImage theBufferType)
|
const Graphic3d_BufferType& theBufferType)
|
||||||
{
|
{
|
||||||
Standard_Integer aWinWidth, aWinHeight;
|
Standard_Integer aWinWidth, aWinHeight;
|
||||||
MyWindow->Size (aWinWidth, aWinHeight);
|
MyWindow->Size (aWinWidth, aWinHeight);
|
||||||
|
Image_AlienPixMap anImage;
|
||||||
Handle(Aspect_PixMap) aPixMap = ToPixMap (aWinWidth, aWinHeight, theBufferType);
|
return ToPixMap (anImage, aWinWidth, aWinHeight, theBufferType) && anImage.Save (theFile);
|
||||||
return !aPixMap.IsNull() && aPixMap->Dump (theFile);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
Standard_Boolean V3d_View::Dump (const Standard_CString theFile,
|
Standard_Boolean V3d_View::Dump (const Standard_CString theFile,
|
||||||
const Aspect_FormatOfSheetPaper theFormat,
|
const Aspect_FormatOfSheetPaper theFormat,
|
||||||
const Image_TypeOfImage theBufferType)
|
const Graphic3d_BufferType& theBufferType)
|
||||||
{
|
{
|
||||||
Standard_Boolean isDone = Standard_False;
|
|
||||||
// convert Aspect_FormatOfSheetPaper size to pixel ...
|
// convert Aspect_FormatOfSheetPaper size to pixel ...
|
||||||
Quantity_Length anSPWidth, anSPHeight;
|
Quantity_Length anSPWidth, anSPHeight;
|
||||||
Aspect::ValuesOfFOSP (theFormat, anSPWidth, anSPHeight);
|
Aspect::ValuesOfFOSP (theFormat, anSPWidth, anSPHeight);
|
||||||
@ -3511,22 +3509,25 @@ Standard_Boolean V3d_View::Dump (const Standard_CString theFile,
|
|||||||
Quantity_Factor aScale = Min (anSPWidth / aWinWidth, anSPHeight / aWinHeight);
|
Quantity_Factor aScale = Min (anSPWidth / aWinWidth, anSPHeight / aWinHeight);
|
||||||
aPixelWidth = Standard_Integer (aPixelWidth * aScale);
|
aPixelWidth = Standard_Integer (aPixelWidth * aScale);
|
||||||
aPixelHeight = Standard_Integer (aPixelHeight * aScale);
|
aPixelHeight = Standard_Integer (aPixelHeight * aScale);
|
||||||
|
|
||||||
|
Image_AlienPixMap anImage;
|
||||||
|
ToPixMap (anImage, aPixelWidth, aPixelHeight, theBufferType);
|
||||||
|
OSD_Environment anEnvGamma ("CSF_GAMMA_CORRECTION");
|
||||||
|
TCollection_AsciiString strGamma (anEnvGamma.Value());
|
||||||
|
if (!anImage.IsEmpty() && !strGamma.IsEmpty())
|
||||||
{
|
{
|
||||||
Handle(Aspect_PixMap) aBitmap = ToPixMap (aPixelWidth, aPixelHeight, theBufferType);
|
Standard_Real aGammaValue = strGamma.RealValue();
|
||||||
Standard_Real aGammaValue = 1.0;
|
anImage.AdjustGamma (aGammaValue);
|
||||||
OSD_Environment anEnvGamma ("CSF_GAMMA_CORRECTION");
|
|
||||||
TCollection_AsciiString strGamma (anEnvGamma.Value());
|
|
||||||
if (!strGamma.IsEmpty()) aGammaValue = strGamma.RealValue();
|
|
||||||
isDone = !aBitmap.IsNull() && aBitmap->Dump (theFile, aGammaValue);
|
|
||||||
}
|
}
|
||||||
return isDone;
|
return anImage.Save (theFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
Handle(Image_PixMap) V3d_View::ToPixMap (const Standard_Integer theWidth,
|
Standard_Boolean V3d_View::ToPixMap (Image_PixMap& theImage,
|
||||||
const Standard_Integer theHeight,
|
const Standard_Integer theWidth,
|
||||||
const Image_TypeOfImage theBufferType,
|
const Standard_Integer theHeight,
|
||||||
const Standard_Boolean theIsForceCentred)
|
const Graphic3d_BufferType& theBufferType,
|
||||||
|
const Standard_Boolean theIsForceCentred)
|
||||||
{
|
{
|
||||||
// always prefer hardware accelerated offscreen buffer
|
// always prefer hardware accelerated offscreen buffer
|
||||||
Graphic3d_CView* cView = (Graphic3d_CView* )MyView->CView();
|
Graphic3d_CView* cView = (Graphic3d_CView* )MyView->CView();
|
||||||
@ -3575,7 +3576,7 @@ Handle(Image_PixMap) V3d_View::ToPixMap (const Standard_Integer theWidth,
|
|||||||
// but currently allow only dumping the window itself
|
// but currently allow only dumping the window itself
|
||||||
if (aFBOVPSizeX != aWinWidth || aFBOVPSizeY != aWinHeight)
|
if (aFBOVPSizeX != aWinWidth || aFBOVPSizeY != aWinHeight)
|
||||||
{
|
{
|
||||||
return Handle(Image_PixMap)();
|
return Standard_False;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3625,15 +3626,25 @@ Handle(Image_PixMap) V3d_View::ToPixMap (const Standard_Integer theWidth,
|
|||||||
MyViewMapping = prevMapping;
|
MyViewMapping = prevMapping;
|
||||||
MyView->SetViewMapping (prevMapping);
|
MyView->SetViewMapping (prevMapping);
|
||||||
|
|
||||||
|
Standard_Boolean isSuccess = Standard_True;
|
||||||
|
|
||||||
// allocate image buffer for dumping
|
// allocate image buffer for dumping
|
||||||
Image_CRawBufferData aRawBuffer;
|
if (theImage.IsEmpty()
|
||||||
Handle(Image_PixMap) anImageBitmap = new Image_PixMap (aFBOVPSizeX, aFBOVPSizeY, theBufferType);
|
|| (Standard_Size )aFBOVPSizeX != theImage.SizeX()
|
||||||
anImageBitmap->AccessBuffer (aRawBuffer);
|
|| (Standard_Size )aFBOVPSizeY != theImage.SizeY())
|
||||||
if (!MyView->BufferDump (aRawBuffer))
|
|
||||||
{
|
{
|
||||||
// dump is failed!
|
bool isBigEndian = Image_PixMap::IsBigEndianHost();
|
||||||
anImageBitmap = Handle(Image_PixMap)();
|
Image_PixMap::ImgFormat aFormat = Image_PixMap::ImgUNKNOWN;
|
||||||
|
switch (theBufferType)
|
||||||
|
{
|
||||||
|
case Graphic3d_BT_RGB: aFormat = isBigEndian ? Image_PixMap::ImgRGB : Image_PixMap::ImgBGR; break;
|
||||||
|
case Graphic3d_BT_RGBA: aFormat = isBigEndian ? Image_PixMap::ImgRGBA : Image_PixMap::ImgBGRA; break;
|
||||||
|
case Graphic3d_BT_Depth: aFormat = Image_PixMap::ImgGrayF; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
isSuccess = isSuccess && theImage.InitZero (aFormat, aFBOVPSizeX, aFBOVPSizeY);
|
||||||
}
|
}
|
||||||
|
isSuccess = isSuccess && MyView->BufferDump (theImage, theBufferType);
|
||||||
|
|
||||||
// FBO now useless, free resources
|
// FBO now useless, free resources
|
||||||
if (aFBOPtr != aPrevFBOPtr)
|
if (aFBOPtr != aPrevFBOPtr)
|
||||||
@ -3645,5 +3656,5 @@ Handle(Image_PixMap) V3d_View::ToPixMap (const Standard_Integer theWidth,
|
|||||||
MyView->FBOChangeViewport (aPrevFBOPtr, aPrevFBOVPSizeX, aPrevFBOVPSizeY);
|
MyView->FBOChangeViewport (aPrevFBOPtr, aPrevFBOVPSizeX, aPrevFBOVPSizeY);
|
||||||
}
|
}
|
||||||
cView->ptrFBO = aPrevFBOPtr;
|
cView->ptrFBO = aPrevFBOPtr;
|
||||||
return anImageBitmap;
|
return isSuccess;
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,7 @@
|
|||||||
#include <AIS_ListIteratorOfListOfInteractive.hxx>
|
#include <AIS_ListIteratorOfListOfInteractive.hxx>
|
||||||
#include <Aspect_InteriorStyle.hxx>
|
#include <Aspect_InteriorStyle.hxx>
|
||||||
#include <Graphic3d_AspectFillArea3d.hxx>
|
#include <Graphic3d_AspectFillArea3d.hxx>
|
||||||
#include <Image_PixMap.hxx>
|
#include <Image_AlienPixMap.hxx>
|
||||||
#include <Prs3d_ShadingAspect.hxx>
|
#include <Prs3d_ShadingAspect.hxx>
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
@ -833,22 +833,21 @@ static Standard_Integer VDump (Draw_Interpretor& di, Standard_Integer argc, cons
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Image_TypeOfImage aBufferType = Image_TOI_RGB;
|
Graphic3d_BufferType aBufferType = Graphic3d_BT_RGB;
|
||||||
|
|
||||||
if (argc > 2)
|
if (argc > 2)
|
||||||
{
|
{
|
||||||
TCollection_AsciiString aBuffTypeStr (argv[2]);
|
TCollection_AsciiString aBuffTypeStr (argv[2]);
|
||||||
if (TCollection_AsciiString::ISSIMILAR (aBuffTypeStr, TCollection_AsciiString ("rgb")))
|
if (TCollection_AsciiString::ISSIMILAR (aBuffTypeStr, TCollection_AsciiString ("rgb")))
|
||||||
{
|
{
|
||||||
aBufferType = Image_TOI_RGB;
|
aBufferType = Graphic3d_BT_RGB;
|
||||||
}
|
}
|
||||||
else if (TCollection_AsciiString::ISSIMILAR (aBuffTypeStr, TCollection_AsciiString ("rgba")))
|
else if (TCollection_AsciiString::ISSIMILAR (aBuffTypeStr, TCollection_AsciiString ("rgba")))
|
||||||
{
|
{
|
||||||
aBufferType = Image_TOI_RGBA;
|
aBufferType = Graphic3d_BT_RGBA;
|
||||||
}
|
}
|
||||||
else if (TCollection_AsciiString::ISSIMILAR (aBuffTypeStr, TCollection_AsciiString ("depth")))
|
else if (TCollection_AsciiString::ISSIMILAR (aBuffTypeStr, TCollection_AsciiString ("depth")))
|
||||||
{
|
{
|
||||||
aBufferType = Image_TOI_FLOAT;
|
aBufferType = Graphic3d_BT_Depth;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -874,21 +873,20 @@ static Standard_Integer VDump (Draw_Interpretor& di, Standard_Integer argc, cons
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle(Image_PixMap) aPixMap = view->ToPixMap (aWidth, aHeight, aBufferType);
|
Image_AlienPixMap aPixMap;
|
||||||
if (aPixMap.IsNull())
|
if (!view->ToPixMap (aPixMap, aWidth, aHeight, aBufferType))
|
||||||
{
|
{
|
||||||
di << "Dumping failed!\n";
|
di << "Dumping failed!\n";
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Image_CRawBufferData aRawBuffer;
|
if (aPixMap.SizeX() != Standard_Size(aWidth)
|
||||||
aPixMap->AccessBuffer (aRawBuffer);
|
|| aPixMap.SizeY() != Standard_Size(aHeight))
|
||||||
if (aRawBuffer.widthPx != aWidth || aRawBuffer.heightPx != aHeight)
|
|
||||||
{
|
{
|
||||||
std::cout << "Warning! Dumped dimensions " << aRawBuffer.widthPx << "x" << aRawBuffer.heightPx
|
std::cout << "Warning! Dumped dimensions " << aPixMap.SizeX() << "x" << aPixMap.SizeY()
|
||||||
<< " are lesser than requested " << aWidth << "x" << aHeight << "\n";
|
<< " are lesser than requested " << aWidth << "x" << aHeight << "\n";
|
||||||
}
|
}
|
||||||
if (!aPixMap->Dump (argv[1]))
|
if (!aPixMap.Save (argv[1]))
|
||||||
{
|
{
|
||||||
di << "Saving image failed!\n";
|
di << "Saving image failed!\n";
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -45,19 +45,21 @@
|
|||||||
#include <Draw.hxx>
|
#include <Draw.hxx>
|
||||||
#include <Draw_Appli.hxx>
|
#include <Draw_Appli.hxx>
|
||||||
#include <Aspect_PrintAlgo.hxx>
|
#include <Aspect_PrintAlgo.hxx>
|
||||||
#include <Image_PixMap.hxx>
|
#include <Image_AlienPixMap.hxx>
|
||||||
#include <OSD_Timer.hxx>
|
#include <OSD_Timer.hxx>
|
||||||
#include <TColStd_SequenceOfInteger.hxx>
|
#include <TColStd_SequenceOfInteger.hxx>
|
||||||
#include <Visual3d_LayerItem.hxx>
|
#include <Visual3d_LayerItem.hxx>
|
||||||
#include <V3d_LayerMgr.hxx>
|
#include <V3d_LayerMgr.hxx>
|
||||||
#include <V3d_LayerMgrPointer.hxx>
|
#include <V3d_LayerMgrPointer.hxx>
|
||||||
#include <Aspect_TypeOfLine.hxx>
|
#include <Aspect_TypeOfLine.hxx>
|
||||||
|
#include <Image_Diff.hxx>
|
||||||
|
|
||||||
#ifdef WNT
|
#ifdef WNT
|
||||||
#undef DrawText
|
#undef DrawText
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <Visual3d_Layer.hxx>
|
#include <Visual3d_Layer.hxx>
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
#ifndef WNT
|
#ifndef WNT
|
||||||
#include <Graphic3d_GraphicDevice.hxx>
|
#include <Graphic3d_GraphicDevice.hxx>
|
||||||
@ -2151,10 +2153,8 @@ static int VPrintView (Draw_Interpretor& di, Standard_Integer argc,
|
|||||||
if (aMode != 0 && aMode != 1)
|
if (aMode != 0 && aMode != 1)
|
||||||
aMode = 0;
|
aMode = 0;
|
||||||
|
|
||||||
Image_CRawBufferData aRawBuffer;
|
|
||||||
HDC anDC = CreateCompatibleDC(0);
|
|
||||||
|
|
||||||
// define compatible bitmap
|
// define compatible bitmap
|
||||||
|
HDC anDC = CreateCompatibleDC(0);
|
||||||
BITMAPINFO aBitmapData;
|
BITMAPINFO aBitmapData;
|
||||||
memset (&aBitmapData, 0, sizeof (BITMAPINFOHEADER));
|
memset (&aBitmapData, 0, sizeof (BITMAPINFOHEADER));
|
||||||
aBitmapData.bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
|
aBitmapData.bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
|
||||||
@ -2170,12 +2170,13 @@ static int VPrintView (Draw_Interpretor& di, Standard_Integer argc,
|
|||||||
aBitmapData.bmiHeader.biSizeImage = 0;
|
aBitmapData.bmiHeader.biSizeImage = 0;
|
||||||
|
|
||||||
// Create Device Independent Bitmap
|
// Create Device Independent Bitmap
|
||||||
|
void* aBitsOut = NULL;
|
||||||
HBITMAP aMemoryBitmap = CreateDIBSection (anDC, &aBitmapData, DIB_RGB_COLORS,
|
HBITMAP aMemoryBitmap = CreateDIBSection (anDC, &aBitmapData, DIB_RGB_COLORS,
|
||||||
&aRawBuffer.dataPtr, NULL, 0);
|
&aBitsOut, NULL, 0);
|
||||||
HGDIOBJ anOldBitmap = SelectObject(anDC, aMemoryBitmap);
|
HGDIOBJ anOldBitmap = SelectObject(anDC, aMemoryBitmap);
|
||||||
|
|
||||||
Standard_Boolean isSaved = Standard_False, isPrinted = Standard_False;
|
Standard_Boolean isSaved = Standard_False, isPrinted = Standard_False;
|
||||||
if (aRawBuffer.dataPtr != 0)
|
if (aBitsOut != NULL)
|
||||||
{
|
{
|
||||||
if (aMode == 0)
|
if (aMode == 0)
|
||||||
isPrinted = aView->Print(anDC,1,1,0,Aspect_PA_STRETCH);
|
isPrinted = aView->Print(anDC,1,1,0,Aspect_PA_STRETCH);
|
||||||
@ -2185,11 +2186,13 @@ static int VPrintView (Draw_Interpretor& di, Standard_Integer argc,
|
|||||||
// succesfully printed into an intermediate buffer
|
// succesfully printed into an intermediate buffer
|
||||||
if (isPrinted)
|
if (isPrinted)
|
||||||
{
|
{
|
||||||
Handle(Image_PixMap) anImageBitmap =
|
Image_PixMap aWrapper;
|
||||||
new Image_PixMap ((Standard_PByte)aRawBuffer.dataPtr,
|
aWrapper.InitWrapper (Image_PixMap::ImgBGR, (Standard_Byte* )aBitsOut, aWidth, aHeight, aWidth * 3 + aWidth % 4);
|
||||||
aWidth, aHeight,
|
aWrapper.SetTopDown (false);
|
||||||
aWidth*3 + aWidth%4, 24, 0);
|
|
||||||
isSaved = anImageBitmap->Dump(aFileName.ToCString());
|
Image_AlienPixMap anImageBitmap;
|
||||||
|
anImageBitmap.InitCopy (aWrapper);
|
||||||
|
isSaved = anImageBitmap.Save (aFileName);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -2898,7 +2901,9 @@ static int VReadPixel (Draw_Interpretor& theDI,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Image_TypeOfImage aBufferType = Image_TOI_RGBA;
|
Image_PixMap::ImgFormat aFormat = Image_PixMap::IsBigEndianHost() ? Image_PixMap::ImgRGBA : Image_PixMap::ImgBGRA;
|
||||||
|
Graphic3d_BufferType aBufferType = Graphic3d_BT_RGBA;
|
||||||
|
|
||||||
Standard_Integer aWidth, aHeight;
|
Standard_Integer aWidth, aHeight;
|
||||||
aView->Window()->Size (aWidth, aHeight);
|
aView->Window()->Size (aWidth, aHeight);
|
||||||
const Standard_Integer anX = atoi (theArgVec[1]);
|
const Standard_Integer anX = atoi (theArgVec[1]);
|
||||||
@ -2916,28 +2921,34 @@ static int VReadPixel (Draw_Interpretor& theDI,
|
|||||||
TCollection_AsciiString aParam (theArgVec[anIter]);
|
TCollection_AsciiString aParam (theArgVec[anIter]);
|
||||||
if (TCollection_AsciiString::ISSIMILAR (aParam, TCollection_AsciiString ("rgb")))
|
if (TCollection_AsciiString::ISSIMILAR (aParam, TCollection_AsciiString ("rgb")))
|
||||||
{
|
{
|
||||||
aBufferType = Image_TOI_RGB;
|
aFormat = Image_PixMap::IsBigEndianHost() ? Image_PixMap::ImgRGB : Image_PixMap::ImgBGR;
|
||||||
|
aBufferType = Graphic3d_BT_RGB;
|
||||||
}
|
}
|
||||||
else if (TCollection_AsciiString::ISSIMILAR (aParam, TCollection_AsciiString ("hls")))
|
else if (TCollection_AsciiString::ISSIMILAR (aParam, TCollection_AsciiString ("hls")))
|
||||||
{
|
{
|
||||||
aBufferType = Image_TOI_RGB;
|
aFormat = Image_PixMap::IsBigEndianHost() ? Image_PixMap::ImgRGB : Image_PixMap::ImgBGR;
|
||||||
|
aBufferType = Graphic3d_BT_RGB;
|
||||||
toShowHls = Standard_True;
|
toShowHls = Standard_True;
|
||||||
}
|
}
|
||||||
else if (TCollection_AsciiString::ISSIMILAR (aParam, TCollection_AsciiString ("rgbf")))
|
else if (TCollection_AsciiString::ISSIMILAR (aParam, TCollection_AsciiString ("rgbf")))
|
||||||
{
|
{
|
||||||
aBufferType = Image_TOI_RGBF;
|
aFormat = Image_PixMap::ImgRGBF;
|
||||||
|
aBufferType = Graphic3d_BT_RGB;
|
||||||
}
|
}
|
||||||
else if (TCollection_AsciiString::ISSIMILAR (aParam, TCollection_AsciiString ("rgba")))
|
else if (TCollection_AsciiString::ISSIMILAR (aParam, TCollection_AsciiString ("rgba")))
|
||||||
{
|
{
|
||||||
aBufferType = Image_TOI_RGBA;
|
aFormat = Image_PixMap::IsBigEndianHost() ? Image_PixMap::ImgRGBA : Image_PixMap::ImgBGRA;
|
||||||
|
aBufferType = Graphic3d_BT_RGBA;
|
||||||
}
|
}
|
||||||
else if (TCollection_AsciiString::ISSIMILAR (aParam, TCollection_AsciiString ("rgbaf")))
|
else if (TCollection_AsciiString::ISSIMILAR (aParam, TCollection_AsciiString ("rgbaf")))
|
||||||
{
|
{
|
||||||
aBufferType = Image_TOI_RGBAF;
|
aFormat = Image_PixMap::ImgRGBAF;
|
||||||
|
aBufferType = Graphic3d_BT_RGBA;
|
||||||
}
|
}
|
||||||
else if (TCollection_AsciiString::ISSIMILAR (aParam, TCollection_AsciiString ("depth")))
|
else if (TCollection_AsciiString::ISSIMILAR (aParam, TCollection_AsciiString ("depth")))
|
||||||
{
|
{
|
||||||
aBufferType = Image_TOI_FLOAT;
|
aFormat = Image_PixMap::ImgGrayF;
|
||||||
|
aBufferType = Graphic3d_BT_Depth;
|
||||||
}
|
}
|
||||||
else if (TCollection_AsciiString::ISSIMILAR (aParam, TCollection_AsciiString ("name")))
|
else if (TCollection_AsciiString::ISSIMILAR (aParam, TCollection_AsciiString ("name")))
|
||||||
{
|
{
|
||||||
@ -2945,19 +2956,23 @@ static int VReadPixel (Draw_Interpretor& theDI,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle(Image_PixMap) anImage = aView->ToPixMap (aWidth, aHeight, aBufferType);
|
Image_PixMap anImage;
|
||||||
if (anImage.IsNull())
|
if (!anImage.InitTrash (aFormat, aWidth, aHeight))
|
||||||
|
{
|
||||||
|
std::cerr << "Image allocation failed\n";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else if (!aView->ToPixMap (anImage, aWidth, aHeight, aBufferType))
|
||||||
{
|
{
|
||||||
std::cerr << "Image dump failed\n";
|
std::cerr << "Image dump failed\n";
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Quantity_Parameter anAlpha;
|
Quantity_Parameter anAlpha;
|
||||||
Quantity_Color aColor = anImage->PixelColor (anX, anY, anAlpha);
|
Quantity_Color aColor = anImage.PixelColor (anX, anY, anAlpha);
|
||||||
if (toShowName)
|
if (toShowName)
|
||||||
{
|
{
|
||||||
if (aBufferType == Image_TOI_RGBA
|
if (aBufferType == Graphic3d_BT_RGBA)
|
||||||
|| aBufferType == Image_TOI_RGBAF)
|
|
||||||
{
|
{
|
||||||
theDI << Quantity_Color::StringName (aColor.Name()) << " " << anAlpha << "\n";
|
theDI << Quantity_Color::StringName (aColor.Name()) << " " << anAlpha << "\n";
|
||||||
}
|
}
|
||||||
@ -2971,8 +2986,7 @@ static int VReadPixel (Draw_Interpretor& theDI,
|
|||||||
switch (aBufferType)
|
switch (aBufferType)
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
case Image_TOI_RGB:
|
case Graphic3d_BT_RGB:
|
||||||
case Image_TOI_RGBF:
|
|
||||||
{
|
{
|
||||||
if (toShowHls)
|
if (toShowHls)
|
||||||
{
|
{
|
||||||
@ -2984,13 +2998,12 @@ static int VReadPixel (Draw_Interpretor& theDI,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Image_TOI_RGBA:
|
case Graphic3d_BT_RGBA:
|
||||||
case Image_TOI_RGBAF:
|
|
||||||
{
|
{
|
||||||
theDI << aColor.Red() << " " << aColor.Green() << " " << aColor.Blue() << " " << anAlpha << "\n";
|
theDI << aColor.Red() << " " << aColor.Green() << " " << aColor.Blue() << " " << anAlpha << "\n";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Image_TOI_FLOAT:
|
case Graphic3d_BT_Depth:
|
||||||
{
|
{
|
||||||
theDI << aColor.Red() << "\n";
|
theDI << aColor.Red() << "\n";
|
||||||
break;
|
break;
|
||||||
@ -3001,6 +3014,57 @@ static int VReadPixel (Draw_Interpretor& theDI,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
//function : VDiffImage
|
||||||
|
//purpose : The draw-command compares two images.
|
||||||
|
//==============================================================================
|
||||||
|
|
||||||
|
static int VDiffImage (Draw_Interpretor& theDI, Standard_Integer theArgNb, const char** theArgVec)
|
||||||
|
{
|
||||||
|
if (theArgNb < 6)
|
||||||
|
{
|
||||||
|
theDI << "Not enough arguments.\n";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// image file names
|
||||||
|
const char* anImgPathRef = theArgVec[1];
|
||||||
|
const char* anImgPathNew = theArgVec[2];
|
||||||
|
|
||||||
|
// get string tolerance and check its validity
|
||||||
|
Standard_Real aTolColor = atof (theArgVec[3]);
|
||||||
|
if (aTolColor < 0.0)
|
||||||
|
aTolColor = 0.0;
|
||||||
|
if (aTolColor > 1.0)
|
||||||
|
aTolColor = 1.0;
|
||||||
|
|
||||||
|
Standard_Boolean toBlackWhite = (atoi (theArgVec[4]) == 1);
|
||||||
|
Standard_Boolean isBorderFilterOn = (atoi (theArgVec[5]) == 1);
|
||||||
|
|
||||||
|
// image file of difference
|
||||||
|
const char* aDiffImagePath = (theArgNb >= 7) ? theArgVec[6] : NULL;
|
||||||
|
|
||||||
|
// compare the images
|
||||||
|
Image_Diff aComparer;
|
||||||
|
if (!aComparer.Init (anImgPathRef, anImgPathNew, toBlackWhite))
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
aComparer.SetColorTolerance (aTolColor);
|
||||||
|
aComparer.SetBorderFilterOn (isBorderFilterOn);
|
||||||
|
Standard_Integer aDiffColorsNb = aComparer.Compare();
|
||||||
|
theDI << aDiffColorsNb << "\n";
|
||||||
|
|
||||||
|
// save image of difference
|
||||||
|
if (aDiffImagePath != NULL)
|
||||||
|
{
|
||||||
|
aComparer.SaveDiffImage (aDiffImagePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
//function : ViewerCommands
|
//function : ViewerCommands
|
||||||
//purpose :
|
//purpose :
|
||||||
@ -3131,4 +3195,7 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
|
|||||||
"vreadpixel xPixel yPixel [{rgb|rgba|depth|hls|rgbf|rgbaf}=rgba] [name]"
|
"vreadpixel xPixel yPixel [{rgb|rgba|depth|hls|rgbf|rgbaf}=rgba] [name]"
|
||||||
" : Read pixel value for active view",
|
" : Read pixel value for active view",
|
||||||
__FILE__, VReadPixel, group);
|
__FILE__, VReadPixel, group);
|
||||||
|
theCommands.Add("diffimage",
|
||||||
|
"diffimage : diffimage imageFile1 imageFile2 toleranceOfColor(0..1) blackWhite(1|0) borderFilter(1|0) [diffImageFile]",
|
||||||
|
__FILE__, VDiffImage, group);
|
||||||
}
|
}
|
||||||
|
@ -87,8 +87,7 @@ uses
|
|||||||
ColorScale from Aspect,
|
ColorScale from Aspect,
|
||||||
PrintAlgo from Aspect,
|
PrintAlgo from Aspect,
|
||||||
|
|
||||||
CRawBufferData from Image,
|
BufferType from Graphic3d,
|
||||||
|
|
||||||
CBitFields8 from Graphic3d,
|
CBitFields8 from Graphic3d,
|
||||||
CView from Graphic3d,
|
CView from Graphic3d,
|
||||||
GraphicDriver from Graphic3d,
|
GraphicDriver from Graphic3d,
|
||||||
@ -121,7 +120,9 @@ uses
|
|||||||
FontAspect from OSD,
|
FontAspect from OSD,
|
||||||
AsciiString from TCollection,
|
AsciiString from TCollection,
|
||||||
ExtendedString from TCollection,
|
ExtendedString from TCollection,
|
||||||
CGraduatedTrihedron from Graphic3d
|
CGraduatedTrihedron from Graphic3d,
|
||||||
|
|
||||||
|
PixMap from Image
|
||||||
|
|
||||||
raises
|
raises
|
||||||
TransformError from Visual3d,
|
TransformError from Visual3d,
|
||||||
@ -1238,7 +1239,8 @@ is
|
|||||||
---Purpose: Change offscreen FBO viewport.
|
---Purpose: Change offscreen FBO viewport.
|
||||||
|
|
||||||
BufferDump( me : mutable;
|
BufferDump( me : mutable;
|
||||||
buffer : in out CRawBufferData from Image )
|
theImage : in out PixMap from Image;
|
||||||
|
theBufferType : BufferType from Graphic3d )
|
||||||
returns Boolean from Standard
|
returns Boolean from Standard
|
||||||
is static;
|
is static;
|
||||||
---Level: Public
|
---Level: Public
|
||||||
|
@ -4277,9 +4277,10 @@ void Visual3d_View::FBOChangeViewport(Graphic3d_PtrFrameBuffer& theFBOPtr,
|
|||||||
theWidth, theHeight );
|
theWidth, theHeight );
|
||||||
}
|
}
|
||||||
|
|
||||||
Standard_Boolean Visual3d_View::BufferDump (Image_CRawBufferData& theBuffer)
|
Standard_Boolean Visual3d_View::BufferDump (Image_PixMap& theImage,
|
||||||
|
const Graphic3d_BufferType& theBufferType)
|
||||||
{
|
{
|
||||||
return MyGraphicDriver->BufferDump( MyCView, theBuffer);
|
return MyGraphicDriver->BufferDump (MyCView, theImage, theBufferType);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Visual3d_View::EnableGLLight( const Standard_Boolean enable ) const
|
void Visual3d_View::EnableGLLight( const Standard_Boolean enable ) const
|
||||||
|
@ -43,7 +43,8 @@
|
|||||||
#include <Quantity_Color.hxx>
|
#include <Quantity_Color.hxx>
|
||||||
#include <WNT_GraphicDevice.hxx>
|
#include <WNT_GraphicDevice.hxx>
|
||||||
#include <WNT_TypeOfImage.hxx>
|
#include <WNT_TypeOfImage.hxx>
|
||||||
#include <Image_PixMap.hxx>
|
#include <Image_AlienPixMap.hxx>
|
||||||
|
#include <TCollection_AsciiString.hxx>
|
||||||
|
|
||||||
//***//
|
//***//
|
||||||
#define I_SUCCESS Standard_True
|
#define I_SUCCESS Standard_True
|
||||||
@ -285,64 +286,45 @@ int __WNT_API SaveWindowToFile (
|
|||||||
|
|
||||||
} // end SaveWindowToFile
|
} // end SaveWindowToFile
|
||||||
|
|
||||||
int DumpBitmapToFile (Handle(WNT_GraphicDevice)& , HDC ,
|
int DumpBitmapToFile (HBITMAP theHBitmap,
|
||||||
HBITMAP theHBitmap,
|
const char* theFileName)
|
||||||
char* theFileName)
|
|
||||||
{
|
{
|
||||||
// Copy data from HBITMAP
|
// get informations about the bitmap
|
||||||
BITMAP aBitmap;
|
BITMAP aBitmap;
|
||||||
|
if (GetObject (theHBitmap, sizeof(BITMAP), &aBitmap) == 0)
|
||||||
|
{
|
||||||
|
return I_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
// Get informations about the bitmap
|
Image_AlienPixMap anImage;
|
||||||
GetObject (theHBitmap, sizeof(BITMAP), (LPSTR )&aBitmap);
|
const Standard_Size aSizeRowBytes = Standard_Size(aBitmap.bmWidth) * 4;
|
||||||
Standard_Integer aWidth = aBitmap.bmWidth;
|
if (!anImage.InitTrash (Image_PixMap::ImgBGR32, Standard_Size(aBitmap.bmWidth), Standard_Size(aBitmap.bmHeight), aSizeRowBytes))
|
||||||
Standard_Integer aHeight = aBitmap.bmHeight;
|
{
|
||||||
|
return I_ERROR;
|
||||||
|
}
|
||||||
|
anImage.SetTopDown (false);
|
||||||
|
|
||||||
// Setup image data
|
// Setup image data
|
||||||
BITMAPINFOHEADER aBitmapInfo;
|
BITMAPINFOHEADER aBitmapInfo;
|
||||||
memset (&aBitmapInfo, 0, sizeof(BITMAPINFOHEADER));
|
memset (&aBitmapInfo, 0, sizeof(BITMAPINFOHEADER));
|
||||||
aBitmapInfo.biSize = sizeof(BITMAPINFOHEADER);
|
aBitmapInfo.biSize = sizeof(BITMAPINFOHEADER);
|
||||||
aBitmapInfo.biWidth = aWidth;
|
aBitmapInfo.biWidth = aBitmap.bmWidth;
|
||||||
aBitmapInfo.biHeight = aHeight; // positive means bottom-up!
|
aBitmapInfo.biHeight = aBitmap.bmHeight; // positive means bottom-up!
|
||||||
aBitmapInfo.biPlanes = 1;
|
aBitmapInfo.biPlanes = 1;
|
||||||
aBitmapInfo.biBitCount = 32;
|
aBitmapInfo.biBitCount = 32; // use 32bit for automatic word-alignment per row
|
||||||
aBitmapInfo.biCompression = BI_RGB;
|
aBitmapInfo.biCompression = BI_RGB;
|
||||||
|
|
||||||
Standard_Integer aBytesPerLine = aWidth * 4;
|
|
||||||
Standard_Byte* aDataPtr = new Standard_Byte[aBytesPerLine * aHeight];
|
|
||||||
|
|
||||||
// Copy the pixels
|
// Copy the pixels
|
||||||
HDC aDC = GetDC (NULL);
|
HDC aDC = GetDC (NULL);
|
||||||
Standard_Boolean isSuccess
|
Standard_Boolean isSuccess = GetDIBits (aDC, theHBitmap,
|
||||||
= GetDIBits (aDC, // handle to DC
|
0, // first scan line to set
|
||||||
theHBitmap, // handle to bitmap
|
aBitmap.bmHeight, // number of scan lines to copy
|
||||||
0, // first scan line to set
|
anImage.ChangeData(), // array for bitmap bits
|
||||||
aHeight, // number of scan lines to copy
|
(LPBITMAPINFO )&aBitmapInfo, // bitmap data info
|
||||||
aDataPtr, // array for bitmap bits
|
DIB_RGB_COLORS) != 0;
|
||||||
(LPBITMAPINFO )&aBitmapInfo, // bitmap data info
|
|
||||||
DIB_RGB_COLORS // RGB
|
|
||||||
) != 0;
|
|
||||||
|
|
||||||
if (isSuccess)
|
|
||||||
{
|
|
||||||
Handle(Image_PixMap) anImagePixMap = new Image_PixMap (aDataPtr,
|
|
||||||
aWidth, aHeight,
|
|
||||||
aBytesPerLine,
|
|
||||||
aBitmapInfo.biBitCount,
|
|
||||||
Standard_False); // bottom-up!
|
|
||||||
|
|
||||||
// Release dump memory here
|
|
||||||
delete[] aDataPtr;
|
|
||||||
|
|
||||||
// save the image
|
|
||||||
anImagePixMap->Dump (theFileName);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Release dump memory
|
|
||||||
delete[] aDataPtr;
|
|
||||||
}
|
|
||||||
ReleaseDC (NULL, aDC);
|
ReleaseDC (NULL, aDC);
|
||||||
return isSuccess ? I_SUCCESS : I_ERROR;
|
return (isSuccess && anImage.Save (theFileName)) ? I_SUCCESS : I_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
//***//
|
//***//
|
||||||
@ -401,8 +383,7 @@ int SaveBitmapToFile (Handle(WNT_GraphicDevice)& gDev,
|
|||||||
hNewBmp = hBmp;
|
hNewBmp = hBmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
retVal = DumpBitmapToFile (gDev, NULL,
|
retVal = DumpBitmapToFile (hNewBmp, fName);
|
||||||
hNewBmp, fName);
|
|
||||||
} // end __try
|
} // end __try
|
||||||
__finally {
|
__finally {
|
||||||
if (hNewBmp != NULL && newBmp) DeleteObject (hNewBmp);
|
if (hNewBmp != NULL && newBmp) DeleteObject (hNewBmp);
|
||||||
|
@ -30,7 +30,7 @@ class PixMap from WNT
|
|||||||
---Keywords: Bitmap, Pixmap
|
---Keywords: Bitmap, Pixmap
|
||||||
|
|
||||||
inherits
|
inherits
|
||||||
PixMap from Aspect
|
Transient from Standard
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Handle from Aspect,
|
Handle from Aspect,
|
||||||
@ -99,7 +99,10 @@ is
|
|||||||
returns Integer from Standard is private;
|
returns Integer from Standard is private;
|
||||||
|
|
||||||
fields
|
fields
|
||||||
myDC : Handle from Aspect is protected;
|
myDC : Handle from Aspect is protected;
|
||||||
myBitmap : Handle from Aspect is protected;
|
myBitmap : Handle from Aspect is protected;
|
||||||
myWND : Window from Aspect;
|
myWND : Window from Aspect;
|
||||||
|
myWidth : Integer from Standard is protected;
|
||||||
|
myHeight : Integer from Standard is protected;
|
||||||
|
myDepth : Integer from Standard is protected;
|
||||||
end PixMap;
|
end PixMap;
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
#include <WNT_Window.hxx>
|
#include <WNT_Window.hxx>
|
||||||
|
|
||||||
extern int DumpBitmapToFile( Handle(WNT_GraphicDevice)&, HDC, HBITMAP, char* );
|
extern int DumpBitmapToFile (HBITMAP, const char* );
|
||||||
|
|
||||||
#include <WNT_GraphicDevice.hxx>
|
#include <WNT_GraphicDevice.hxx>
|
||||||
|
|
||||||
@ -50,15 +50,16 @@ Standard_Integer WNT_PixMap::PreferedDepth(
|
|||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////
|
||||||
WNT_PixMap::WNT_PixMap ( const Handle(Aspect_Window)& aWindow,
|
WNT_PixMap::WNT_PixMap (const Handle(Aspect_Window)& theWindow,
|
||||||
const Standard_Integer aWidth,
|
const Standard_Integer theWidth,
|
||||||
const Standard_Integer anHeight,
|
const Standard_Integer theHeight,
|
||||||
const Standard_Integer aCDepth ) :
|
const Standard_Integer theDepth)
|
||||||
Aspect_PixMap(aWidth, anHeight, PreferedDepth(aWindow, aCDepth))
|
: myWND (theWindow),
|
||||||
|
myWidth (theWidth),
|
||||||
|
myHeight (theHeight),
|
||||||
|
myDepth (PreferedDepth (theWindow, theDepth))
|
||||||
{
|
{
|
||||||
myWND = aWindow;
|
const Handle(WNT_Window)& hWindow = Handle(WNT_Window)::DownCast(theWindow);
|
||||||
|
|
||||||
const Handle(WNT_Window)& hWindow = Handle(WNT_Window)::DownCast(aWindow);
|
|
||||||
HDC hdc = GetDC ( (HWND)(hWindow->HWindow()) );
|
HDC hdc = GetDC ( (HWND)(hWindow->HWindow()) );
|
||||||
HDC hdcMem = CreateCompatibleDC ( hdc );
|
HDC hdcMem = CreateCompatibleDC ( hdc );
|
||||||
ReleaseDC ( (HWND)(hWindow->HWindow()), hdc );
|
ReleaseDC ( (HWND)(hWindow->HWindow()), hdc );
|
||||||
@ -80,8 +81,8 @@ Aspect_PixMap(aWidth, anHeight, PreferedDepth(aWindow, aCDepth))
|
|||||||
ZeroMemory ( pBmi, sizeBmi );
|
ZeroMemory ( pBmi, sizeBmi );
|
||||||
|
|
||||||
pBmi->bmiHeader.biSize = sizeof (BITMAPINFOHEADER); //sizeBmi
|
pBmi->bmiHeader.biSize = sizeof (BITMAPINFOHEADER); //sizeBmi
|
||||||
pBmi->bmiHeader.biWidth = aWidth;
|
pBmi->bmiHeader.biWidth = myWidth;
|
||||||
pBmi->bmiHeader.biHeight = anHeight;
|
pBmi->bmiHeader.biHeight = myHeight;
|
||||||
pBmi->bmiHeader.biPlanes = 1;
|
pBmi->bmiHeader.biPlanes = 1;
|
||||||
pBmi->bmiHeader.biBitCount = myDepth; //WIL001: was 24
|
pBmi->bmiHeader.biBitCount = myDepth; //WIL001: was 24
|
||||||
pBmi->bmiHeader.biCompression = BI_RGB;
|
pBmi->bmiHeader.biCompression = BI_RGB;
|
||||||
@ -127,8 +128,8 @@ void WNT_PixMap::Destroy ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
Standard_Boolean WNT_PixMap::Dump ( const Standard_CString aFilename,
|
Standard_Boolean WNT_PixMap::Dump (const Standard_CString theFilename,
|
||||||
const Standard_Real aGammaValue ) const
|
const Standard_Real theGammaValue) const
|
||||||
{
|
{
|
||||||
// *** gamma correction must be implemented also on WNT system ...
|
// *** gamma correction must be implemented also on WNT system ...
|
||||||
const Handle(WNT_Window) hWindow = Handle(WNT_Window)::DownCast(myWND);
|
const Handle(WNT_Window) hWindow = Handle(WNT_Window)::DownCast(myWND);
|
||||||
@ -138,7 +139,7 @@ Standard_Boolean WNT_PixMap::Dump ( const Standard_CString aFilename,
|
|||||||
if ( dev.IsNull() ) return Standard_False;
|
if ( dev.IsNull() ) return Standard_False;
|
||||||
//Aspect_PixmapError::Raise ( "WNT_GraphicDevice is NULL" );
|
//Aspect_PixmapError::Raise ( "WNT_GraphicDevice is NULL" );
|
||||||
|
|
||||||
return DumpBitmapToFile ( dev, (HDC)myDC, (HBITMAP)myBitmap, (Standard_PCharacter)aFilename );
|
return DumpBitmapToFile ((HBITMAP)myBitmap, theFilename);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
|
@ -47,7 +47,7 @@ class Window from WNT inherits Window from Aspect
|
|||||||
TypeOfResize from Aspect,
|
TypeOfResize from Aspect,
|
||||||
FillMethod from Aspect,
|
FillMethod from Aspect,
|
||||||
GradientFillMethod from Aspect,
|
GradientFillMethod from Aspect,
|
||||||
PixMap from Aspect,
|
PixMap from Image,
|
||||||
NameOfColor from Quantity,
|
NameOfColor from Quantity,
|
||||||
Color from Quantity,
|
Color from Quantity,
|
||||||
Parameter from Quantity,
|
Parameter from Quantity,
|
||||||
@ -354,8 +354,8 @@ class Window from WNT inherits Window from Aspect
|
|||||||
-- or the area is out of the Window.
|
-- or the area is out of the Window.
|
||||||
raises WindowError from Aspect is virtual;
|
raises WindowError from Aspect is virtual;
|
||||||
|
|
||||||
ToPixMap ( me )
|
ToPixMap ( me ; theImage : in out PixMap from Image )
|
||||||
returns PixMap from Aspect
|
returns Boolean
|
||||||
---Level : Public
|
---Level : Public
|
||||||
---Purpose : dump the full contents of the window to a pixmap.
|
---Purpose : dump the full contents of the window to a pixmap.
|
||||||
is virtual;
|
is virtual;
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
#include <WNT_Window.ixx>
|
#include <WNT_Window.ixx>
|
||||||
|
|
||||||
#include <Image_PixMap.hxx>
|
#include <Image_AlienPixMap.hxx>
|
||||||
#include <Aspect_Convert.hxx>
|
#include <Aspect_Convert.hxx>
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -733,7 +733,16 @@ void WNT_Window :: RestoreArea (
|
|||||||
Standard_Boolean WNT_Window::Dump (const Standard_CString theFilename,
|
Standard_Boolean WNT_Window::Dump (const Standard_CString theFilename,
|
||||||
const Standard_Real theGammaValue) const
|
const Standard_Real theGammaValue) const
|
||||||
{
|
{
|
||||||
return ToPixMap()->Dump (theFilename, theGammaValue);
|
Image_AlienPixMap anImg;
|
||||||
|
if (!ToPixMap (anImg) || anImg.IsEmpty())
|
||||||
|
{
|
||||||
|
return Standard_False;
|
||||||
|
}
|
||||||
|
if (Abs (theGammaValue - 1.0) > 0.001)
|
||||||
|
{
|
||||||
|
anImg.AdjustGamma (theGammaValue);
|
||||||
|
}
|
||||||
|
return anImg.Save (theFilename);
|
||||||
} // end WNT_Window :: Dump
|
} // end WNT_Window :: Dump
|
||||||
//***//
|
//***//
|
||||||
//*************************** DumpArea ***********************************//
|
//*************************** DumpArea ***********************************//
|
||||||
@ -753,61 +762,50 @@ Standard_Boolean WNT_Window::DumpArea (const Standard_CString theFilename,
|
|||||||
} // end WNT_Window :: DumpArea
|
} // end WNT_Window :: DumpArea
|
||||||
//***//
|
//***//
|
||||||
|
|
||||||
static Handle(Image_PixMap) ConvertBitmap (HBITMAP theHBitmap)
|
static Standard_Boolean ConvertBitmap (HBITMAP theHBitmap,
|
||||||
|
Image_PixMap& thePixMap)
|
||||||
{
|
{
|
||||||
Handle(Image_PixMap) anImagePixMap;
|
|
||||||
// Copy data from HBITMAP
|
|
||||||
BITMAP aBitmap;
|
|
||||||
|
|
||||||
// Get informations about the bitmap
|
// Get informations about the bitmap
|
||||||
GetObject (theHBitmap, sizeof(BITMAP), (LPSTR )&aBitmap);
|
BITMAP aBitmap;
|
||||||
Standard_Integer aWidth = aBitmap.bmWidth;
|
if (GetObject (theHBitmap, sizeof(BITMAP), (LPSTR )&aBitmap) == 0)
|
||||||
Standard_Integer aHeight = aBitmap.bmHeight;
|
{
|
||||||
|
return Standard_False;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Standard_Size aSizeRowBytes = Standard_Size(aBitmap.bmWidth) * 4;
|
||||||
|
if (!thePixMap.InitTrash (Image_PixMap::ImgBGR32, Standard_Size(aBitmap.bmWidth), Standard_Size(aBitmap.bmHeight), aSizeRowBytes))
|
||||||
|
{
|
||||||
|
return Standard_False;
|
||||||
|
}
|
||||||
|
thePixMap.SetTopDown (false);
|
||||||
|
|
||||||
// Setup image data
|
// Setup image data
|
||||||
BITMAPINFOHEADER aBitmapInfo;
|
BITMAPINFOHEADER aBitmapInfo;
|
||||||
memset (&aBitmapInfo, 0, sizeof(BITMAPINFOHEADER));
|
memset (&aBitmapInfo, 0, sizeof(BITMAPINFOHEADER));
|
||||||
aBitmapInfo.biSize = sizeof(BITMAPINFOHEADER);
|
aBitmapInfo.biSize = sizeof(BITMAPINFOHEADER);
|
||||||
aBitmapInfo.biWidth = aWidth;
|
aBitmapInfo.biWidth = aBitmap.bmWidth;
|
||||||
aBitmapInfo.biHeight = aHeight; // positive means bottom-up!
|
aBitmapInfo.biHeight = aBitmap.bmHeight; // positive means bottom-up!
|
||||||
aBitmapInfo.biPlanes = 1;
|
aBitmapInfo.biPlanes = 1;
|
||||||
aBitmapInfo.biBitCount = 32;
|
aBitmapInfo.biBitCount = 32; // use 32bit for automatic word-alignment per row
|
||||||
aBitmapInfo.biCompression = BI_RGB;
|
aBitmapInfo.biCompression = BI_RGB;
|
||||||
|
|
||||||
Standard_Integer aBytesPerLine = aWidth * 4;
|
|
||||||
Standard_Byte* aDataPtr = new Standard_Byte[aBytesPerLine * aHeight];
|
|
||||||
|
|
||||||
// Copy the pixels
|
// Copy the pixels
|
||||||
HDC aDC = GetDC (NULL);
|
HDC aDC = GetDC (NULL);
|
||||||
Standard_Boolean isSuccess
|
Standard_Boolean isSuccess = GetDIBits (aDC, theHBitmap,
|
||||||
= GetDIBits (aDC, // handle to DC
|
0, // first scan line to set
|
||||||
theHBitmap, // handle to bitmap
|
aBitmap.bmHeight, // number of scan lines to copy
|
||||||
0, // first scan line to set
|
thePixMap.ChangeData(), // array for bitmap bits
|
||||||
aHeight, // number of scan lines to copy
|
(LPBITMAPINFO )&aBitmapInfo, // bitmap data info
|
||||||
aDataPtr, // array for bitmap bits
|
DIB_RGB_COLORS) != 0;
|
||||||
(LPBITMAPINFO )&aBitmapInfo, // bitmap data info
|
|
||||||
DIB_RGB_COLORS // RGB
|
|
||||||
) != 0;
|
|
||||||
|
|
||||||
if (isSuccess)
|
|
||||||
{
|
|
||||||
anImagePixMap = new Image_PixMap (aDataPtr,
|
|
||||||
aWidth, aHeight,
|
|
||||||
aBytesPerLine,
|
|
||||||
aBitmapInfo.biBitCount,
|
|
||||||
Standard_False); // bottom-up!
|
|
||||||
}
|
|
||||||
// Release dump memory
|
|
||||||
delete[] aDataPtr;
|
|
||||||
ReleaseDC (NULL, aDC);
|
ReleaseDC (NULL, aDC);
|
||||||
return anImagePixMap;
|
return isSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle(Aspect_PixMap) WNT_Window::ToPixMap() const
|
Standard_Boolean WNT_Window::ToPixMap (Image_PixMap& thePixMap) const
|
||||||
{
|
{
|
||||||
if (myDoubleBuffer && myHPixmap)
|
if (myDoubleBuffer && myHPixmap)
|
||||||
{
|
{
|
||||||
return ConvertBitmap ((HBITMAP )myHPixmap);
|
return ConvertBitmap ((HBITMAP )myHPixmap, thePixMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
RECT aRect;
|
RECT aRect;
|
||||||
@ -825,13 +823,13 @@ Handle(Aspect_PixMap) WNT_Window::ToPixMap() const
|
|||||||
HBITMAP anHBitmapOld = (HBITMAP )SelectObject (aMemDC, anHBitmapDump);
|
HBITMAP anHBitmapOld = (HBITMAP )SelectObject (aMemDC, anHBitmapDump);
|
||||||
BitBlt (aMemDC, 0, 0, aWidth, aHeight, aSrcDC, 0, 0, SRCCOPY);
|
BitBlt (aMemDC, 0, 0, aWidth, aHeight, aSrcDC, 0, 0, SRCCOPY);
|
||||||
|
|
||||||
Handle(Image_PixMap) anImagePixMap = ConvertBitmap (anHBitmapDump);
|
Standard_Boolean isSuccess = ConvertBitmap (anHBitmapDump, thePixMap);
|
||||||
|
|
||||||
// Free objects
|
// Free objects
|
||||||
DeleteObject (SelectObject (aMemDC, anHBitmapOld));
|
DeleteObject (SelectObject (aMemDC, anHBitmapOld));
|
||||||
DeleteDC (aMemDC);
|
DeleteDC (aMemDC);
|
||||||
|
|
||||||
return anImagePixMap;
|
return isSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
//****************************** Load ************************************//
|
//****************************** Load ************************************//
|
||||||
|
@ -30,7 +30,7 @@ class PixMap from Xw
|
|||||||
---Keywords: Bitmap, Pixmap, X11
|
---Keywords: Bitmap, Pixmap, X11
|
||||||
|
|
||||||
inherits
|
inherits
|
||||||
PixMap from Aspect
|
Transient from Standard
|
||||||
uses
|
uses
|
||||||
Handle from Aspect,
|
Handle from Aspect,
|
||||||
Color from Quantity,
|
Color from Quantity,
|
||||||
@ -97,4 +97,7 @@ is
|
|||||||
fields
|
fields
|
||||||
myPixmap : Handle from Aspect is protected;
|
myPixmap : Handle from Aspect is protected;
|
||||||
myWindow : Window from Xw;
|
myWindow : Window from Xw;
|
||||||
|
myWidth : Integer from Standard is protected;
|
||||||
|
myHeight : Integer from Standard is protected;
|
||||||
|
myDepth : Integer from Standard is protected;
|
||||||
end PixMap;
|
end PixMap;
|
||||||
|
@ -28,6 +28,9 @@
|
|||||||
|
|
||||||
#define xTRACE 1
|
#define xTRACE 1
|
||||||
|
|
||||||
|
#include <TCollection_AsciiString.hxx>
|
||||||
|
#include <Image_AlienPixMap.hxx>
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
@ -36,9 +39,6 @@
|
|||||||
#include <Xw_Window.hxx>
|
#include <Xw_Window.hxx>
|
||||||
#include <Xw_Extension.h>
|
#include <Xw_Extension.h>
|
||||||
|
|
||||||
#include <TCollection_AsciiString.hxx>
|
|
||||||
#include <Image_PixMap.hxx>
|
|
||||||
|
|
||||||
XW_STATUS Xw_save_xwd_image ( void*, void*, char* );
|
XW_STATUS Xw_save_xwd_image ( void*, void*, char* );
|
||||||
XW_STATUS Xw_save_bmp_image ( void*, void*, char* );
|
XW_STATUS Xw_save_bmp_image ( void*, void*, char* );
|
||||||
XW_STATUS Xw_save_gif_image ( void*, void*, char* );
|
XW_STATUS Xw_save_gif_image ( void*, void*, char* );
|
||||||
@ -63,15 +63,15 @@ Standard_Integer Xw_PixMap::PreferedDepth(
|
|||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
Xw_PixMap::Xw_PixMap ( const Handle(Aspect_Window)& aWindow,
|
Xw_PixMap::Xw_PixMap (const Handle(Aspect_Window)& theWindow,
|
||||||
const Standard_Integer aWidth,
|
const Standard_Integer theWidth,
|
||||||
const Standard_Integer anHeight,
|
const Standard_Integer theHeight,
|
||||||
const Standard_Integer aDepth ) :
|
const Standard_Integer theDepth)
|
||||||
Aspect_PixMap(aWidth, anHeight, PreferedDepth(aWindow, aDepth))
|
: myWindow (Handle(Xw_Window)::DownCast(theWindow)),
|
||||||
|
myWidth (theWidth),
|
||||||
|
myHeight (theHeight),
|
||||||
|
myDepth (PreferedDepth (theWindow, theDepth))
|
||||||
{
|
{
|
||||||
|
|
||||||
myWindow = Handle(Xw_Window)::DownCast(aWindow);
|
|
||||||
|
|
||||||
XW_EXT_WINDOW *pwindow = (XW_EXT_WINDOW*) myWindow->ExtendedWindow();
|
XW_EXT_WINDOW *pwindow = (XW_EXT_WINDOW*) myWindow->ExtendedWindow();
|
||||||
|
|
||||||
Xw_print_error();
|
Xw_print_error();
|
||||||
@ -99,46 +99,54 @@ Xw_PixMap::Destroy ()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
Standard_Boolean Xw_PixMap::Dump (const Standard_CString theFilename,
|
Standard_Boolean Xw_PixMap::Dump (const Standard_CString theFileName,
|
||||||
const Standard_Real theGammaValue) const
|
const Standard_Real theGammaValue) const
|
||||||
{
|
{
|
||||||
// the attributes
|
// the attributes
|
||||||
XWindowAttributes winAttr;
|
XWindowAttributes winAttr;
|
||||||
XW_EXT_WINDOW *pwindow = (XW_EXT_WINDOW*) myWindow->ExtendedWindow();
|
XW_EXT_WINDOW *pwindow = (XW_EXT_WINDOW*) myWindow->ExtendedWindow();
|
||||||
XGetWindowAttributes (_DISPLAY, _WINDOW, &winAttr);
|
XGetWindowAttributes (_DISPLAY, _WINDOW, &winAttr);
|
||||||
|
if (winAttr.visual->c_class != TrueColor)
|
||||||
// find the image
|
|
||||||
XImage* pximage = XGetImage (_DISPLAY, myPixmap,
|
|
||||||
0, 0, myWidth, myHeight,
|
|
||||||
AllPlanes, ZPixmap);
|
|
||||||
if (pximage == NULL)
|
|
||||||
{
|
|
||||||
return Standard_False;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (winAttr.visual->c_class == TrueColor)
|
|
||||||
{
|
|
||||||
Standard_Byte* aDataPtr = (Standard_Byte* )pximage->data;
|
|
||||||
Handle(Image_PixMap) anImagePixMap = new Image_PixMap (aDataPtr,
|
|
||||||
pximage->width, pximage->height,
|
|
||||||
pximage->bytes_per_line,
|
|
||||||
pximage->bits_per_pixel,
|
|
||||||
Standard_True);
|
|
||||||
// destroy the image
|
|
||||||
XDestroyImage (pximage);
|
|
||||||
|
|
||||||
// save the image
|
|
||||||
return anImagePixMap->Dump (theFilename, theGammaValue);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
std::cerr << "Visual Type not supported!";
|
std::cerr << "Visual Type not supported!";
|
||||||
// destroy the image
|
|
||||||
XDestroyImage (pximage);
|
|
||||||
return Standard_False;
|
return Standard_False;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Image_AlienPixMap anImage;
|
||||||
|
bool isBigEndian = Image_PixMap::IsBigEndianHost();
|
||||||
|
const Standard_Size aSizeRowBytes = Standard_Size(winAttr.width) * 4;
|
||||||
|
if (!anImage.InitTrash (isBigEndian ? Image_PixMap::ImgRGB32 : Image_PixMap::ImgBGR32,
|
||||||
|
Standard_Size(winAttr.width), Standard_Size(winAttr.height), aSizeRowBytes))
|
||||||
|
{
|
||||||
|
return Standard_False;
|
||||||
|
}
|
||||||
|
anImage.SetTopDown (true);
|
||||||
|
|
||||||
|
XImage* anXImage = XCreateImage (_DISPLAY, winAttr.visual,
|
||||||
|
32, ZPixmap, 0, (char* )anImage.ChangeData(), winAttr.width, winAttr.height, 32, int(aSizeRowBytes));
|
||||||
|
anXImage->bitmap_bit_order = anXImage->byte_order = (isBigEndian ? MSBFirst : LSBFirst);
|
||||||
|
if (XGetSubImage (_DISPLAY, myPixmap,
|
||||||
|
0, 0, winAttr.width, winAttr.height,
|
||||||
|
AllPlanes, ZPixmap, anXImage, 0, 0) == NULL)
|
||||||
|
{
|
||||||
|
anXImage->data = NULL;
|
||||||
|
XDestroyImage (anXImage);
|
||||||
|
return Standard_False;
|
||||||
|
}
|
||||||
|
|
||||||
|
// destroy the image
|
||||||
|
anXImage->data = NULL;
|
||||||
|
XDestroyImage (anXImage);
|
||||||
|
|
||||||
|
// save the image
|
||||||
|
if (Abs (theGammaValue - 1.0) > 0.001)
|
||||||
|
{
|
||||||
|
anImage.AdjustGamma (theGammaValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
// save the image
|
||||||
|
return anImage.Save (theFileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
|
@ -49,7 +49,7 @@ uses
|
|||||||
Handle from Aspect,
|
Handle from Aspect,
|
||||||
FillMethod from Aspect,
|
FillMethod from Aspect,
|
||||||
GradientFillMethod from Aspect,
|
GradientFillMethod from Aspect,
|
||||||
PixMap from Aspect,
|
PixMap from Image,
|
||||||
NameOfColor from Quantity,
|
NameOfColor from Quantity,
|
||||||
Parameter from Quantity,
|
Parameter from Quantity,
|
||||||
Ratio from Quantity,
|
Ratio from Quantity,
|
||||||
@ -330,8 +330,8 @@ is
|
|||||||
-- or the area is out of the Window.
|
-- or the area is out of the Window.
|
||||||
raises WindowError from Aspect is virtual;
|
raises WindowError from Aspect is virtual;
|
||||||
|
|
||||||
ToPixMap ( me )
|
ToPixMap ( me ; theImage : in out PixMap from Image )
|
||||||
returns PixMap from Aspect
|
returns Boolean
|
||||||
---Level : Public
|
---Level : Public
|
||||||
---Purpose : dump the full contents of the window to a pixmap.
|
---Purpose : dump the full contents of the window to a pixmap.
|
||||||
is virtual;
|
is virtual;
|
||||||
|
@ -77,7 +77,7 @@
|
|||||||
#include <Xw_Cextern.hxx>
|
#include <Xw_Cextern.hxx>
|
||||||
//}
|
//}
|
||||||
#include <Aspect_Convert.hxx>
|
#include <Aspect_Convert.hxx>
|
||||||
#include <Image_PixMap.hxx>
|
#include <Image_AlienPixMap.hxx>
|
||||||
|
|
||||||
#include <Xw_Extension.h>
|
#include <Xw_Extension.h>
|
||||||
|
|
||||||
@ -862,15 +862,14 @@ Standard_Boolean Xw_Window::DumpArea (const Standard_CString theFilename,
|
|||||||
return Standard_Boolean(aStatus);
|
return Standard_Boolean(aStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle(Aspect_PixMap) Xw_Window::ToPixMap() const
|
Standard_Boolean Xw_Window::ToPixMap (Image_PixMap& thePixMap) const
|
||||||
{
|
{
|
||||||
Handle(Image_PixMap) anImagePixMap;
|
|
||||||
int aDummy, aWidth, aHeight;
|
int aDummy, aWidth, aHeight;
|
||||||
XW_WINDOWSTATE state = Xw_get_window_position (MyExtendedWindow,
|
XW_WINDOWSTATE state = Xw_get_window_position (MyExtendedWindow,
|
||||||
&aDummy, &aDummy, &aWidth, &aHeight);
|
&aDummy, &aDummy, &aWidth, &aHeight);
|
||||||
if (state == XW_WS_UNKNOWN)
|
if (state == XW_WS_UNKNOWN)
|
||||||
{
|
{
|
||||||
return anImagePixMap;
|
return Standard_False;
|
||||||
}
|
}
|
||||||
|
|
||||||
XW_EXT_IMAGEDATA* pimage = NULL;
|
XW_EXT_IMAGEDATA* pimage = NULL;
|
||||||
@ -895,22 +894,27 @@ Handle(Aspect_PixMap) Xw_Window::ToPixMap() const
|
|||||||
|
|
||||||
if (pimage == NULL)
|
if (pimage == NULL)
|
||||||
{
|
{
|
||||||
return anImagePixMap;
|
return Standard_False;
|
||||||
}
|
}
|
||||||
|
|
||||||
XImage* pximage = (pimage->zximage) ? pimage->zximage : pimage->pximage;
|
XImage* pximage = (pimage->zximage) ? pimage->zximage : pimage->pximage;
|
||||||
XW_EXT_WINDOW* pwindow = (XW_EXT_WINDOW* )MyExtendedWindow;
|
XW_EXT_WINDOW* pwindow = (XW_EXT_WINDOW* )MyExtendedWindow;
|
||||||
if (pwindow->pcolormap->visual->c_class == TrueColor)
|
if (pwindow->pcolormap->visual->c_class != TrueColor)
|
||||||
{
|
{
|
||||||
Standard_Byte* aDataPtr = (Standard_Byte* )pximage->data;
|
return Standard_False;
|
||||||
anImagePixMap = new Image_PixMap (aDataPtr,
|
|
||||||
pximage->width, pximage->height,
|
|
||||||
pximage->bytes_per_line,
|
|
||||||
pximage->bits_per_pixel,
|
|
||||||
Standard_True);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const bool isBigEndian = (pximage->byte_order == MSBFirst);
|
||||||
|
Image_PixMap::ImgFormat aFormat = (pximage->bits_per_pixel == 32)
|
||||||
|
? (isBigEndian ? Image_PixMap::ImgRGB32 : Image_PixMap::ImgBGR32)
|
||||||
|
: (isBigEndian ? Image_PixMap::ImgRGB : Image_PixMap::ImgBGR);
|
||||||
|
Image_PixMap aWrapper;
|
||||||
|
aWrapper.InitWrapper (aFormat, (Standard_Byte* )pximage->data, pximage->width, pximage->height, pximage->bytes_per_line);
|
||||||
|
aWrapper.SetTopDown (true);
|
||||||
|
|
||||||
|
Standard_Boolean isSuccess = thePixMap.InitCopy (aWrapper);
|
||||||
Xw_close_image (pimage);
|
Xw_close_image (pimage);
|
||||||
return anImagePixMap;
|
return isSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
Standard_Boolean Xw_Window::Load (const Standard_CString aFilename) const {
|
Standard_Boolean Xw_Window::Load (const Standard_CString aFilename) const {
|
||||||
|
@ -34,13 +34,14 @@
|
|||||||
# include <config.h>
|
# include <config.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <Image_AlienPixMap.hxx>
|
||||||
|
#include <TCollection_AsciiString.hxx>
|
||||||
|
|
||||||
#include <Xw_Extension.h>
|
#include <Xw_Extension.h>
|
||||||
#ifdef HAVE_STRINGS_H
|
#ifdef HAVE_STRINGS_H
|
||||||
# include <strings.h>
|
# include <strings.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <Image_PixMap.hxx>
|
|
||||||
|
|
||||||
#ifdef XW_PROTOTYPE
|
#ifdef XW_PROTOTYPE
|
||||||
XW_STATUS Xw_save_image_adv (Display *aDisplay,Window aWindow,XWindowAttributes aWinAttr,XImage *aPximage,Colormap aColormap,int aNcolors,char *filename)
|
XW_STATUS Xw_save_image_adv (Display *aDisplay,Window aWindow,XWindowAttributes aWinAttr,XImage *aPximage,Colormap aColormap,int aNcolors,char *filename)
|
||||||
#else
|
#else
|
||||||
@ -54,22 +55,22 @@ int ncolors;
|
|||||||
char *filename;
|
char *filename;
|
||||||
#endif /*XW_PROTOTYPE*/
|
#endif /*XW_PROTOTYPE*/
|
||||||
{
|
{
|
||||||
if (aWinAttr.visual->c_class == TrueColor)
|
if (aWinAttr.visual->c_class != TrueColor)
|
||||||
{
|
|
||||||
Standard_Byte* aDataPtr = (Standard_Byte* )aPximage->data;
|
|
||||||
Handle(Image_PixMap) anImagePixMap = new Image_PixMap (aDataPtr,
|
|
||||||
aPximage->width, aPximage->height,
|
|
||||||
aPximage->bytes_per_line,
|
|
||||||
aPximage->bits_per_pixel,
|
|
||||||
Standard_True);
|
|
||||||
// save the image
|
|
||||||
return anImagePixMap->Dump (filename) ? XW_SUCCESS : XW_ERROR;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
std::cerr << "Visual Type not supported!";
|
std::cerr << "Visual Type not supported!";
|
||||||
return XW_SUCCESS;
|
return XW_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const bool isBigEndian = (aPximage->byte_order == MSBFirst);
|
||||||
|
Image_PixMap::ImgFormat aFormat = (aPximage->bits_per_pixel == 32)
|
||||||
|
? (isBigEndian ? Image_PixMap::ImgRGB32 : Image_PixMap::ImgBGR32)
|
||||||
|
: (isBigEndian ? Image_PixMap::ImgRGB : Image_PixMap::ImgBGR);
|
||||||
|
Image_PixMap aWrapper;
|
||||||
|
aWrapper.InitWrapper (aFormat, (Standard_Byte* )aPximage->data, aPximage->width, aPximage->height, aPximage->bytes_per_line);
|
||||||
|
aWrapper.SetTopDown (true);
|
||||||
|
|
||||||
|
Image_AlienPixMap anAlienImage;
|
||||||
|
return (anAlienImage.InitCopy (aWrapper) && anAlienImage.Save (filename)) ? XW_SUCCESS : XW_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef XW_PROTOTYPE
|
#ifdef XW_PROTOTYPE
|
||||||
|
Loading…
x
Reference in New Issue
Block a user