/* Copyright (c) 2009 Cognitive Technologies Copyright (c) 2009 OpenOCR Developers All rights reserved. Ðàçðåøàåòñÿ ïîâòîðíîå ðàñïðîñòðàíåíèå è èñïîëüçîâàíèå êàê â âèäå èñõîäíîãî êîäà, òàê è â äâîè÷íîé ôîðìå, ñ èçìåíåíèÿìè èëè áåç, ïðè ñîáëþäåíèè ñëåäóþùèõ óñëîâèé: * Ïðè ïîâòîðíîì ðàñïðîñòðàíåíèè èñõîäíîãî êîäà äîëæíû îñòàâàòüñÿ óêàçàííîå âûøå óâåäîìëåíèå îá àâòîðñêîì ïðàâå, ýòîò ñïèñîê óñëîâèé è ïîñëåäóþùèé îòêàç îò ãàðàíòèé. * Ïðè ïîâòîðíîì ðàñïðîñòðàíåíèè äâîè÷íîãî êîäà â äîêóìåíòàöèè è/èëè â äðóãèõ ìàòåðèàëàõ, ïîñòàâëÿåìûõ ïðè ðàñïðîñòðàíåíèè, äîëæíû ñîõðàíÿòüñÿ óêàçàííàÿ âûøå èíôîðìàöèÿ îá àâòîðñêîì ïðàâå, ýòîò ñïèñîê óñëîâèé è ïîñëåäóþùèé îòêàç îò ãàðàíòèé. * Íè íàçâàíèå Cognitive Technologies, íè èìåíà åå ñîòðóäíèêîâ íå ìîãóò áûòü èñïîëüçîâàíû â êà÷åñòâå ñðåäñòâà ïîääåðæêè è/èëè ïðîäâèæåíèÿ ïðîäóêòîâ, îñíîâàííûõ íà ýòîì ÏÎ, áåç ïðåäâàðèòåëüíîãî ïèñüìåííîãî ðàçðåøåíèÿ. ÝÒÀ ÏÐÎÃÐÀÌÌÀ ÏÐÅÄÎÑÒÀÂËÅÍÀ ÂËÀÄÅËÜÖÀÌÈ ÀÂÒÎÐÑÊÈÕ ÏÐÀ È/ÈËÈ ÄÐÓÃÈÌÈ ËÈÖÀÌÈ "ÊÀÊ ÎÍÀ ÅÑÒÜ" ÁÅÇ ÊÀÊÎÃÎ-ËÈÁÎ ÂÈÄÀ ÃÀÐÀÍÒÈÉ, ÂÛÐÀÆÅÍÍÛÕ ßÂÍÎ ÈËÈ ÏÎÄÐÀÇÓÌÅÂÀÅÌÛÕ, ÂÊËÞ×Àß ÃÀÐÀÍÒÈÈ ÊÎÌÌÅÐ×ÅÑÊÎÉ ÖÅÍÍÎÑÒÈ È ÏÐÈÃÎÄÍÎÑÒÈ ÄËß ÊÎÍÊÐÅÒÍÎÉ ÖÅËÈ, ÍÎ ÍÅ ÎÃÐÀÍÈ×ÈÂÀßÑÜ ÈÌÈ. ÍÈ ÂËÀÄÅËÅÖ ÀÂÒÎÐÑÊÈÕ ÏÐÀÂ È ÍÈ ÎÄÍÎ ÄÐÓÃÎÅ ËÈÖÎ, ÊÎÒÎÐÎÅ ÌÎÆÅÒ ÈÇÌÅÍßÒÜ È/ÈËÈ ÏÎÂÒÎÐÍÎ ÐÀÑÏÐÎÑÒÐÀÍßÒÜ ÏÐÎÃÐÀÌÌÓ, ÍÈ Â ÊÎÅÌ ÑËÓ×ÀÅ ÍÅ ÍÅÑ¨Ò ÎÒÂÅÒÑÒÂÅÍÍÎÑÒÈ, ÂÊËÞ×Àß ËÞÁÛÅ ÎÁÙÈÅ, ÑËÓ×ÀÉÍÛÅ, ÑÏÅÖÈÀËÜÍÛÅ ÈËÈ ÏÎÑËÅÄÎÂÀÂØÈÅ ÓÁÛÒÊÈ, ÑÂßÇÀÍÍÛÅ Ñ ÈÑÏÎËÜÇÎÂÀÍÈÅÌ ÈËÈ ÏÎÍÅÑÅÍÍÛÅ ÂÑËÅÄÑÒÂÈÅ ÍÅÂÎÇÌÎÆÍÎÑÒÈ ÈÑÏÎËÜÇÎÂÀÍÈß ÏÐÎÃÐÀÌÌÛ (ÂÊËÞ×Àß ÏÎÒÅÐÈ ÄÀÍÍÛÕ, ÈËÈ ÄÀÍÍÛÅ, ÑÒÀÂØÈÅ ÍÅÃÎÄÍÛÌÈ, ÈËÈ ÓÁÛÒÊÈ È/ÈËÈ ÏÎÒÅÐÈ ÄÎÕÎÄÎÂ, ÏÎÍÅÑÅÍÍÛÅ ÈÇ-ÇÀ ÄÅÉÑÒÂÈÉ ÒÐÅÒÜÈÕ ËÈÖ È/ÈËÈ ÎÒÊÀÇÀ ÏÐÎÃÐÀÌÌÛ ÐÀÁÎÒÀÒÜ ÑÎÂÌÅÑÒÍÎ Ñ ÄÐÓÃÈÌÈ ÏÐÎÃÐÀÌÌÀÌÈ, ÍÎ ÍÅ ÎÃÐÀÍÈ×ÈÂÀßÑÜ ÝÒÈÌÈ ÑËÓ×ÀßÌÈ), ÍÎ ÍÅ ÎÃÐÀÍÈ×ÈÂÀßÑÜ ÈÌÈ, ÄÀÆÅ ÅÑËÈ ÒÀÊÎÉ ÂËÀÄÅËÅÖ ÈËÈ ÄÐÓÃÎÅ ËÈÖÎ ÁÛËÈ ÈÇÂÅÙÅÍÛ Î ÂÎÇÌÎÆÍÎÑÒÈ ÒÀÊÈÕ ÓÁÛÒÊÎÂ È ÏÎÒÅÐÜ. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Cognitive Technologies nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file cimagereader.cpp \brief \~english \~russian \author Polevoy Dmitry \date 01.05.2009 */ #include "cimagereader.h" #include "utilconf.h" #if CF_USE_IL_QT #include #include #elif CF_USE_IL_FREEIMAGE //#include "FreeImage.h" #elif CF_USE_IL_IMAGEMAGICK // TODO: check the reason of warnings in MS VC 9.0 #pragma warning (push) #pragma warning (disable : 4251) #include #pragma warning (pop) using namespace Magick; #else #include #endif #include #include "xpath.h" // TODO: include BEFORE gives errors under MinGW using namespace std; CImageReader::CImageReader() : m_path() , m_name() , m_pDib(0) { } CImageReader::~CImageReader() { delete[] m_pDib; } unsigned char* CImageReader::getData() const { return m_pDib; } const std::string& CImageReader::getImageName() const { return m_name; } const std::string& CImageReader::getImagePath() const { return m_path; } void CImageReader::setImagePath(const string& path) { m_path = path; XPath xpImage(m_path.c_str()); m_name.assign(xpImage.CutNameEx()); } #if CF_USE_IL_QT void CImageReader::read(const string& path) { setImagePath(path); QImage image; // ok, let's load the file if (image.load(path.c_str())) // image file is loaded { const QImage& raster = image.mirrored();/*.rgbSwapped();*/ BITMAPINFO dibInfo = {0}; dibInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); dibInfo.bmiHeader.biWidth = raster.width(); dibInfo.bmiHeader.biHeight = raster.height(); dibInfo.bmiHeader.biPlanes = 1; dibInfo.bmiHeader.biBitCount = raster.depth(); dibInfo.bmiHeader.biCompression = 0; // BI_RGB - uncompresed dibInfo.bmiHeader.biSizeImage = 0; dibInfo.bmiHeader.biXPelsPerMeter = 4 * raster.dotsPerMeterX(); dibInfo.bmiHeader.biYPelsPerMeter = 4 * raster.dotsPerMeterY(); int nColors(raster.colorCount()); QVector colorTable(raster.colorTable()); /*if (32 == raster.depth()) { nColors } else { } colorCount() */ dibInfo.bmiHeader.biClrUsed = nColors; dibInfo.bmiHeader.biClrImportant = 0; unsigned int sizeRaster = raster.byteCount(); unsigned int sizeInfo = dibInfo.bmiHeader.biSize; unsigned int sizePalete = 0; if (0 != dibInfo.bmiHeader.biClrUsed) { sizePalete = dibInfo.bmiHeader.biClrUsed * sizeof(RGBQUAD); // TODO } else { sizePalete = sizeof(RGBQUAD); } RGBQUAD rgbWhite = {255, 255, 255, 0}; dibInfo.bmiColors[0] = rgbWhite; RGBQUAD rgbBlack = {0, 0, 0, 0}; unsigned char* pDib = new unsigned char[sizeInfo + sizePalete + sizeRaster]; memset(pDib, 0x00, sizeInfo + sizePalete + sizeRaster); memcpy(pDib, &dibInfo, sizeInfo); if (0 != sizePalete) { memcpy(pDib + sizeInfo, (const unsigned char*)colorTable.data(), sizePalete); } unsigned char* pRaster = pDib + sizePalete + sizeInfo; memcpy(pDib + sizePalete + sizeInfo, raster.bits(), sizeRaster); m_pDib = pDib; /* QFile bmpFile("c:/1.bmp"); if (bmpFile.open(QIODevice::WriteOnly)) { struct bmpfile_magic { unsigned char magic[2]; }; struct bmpfile_header { uint32_t filesz; uint16_t creator1; uint16_t creator2; uint32_t bmp_offset; }; bmpfile_magic magic = {'\x42', '\x4D'}; bmpfile_header header = {sizeof(magic) + sizeof(bmpfile_header) + sizeInfo + sizeRaster, 0, 0, sizeof(magic) + sizeof(bmpfile_header) + sizeInfo + sizePalete}; QDataStream bmpStream(&bmpFile); bmpStream.writeRawData((const char*)&magic, sizeof(magic)); bmpStream.writeRawData((const char*)&header, sizeof(header)); bmpStream.writeRawData((const char*)pDib, sizeInfo + sizeRaster); } */ } else // image file not loaded { // TODO: } } #elif CF_USE_IL_FREEIMAGE // use #include "FreeImage.h" // should be included after xpath.h due to BOOL and so on (MS incompatible) void CImageReader::read(const string& path) { setImagePath(path); FREE_IMAGE_FORMAT fif = FIF_UNKNOWN; // check the file signature and deduce its format // (the second argument is currently not used by FreeImage) fif = FreeImage_GetFileType(m_path.c_str(), 0); if (fif == FIF_UNKNOWN) { // no signature ? // try to guess the file format from the file extension fif = FreeImage_GetFIFFromFilename(m_path.c_str()); } // check that the plugin has reading capabilities ... if ((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif)) { // ok, let's load the file FIBITMAP *dib = FreeImage_Load(fif, m_path.c_str(), 0); if (0 != dib) // image file is loaded { unsigned char* pDib = new unsigned char[FreeImage_GetDIBSize(dib)]; BITMAPINFO *pDibInfo = FreeImage_GetInfo(dib); unsigned int sizeInfo = pDibInfo->bmiHeader.biSize; if (0 != FreeImage_GetColorsUsed(dib)) { sizeInfo += FreeImage_GetColorsUsed(dib) * sizeof(RGBQUAD); } else { sizeInfo += sizeof(RGBQUAD); } memcpy(pDib, pDibInfo, sizeInfo); memcpy(pDib + sizeInfo, FreeImage_GetBits(dib), FreeImage_GetDIBSize(dib) - sizeInfo); m_pDib = pDib; // unless a bad file format, we are done ! FreeImage_Unload(dib); } else // image file not loaded { // TODO: } } } #elif CF_USE_IL_IMAGEMAGICK void CImageReader::read(const string& path) { setImagePath(path); try { Image image(m_path.c_str()); // Write to BLOB in BMP format Blob blob; image.write(&blob, "DIB"); const size_t sizeData = blob.length(); unsigned char* pDib = new unsigned char[sizeData]; memcpy(pDib, blob.data(), sizeData); m_pDib = pDib; } catch(Exception &error_) { cerr << error_.what() << endl; } } #else // no image libraries void CImageReader::read(const string& path) { setImagePath(path); ifstream strm(m_path.c_str(), ios::binary | ios::in); if (strm.good()) { unsigned char* pDib(0); char pBmpHeader[2] = {0}; strm.read(pBmpHeader, sizeof(pBmpHeader)); if (('B' != pBmpHeader[0]) || ('M' != pBmpHeader[1])) { cerr << m_path.c_str() << " is not a BMP file." << endl; } else { int32_t size(0); strm.read(reinterpret_cast(&size), sizeof(size)); strm.read(pBmpHeader, sizeof(pBmpHeader)); strm.read(pBmpHeader, sizeof(pBmpHeader)); int32_t offset(0); strm.read(reinterpret_cast(&offset), sizeof(offset)); size -= strm.tellg(); pDib = new unsigned char[size]; strm.read(reinterpret_cast(pDib), size); if (*((int32_t*)pDib) != 40) { cerr << m_path.c_str() << " is not of type \"Windows V3\" BMP, which is the only supported format.\n"; cerr << "Please convert your BMP to uncompressed V3 format and try again." << endl; delete[] pDib; pDib = 0; } if (*((int32_t*)(pDib + 16)) != 0) { cerr << m_path.c_str() << "is a compressed BMP. Only uncompressed BMP files are supported.\n"; cerr << "Please convert your BMP to uncompressed V3 format and try again." << endl; delete[] pDib; pDib = 0; } } m_pDib = pDib; } else { // TODO: cerr << "Could not open file " << m_path.c_str() << "." << endl; } } #endif