Commit ed5b4dac authored by Alexey.Musinov's avatar Alexey.Musinov Committed by Alexander Trofimov

(1.0.0.126) Поддержка изображений в формате 'dib' - http://bugzserver/show_bug.cgi?id=25091






git-svn-id: svn://fileserver/activex/AVS/Sources/TeamlabOffice/trunk/ServerComponents@57057 954022d7-b5bf-4e40-9824-e11837661b57
parent be307359
......@@ -2,6 +2,6 @@
//1
//0
//0
//125
#define INTVER 1,0,0,125
#define STRVER "1,0,0,125\0"
//126
#define INTVER 1,0,0,126
#define STRVER "1,0,0,126\0"
......@@ -4,10 +4,13 @@
namespace DocFileFormat
{
typedef enum FibVersion
{
Fib1997 = 0x00C1,
//Fib1993 = 0x0065, // Word 6.0
//Fib1995 = 0x0068, // Word 7.0 (95)
//Fib2002 = 0x0069, // Word 8.0 (97)
Fib1997 = 0x00C1,
Fib2000 = 0x00D9,
Fib2002 = 0x0101,
Fib2003 = 0x010C,
......
......@@ -13,55 +13,56 @@ namespace DocFileFormat
static const unsigned short TYPE_CODE_0xF020 = 0xF020;
static const unsigned short TYPE_CODE_0xF021 = 0xF021;
/// The secondary, or data, UID - should always be set.
byte* m_rgbUid;
/// The primary UID - this defaults to 0, in which case the primary ID is that of the internal data.
/// NOTE!: The primary UID is only saved to disk if (blip_instance ^ blip_signature == 1).
/// Blip_instance is MSOFBH.finst and blip_signature is one of the values defined in MSOBI
byte* m_rgbUidPrimary;
byte m_bTag;
/// Raster bits of the blip
byte* m_pvBits;
unsigned int pvBitsSize;
BitmapBlip():
Record(), m_rgbUid(NULL), m_rgbUidPrimary(NULL), m_bTag(0), m_pvBits(NULL)
public:
BitmapBlip() : Record(), m_rgbUid(NULL), m_rgbUidPrimary(NULL), m_bTag(0), m_pvBits(NULL)
{
}
BitmapBlip( IBinaryReader* _reader, unsigned int size, unsigned int typeCode, unsigned int version, unsigned int instance ):
Record( _reader, size, typeCode, version, instance ), m_rgbUid(NULL), m_rgbUidPrimary(NULL), m_bTag(0), m_pvBits(NULL), pvBitsSize(0)
BitmapBlip(IBinaryReader* _reader, unsigned int size, unsigned int typeCode, unsigned int version, unsigned int instance) :
Record(_reader, size, typeCode, version, instance ), m_rgbUid(NULL), m_rgbUidPrimary(NULL), m_bTag(0), m_pvBits(NULL), pvBitsSize(0)
{
this->m_rgbUid = this->Reader->ReadBytes( 16, true );
m_rgbUid = Reader->ReadBytes(16, true);
if ( ( instance == 0x46B ) || ( instance == 0x6E3 ) || ( instance == 0x6E1 ) || ( instance == 0x7A9 ) ||
( instance == 0x6E5 ) )
if ((instance == 0x46B) || (instance == 0x6E3) || (instance == 0x6E1) || (instance == 0x7A9) || (instance == 0x6E5))
{
this->m_rgbUidPrimary = this->Reader->ReadBytes( 16, true );
m_rgbUidPrimary = Reader->ReadBytes(16, true);
}
this->m_bTag = this->Reader->ReadByte();
m_bTag = Reader->ReadByte();
this->pvBitsSize = ( size - 17 );
pvBitsSize = (size - 17);
if ( this->m_rgbUidPrimary != NULL )
if (m_rgbUidPrimary)
{
this->pvBitsSize -= 16;
pvBitsSize -= 16;
}
this->m_pvBits = this->Reader->ReadBytes( (int)( this->pvBitsSize ), true );
m_pvBits = Reader->ReadBytes((int)(pvBitsSize), true);
}
virtual ~BitmapBlip()
{
RELEASEARRAYOBJECTS( this->m_rgbUid );
RELEASEARRAYOBJECTS( this->m_rgbUidPrimary );
RELEASEARRAYOBJECTS( this->m_pvBits );
RELEASEARRAYOBJECTS(m_rgbUid);
RELEASEARRAYOBJECTS(m_rgbUidPrimary);
RELEASEARRAYOBJECTS(m_pvBits);
}
virtual Record* NewObject( IBinaryReader* _reader, unsigned int bodySize, unsigned int typeCode, unsigned int version, unsigned int instance )
virtual Record* NewObject(IBinaryReader* _reader, unsigned int bodySize, unsigned int typeCode, unsigned int version, unsigned int instance)
{
return new BitmapBlip( _reader, bodySize, typeCode, version, instance );
return new BitmapBlip(_reader, bodySize, typeCode, version, instance);
}
public:
/// The secondary, or data, UID - should always be set.
byte* m_rgbUid;
/// The primary UID - this defaults to 0, in which case the primary ID is that of the internal data.
/// NOTE!: The primary UID is only saved to disk if (blip_instance ^ blip_signature == 1).
/// Blip_instance is MSOFBH.finst and blip_signature is one of the values defined in MSOBI
byte* m_rgbUidPrimary;
byte m_bTag;
/// Raster bits of the blip
byte* m_pvBits;
unsigned int pvBitsSize;
};
}
\ No newline at end of file
......@@ -62,17 +62,19 @@ namespace DocFileFormat
struct ImageFileStructure
{
wstring ext;
vector<byte> data;
ImageFileStructure()
{
}
ImageFileStructure( const wstring& _ext, const vector<byte>& _data ):
ext(_ext), data(_data)
ImageFileStructure(const wstring& _ext, const vector<byte>& _data, Global::BlipType _blipType = Global::msoblipUNKNOWN) : ext(_ext), data(_data), blipType(_blipType)
{
}
std::wstring ext;
std::vector<byte> data;
Global::BlipType blipType;
};
struct OleObjectFileStructure
......
......@@ -412,7 +412,10 @@ namespace DocFileFormat
}
else if (fcEnd < (int)pcd.fc) // this piece is beyond the requested range
{
//ATLTRACE(_T("PieceTable::GetChars() - fcEnd < (int)pcd.fc\n"));
#ifdef _DEBUG
ATLTRACE(_T("PieceTable::GetChars() - fcEnd < (int)pcd.fc\n"));
#endif
// ,
......
#include "stdafx.h"
#include "VMLPictureMapping.h"
#include "GdiplusEx.h"
namespace DocFileFormat
{
VMLPictureMapping::VMLPictureMapping(ConversionContext* ctx, XmlUtils::CXmlWriter* writer, bool olePreview, IMapping* caller, bool isBulletPicture) : PropertiesMapping(writer)
......@@ -79,11 +81,11 @@ namespace DocFileFormat
//BORDERS
case borderBottomColor:
{
RGBColor bottomColor( (int)iter->op, RedFirst );
m_pXmlWriter->WriteAttribute( _T( "o:borderbottomcolor" ), ( wstring( _T( "#" ) ) + bottomColor.SixDigitHexCode ).c_str() );
}
break;
{
RGBColor bottomColor( (int)iter->op, RedFirst );
m_pXmlWriter->WriteAttribute( _T( "o:borderbottomcolor" ), ( wstring( _T( "#" ) ) + bottomColor.SixDigitHexCode ).c_str() );
}
break;
case borderLeftColor:
{
......@@ -96,14 +98,14 @@ namespace DocFileFormat
{
RGBColor rightColor( (int)iter->op, RedFirst );
m_pXmlWriter->WriteAttribute( _T( "o:borderrightcolor" ), ( wstring( _T( "#" ) ) + rightColor.SixDigitHexCode ).c_str() );
}
}
break;
case borderTopColor:
{
RGBColor topColor( (int)iter->op, RedFirst );
m_pXmlWriter->WriteAttribute( _T( "o:bordertopcolor" ), ( wstring( _T( "#" ) ) + topColor.SixDigitHexCode ).c_str() );
}
}
break;
//CROPPING
......@@ -113,7 +115,7 @@ namespace DocFileFormat
//cast to signed integer
int cropBottom = (int)iter->op;
appendValueAttribute( this->_imageData, _T( "cropbottom" ), ( FormatUtils::IntToWideString( cropBottom ) + wstring( _T( "f" ) ) ).c_str() );
}
}
break;
case cropFromLeft:
......@@ -121,24 +123,24 @@ namespace DocFileFormat
//cast to signed integer
int cropLeft = (int)iter->op;
appendValueAttribute( this->_imageData, _T( "cropleft" ), ( FormatUtils::IntToWideString( cropLeft ) + wstring( _T( "f" ) ) ).c_str() );
}
}
break;
case cropFromRight:
{
//cast to signed integer
int cropRight = (int)iter->op;
appendValueAttribute( this->_imageData, _T( "cropright" ), ( FormatUtils::IntToWideString( cropRight ) + wstring( _T( "f" ) ) ).c_str() );
}
break;
{
//cast to signed integer
int cropRight = (int)iter->op;
appendValueAttribute( this->_imageData, _T( "cropright" ), ( FormatUtils::IntToWideString( cropRight ) + wstring( _T( "f" ) ) ).c_str() );
}
break;
case cropFromTop:
{
//cast to signed integer
int cropTop = (int)iter->op;
appendValueAttribute( this->_imageData, _T( "croptop" ), ( FormatUtils::IntToWideString( cropTop ) + wstring( _T( "f" ) ) ).c_str() );
}
break;
{
//cast to signed integer
int cropTop = (int)iter->op;
appendValueAttribute( this->_imageData, _T( "croptop" ), ( FormatUtils::IntToWideString( cropTop ) + wstring( _T( "f" ) ) ).c_str() );
}
break;
}
}
......@@ -190,16 +192,19 @@ namespace DocFileFormat
{
//it's a meta image
MetafilePictBlip* metaBlip = static_cast<MetafilePictBlip*>(oBlipEntry->Blip);
//meta images can be compressed
byte* decompressed = NULL;
int decompressedSize = 0;
decompressedSize = metaBlip->Decompress( &decompressed );
_ctx->_docx->ImagesList.push_back (ImageFileStructure (GetTargetExt(oBlipEntry->btWin32 ), vector<byte>( decompressed, ( decompressed + decompressedSize ) ) ) );
RELEASEARRAYOBJECTS( decompressed );
if (metaBlip)
{
//meta images can be compressed
byte* decompressed = NULL;
int decompressedSize = 0;
decompressedSize = metaBlip->Decompress(&decompressed);
if (0 != decompressedSize && NULL != decompressed)
{
_ctx->_docx->ImagesList.push_back(ImageFileStructure(GetTargetExt(oBlipEntry->btWin32), std::vector<byte>(decompressed, (decompressed + decompressedSize))));
RELEASEARRAYOBJECTS(decompressed);
}
}
}
break;
......@@ -209,10 +214,12 @@ namespace DocFileFormat
case Global::msoblipTIFF:
case Global::msoblipDIB:
{
//it's a bitmap image
BitmapBlip* bitBlip = static_cast<BitmapBlip*>(oBlipEntry->Blip);
_ctx->_docx->ImagesList.push_back(ImageFileStructure (GetTargetExt(oBlipEntry->btWin32 ), vector<byte>( bitBlip->m_pvBits, ( bitBlip->m_pvBits + bitBlip->pvBitsSize ) ) ));
if (bitBlip)
{
_ctx->_docx->ImagesList.push_back(ImageFileStructure(GetTargetExt(oBlipEntry->btWin32),
vector<byte>(bitBlip->m_pvBits, (bitBlip->m_pvBits + bitBlip->pvBitsSize)), oBlipEntry->btWin32));
}
}
break;
......@@ -225,7 +232,7 @@ namespace DocFileFormat
break;
}
m_nImageId = _ctx->_docx->RegisterImage (_caller, oBlipEntry->btWin32);
m_nImageId = _ctx->_docx->RegisterImage(_caller, oBlipEntry->btWin32);
result = true;
}
......@@ -240,24 +247,27 @@ namespace DocFileFormat
{
switch (nType)
{
//case msoblipBMP:
// return wstring( _T( ".bmp" ) );
//case Global::msoblipDIB:
// return std::wstring( _T( ".bmp" ) );
//case msoblipBMP:
// return wstring( _T( ".bmp" ) );
case Global::msoblipEMF:
return std::wstring(_T(".emf"));
//case msoblipGIF:
// return wstring( _T( ".gif" ) );
//case msoblipGIF:
// return wstring( _T( ".gif" ) );
//case msoblipICON:
// return wstring( _T( ".ico" ) );
//case msoblipICON:
// return wstring( _T( ".ico" ) );
case Global::msoblipJPEG:
case Global::msoblipCMYKJPEG:
return std::wstring(_T(".jpg"));
//case msoblipPCX:
// return wstring( _T( ".pcx" ) );
//case msoblipPCX:
// return wstring( _T( ".pcx" ) );
case Global::msoblipPNG:
return std::wstring(_T(".png"));
......@@ -277,24 +287,24 @@ namespace DocFileFormat
{
switch (nType)
{
//case msoblipBMP:
// return wstring( _T( "image/bmp" ) );
//case msoblipBMP:
// return wstring( _T( "image/bmp" ) );
case Global::msoblipEMF:
return std::wstring(OpenXmlContentTypes::Emf);
//case msoblipGIF:
// return wstring( _T( "image/gif" ) );
//case msoblipGIF:
// return wstring( _T( "image/gif" ) );
//case msoblipICON:
// return wstring( _T( "image/x-icon" ) );
//case msoblipICON:
// return wstring( _T( "image/x-icon" ) );
case Global::msoblipJPEG:
case Global::msoblipCMYKJPEG:
return std::wstring(OpenXmlContentTypes::Jpeg);
//case msoblipPCX:
// return wstring( _T( "image/pcx" ) );
//case msoblipPCX:
// return wstring( _T( "image/pcx" ) );
case Global::msoblipPNG:
return std::wstring(OpenXmlContentTypes::Png);
......
......@@ -1156,24 +1156,28 @@ namespace DocFileFormat
{
VirtualStreamReader reader(_ctx->_doc->WordDocumentStream, oBlip->foDelay);
switch ( oBlip->btWin32 )
switch (oBlip->btWin32)
{
case Global::msoblipEMF:
case Global::msoblipWMF:
{
//it's a meta image
MetafilePictBlip* metaBlip = static_cast<MetafilePictBlip*>(RecordFactory::ReadRecord( &reader, 0 ));
//meta images can be compressed
byte* decompressed = NULL;
int decompressedSize = 0;
decompressedSize = metaBlip->Decompress( &decompressed );
MetafilePictBlip* metaBlip = static_cast<MetafilePictBlip*>(RecordFactory::ReadRecord(&reader, 0));
if (metaBlip)
{
//meta images can be compressed
byte* decompressed = NULL;
int decompressedSize = 0;
_ctx->_docx->ImagesList.push_back( ImageFileStructure( GetTargetExt( oBlip->btWin32 ), vector<byte>( decompressed, ( decompressed + decompressedSize ) ) ) );
decompressedSize = metaBlip->Decompress(&decompressed);
if (0 != decompressedSize && NULL != decompressed)
{
_ctx->_docx->ImagesList.push_back(ImageFileStructure(GetTargetExt(oBlip->btWin32), vector<byte>(decompressed, (decompressed + decompressedSize))));
RELEASEARRAYOBJECTS(decompressed);
}
RELEASEARRAYOBJECTS( decompressed );
RELEASEOBJECT( metaBlip );
RELEASEOBJECT(metaBlip);
}
}
break;
......@@ -1184,18 +1188,19 @@ namespace DocFileFormat
case Global::msoblipDIB:
{
//it's a bitmap image
BitmapBlip* bitBlip = static_cast<BitmapBlip*>(RecordFactory::ReadRecord( &reader, 0 ));
_ctx->_docx->ImagesList.push_back( ImageFileStructure( GetTargetExt( oBlip->btWin32 ), vector<byte>( bitBlip->m_pvBits, ( bitBlip->m_pvBits + bitBlip->pvBitsSize ) ) ) );
RELEASEOBJECT (bitBlip);
BitmapBlip* bitBlip = static_cast<BitmapBlip*>(RecordFactory::ReadRecord(&reader, 0));
if (bitBlip)
{
_ctx->_docx->ImagesList.push_back(ImageFileStructure(GetTargetExt(oBlip->btWin32),
vector<byte>(bitBlip->m_pvBits, (bitBlip->m_pvBits + bitBlip->pvBitsSize)), oBlip->btWin32));
RELEASEOBJECT (bitBlip);
}
}
break;
default:
{
result = false;
return result;
}
break;
......
......@@ -146,11 +146,30 @@ namespace DocFileFormat
}
// Parse FIB
FIB = new FileInformationBlock ( VirtualStreamReader (WordDocumentStream,0));
FIB = new FileInformationBlock(VirtualStreamReader(WordDocumentStream,0));
#ifdef _DEBUG
if (Fib2007 == FIB->m_FibBase.nFib) ATLTRACE (_T("NOTE: OFFICE 2007 file format\n"));
else if (Fib2003 == FIB->m_FibBase.nFib) ATLTRACE (_T("NOTE: OFFICE 2003 file format\n"));
else if (Fib2002 == FIB->m_FibBase.nFib) ATLTRACE (_T("NOTE: OFFICE 2002 file format\n"));
else if (Fib2000 == FIB->m_FibBase.nFib) ATLTRACE (_T("NOTE: OFFICE 2000 file format\n"));
else if (Fib1997 == FIB->m_FibBase.nFib) ATLTRACE (_T("NOTE: OFFICE 1997 file format\n"));
else if (Fib1997 < FIB->m_FibBase.nFib) ATLTRACE (_T("ERROR: OFFICE file format - UNSUPPORTED\n"));
#endif
// Check the file version
if (FIB->m_FibBase.nFib)
{
// nFib (2 bytes): An unsigned integer that specifies the version number of the file format used.
// Superseded by FibRgCswNew.nFibNew if it is present. This value SHOULD<12> be 0x00C1.
// <12> Section 2.5.2: A special empty document is installed with Word 97, Word 2000, Word 2002,
// and Office Word 2003 to allow "Create New Word Document" from the operating system. This
// document has an nFib of 0x00C0. In addition the BiDi build of Word 97 differentiates its documents
// by saving 0x00C2 as the nFib. In both cases treat them as if they were 0x00C1.
// FIB version written. This will be >= 101 for all Word 6.0 for Windows and after documents
if (FIB->m_FibBase.nFib < Fib1997)
{
Clear();
......
#include "stdafx.h"
#include "WordprocessingDocument.h"
#include "GdiplusEx.h"
namespace ImageHelper
{
inline static int CompareStrings (const WCHAR* str1, const WCHAR* str2)
{
CString cstr1; cstr1 = str1;
CString cstr2; cstr2 = str2;
if (cstr1 == cstr2)
return 0;
return 1;
}
inline static void GetEncoderCLSID (const WCHAR* pFormat, CLSID* pClsid)
{
// variables
UINT nEncoders = 0;
UINT nSize = 0;
Gdiplus::ImageCodecInfo* pImageCodecInfo = 0;
// retrieve encoders info
Gdiplus::GetImageEncodersSize(&nEncoders, &nSize);
// check for valid encoders
if (!nSize)
throw 0;
// create encoders info structure of necessary size
pImageCodecInfo = (Gdiplus::ImageCodecInfo*)(malloc(nSize));
// check for valid encoder
if (!pImageCodecInfo)
throw 0;
// retrieve all encoders
Gdiplus::GetImageEncoders(nEncoders, nSize, pImageCodecInfo);
// locate necessary encoder
for (UINT nEncoder = 0; nEncoder < nEncoders; ++nEncoder)
{
// compare MIME strings
if (CompareStrings(pImageCodecInfo[nEncoder].MimeType, pFormat) == 0)
{
// save CLSID
*pClsid = pImageCodecInfo[nEncoder].Clsid;
// clear memory
free(pImageCodecInfo);
// all ok
return;
}
}
// clear memory
free(pImageCodecInfo);
// codec not found
throw 0;
}
inline bool SaveImageToFileFromDIB(unsigned char* buffer, const std::wstring& file)
{
const BITMAPFILEHEADER* bmfh = (BITMAPFILEHEADER*)buffer;
const BITMAPINFO* info = (BITMAPINFO*)buffer;
if (NULL != bmfh && NULL != info)
{
HDC hdc = GetDC(NULL);
if (hdc)
{
HBITMAP hbm = ::CreateDIBitmap(hdc, &info->bmiHeader, CBM_INIT, (buffer + sizeof(BITMAPINFO)), info, DIB_RGB_COLORS);
if (hbm)
{
Gdiplus::Bitmap oBitmap (hbm, NULL);
if (Gdiplus::Ok == oBitmap.GetLastStatus())
{
CLSID guid;
GetEncoderCLSID (L"image/png", &guid);
if (Gdiplus::Ok == oBitmap.Save (file.c_str(), &guid))
{
oBitmap.Save(file.c_str(), &guid);
DeleteObject(hbm);
ReleaseDC(NULL, hdc);
return (Gdiplus::Ok == oBitmap.GetLastStatus());
}
}
DeleteObject(hbm);
}
ReleaseDC(NULL, hdc);
}
}
return false;
}
}
namespace DocFileFormat
{
WordprocessingDocument::WordprocessingDocument(const WCHAR* _fileName, const WordDocument* _docFile) : OpenXmlPackage( _docFile ), FontTableXML( _T( "" ) ), DocumentXML( _T( "" ) ),
......@@ -76,18 +178,29 @@ namespace DocFileFormat
int i = 1;
for (list<ImageFileStructure>::iterator iter = this->ImagesList.begin(); iter != this->ImagesList.end(); ++iter)
for (list<ImageFileStructure>::iterator iter = ImagesList.begin(); iter != ImagesList.end(); ++iter)
{
byte *bytes = NULL;
byte* bytes = NULL;
bytes = new byte[iter->data.size()];
if (bytes)
{
copy(iter->data.begin(), iter->data.end(), bytes);
if (Global::msoblipDIB == iter->blipType)
{
std::wstring file = m_strOutputPath + std::wstring(_T("\\word\\media\\image")) + FormatUtils::IntToWideString(i++) + iter->ext;
ImageHelper::SaveImageToFileFromDIB(bytes, file);
}
else
{
#ifdef CREATE_ZIPPED_DOCX
SaveToFile(m_strOutputPath, ( wstring( _T( "\\word\\media\\image" ) ) + FormatUtils::IntToWideString(i++) + iter->ext), this->zf, (void*)bytes, (unsigned int)iter->data.size());
SaveToFile(m_strOutputPath, ( wstring( _T( "\\word\\media\\image" ) ) + FormatUtils::IntToWideString(i++) + iter->ext), this->zf, (void*)bytes, (unsigned int)iter->data.size());
#else
SaveToFile(m_strOutputPath, ( wstring( _T( "\\word\\media\\image" ) ) + FormatUtils::IntToWideString(i++) + iter->ext), (void*)bytes, (unsigned int)iter->data.size());
#endif // CREATE_ZIPPED_DOCX
SaveToFile(m_strOutputPath, ( wstring( _T( "\\word\\media\\image" ) ) + FormatUtils::IntToWideString(i++) + iter->ext), (void*)bytes, (unsigned int)iter->data.size());
#endif // CREATE_ZIPPED_DOCX
}
RELEASEARRAYOBJECTS(bytes);
}
}
......
......@@ -63,14 +63,11 @@ namespace GdiPlusHelper
// codec not found
throw 0;
}
}
namespace OfficeArt
{
OfficeArtBlip* BlipFactory::GetBlipWithPngTransform ()
OfficeArtBlip* BlipFactory::GetBlipWithPngTransform()
{
CString strTempPath;
if (::GetTempPath(_MAX_PATH, strTempPath.GetBuffer(_MAX_PATH)) != 0)
......
......@@ -112,7 +112,7 @@ namespace OfficeArt
// MS WORD PNG ( UUID BMP )
m_sOriginalData = xstr;
officeArtBlip = GetBlipWithPngTransform ();
officeArtBlip = GetBlipWithPngTransform();
}
else if ((extension == std::wstring(L"jpg")) || (extension == std::wstring(L"jpeg")))
{
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment