Kaydet (Commit) e1664176 authored tarafından Tomaž Vajngerl's avatar Tomaž Vajngerl Kaydeden (comit) Tomaž Vajngerl

introduce graphic format detector (and basic metadata)

Currently we detect a graphic format in a ImpPeekGraphicFormat
method, which is called when reading a graphic from a stream.
The code is quite convoluted and doesn't help with readability
of graphicfilter.cxx

Additionally there exists an detection code written for the UNO
class GraphicDescriptor, which duplicates the detection, but can
in addition also extract other metadata at the same time.

This introduces the initial implementation of GraphicFormatDetector
class. It will first replace the code in ImpPeekGraphicFormat
to detect the graphic format and then later also be extended to
do what the GraphicDescriptor is doing. But currently it only
duplicates the implementation of ImpPeekGraphicFormat.

The problem with both of the current solution is that there are
not any tests written. For the GraphicFormatDetector however the
approach is to add test cases to check the current implementation
and only then refactor the code.

Change-Id: Idb9d3859b4380e3f15237d97aff969ce81e631dd
Reviewed-on: https://gerrit.libreoffice.org/72086
Tested-by: Jenkins
Reviewed-by: 's avatarTomaž Vajngerl <quikee@gmail.com>
üst b8e002f4
......@@ -12,6 +12,7 @@ $(eval $(call gb_CppunitTest_CppunitTest,vcl_graphic_test))
$(eval $(call gb_CppunitTest_add_exception_objects,vcl_graphic_test, \
vcl/qa/cppunit/GraphicTest \
vcl/qa/cppunit/GraphicDescriptorTest \
vcl/qa/cppunit/GraphicFormatDetectorTest \
))
$(eval $(call gb_CppunitTest_use_externals,vcl_graphic_test,\
......
......@@ -395,6 +395,7 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\
vcl/source/filter/graphicfilter2 \
vcl/source/filter/GraphicNativeTransform \
vcl/source/filter/GraphicNativeMetadata \
vcl/source/filter/GraphicFormatDetector \
vcl/source/filter/igif/decode \
vcl/source/filter/igif/gifread \
vcl/source/filter/ipdf/pdfread \
......
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#ifndef INCLUDED_VCL_INC_GRAPHICFORMATDETECTOR_HXX
#define INCLUDED_VCL_INC_GRAPHICFORMATDETECTOR_HXX
#include <tools/stream.hxx>
#include <vector>
VCL_DLLPUBLIC bool ImpPeekGraphicFormat(SvStream& rStream, OUString& rFormatExtension, bool bTest);
namespace vcl
{
class VCL_DLLPUBLIC GraphicFormatDetector
{
public:
SvStream& mrStream;
OUString maExtension;
std::vector<sal_uInt8> maFirstBytes;
sal_uInt32 mnFirstLong;
sal_uInt32 mnSecondLong;
sal_uInt64 mnStreamPosition;
sal_uInt64 mnStreamLength;
OUString msDetectedFormat;
GraphicFormatDetector(SvStream& rStream, OUString const& rFormatExtension);
bool detect();
bool checkMET();
bool checkBMP();
bool checkWMForEMF();
bool checkPCX();
bool checkTIF();
bool checkGIF();
bool checkPNG();
bool checkJPG();
bool checkSVM();
bool checkPCD();
bool checkPSD();
bool checkEPS();
bool checkDXF();
bool checkPCT();
bool checkPBMorPGMorPPM();
bool checkRAS();
bool checkXPM();
bool checkXBM();
bool checkSVG();
bool checkTGA();
bool checkMOV();
bool checkPDF();
};
}
#endif // INCLUDED_VCL_INC_GRAPHICFORMATDETECTOR_HXX
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include <cppunit/TestAssert.h>
#include <cppunit/TestFixture.h>
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/plugin/TestPlugIn.h>
#include <unotest/bootstrapfixturebase.hxx>
#include <com/sun/star/uno/Sequence.hxx>
#include <com/sun/star/beans/PropertyValue.hpp>
#include <vcl/graph.hxx>
#include <vcl/graphicfilter.hxx>
#include <graphic/GraphicFormatDetector.hxx>
#include <tools/stream.hxx>
using namespace css;
namespace
{
class GraphicFormatDetectorTest : public test::BootstrapFixtureBase
{
OUString getFullUrl(const OUString& sFileName)
{
return m_directories.getURLFromSrc("/vcl/qa/cppunit/data/") + sFileName;
}
void testDetectMET();
void testDetectBMP();
void testDetectWMF();
void testDetectPCX();
void testDetectJPG();
void testDetectPNG();
void testDetectGIF();
void testDetectPSD();
void testDetectTGA();
void testDetectTIF();
void testDetectXBM();
void testDetectXPM();
void testDetectSVG();
void testDetectSVGZ();
void testDetectPDF();
CPPUNIT_TEST_SUITE(GraphicFormatDetectorTest);
CPPUNIT_TEST(testDetectMET);
CPPUNIT_TEST(testDetectBMP);
CPPUNIT_TEST(testDetectWMF);
CPPUNIT_TEST(testDetectPCX);
CPPUNIT_TEST(testDetectJPG);
CPPUNIT_TEST(testDetectPNG);
CPPUNIT_TEST(testDetectGIF);
CPPUNIT_TEST(testDetectPSD);
CPPUNIT_TEST(testDetectTGA);
CPPUNIT_TEST(testDetectTIF);
CPPUNIT_TEST(testDetectXBM);
CPPUNIT_TEST(testDetectXPM);
CPPUNIT_TEST(testDetectSVG);
CPPUNIT_TEST(testDetectSVGZ);
CPPUNIT_TEST(testDetectPDF);
CPPUNIT_TEST_SUITE_END();
};
void GraphicFormatDetectorTest::testDetectMET()
{
SvFileStream aFileStream(getFullUrl("TypeDetectionExample.met"), StreamMode::READ);
vcl::GraphicFormatDetector aDetector(aFileStream, "MET");
CPPUNIT_ASSERT(aDetector.detect());
CPPUNIT_ASSERT(aDetector.checkMET());
aFileStream.Seek(aDetector.mnStreamPosition);
OUString rFormatExtension;
CPPUNIT_ASSERT(ImpPeekGraphicFormat(aFileStream, rFormatExtension, false));
CPPUNIT_ASSERT_EQUAL(OUString("MET"), rFormatExtension);
}
void GraphicFormatDetectorTest::testDetectBMP()
{
SvFileStream aFileStream(getFullUrl("TypeDetectionExample.bmp"), StreamMode::READ);
vcl::GraphicFormatDetector aDetector(aFileStream, "BMP");
CPPUNIT_ASSERT(aDetector.detect());
CPPUNIT_ASSERT(aDetector.checkBMP());
aFileStream.Seek(aDetector.mnStreamPosition);
OUString rFormatExtension;
CPPUNIT_ASSERT(ImpPeekGraphicFormat(aFileStream, rFormatExtension, false));
CPPUNIT_ASSERT_EQUAL(OUString("BMP"), rFormatExtension);
}
void GraphicFormatDetectorTest::testDetectWMF()
{
SvFileStream aFileStream(getFullUrl("TypeDetectionExample.wmf"), StreamMode::READ);
vcl::GraphicFormatDetector aDetector(aFileStream, "WMF");
CPPUNIT_ASSERT(aDetector.detect());
CPPUNIT_ASSERT(aDetector.checkWMForEMF());
aFileStream.Seek(aDetector.mnStreamPosition);
OUString rFormatExtension;
CPPUNIT_ASSERT(ImpPeekGraphicFormat(aFileStream, rFormatExtension, false));
CPPUNIT_ASSERT_EQUAL(OUString("WMF"), rFormatExtension);
}
void GraphicFormatDetectorTest::testDetectPCX()
{
SvFileStream aFileStream(getFullUrl("TypeDetectionExample.pcx"), StreamMode::READ);
vcl::GraphicFormatDetector aDetector(aFileStream, "PCX");
CPPUNIT_ASSERT(aDetector.detect());
CPPUNIT_ASSERT(aDetector.checkPCX());
aFileStream.Seek(aDetector.mnStreamPosition);
OUString rFormatExtension;
CPPUNIT_ASSERT(ImpPeekGraphicFormat(aFileStream, rFormatExtension, false));
CPPUNIT_ASSERT_EQUAL(OUString("PCX"), rFormatExtension);
}
void GraphicFormatDetectorTest::testDetectJPG()
{
SvFileStream aFileStream(getFullUrl("TypeDetectionExample.jpg"), StreamMode::READ);
vcl::GraphicFormatDetector aDetector(aFileStream, "JPG");
CPPUNIT_ASSERT(aDetector.detect());
CPPUNIT_ASSERT(aDetector.checkJPG());
aFileStream.Seek(aDetector.mnStreamPosition);
OUString rFormatExtension;
CPPUNIT_ASSERT(ImpPeekGraphicFormat(aFileStream, rFormatExtension, false));
CPPUNIT_ASSERT_EQUAL(OUString("JPG"), rFormatExtension);
}
void GraphicFormatDetectorTest::testDetectPNG()
{
SvFileStream aFileStream(getFullUrl("TypeDetectionExample.png"), StreamMode::READ);
vcl::GraphicFormatDetector aDetector(aFileStream, "PNG");
CPPUNIT_ASSERT(aDetector.detect());
CPPUNIT_ASSERT(aDetector.checkPNG());
aFileStream.Seek(aDetector.mnStreamPosition);
OUString rFormatExtension;
CPPUNIT_ASSERT(ImpPeekGraphicFormat(aFileStream, rFormatExtension, false));
CPPUNIT_ASSERT_EQUAL(OUString("PNG"), rFormatExtension);
}
void GraphicFormatDetectorTest::testDetectGIF()
{
SvFileStream aFileStream(getFullUrl("TypeDetectionExample.gif"), StreamMode::READ);
vcl::GraphicFormatDetector aDetector(aFileStream, "GIF");
CPPUNIT_ASSERT(aDetector.detect());
CPPUNIT_ASSERT(aDetector.checkGIF());
aFileStream.Seek(aDetector.mnStreamPosition);
OUString rFormatExtension;
CPPUNIT_ASSERT(ImpPeekGraphicFormat(aFileStream, rFormatExtension, false));
CPPUNIT_ASSERT_EQUAL(OUString("GIF"), rFormatExtension);
}
void GraphicFormatDetectorTest::testDetectPSD()
{
SvFileStream aFileStream(getFullUrl("TypeDetectionExample.psd"), StreamMode::READ);
vcl::GraphicFormatDetector aDetector(aFileStream, "PSD");
CPPUNIT_ASSERT(aDetector.detect());
CPPUNIT_ASSERT(aDetector.checkPSD());
aFileStream.Seek(aDetector.mnStreamPosition);
OUString rFormatExtension;
CPPUNIT_ASSERT(ImpPeekGraphicFormat(aFileStream, rFormatExtension, false));
CPPUNIT_ASSERT_EQUAL(OUString("PSD"), rFormatExtension);
}
void GraphicFormatDetectorTest::testDetectTGA()
{
SvFileStream aFileStream(getFullUrl("TypeDetectionExample.tga"), StreamMode::READ);
vcl::GraphicFormatDetector aDetector(aFileStream, "TGA");
CPPUNIT_ASSERT(aDetector.detect());
CPPUNIT_ASSERT(aDetector.checkTGA());
aFileStream.Seek(aDetector.mnStreamPosition);
OUString rFormatExtension("TGA"); // detection is based on extension only
CPPUNIT_ASSERT(ImpPeekGraphicFormat(aFileStream, rFormatExtension, false));
CPPUNIT_ASSERT_EQUAL(OUString("TGA"), rFormatExtension);
}
void GraphicFormatDetectorTest::testDetectTIF()
{
SvFileStream aFileStream(getFullUrl("TypeDetectionExample.tif"), StreamMode::READ);
vcl::GraphicFormatDetector aDetector(aFileStream, "TIF");
CPPUNIT_ASSERT(aDetector.detect());
CPPUNIT_ASSERT(aDetector.checkTIF());
aFileStream.Seek(aDetector.mnStreamPosition);
OUString rFormatExtension;
CPPUNIT_ASSERT(ImpPeekGraphicFormat(aFileStream, rFormatExtension, false));
CPPUNIT_ASSERT_EQUAL(OUString("TIF"), rFormatExtension);
}
void GraphicFormatDetectorTest::testDetectXBM()
{
SvFileStream aFileStream(getFullUrl("TypeDetectionExample.xbm"), StreamMode::READ);
vcl::GraphicFormatDetector aDetector(aFileStream, "XBM");
CPPUNIT_ASSERT(aDetector.detect());
CPPUNIT_ASSERT(aDetector.checkXBM());
aFileStream.Seek(aDetector.mnStreamPosition);
OUString rFormatExtension;
CPPUNIT_ASSERT(ImpPeekGraphicFormat(aFileStream, rFormatExtension, false));
CPPUNIT_ASSERT_EQUAL(OUString("XBM"), rFormatExtension);
}
void GraphicFormatDetectorTest::testDetectXPM()
{
SvFileStream aFileStream(getFullUrl("TypeDetectionExample.xpm"), StreamMode::READ);
vcl::GraphicFormatDetector aDetector(aFileStream, "XPM");
CPPUNIT_ASSERT(aDetector.detect());
CPPUNIT_ASSERT(aDetector.checkXPM());
aFileStream.Seek(aDetector.mnStreamPosition);
OUString rFormatExtension;
CPPUNIT_ASSERT(ImpPeekGraphicFormat(aFileStream, rFormatExtension, false));
CPPUNIT_ASSERT_EQUAL(OUString("XPM"), rFormatExtension);
}
void GraphicFormatDetectorTest::testDetectSVG()
{
SvFileStream aFileStream(getFullUrl("TypeDetectionExample.svg"), StreamMode::READ);
vcl::GraphicFormatDetector aDetector(aFileStream, "SVG");
CPPUNIT_ASSERT(aDetector.detect());
CPPUNIT_ASSERT(aDetector.checkSVG());
aFileStream.Seek(aDetector.mnStreamPosition);
OUString rFormatExtension;
CPPUNIT_ASSERT(ImpPeekGraphicFormat(aFileStream, rFormatExtension, false));
CPPUNIT_ASSERT_EQUAL(OUString("SVG"), rFormatExtension);
}
void GraphicFormatDetectorTest::testDetectSVGZ()
{
SvFileStream aFileStream(getFullUrl("TypeDetectionExample.svgz"), StreamMode::READ);
vcl::GraphicFormatDetector aDetector(aFileStream, "SVG");
CPPUNIT_ASSERT(aDetector.detect());
CPPUNIT_ASSERT(aDetector.checkSVG());
aFileStream.Seek(aDetector.mnStreamPosition);
OUString rFormatExtension;
CPPUNIT_ASSERT(ImpPeekGraphicFormat(aFileStream, rFormatExtension, false));
CPPUNIT_ASSERT_EQUAL(OUString("SVG"), rFormatExtension);
}
void GraphicFormatDetectorTest::testDetectPDF()
{
SvFileStream aFileStream(getFullUrl("TypeDetectionExample.pdf"), StreamMode::READ);
vcl::GraphicFormatDetector aDetector(aFileStream, "PDF");
CPPUNIT_ASSERT(aDetector.detect());
CPPUNIT_ASSERT(aDetector.checkPDF());
aFileStream.Seek(aDetector.mnStreamPosition);
OUString rFormatExtension;
CPPUNIT_ASSERT(ImpPeekGraphicFormat(aFileStream, rFormatExtension, false));
CPPUNIT_ASSERT_EQUAL(OUString("PDF"), rFormatExtension);
}
} // namespace
CPPUNIT_TEST_SUITE_REGISTRATION(GraphicFormatDetectorTest);
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
This diff was suppressed by a .gitattributes entry.
#define sample_width 10
#define sample_height 10
static unsigned char sample_bits[] = {
0x00, 0x00, 0xfe, 0x01, 0xfe, 0x01, 0xfe, 0x01, 0xfe, 0x01, 0xfe, 0x01,
0xfe, 0x01, 0xfe, 0x01, 0xfe, 0x01, 0x00, 0x00 };
/* XPM */
static char * sample_xpm[] = {
"10 10 2 1",
" c #FFFFFF",
". c #72D1C8",
" ",
" ........ ",
" ........ ",
" ........ ",
" ........ ",
" ........ ",
" ........ ",
" ........ ",
" ........ ",
" "};
This diff is collapsed.
......@@ -73,6 +73,8 @@
#include "FilterConfigCache.hxx"
#include "graphicfilter_internal.hxx"
#include <graphic/GraphicFormatDetector.hxx>
#define PMGCHUNG_msOG 0x6d734f47 // Microsoft Office Animated GIF
typedef ::std::vector< GraphicFilter* > FilterList_impl;
......@@ -238,52 +240,18 @@ bool isPCT(SvStream& rStream, sal_uLong nStreamPos, sal_uLong nStreamLen)
*
*************************************************************************/
static bool ImpPeekGraphicFormat( SvStream& rStream, OUString& rFormatExtension, bool bTest )
bool ImpPeekGraphicFormat( SvStream& rStream, OUString& rFormatExtension, bool bTest )
{
sal_uInt8 sFirstBytes[ 256 ];
sal_uLong nFirstLong(0), nSecondLong(0);
sal_uLong nStreamPos = rStream.Tell();
sal_uLong nStreamLen = rStream.remainingSize();
if ( !nStreamLen )
{
SvLockBytes* pLockBytes = rStream.GetLockBytes();
if ( pLockBytes )
pLockBytes->SetSynchronMode();
nStreamLen = rStream.remainingSize();
}
if (!nStreamLen)
{
return false; // this prevents at least a STL assertion
}
else if (nStreamLen >= 256)
{
// load first 256 bytes into a buffer
sal_uLong nRead = rStream.ReadBytes(sFirstBytes, 256);
if (nRead < 256)
nStreamLen = nRead;
}
else
{
nStreamLen = rStream.ReadBytes(sFirstBytes, nStreamLen);
}
if (rStream.GetError())
vcl::GraphicFormatDetector aDetector(rStream, rFormatExtension);
if (!aDetector.detect())
return false;
for (sal_uLong i = nStreamLen; i < 256; ++i)
sFirstBytes[i] = 0;
sal_uInt8* sFirstBytes = aDetector.maFirstBytes.data();
sal_uLong nFirstLong = aDetector.mnFirstLong;
sal_uLong nSecondLong = aDetector.mnSecondLong;
// Accommodate the first 8 bytes in nFirstLong, nSecondLong
// Big-Endian:
for (int i = 0; i < 4; ++i)
{
nFirstLong=(nFirstLong<<8)|static_cast<sal_uLong>(sFirstBytes[i]);
nSecondLong=(nSecondLong<<8)|static_cast<sal_uLong>(sFirstBytes[i+4]);
}
sal_uLong nStreamPos = aDetector.mnStreamPosition;
sal_uLong nStreamLen = aDetector.mnStreamLength;
// The following variable is used when bTest == true. It remains false
// if the format (rFormatExtension) has not yet been set.
......
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