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 @@ ...@@ -2,6 +2,6 @@
//1 //1
//0 //0
//0 //0
//125 //126
#define INTVER 1,0,0,125 #define INTVER 1,0,0,126
#define STRVER "1,0,0,125\0" #define STRVER "1,0,0,126\0"
...@@ -4,9 +4,12 @@ ...@@ -4,9 +4,12 @@
namespace DocFileFormat namespace DocFileFormat
{ {
typedef enum FibVersion typedef enum FibVersion
{ {
//Fib1993 = 0x0065, // Word 6.0
//Fib1995 = 0x0068, // Word 7.0 (95)
//Fib2002 = 0x0069, // Word 8.0 (97)
Fib1997 = 0x00C1, Fib1997 = 0x00C1,
Fib2000 = 0x00D9, Fib2000 = 0x00D9,
Fib2002 = 0x0101, Fib2002 = 0x0101,
......
...@@ -13,55 +13,56 @@ namespace DocFileFormat ...@@ -13,55 +13,56 @@ namespace DocFileFormat
static const unsigned short TYPE_CODE_0xF020 = 0xF020; static const unsigned short TYPE_CODE_0xF020 = 0xF020;
static const unsigned short TYPE_CODE_0xF021 = 0xF021; static const unsigned short TYPE_CODE_0xF021 = 0xF021;
/// The secondary, or data, UID - should always be set. public:
byte* m_rgbUid; BitmapBlip() : Record(), m_rgbUid(NULL), m_rgbUidPrimary(NULL), m_bTag(0), m_pvBits(NULL)
/// 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)
{ {
} }
BitmapBlip( IBinaryReader* _reader, unsigned int size, unsigned int typeCode, unsigned int version, unsigned int instance ): 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) 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 ) || if ((instance == 0x46B) || (instance == 0x6E3) || (instance == 0x6E1) || (instance == 0x7A9) || (instance == 0x6E5))
( 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() virtual ~BitmapBlip()
{ {
RELEASEARRAYOBJECTS( this->m_rgbUid ); RELEASEARRAYOBJECTS(m_rgbUid);
RELEASEARRAYOBJECTS( this->m_rgbUidPrimary ); RELEASEARRAYOBJECTS(m_rgbUidPrimary);
RELEASEARRAYOBJECTS( this->m_pvBits ); 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 ...@@ -62,17 +62,19 @@ namespace DocFileFormat
struct ImageFileStructure struct ImageFileStructure
{ {
wstring ext;
vector<byte> data;
ImageFileStructure() ImageFileStructure()
{ {
} }
ImageFileStructure( const wstring& _ext, const vector<byte>& _data ): ImageFileStructure(const wstring& _ext, const vector<byte>& _data, Global::BlipType _blipType = Global::msoblipUNKNOWN) : ext(_ext), data(_data), blipType(_blipType)
ext(_ext), data(_data)
{ {
} }
std::wstring ext;
std::vector<byte> data;
Global::BlipType blipType;
}; };
struct OleObjectFileStructure struct OleObjectFileStructure
......
...@@ -412,7 +412,10 @@ namespace DocFileFormat ...@@ -412,7 +412,10 @@ namespace DocFileFormat
} }
else if (fcEnd < (int)pcd.fc) // this piece is beyond the requested range 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 "stdafx.h"
#include "VMLPictureMapping.h" #include "VMLPictureMapping.h"
#include "GdiplusEx.h"
namespace DocFileFormat namespace DocFileFormat
{ {
VMLPictureMapping::VMLPictureMapping(ConversionContext* ctx, XmlUtils::CXmlWriter* writer, bool olePreview, IMapping* caller, bool isBulletPicture) : PropertiesMapping(writer) VMLPictureMapping::VMLPictureMapping(ConversionContext* ctx, XmlUtils::CXmlWriter* writer, bool olePreview, IMapping* caller, bool isBulletPicture) : PropertiesMapping(writer)
...@@ -190,16 +192,19 @@ namespace DocFileFormat ...@@ -190,16 +192,19 @@ namespace DocFileFormat
{ {
//it's a meta image //it's a meta image
MetafilePictBlip* metaBlip = static_cast<MetafilePictBlip*>(oBlipEntry->Blip); MetafilePictBlip* metaBlip = static_cast<MetafilePictBlip*>(oBlipEntry->Blip);
if (metaBlip)
{
//meta images can be compressed //meta images can be compressed
byte* decompressed = NULL; byte* decompressed = NULL;
int decompressedSize = 0; int decompressedSize = 0;
decompressedSize = metaBlip->Decompress( &decompressed ); decompressedSize = metaBlip->Decompress(&decompressed);
if (0 != decompressedSize && NULL != decompressed)
_ctx->_docx->ImagesList.push_back (ImageFileStructure (GetTargetExt(oBlipEntry->btWin32 ), vector<byte>( decompressed, ( decompressed + decompressedSize ) ) ) ); {
_ctx->_docx->ImagesList.push_back(ImageFileStructure(GetTargetExt(oBlipEntry->btWin32), std::vector<byte>(decompressed, (decompressed + decompressedSize))));
RELEASEARRAYOBJECTS( decompressed ); RELEASEARRAYOBJECTS(decompressed);
}
}
} }
break; break;
...@@ -209,10 +214,12 @@ namespace DocFileFormat ...@@ -209,10 +214,12 @@ namespace DocFileFormat
case Global::msoblipTIFF: case Global::msoblipTIFF:
case Global::msoblipDIB: case Global::msoblipDIB:
{ {
//it's a bitmap image
BitmapBlip* bitBlip = static_cast<BitmapBlip*>(oBlipEntry->Blip); BitmapBlip* bitBlip = static_cast<BitmapBlip*>(oBlipEntry->Blip);
if (bitBlip)
_ctx->_docx->ImagesList.push_back(ImageFileStructure (GetTargetExt(oBlipEntry->btWin32 ), vector<byte>( bitBlip->m_pvBits, ( bitBlip->m_pvBits + bitBlip->pvBitsSize ) ) )); {
_ctx->_docx->ImagesList.push_back(ImageFileStructure(GetTargetExt(oBlipEntry->btWin32),
vector<byte>(bitBlip->m_pvBits, (bitBlip->m_pvBits + bitBlip->pvBitsSize)), oBlipEntry->btWin32));
}
} }
break; break;
...@@ -225,7 +232,7 @@ namespace DocFileFormat ...@@ -225,7 +232,7 @@ namespace DocFileFormat
break; break;
} }
m_nImageId = _ctx->_docx->RegisterImage (_caller, oBlipEntry->btWin32); m_nImageId = _ctx->_docx->RegisterImage(_caller, oBlipEntry->btWin32);
result = true; result = true;
} }
...@@ -240,6 +247,9 @@ namespace DocFileFormat ...@@ -240,6 +247,9 @@ namespace DocFileFormat
{ {
switch (nType) switch (nType)
{ {
//case Global::msoblipDIB:
// return std::wstring( _T( ".bmp" ) );
//case msoblipBMP: //case msoblipBMP:
// return wstring( _T( ".bmp" ) ); // return wstring( _T( ".bmp" ) );
......
...@@ -1156,24 +1156,28 @@ namespace DocFileFormat ...@@ -1156,24 +1156,28 @@ namespace DocFileFormat
{ {
VirtualStreamReader reader(_ctx->_doc->WordDocumentStream, oBlip->foDelay); VirtualStreamReader reader(_ctx->_doc->WordDocumentStream, oBlip->foDelay);
switch ( oBlip->btWin32 ) switch (oBlip->btWin32)
{ {
case Global::msoblipEMF: case Global::msoblipEMF:
case Global::msoblipWMF: case Global::msoblipWMF:
{ {
//it's a meta image //it's a meta image
MetafilePictBlip* metaBlip = static_cast<MetafilePictBlip*>(RecordFactory::ReadRecord( &reader, 0 )); MetafilePictBlip* metaBlip = static_cast<MetafilePictBlip*>(RecordFactory::ReadRecord(&reader, 0));
if (metaBlip)
{
//meta images can be compressed //meta images can be compressed
byte* decompressed = NULL; byte* decompressed = NULL;
int decompressedSize = 0; int decompressedSize = 0;
decompressedSize = metaBlip->Decompress( &decompressed ); decompressedSize = metaBlip->Decompress(&decompressed);
if (0 != decompressedSize && NULL != decompressed)
_ctx->_docx->ImagesList.push_back( ImageFileStructure( GetTargetExt( oBlip->btWin32 ), vector<byte>( decompressed, ( decompressed + decompressedSize ) ) ) ); {
_ctx->_docx->ImagesList.push_back(ImageFileStructure(GetTargetExt(oBlip->btWin32), vector<byte>(decompressed, (decompressed + decompressedSize))));
RELEASEARRAYOBJECTS(decompressed);
}
RELEASEARRAYOBJECTS( decompressed ); RELEASEOBJECT(metaBlip);
RELEASEOBJECT( metaBlip ); }
} }
break; break;
...@@ -1184,18 +1188,19 @@ namespace DocFileFormat ...@@ -1184,18 +1188,19 @@ namespace DocFileFormat
case Global::msoblipDIB: case Global::msoblipDIB:
{ {
//it's a bitmap image //it's a bitmap image
BitmapBlip* bitBlip = static_cast<BitmapBlip*>(RecordFactory::ReadRecord( &reader, 0 )); 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 ) ) ) ); {
_ctx->_docx->ImagesList.push_back(ImageFileStructure(GetTargetExt(oBlip->btWin32),
vector<byte>(bitBlip->m_pvBits, (bitBlip->m_pvBits + bitBlip->pvBitsSize)), oBlip->btWin32));
RELEASEOBJECT (bitBlip); RELEASEOBJECT (bitBlip);
} }
}
break; break;
default: default:
{ {
result = false; result = false;
return result; return result;
} }
break; break;
......
...@@ -146,11 +146,30 @@ namespace DocFileFormat ...@@ -146,11 +146,30 @@ namespace DocFileFormat
} }
// Parse FIB // 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 // Check the file version
if (FIB->m_FibBase.nFib) 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) if (FIB->m_FibBase.nFib < Fib1997)
{ {
Clear(); Clear();
......
#include "stdafx.h" #include "stdafx.h"
#include "WordprocessingDocument.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 namespace DocFileFormat
{ {
WordprocessingDocument::WordprocessingDocument(const WCHAR* _fileName, const WordDocument* _docFile) : OpenXmlPackage( _docFile ), FontTableXML( _T( "" ) ), DocumentXML( _T( "" ) ), WordprocessingDocument::WordprocessingDocument(const WCHAR* _fileName, const WordDocument* _docFile) : OpenXmlPackage( _docFile ), FontTableXML( _T( "" ) ), DocumentXML( _T( "" ) ),
...@@ -76,18 +178,29 @@ namespace DocFileFormat ...@@ -76,18 +178,29 @@ namespace DocFileFormat
int i = 1; 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()]; bytes = new byte[iter->data.size()];
if (bytes) if (bytes)
{ {
copy(iter->data.begin(), iter->data.end(), 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 #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 #else
SaveToFile(m_strOutputPath, ( wstring( _T( "\\word\\media\\image" ) ) + FormatUtils::IntToWideString(i++) + iter->ext), (void*)bytes, (unsigned int)iter->data.size()); SaveToFile(m_strOutputPath, ( wstring( _T( "\\word\\media\\image" ) ) + FormatUtils::IntToWideString(i++) + iter->ext), (void*)bytes, (unsigned int)iter->data.size());
#endif // CREATE_ZIPPED_DOCX #endif // CREATE_ZIPPED_DOCX
}
RELEASEARRAYOBJECTS(bytes); RELEASEARRAYOBJECTS(bytes);
} }
} }
......
...@@ -63,14 +63,11 @@ namespace GdiPlusHelper ...@@ -63,14 +63,11 @@ namespace GdiPlusHelper
// codec not found // codec not found
throw 0; throw 0;
} }
} }
namespace OfficeArt namespace OfficeArt
{ {
OfficeArtBlip* BlipFactory::GetBlipWithPngTransform () OfficeArtBlip* BlipFactory::GetBlipWithPngTransform()
{ {
CString strTempPath; CString strTempPath;
if (::GetTempPath(_MAX_PATH, strTempPath.GetBuffer(_MAX_PATH)) != 0) if (::GetTempPath(_MAX_PATH, strTempPath.GetBuffer(_MAX_PATH)) != 0)
......
...@@ -112,7 +112,7 @@ namespace OfficeArt ...@@ -112,7 +112,7 @@ namespace OfficeArt
// MS WORD PNG ( UUID BMP ) // MS WORD PNG ( UUID BMP )
m_sOriginalData = xstr; m_sOriginalData = xstr;
officeArtBlip = GetBlipWithPngTransform (); officeArtBlip = GetBlipWithPngTransform();
} }
else if ((extension == std::wstring(L"jpg")) || (extension == std::wstring(L"jpeg"))) 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