mirror of
https://github.com/JakubMelka/PDF4QT.git
synced 2025-03-15 02:40:09 +01:00
Images (just beginning)
This commit is contained in:
parent
0447b9e3a1
commit
3358d49240
BIN
OpenJPEG/bin/concrt140.dll
Normal file
BIN
OpenJPEG/bin/concrt140.dll
Normal file
Binary file not shown.
BIN
OpenJPEG/bin/msvcp140.dll
Normal file
BIN
OpenJPEG/bin/msvcp140.dll
Normal file
Binary file not shown.
BIN
OpenJPEG/bin/openjp2.dll
Normal file
BIN
OpenJPEG/bin/openjp2.dll
Normal file
Binary file not shown.
BIN
OpenJPEG/bin/opj_compress.exe
Normal file
BIN
OpenJPEG/bin/opj_compress.exe
Normal file
Binary file not shown.
BIN
OpenJPEG/bin/opj_decompress.exe
Normal file
BIN
OpenJPEG/bin/opj_decompress.exe
Normal file
Binary file not shown.
BIN
OpenJPEG/bin/opj_dump.exe
Normal file
BIN
OpenJPEG/bin/opj_dump.exe
Normal file
Binary file not shown.
BIN
OpenJPEG/bin/vcruntime140.dll
Normal file
BIN
OpenJPEG/bin/vcruntime140.dll
Normal file
Binary file not shown.
1691
OpenJPEG/include/openjpeg-2.3/openjpeg.h
Normal file
1691
OpenJPEG/include/openjpeg-2.3/openjpeg.h
Normal file
File diff suppressed because it is too large
Load Diff
10
OpenJPEG/include/openjpeg-2.3/opj_config.h
Normal file
10
OpenJPEG/include/openjpeg-2.3/opj_config.h
Normal file
@ -0,0 +1,10 @@
|
||||
/* create opj_config.h for CMake */
|
||||
#define OPJ_HAVE_STDINT_H 1
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* OpenJPEG Versioning */
|
||||
|
||||
/* Version number. */
|
||||
#define OPJ_VERSION_MAJOR 2
|
||||
#define OPJ_VERSION_MINOR 3
|
||||
#define OPJ_VERSION_BUILD 1
|
52
OpenJPEG/include/openjpeg-2.3/opj_stdint.h
Normal file
52
OpenJPEG/include/openjpeg-2.3/opj_stdint.h
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* The copyright in this software is being made available under the 2-clauses
|
||||
* BSD License, included below. This software may be subject to other third
|
||||
* party and contributor rights, including patent rights, and no such rights
|
||||
* are granted under this license.
|
||||
*
|
||||
* Copyright (c) 2012, Mathieu Malaterre <mathieu.malaterre@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef OPJ_STDINT_H
|
||||
#define OPJ_STDINT_H
|
||||
|
||||
#include "opj_config.h"
|
||||
#ifdef OPJ_HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
#else
|
||||
#if defined(_WIN32)
|
||||
typedef signed __int8 int8_t;
|
||||
typedef unsigned __int8 uint8_t;
|
||||
typedef signed __int16 int16_t;
|
||||
typedef unsigned __int16 uint16_t;
|
||||
typedef signed __int32 int32_t;
|
||||
typedef unsigned __int32 uint32_t;
|
||||
typedef signed __int64 int64_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
#else
|
||||
#error unsupported platform
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* OPJ_STDINT_H */
|
BIN
OpenJPEG/lib/openjp2.lib
Normal file
BIN
OpenJPEG/lib/openjp2.lib
Normal file
Binary file not shown.
53
OpenJPEG/lib/openjpeg-2.3/OpenJPEGConfig.cmake
Normal file
53
OpenJPEG/lib/openjpeg-2.3/OpenJPEGConfig.cmake
Normal file
@ -0,0 +1,53 @@
|
||||
#-----------------------------------------------------------------------------
|
||||
#
|
||||
# OPENJPEGConfig.cmake - CMake configuration file for external projects.
|
||||
#
|
||||
# This file is configured by OPENJPEG and used by the UseOPENJPEG.cmake
|
||||
# module to load OPENJPEG's settings for an external project.
|
||||
|
||||
# The OPENJPEG version number.
|
||||
set(OPENJPEG_MAJOR_VERSION "2")
|
||||
set(OPENJPEG_MINOR_VERSION "3")
|
||||
set(OPENJPEG_BUILD_VERSION "1")
|
||||
|
||||
# The libraries.
|
||||
set(OPENJPEG_LIBRARIES "openjp2")
|
||||
|
||||
# The CMake macros dir.
|
||||
set(OPENJPEG_CMAKE_DIR "lib/openjpeg-2.3")
|
||||
|
||||
# The configuration options.
|
||||
set(OPENJPEG_BUILD_SHARED_LIBS "ON")
|
||||
|
||||
# The "use" file.
|
||||
set(OPENJPEG_USE_FILE "")
|
||||
|
||||
get_filename_component(SELF_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
|
||||
if(EXISTS ${SELF_DIR}/OpenJPEGTargets.cmake)
|
||||
# This is an install tree
|
||||
include(${SELF_DIR}/OpenJPEGTargets.cmake)
|
||||
|
||||
# We find a relative path from the PKG directory to header files.
|
||||
set(PKG_DIR "C:/Program Files/OPENJPEG/lib/openjpeg-2.3")
|
||||
set(INC_DIR "C:/Program Files/OPENJPEG/include/openjpeg-2.3")
|
||||
file(RELATIVE_PATH PKG_TO_INC_RPATH "${PKG_DIR}" "${INC_DIR}")
|
||||
|
||||
get_filename_component(OPENJPEG_INCLUDE_DIRS "${SELF_DIR}/${PKG_TO_INC_RPATH}" ABSOLUTE)
|
||||
|
||||
else()
|
||||
if(EXISTS ${SELF_DIR}/OpenJPEGExports.cmake)
|
||||
# This is a build tree
|
||||
set( OPENJPEG_INCLUDE_DIRS )
|
||||
|
||||
include(${SELF_DIR}/OpenJPEGExports.cmake)
|
||||
|
||||
else()
|
||||
message(FATAL_ERROR "ooops")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(OPENJPEG_USE_FILE ${SELF_DIR}/UseOPENJPEG.cmake)
|
||||
|
||||
# Backward compatible part:
|
||||
set(OPENJPEG_FOUND TRUE)
|
||||
|
46
OpenJPEG/lib/openjpeg-2.3/OpenJPEGTargets-release.cmake
Normal file
46
OpenJPEG/lib/openjpeg-2.3/OpenJPEGTargets-release.cmake
Normal file
@ -0,0 +1,46 @@
|
||||
#----------------------------------------------------------------
|
||||
# Generated CMake target import file for configuration "Release".
|
||||
#----------------------------------------------------------------
|
||||
|
||||
# Commands may need to know the format version.
|
||||
set(CMAKE_IMPORT_FILE_VERSION 1)
|
||||
|
||||
# Import target "openjp2" for configuration "Release"
|
||||
set_property(TARGET openjp2 APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
|
||||
set_target_properties(openjp2 PROPERTIES
|
||||
IMPORTED_IMPLIB_RELEASE "${_IMPORT_PREFIX}/lib/openjp2.lib"
|
||||
IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/bin/openjp2.dll"
|
||||
)
|
||||
|
||||
list(APPEND _IMPORT_CHECK_TARGETS openjp2 )
|
||||
list(APPEND _IMPORT_CHECK_FILES_FOR_openjp2 "${_IMPORT_PREFIX}/lib/openjp2.lib" "${_IMPORT_PREFIX}/bin/openjp2.dll" )
|
||||
|
||||
# Import target "opj_decompress" for configuration "Release"
|
||||
set_property(TARGET opj_decompress APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
|
||||
set_target_properties(opj_decompress PROPERTIES
|
||||
IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/bin/opj_decompress.exe"
|
||||
)
|
||||
|
||||
list(APPEND _IMPORT_CHECK_TARGETS opj_decompress )
|
||||
list(APPEND _IMPORT_CHECK_FILES_FOR_opj_decompress "${_IMPORT_PREFIX}/bin/opj_decompress.exe" )
|
||||
|
||||
# Import target "opj_compress" for configuration "Release"
|
||||
set_property(TARGET opj_compress APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
|
||||
set_target_properties(opj_compress PROPERTIES
|
||||
IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/bin/opj_compress.exe"
|
||||
)
|
||||
|
||||
list(APPEND _IMPORT_CHECK_TARGETS opj_compress )
|
||||
list(APPEND _IMPORT_CHECK_FILES_FOR_opj_compress "${_IMPORT_PREFIX}/bin/opj_compress.exe" )
|
||||
|
||||
# Import target "opj_dump" for configuration "Release"
|
||||
set_property(TARGET opj_dump APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
|
||||
set_target_properties(opj_dump PROPERTIES
|
||||
IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/bin/opj_dump.exe"
|
||||
)
|
||||
|
||||
list(APPEND _IMPORT_CHECK_TARGETS opj_dump )
|
||||
list(APPEND _IMPORT_CHECK_FILES_FOR_opj_dump "${_IMPORT_PREFIX}/bin/opj_dump.exe" )
|
||||
|
||||
# Commands beyond this point should not need to know the version.
|
||||
set(CMAKE_IMPORT_FILE_VERSION)
|
98
OpenJPEG/lib/openjpeg-2.3/OpenJPEGTargets.cmake
Normal file
98
OpenJPEG/lib/openjpeg-2.3/OpenJPEGTargets.cmake
Normal file
@ -0,0 +1,98 @@
|
||||
# Generated by CMake
|
||||
|
||||
if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" LESS 2.5)
|
||||
message(FATAL_ERROR "CMake >= 2.6.0 required")
|
||||
endif()
|
||||
cmake_policy(PUSH)
|
||||
cmake_policy(VERSION 2.6)
|
||||
#----------------------------------------------------------------
|
||||
# Generated CMake target import file.
|
||||
#----------------------------------------------------------------
|
||||
|
||||
# Commands may need to know the format version.
|
||||
set(CMAKE_IMPORT_FILE_VERSION 1)
|
||||
|
||||
# Protect against multiple inclusion, which would fail when already imported targets are added once more.
|
||||
set(_targetsDefined)
|
||||
set(_targetsNotDefined)
|
||||
set(_expectedTargets)
|
||||
foreach(_expectedTarget openjp2 opj_decompress opj_compress opj_dump)
|
||||
list(APPEND _expectedTargets ${_expectedTarget})
|
||||
if(NOT TARGET ${_expectedTarget})
|
||||
list(APPEND _targetsNotDefined ${_expectedTarget})
|
||||
endif()
|
||||
if(TARGET ${_expectedTarget})
|
||||
list(APPEND _targetsDefined ${_expectedTarget})
|
||||
endif()
|
||||
endforeach()
|
||||
if("${_targetsDefined}" STREQUAL "${_expectedTargets}")
|
||||
unset(_targetsDefined)
|
||||
unset(_targetsNotDefined)
|
||||
unset(_expectedTargets)
|
||||
set(CMAKE_IMPORT_FILE_VERSION)
|
||||
cmake_policy(POP)
|
||||
return()
|
||||
endif()
|
||||
if(NOT "${_targetsDefined}" STREQUAL "")
|
||||
message(FATAL_ERROR "Some (but not all) targets in this export set were already defined.\nTargets Defined: ${_targetsDefined}\nTargets not yet defined: ${_targetsNotDefined}\n")
|
||||
endif()
|
||||
unset(_targetsDefined)
|
||||
unset(_targetsNotDefined)
|
||||
unset(_expectedTargets)
|
||||
|
||||
|
||||
# Compute the installation prefix relative to this file.
|
||||
get_filename_component(_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_FILE}" PATH)
|
||||
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
|
||||
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
|
||||
if(_IMPORT_PREFIX STREQUAL "/")
|
||||
set(_IMPORT_PREFIX "")
|
||||
endif()
|
||||
|
||||
# Create imported target openjp2
|
||||
add_library(openjp2 SHARED IMPORTED)
|
||||
|
||||
# Create imported target opj_decompress
|
||||
add_executable(opj_decompress IMPORTED)
|
||||
|
||||
# Create imported target opj_compress
|
||||
add_executable(opj_compress IMPORTED)
|
||||
|
||||
# Create imported target opj_dump
|
||||
add_executable(opj_dump IMPORTED)
|
||||
|
||||
# Load information for each installed configuration.
|
||||
get_filename_component(_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
|
||||
file(GLOB CONFIG_FILES "${_DIR}/OpenJPEGTargets-*.cmake")
|
||||
foreach(f ${CONFIG_FILES})
|
||||
include(${f})
|
||||
endforeach()
|
||||
|
||||
# Cleanup temporary variables.
|
||||
set(_IMPORT_PREFIX)
|
||||
|
||||
# Loop over all imported files and verify that they actually exist
|
||||
foreach(target ${_IMPORT_CHECK_TARGETS} )
|
||||
foreach(file ${_IMPORT_CHECK_FILES_FOR_${target}} )
|
||||
if(NOT EXISTS "${file}" )
|
||||
message(FATAL_ERROR "The imported target \"${target}\" references the file
|
||||
\"${file}\"
|
||||
but this file does not exist. Possible reasons include:
|
||||
* The file was deleted, renamed, or moved to another location.
|
||||
* An install or uninstall procedure did not complete successfully.
|
||||
* The installation package was faulty and contained
|
||||
\"${CMAKE_CURRENT_LIST_FILE}\"
|
||||
but not all the files it references.
|
||||
")
|
||||
endif()
|
||||
endforeach()
|
||||
unset(_IMPORT_CHECK_FILES_FOR_${target})
|
||||
endforeach()
|
||||
unset(_IMPORT_CHECK_TARGETS)
|
||||
|
||||
# This file does not depend on other imported targets which have
|
||||
# been exported from the same project but in a separate export set.
|
||||
|
||||
# Commands beyond this point should not need to know the version.
|
||||
set(CMAKE_IMPORT_FILE_VERSION)
|
||||
cmake_policy(POP)
|
@ -55,7 +55,8 @@ SOURCES += \
|
||||
sources/pdfrenderingerrorswidget.cpp \
|
||||
sources/pdffunction.cpp \
|
||||
sources/pdfnametounicode.cpp \
|
||||
sources/pdffont.cpp
|
||||
sources/pdffont.cpp \
|
||||
sources/pdfimage.cpp
|
||||
|
||||
HEADERS += \
|
||||
sources/pdfobject.h \
|
||||
@ -84,7 +85,8 @@ HEADERS += \
|
||||
sources/pdffunction.h \
|
||||
sources/pdfnametounicode.h \
|
||||
sources/pdffont.h \
|
||||
sources/pdfexception.h
|
||||
sources/pdfexception.h \
|
||||
sources/pdfimage.h
|
||||
|
||||
FORMS += \
|
||||
sources/pdfrenderingerrorswidget.ui
|
||||
@ -99,6 +101,21 @@ freetype_lib.files = $$PWD/../FreeType/freetype.dll
|
||||
freetype_lib.path = $$DESTDIR
|
||||
INSTALLS += freetype_lib
|
||||
|
||||
# Link to OpenJPEG library
|
||||
LIBS += -L$$PWD/../OpenJPEG/lib/ -lopenjp2
|
||||
INCLUDEPATH += $$PWD/../OpenJPEG/include/openjpeg-2.3
|
||||
DEPENDPATH += $$PWD/../OpenJPEG/include/openjpeg-2.3
|
||||
|
||||
# Add OpenJPEG to installations
|
||||
openjpeg_lib.files = $$PWD/../OpenJPEG/openjp2.dll
|
||||
openjpeg_lib.path = $$DESTDIR
|
||||
INSTALLS += openjpeg_lib
|
||||
|
||||
# Link to Independent JPEG Groups libjpeg
|
||||
LIBS += -L$$PWD/../libjpeg/bin/ -ljpeg
|
||||
INCLUDEPATH += $$PWD/../libjpeg/include
|
||||
DEPENDPATH += $$PWD/../libjpeg/include
|
||||
|
||||
# ensure debug info even for RELEASE build
|
||||
CONFIG += force_debug_info
|
||||
|
||||
|
@ -85,6 +85,54 @@ size_t PDFDeviceCMYKColorSpace::getColorComponentCount() const
|
||||
return 4;
|
||||
}
|
||||
|
||||
QImage PDFAbstractColorSpace::getImage(const PDFImageData& imageData) const
|
||||
{
|
||||
if (imageData.isValid())
|
||||
{
|
||||
QImage image(imageData.getWidth(), imageData.getHeight(), QImage::Format_RGB888);
|
||||
image.fill(QColor(Qt::white));
|
||||
|
||||
// TODO: Implement images with bits different than 8
|
||||
Q_ASSERT(imageData.getBitsPerComponent() == 8);
|
||||
unsigned int componentCount = imageData.getComponents();
|
||||
|
||||
if (componentCount != getColorComponentCount())
|
||||
{
|
||||
throw PDFParserException(PDFTranslationContext::tr("Invalid colors for color space. Color space has %1 colors. Provided color count is %4.").arg(getColorComponentCount()).arg(componentCount));
|
||||
}
|
||||
|
||||
PDFColor color;
|
||||
color.resize(componentCount);
|
||||
|
||||
for (unsigned int i = 0, rowCount = imageData.getHeight(); i < rowCount; ++i)
|
||||
{
|
||||
const unsigned char* rowData = imageData.getRow(i);
|
||||
unsigned char* outputLine = image.scanLine(i);
|
||||
|
||||
for (unsigned int j = 0; j < imageData.getWidth(); ++j)
|
||||
{
|
||||
const unsigned char* currentData = rowData + (j * componentCount);
|
||||
for (unsigned int k = 0; k < componentCount; ++k)
|
||||
{
|
||||
constexpr const double COEFFICIENT = 1.0 / 255.0;
|
||||
color[k] = currentData[k] * COEFFICIENT;
|
||||
}
|
||||
|
||||
QColor transformedColor = getColor(color);
|
||||
QRgb rgb = transformedColor.rgb();
|
||||
|
||||
*outputLine++ = qRed(rgb);
|
||||
*outputLine++ = qGreen(rgb);
|
||||
*outputLine++ = qBlue(rgb);
|
||||
}
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
return QImage();
|
||||
}
|
||||
|
||||
PDFColorSpacePointer PDFAbstractColorSpace::createColorSpace(const PDFDictionary* colorSpaceDictionary,
|
||||
const PDFDocument* document,
|
||||
const PDFObject& colorSpace)
|
||||
@ -708,4 +756,12 @@ PDFColorSpacePointer PDFSeparationColorSpace::createSeparationColorSpace(const P
|
||||
return PDFColorSpacePointer(new PDFSeparationColorSpace(qMove(colorName), qMove(alternateColorSpace), qMove(tintTransform)));
|
||||
}
|
||||
|
||||
const unsigned char* PDFImageData::getRow(unsigned int rowIndex) const
|
||||
{
|
||||
const unsigned char* data = reinterpret_cast<const unsigned char*>(m_data.constData());
|
||||
|
||||
Q_ASSERT(rowIndex < m_height);
|
||||
return data + (rowIndex * m_stride);
|
||||
}
|
||||
|
||||
} // namespace pdf
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (C) 2019 Jakub Melka
|
||||
// Copyright (C) 2019 Jakub Melka
|
||||
//
|
||||
// This file is part of PdfForQt.
|
||||
//
|
||||
@ -22,6 +22,7 @@
|
||||
#include "pdffunction.h"
|
||||
|
||||
#include <QColor>
|
||||
#include <QImage>
|
||||
#include <QSharedPointer>
|
||||
|
||||
namespace pdf
|
||||
@ -70,6 +71,57 @@ static constexpr const char* ICCBASED_ALTERNATE = "Alternate";
|
||||
static constexpr const char* ICCBASED_N = "N";
|
||||
static constexpr const char* ICCBASED_RANGE = "Range";
|
||||
|
||||
/// Image raw data - containing data for image. Image data are row-ordered, and by components.
|
||||
/// So the row can be for 3-components RGB like 'RGBRGBRGB...RGB', where size of row in bytes is 3 * width of image.
|
||||
class PDFImageData
|
||||
{
|
||||
public:
|
||||
explicit PDFImageData() :
|
||||
m_components(0),
|
||||
m_bitsPerComponent(0),
|
||||
m_width(0),
|
||||
m_height(0),
|
||||
m_stride(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
explicit inline PDFImageData(unsigned int components,
|
||||
unsigned int bitsPerComponent,
|
||||
unsigned int width,
|
||||
unsigned int height,
|
||||
unsigned int stride,
|
||||
QByteArray data) :
|
||||
m_components(components),
|
||||
m_bitsPerComponent(bitsPerComponent),
|
||||
m_width(width),
|
||||
m_height(height),
|
||||
m_stride(stride),
|
||||
m_data(qMove(data))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
unsigned int getComponents() const { return m_components; }
|
||||
unsigned int getBitsPerComponent() const { return m_bitsPerComponent; }
|
||||
unsigned int getWidth() const { return m_width; }
|
||||
unsigned int getHeight() const { return m_height; }
|
||||
unsigned int getStride() const { return m_stride; }
|
||||
|
||||
bool isValid() const { return m_width && m_height && m_components && m_bitsPerComponent; }
|
||||
|
||||
const unsigned char* getRow(unsigned int rowIndex) const;
|
||||
|
||||
private:
|
||||
unsigned int m_components;
|
||||
unsigned int m_bitsPerComponent;
|
||||
unsigned int m_width;
|
||||
unsigned int m_height;
|
||||
unsigned int m_stride;
|
||||
|
||||
QByteArray m_data;
|
||||
};
|
||||
|
||||
using PDFColor3 = std::array<PDFColorComponent, 3>;
|
||||
|
||||
/// Matrix for color component multiplication (for example, conversion between some color spaces)
|
||||
@ -117,6 +169,7 @@ public:
|
||||
virtual QColor getDefaultColor() const = 0;
|
||||
virtual QColor getColor(const PDFColor& color) const = 0;
|
||||
virtual size_t getColorComponentCount() const = 0;
|
||||
virtual QImage getImage(const PDFImageData& imageData) const;
|
||||
|
||||
/// Parses the desired color space. If desired color space is not found, then exception is thrown.
|
||||
/// If everything is OK, then shared pointer to the new color space is returned.
|
||||
|
@ -430,7 +430,7 @@ void PDFRealizedFontImpl::fillTextSequence(const QByteArray& byteArray, TextSequ
|
||||
if (!glyphIndex)
|
||||
{
|
||||
// Try to obtain glyph index from unicode
|
||||
if (m_face->charmap->encoding == FT_ENCODING_UNICODE)
|
||||
if (m_face->charmap && m_face->charmap->encoding == FT_ENCODING_UNICODE)
|
||||
{
|
||||
glyphIndex = FT_Get_Char_Index(m_face, (*encoding)[static_cast<uint8_t>(byteArray[i])].unicode());
|
||||
}
|
||||
|
356
PdfForQtLib/sources/pdfimage.cpp
Normal file
356
PdfForQtLib/sources/pdfimage.cpp
Normal file
@ -0,0 +1,356 @@
|
||||
// Copyright (C) 2019 Jakub Melka
|
||||
//
|
||||
// This file is part of PdfForQt.
|
||||
//
|
||||
// PdfForQt is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// PdfForQt is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with PDFForQt. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include "pdfimage.h"
|
||||
#include "pdfdocument.h"
|
||||
#include "pdfconstants.h"
|
||||
#include "pdfexception.h"
|
||||
|
||||
#include <openjpeg.h>
|
||||
#include <jpeglib.h>
|
||||
|
||||
namespace pdf
|
||||
{
|
||||
|
||||
struct PDFJPEG2000ImageData
|
||||
{
|
||||
const QByteArray* byteArray = nullptr;
|
||||
OPJ_SIZE_T position = 0;
|
||||
|
||||
static OPJ_SIZE_T read(void* p_buffer, OPJ_SIZE_T p_nb_bytes, void* p_user_data);
|
||||
static OPJ_BOOL seek(OPJ_OFF_T p_nb_bytes, void* p_user_data);
|
||||
static OPJ_OFF_T skip(OPJ_OFF_T p_nb_bytes, void* p_user_data);
|
||||
};
|
||||
|
||||
struct PDFJPEGDCTSource
|
||||
{
|
||||
jpeg_source_mgr sourceManager;
|
||||
const QByteArray* buffer = nullptr;
|
||||
};
|
||||
|
||||
PDFImage PDFImage::createImage(const PDFDocument* document, const PDFStream* stream, PDFColorSpacePointer colorSpace)
|
||||
{
|
||||
PDFImage image;
|
||||
image.m_colorSpace = colorSpace;
|
||||
|
||||
// TODO: Implement ImageMask
|
||||
// TODO: Implement Mask
|
||||
// TODO: Implement Decode
|
||||
// TODO: Implement SMask
|
||||
// TODO: Implement SMaskInData
|
||||
|
||||
const PDFDictionary* dictionary = stream->getDictionary();
|
||||
QByteArray content = document->getDecodedStream(stream);
|
||||
PDFDocumentDataLoaderDecorator loader(document);
|
||||
|
||||
if (content.isEmpty())
|
||||
{
|
||||
throw PDFParserException(PDFTranslationContext::tr("Image has not data."));
|
||||
}
|
||||
|
||||
// Retrieve filters
|
||||
PDFObject filters;
|
||||
if (dictionary->hasKey(PDF_STREAM_DICT_FILTER))
|
||||
{
|
||||
filters = document->getObject(dictionary->get(PDF_STREAM_DICT_FILTER));
|
||||
}
|
||||
else if (dictionary->hasKey(PDF_STREAM_DICT_FILE_FILTER))
|
||||
{
|
||||
filters = document->getObject(dictionary->get(PDF_STREAM_DICT_FILE_FILTER));
|
||||
}
|
||||
|
||||
// Retrieve filter parameters
|
||||
PDFObject filterParameters;
|
||||
if (dictionary->hasKey(PDF_STREAM_DICT_DECODE_PARMS))
|
||||
{
|
||||
filterParameters = document->getObject(dictionary->get(PDF_STREAM_DICT_DECODE_PARMS));
|
||||
}
|
||||
else if (dictionary->hasKey(PDF_STREAM_DICT_FDECODE_PARMS))
|
||||
{
|
||||
filterParameters = document->getObject(dictionary->get(PDF_STREAM_DICT_FDECODE_PARMS));
|
||||
}
|
||||
|
||||
QByteArray imageFilterName;
|
||||
if (filters.isName())
|
||||
{
|
||||
imageFilterName = filters.getString();
|
||||
}
|
||||
else if (filters.isArray())
|
||||
{
|
||||
const PDFArray* filterArray = filters.getArray();
|
||||
const size_t filterCount = filterArray->getCount();
|
||||
|
||||
if (filterCount)
|
||||
{
|
||||
const PDFObject& object = document->getObject(filterArray->getItem(filterCount - 1));
|
||||
if (object.isName())
|
||||
{
|
||||
imageFilterName = object.getString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (imageFilterName == "DCTDecode" || imageFilterName == "DCT")
|
||||
{
|
||||
// TODO: Check, if mutex is needed
|
||||
// Used library is not thread safe. We must use a mutex!
|
||||
static QMutex mutex;
|
||||
QMutexLocker lock(&mutex);
|
||||
|
||||
int colorTransform = loader.readIntegerFromDictionary(dictionary, "ColorTransform", -1);
|
||||
|
||||
jpeg_decompress_struct codec;
|
||||
jpeg_error_mgr errorManager;
|
||||
std::memset(&codec, 0, sizeof(jpeg_decompress_struct));
|
||||
std::memset(&errorManager, 0, sizeof(errorManager));
|
||||
|
||||
PDFJPEGDCTSource source;
|
||||
source.buffer = &content;
|
||||
std::memset(&source.sourceManager, 0, sizeof(jpeg_source_mgr));
|
||||
|
||||
auto errorMethod = [](j_common_ptr ptr)
|
||||
{
|
||||
char buffer[JMSG_LENGTH_MAX] = { };
|
||||
(ptr->err->format_message)(ptr, buffer);
|
||||
|
||||
jpeg_destroy(ptr);
|
||||
throw PDFParserException(PDFTranslationContext::tr("Error reading JPEG (DCT) image: %1.").arg(QString::fromLatin1(buffer)));
|
||||
};
|
||||
|
||||
auto fillInputBufferMethod = [](j_decompress_ptr decompress) -> boolean
|
||||
{
|
||||
PDFJPEGDCTSource* source = reinterpret_cast<PDFJPEGDCTSource*>(decompress->src);
|
||||
|
||||
if (!source->sourceManager.next_input_byte)
|
||||
{
|
||||
const QByteArray* buffer = source->buffer;
|
||||
source->sourceManager.next_input_byte = reinterpret_cast<const JOCTET*>(buffer->constData());
|
||||
source->sourceManager.bytes_in_buffer = buffer->size();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
};
|
||||
|
||||
auto skipInputDataMethod = [](j_decompress_ptr decompress, long num_bytes)
|
||||
{
|
||||
PDFJPEGDCTSource* source = reinterpret_cast<PDFJPEGDCTSource*>(decompress->src);
|
||||
|
||||
const size_t skippedBytes = qMin(source->sourceManager.bytes_in_buffer, static_cast<size_t>(num_bytes));
|
||||
source->sourceManager.next_input_byte += skippedBytes;
|
||||
source->sourceManager.bytes_in_buffer -= skippedBytes;
|
||||
};
|
||||
|
||||
source.sourceManager.bytes_in_buffer = 0;
|
||||
source.sourceManager.next_input_byte = nullptr;
|
||||
source.sourceManager.init_source = [](j_decompress_ptr) { };
|
||||
source.sourceManager.fill_input_buffer = fillInputBufferMethod;
|
||||
source.sourceManager.skip_input_data = skipInputDataMethod;
|
||||
source.sourceManager.resync_to_restart = jpeg_resync_to_restart;
|
||||
source.sourceManager.term_source = [](j_decompress_ptr) { };
|
||||
|
||||
jpeg_std_error(&errorManager);
|
||||
errorManager.error_exit = errorMethod;
|
||||
codec.err = &errorManager;
|
||||
|
||||
jpeg_create_decompress(&codec);
|
||||
codec.src = reinterpret_cast<jpeg_source_mgr*>(&source);
|
||||
|
||||
if (jpeg_read_header(&codec, TRUE) == JPEG_HEADER_OK)
|
||||
{
|
||||
// Determine color transform
|
||||
if (colorTransform == -1 && codec.saw_Adobe_marker)
|
||||
{
|
||||
colorTransform = codec.Adobe_transform;
|
||||
}
|
||||
|
||||
// Set the input transform
|
||||
if (colorTransform > -1)
|
||||
{
|
||||
switch (codec.num_components)
|
||||
{
|
||||
case 3:
|
||||
{
|
||||
codec.jpeg_color_space = colorTransform ? JCS_YCbCr : JCS_RGB;
|
||||
break;
|
||||
}
|
||||
|
||||
case 4:
|
||||
{
|
||||
codec.jpeg_color_space = colorTransform ? JCS_YCCK : JCS_CMYK;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
jpeg_start_decompress(&codec);
|
||||
|
||||
const JDIMENSION rowStride = codec.output_width * codec.output_components;
|
||||
JSAMPARRAY samples = codec.mem->alloc_sarray(reinterpret_cast<j_common_ptr>(&codec), JPOOL_IMAGE, rowStride, 1);
|
||||
JDIMENSION scanLineCount = codec.output_height;
|
||||
|
||||
const unsigned int width = codec.output_width;
|
||||
const unsigned int height = codec.output_height;
|
||||
const unsigned int components = codec.output_components;
|
||||
const unsigned int bitsPerComponent = 8;
|
||||
QByteArray buffer(rowStride * height, 0);
|
||||
JSAMPROW rowData = reinterpret_cast<JSAMPROW>(buffer.data());
|
||||
|
||||
while (scanLineCount)
|
||||
{
|
||||
JDIMENSION readCount = jpeg_read_scanlines(&codec, samples, 1);
|
||||
std::memcpy(rowData, samples[0], rowStride);
|
||||
scanLineCount -= readCount;
|
||||
rowData += rowStride;
|
||||
}
|
||||
|
||||
jpeg_finish_decompress(&codec);
|
||||
image.m_imageData = PDFImageData(components, bitsPerComponent, width, height, rowStride, qMove(buffer));
|
||||
}
|
||||
|
||||
jpeg_destroy_decompress(&codec);
|
||||
}
|
||||
else if (imageFilterName == "JPXDecode")
|
||||
{
|
||||
PDFJPEG2000ImageData imageData;
|
||||
imageData.byteArray = &content;
|
||||
imageData.position = 0;
|
||||
|
||||
opj_stream_t* stream = opj_stream_default_create(OPJ_TRUE);
|
||||
opj_stream_set_user_data(stream, &imageData, nullptr);
|
||||
opj_stream_set_user_data_length(stream, sizeof(PDFJPEG2000ImageData));
|
||||
opj_stream_set_read_function(stream, &PDFJPEG2000ImageData::read);
|
||||
opj_stream_set_seek_function(stream, &PDFJPEG2000ImageData::seek);
|
||||
opj_stream_set_skip_function(stream, &PDFJPEG2000ImageData::skip);
|
||||
|
||||
opj_dparameters_t decompressParameters;
|
||||
opj_set_default_decoder_parameters(&decompressParameters);
|
||||
|
||||
CODEC_FORMAT formats[] = { OPJ_CODEC_J2K, OPJ_CODEC_JPT, OPJ_CODEC_JP2, OPJ_CODEC_JPP, OPJ_CODEC_JPX };
|
||||
for (CODEC_FORMAT format : formats)
|
||||
{
|
||||
opj_codec_t* codec = opj_create_decompress(format);
|
||||
|
||||
if (!codec)
|
||||
{
|
||||
// Codec is not present
|
||||
continue;
|
||||
}
|
||||
|
||||
// Setup the decoder
|
||||
opj_setup_decoder(codec, &decompressParameters);
|
||||
|
||||
// Try to read the header
|
||||
opj_image_t* image = nullptr;
|
||||
if (opj_read_header(stream, codec, &image))
|
||||
{
|
||||
if (opj_set_decode_area(codec, image, decompressParameters.DA_x0, decompressParameters.DA_y0, decompressParameters.DA_x1, decompressParameters.DA_y1))
|
||||
{
|
||||
if (opj_decode(codec, stream, image))
|
||||
{
|
||||
if (opj_end_decompress(codec, stream))
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
opj_destroy_codec(codec);
|
||||
}
|
||||
|
||||
opj_stream_destroy(stream);
|
||||
stream = nullptr;
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
QImage PDFImage::getImage() const
|
||||
{
|
||||
if (m_colorSpace)
|
||||
{
|
||||
return m_colorSpace->getImage(m_imageData);
|
||||
}
|
||||
|
||||
return QImage();
|
||||
}
|
||||
|
||||
OPJ_SIZE_T PDFJPEG2000ImageData::read(void* p_buffer, OPJ_SIZE_T p_nb_bytes, void* p_user_data)
|
||||
{
|
||||
PDFJPEG2000ImageData* data = reinterpret_cast<PDFJPEG2000ImageData*>(p_user_data);
|
||||
|
||||
// Remaining length
|
||||
OPJ_OFF_T length = static_cast<OPJ_OFF_T>(data->byteArray->size()) - data->position;
|
||||
|
||||
if (length < 0)
|
||||
{
|
||||
length = 0;
|
||||
}
|
||||
|
||||
if (length > static_cast<OPJ_OFF_T>(p_nb_bytes))
|
||||
{
|
||||
length = static_cast<OPJ_OFF_T>(p_nb_bytes);
|
||||
}
|
||||
|
||||
if (length > 0)
|
||||
{
|
||||
std::memcpy(p_buffer, data->byteArray->constData() + data->position, length);
|
||||
data->position += length;
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
OPJ_BOOL PDFJPEG2000ImageData::seek(OPJ_OFF_T p_nb_bytes, void* p_user_data)
|
||||
{
|
||||
PDFJPEG2000ImageData* data = reinterpret_cast<PDFJPEG2000ImageData*>(p_user_data);
|
||||
|
||||
if (p_nb_bytes >= data->byteArray->size())
|
||||
{
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
|
||||
data->position = p_nb_bytes;
|
||||
return OPJ_TRUE;
|
||||
}
|
||||
|
||||
OPJ_OFF_T PDFJPEG2000ImageData::skip(OPJ_OFF_T p_nb_bytes, void* p_user_data)
|
||||
{
|
||||
PDFJPEG2000ImageData* data = reinterpret_cast<PDFJPEG2000ImageData*>(p_user_data);
|
||||
|
||||
// Remaining length
|
||||
OPJ_OFF_T length = static_cast<OPJ_OFF_T>(data->byteArray->size()) - data->position;
|
||||
|
||||
if (length < 0)
|
||||
{
|
||||
length = 0;
|
||||
}
|
||||
|
||||
if (length > static_cast<OPJ_OFF_T>(p_nb_bytes))
|
||||
{
|
||||
length = static_cast<OPJ_OFF_T>(p_nb_bytes);
|
||||
}
|
||||
|
||||
data->position += length;
|
||||
return length;
|
||||
}
|
||||
|
||||
} // namespace pdf
|
54
PdfForQtLib/sources/pdfimage.h
Normal file
54
PdfForQtLib/sources/pdfimage.h
Normal file
@ -0,0 +1,54 @@
|
||||
// Copyright (C) 2019 Jakub Melka
|
||||
//
|
||||
// This file is part of PdfForQt.
|
||||
//
|
||||
// PdfForQt is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// PdfForQt is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with PDFForQt. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef PDFIMAGE_H
|
||||
#define PDFIMAGE_H
|
||||
|
||||
#include "pdfcolorspaces.h"
|
||||
|
||||
#include <QByteArray>
|
||||
|
||||
class QByteArray;
|
||||
|
||||
namespace pdf
|
||||
{
|
||||
class PDFStream;
|
||||
class PDFDocument;
|
||||
|
||||
class PDFImage
|
||||
{
|
||||
public:
|
||||
|
||||
/// Creates image from the content and the dictionary. If image can't be created, then exception is thrown.
|
||||
/// \param document Document
|
||||
/// \param stream Stream with image
|
||||
/// \param colorSpace Color space of the image
|
||||
static PDFImage createImage(const PDFDocument* document, const PDFStream* stream, PDFColorSpacePointer colorSpace);
|
||||
|
||||
/// Returns image transformed from image data and color space
|
||||
QImage getImage() const;
|
||||
|
||||
private:
|
||||
PDFImage() = default;
|
||||
|
||||
PDFImageData m_imageData;
|
||||
PDFColorSpacePointer m_colorSpace;
|
||||
};
|
||||
|
||||
} // namespace pdf
|
||||
|
||||
#endif // PDFIMAGE_H
|
@ -18,6 +18,7 @@
|
||||
#include "pdfpagecontentprocessor.h"
|
||||
#include "pdfdocument.h"
|
||||
#include "pdfexception.h"
|
||||
#include "pdfimage.h"
|
||||
|
||||
namespace pdf
|
||||
{
|
||||
@ -156,6 +157,7 @@ PDFPageContentProcessor::PDFPageContentProcessor(const PDFPage* page, const PDFD
|
||||
m_fontCache(fontCache),
|
||||
m_colorSpaceDictionary(nullptr),
|
||||
m_fontDictionary(nullptr),
|
||||
m_xobjectDictionary(nullptr),
|
||||
m_textBeginEndState(0)
|
||||
{
|
||||
Q_ASSERT(page);
|
||||
@ -178,6 +180,7 @@ PDFPageContentProcessor::PDFPageContentProcessor(const PDFPage* page, const PDFD
|
||||
|
||||
m_colorSpaceDictionary = getDictionary(COLOR_SPACE_DICTIONARY);
|
||||
m_fontDictionary = getDictionary("Font");
|
||||
m_xobjectDictionary = getDictionary("XObject");
|
||||
}
|
||||
|
||||
PDFPageContentProcessor::~PDFPageContentProcessor()
|
||||
@ -277,6 +280,11 @@ void PDFPageContentProcessor::performClipping(const QPainterPath& path, Qt::Fill
|
||||
Q_UNUSED(fillRule);
|
||||
}
|
||||
|
||||
void PDFPageContentProcessor::performImagePainting(const QImage& image)
|
||||
{
|
||||
Q_UNUSED(image);
|
||||
}
|
||||
|
||||
void PDFPageContentProcessor::performUpdateGraphicsState(const PDFPageContentProcessorState& state)
|
||||
{
|
||||
if (state.getStateFlags().testFlag(PDFPageContentProcessorState::StateTextFont) ||
|
||||
@ -738,6 +746,13 @@ void PDFPageContentProcessor::processCommand(const QByteArray& command)
|
||||
break;
|
||||
}
|
||||
|
||||
case Operator::PaintXObject:
|
||||
{
|
||||
// Do, paint the X Object (image, form, ...)
|
||||
invokeOperator(&PDFPageContentProcessor::operatorPaintXObject);
|
||||
break;
|
||||
}
|
||||
|
||||
case Operator::Invalid:
|
||||
{
|
||||
m_errorList.append(PDFRenderError(RenderErrorType::Error, PDFTranslationContext::tr("Unknown operator '%1'.").arg(QString::fromLatin1(command))));
|
||||
@ -1752,6 +1767,64 @@ void PDFPageContentProcessor::operatorTextSetSpacingAndShowText(PDFReal t_w, PDF
|
||||
operatorTextNextLineShowText(qMove(text));
|
||||
}
|
||||
|
||||
void PDFPageContentProcessor::operatorPaintXObject(PDFPageContentProcessor::PDFOperandName name)
|
||||
{
|
||||
if (m_xobjectDictionary)
|
||||
{
|
||||
const PDFObject& object = m_document->getObject(m_xobjectDictionary->get(name.name));
|
||||
if (object.isStream())
|
||||
{
|
||||
const PDFStream* stream = object.getStream();
|
||||
const PDFDictionary* streamDictionary = stream->getDictionary();
|
||||
|
||||
PDFDocumentDataLoaderDecorator loader(m_document);
|
||||
QByteArray subtype = loader.readNameFromDictionary(streamDictionary, "Subtype");
|
||||
if (subtype == "Image")
|
||||
{
|
||||
PDFColorSpacePointer colorSpace;
|
||||
|
||||
if (streamDictionary->hasKey("ColorSpace"))
|
||||
{
|
||||
const PDFObject& colorSpaceObject = m_document->getObject(streamDictionary->get("ColorSpace"));
|
||||
if (colorSpaceObject.isName() || colorSpaceObject.isArray())
|
||||
{
|
||||
colorSpace = PDFAbstractColorSpace::createColorSpace(m_colorSpaceDictionary, m_document, colorSpaceObject);
|
||||
}
|
||||
else if (!colorSpaceObject.isNull())
|
||||
{
|
||||
throw PDFRendererException(RenderErrorType::Error, PDFTranslationContext::tr("Invalid color space of the image."));
|
||||
}
|
||||
}
|
||||
|
||||
PDFImage pdfImage = PDFImage::createImage(m_document, stream, qMove(colorSpace));
|
||||
QImage image = pdfImage.getImage();
|
||||
|
||||
if (!image.isNull())
|
||||
{
|
||||
performImagePainting(image);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw PDFRendererException(RenderErrorType::Error, PDFTranslationContext::tr("Can't decode the image."));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: Handle another XObjects
|
||||
throw PDFRendererException(RenderErrorType::NotImplemented, PDFTranslationContext::tr("Unknown XObject type '%1'.").arg(QString::fromLatin1(subtype)));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw PDFRendererException(RenderErrorType::Error, PDFTranslationContext::tr("Invalid format of XObject. Dictionary expected."));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw PDFRendererException(RenderErrorType::Error, PDFTranslationContext::tr("XObject resource dictionary not found."));
|
||||
}
|
||||
}
|
||||
|
||||
void PDFPageContentProcessor::drawText(const TextSequence& textSequence)
|
||||
{
|
||||
if (textSequence.items.empty())
|
||||
|
@ -355,6 +355,11 @@ protected:
|
||||
/// clip along the path (intersect with current clipping path).
|
||||
virtual void performClipping(const QPainterPath& path, Qt::FillRule fillRule);
|
||||
|
||||
/// This function has to be implemented in the client drawing implementation, it should
|
||||
/// draw the image.
|
||||
/// \param image Image to be painted
|
||||
virtual void performImagePainting(const QImage& image);
|
||||
|
||||
/// This function has to be implemented in the client drawing implementation, it should
|
||||
/// update the device according to the graphic state change. The flags are set when
|
||||
/// the value differs from the previous graphic state.
|
||||
@ -554,6 +559,9 @@ private:
|
||||
void operatorTextNextLineShowText(PDFOperandString text); ///< ', move to the next line and show text ("string '" is equivalent to "T* string Tj")
|
||||
void operatorTextSetSpacingAndShowText(PDFReal t_w, PDFReal t_c, PDFOperandString text); ///< ", move to the next line, set spacing and show text (equivalent to sequence "w1 Tw w2 Tc string '")
|
||||
|
||||
// XObject: Do
|
||||
void operatorPaintXObject(PDFOperandName name); ///< Do, paint the X Object (image, form, ...)
|
||||
|
||||
// Draws the text using the text sequence
|
||||
void drawText(const TextSequence& textSequence);
|
||||
|
||||
@ -574,6 +582,7 @@ private:
|
||||
const PDFFontCache* m_fontCache;
|
||||
const PDFDictionary* m_colorSpaceDictionary;
|
||||
const PDFDictionary* m_fontDictionary;
|
||||
const PDFDictionary* m_xobjectDictionary;
|
||||
|
||||
// Default color spaces
|
||||
PDFColorSpacePointer m_deviceGrayColorSpace;
|
||||
|
@ -82,6 +82,25 @@ void PDFPainter::performClipping(const QPainterPath& path, Qt::FillRule fillRule
|
||||
m_painter->setClipPath(path, Qt::IntersectClip);
|
||||
}
|
||||
|
||||
void PDFPainter::performImagePainting(const QImage& image)
|
||||
{
|
||||
m_painter->save();
|
||||
|
||||
// TODO: Draw smooth images
|
||||
QMatrix imageTransform(1.0 / image.width(), 0, 0, 1.0 / image.height(), 0, 0);
|
||||
QMatrix worldMatrix = imageTransform * m_painter->worldMatrix();
|
||||
|
||||
// Because Qt uses opposite axis direction than PDF, then we must transform the y-axis
|
||||
// to the opposite (so the image is then unchanged)
|
||||
worldMatrix.translate(0, image.height());
|
||||
worldMatrix.scale(1, -1);
|
||||
|
||||
m_painter->setWorldMatrix(worldMatrix);
|
||||
m_painter->drawImage(0, 0, image);
|
||||
|
||||
m_painter->restore();
|
||||
}
|
||||
|
||||
void PDFPainter::performUpdateGraphicsState(const PDFPageContentProcessorState& state)
|
||||
{
|
||||
const PDFPageContentProcessorState::StateFlags flags = state.getStateFlags();
|
||||
|
@ -51,6 +51,7 @@ public:
|
||||
protected:
|
||||
virtual void performPathPainting(const QPainterPath& path, bool stroke, bool fill, bool text, Qt::FillRule fillRule) override;
|
||||
virtual void performClipping(const QPainterPath& path, Qt::FillRule fillRule) override;
|
||||
virtual void performImagePainting(const QImage& image);
|
||||
virtual void performUpdateGraphicsState(const PDFPageContentProcessorState& state) override;
|
||||
virtual void performSaveGraphicState(ProcessOrder order) override;
|
||||
virtual void performRestoreGraphicState(ProcessOrder order) override;
|
||||
|
378
libjpeg/README
Normal file
378
libjpeg/README
Normal file
@ -0,0 +1,378 @@
|
||||
The Independent JPEG Group's JPEG software
|
||||
==========================================
|
||||
|
||||
README for release 9c of 14-Jan-2018
|
||||
====================================
|
||||
|
||||
This distribution contains the ninth public release of the Independent JPEG
|
||||
Group's free JPEG software. You are welcome to redistribute this software and
|
||||
to use it for any purpose, subject to the conditions under LEGAL ISSUES, below.
|
||||
|
||||
This software is the work of Tom Lane, Guido Vollbeding, Philip Gladstone,
|
||||
Bill Allombert, Jim Boucher, Lee Crocker, Bob Friesenhahn, Ben Jackson,
|
||||
Julian Minguillon, Luis Ortiz, George Phillips, Davide Rossi, Ge' Weijers,
|
||||
and other members of the Independent JPEG Group.
|
||||
|
||||
IJG is not affiliated with the ISO/IEC JTC1/SC29/WG1 standards committee
|
||||
(previously known as JPEG, together with ITU-T SG16).
|
||||
|
||||
|
||||
DOCUMENTATION ROADMAP
|
||||
=====================
|
||||
|
||||
This file contains the following sections:
|
||||
|
||||
OVERVIEW General description of JPEG and the IJG software.
|
||||
LEGAL ISSUES Copyright, lack of warranty, terms of distribution.
|
||||
REFERENCES Where to learn more about JPEG.
|
||||
ARCHIVE LOCATIONS Where to find newer versions of this software.
|
||||
ACKNOWLEDGMENTS Special thanks.
|
||||
FILE FORMAT WARS Software *not* to get.
|
||||
TO DO Plans for future IJG releases.
|
||||
|
||||
Other documentation files in the distribution are:
|
||||
|
||||
User documentation:
|
||||
install.txt How to configure and install the IJG software.
|
||||
usage.txt Usage instructions for cjpeg, djpeg, jpegtran,
|
||||
rdjpgcom, and wrjpgcom.
|
||||
*.1 Unix-style man pages for programs (same info as usage.txt).
|
||||
wizard.txt Advanced usage instructions for JPEG wizards only.
|
||||
change.log Version-to-version change highlights.
|
||||
Programmer and internal documentation:
|
||||
libjpeg.txt How to use the JPEG library in your own programs.
|
||||
example.c Sample code for calling the JPEG library.
|
||||
structure.txt Overview of the JPEG library's internal structure.
|
||||
filelist.txt Road map of IJG files.
|
||||
coderules.txt Coding style rules --- please read if you contribute code.
|
||||
|
||||
Please read at least the files install.txt and usage.txt. Some information
|
||||
can also be found in the JPEG FAQ (Frequently Asked Questions) article. See
|
||||
ARCHIVE LOCATIONS below to find out where to obtain the FAQ article.
|
||||
|
||||
If you want to understand how the JPEG code works, we suggest reading one or
|
||||
more of the REFERENCES, then looking at the documentation files (in roughly
|
||||
the order listed) before diving into the code.
|
||||
|
||||
|
||||
OVERVIEW
|
||||
========
|
||||
|
||||
This package contains C software to implement JPEG image encoding, decoding,
|
||||
and transcoding. JPEG (pronounced "jay-peg") is a standardized compression
|
||||
method for full-color and grayscale images.
|
||||
|
||||
This software implements JPEG baseline, extended-sequential, and progressive
|
||||
compression processes. Provision is made for supporting all variants of these
|
||||
processes, although some uncommon parameter settings aren't implemented yet.
|
||||
We have made no provision for supporting the hierarchical or lossless
|
||||
processes defined in the standard.
|
||||
|
||||
We provide a set of library routines for reading and writing JPEG image files,
|
||||
plus two sample applications "cjpeg" and "djpeg", which use the library to
|
||||
perform conversion between JPEG and some other popular image file formats.
|
||||
The library is intended to be reused in other applications.
|
||||
|
||||
In order to support file conversion and viewing software, we have included
|
||||
considerable functionality beyond the bare JPEG coding/decoding capability;
|
||||
for example, the color quantization modules are not strictly part of JPEG
|
||||
decoding, but they are essential for output to colormapped file formats or
|
||||
colormapped displays. These extra functions can be compiled out of the
|
||||
library if not required for a particular application.
|
||||
|
||||
We have also included "jpegtran", a utility for lossless transcoding between
|
||||
different JPEG processes, and "rdjpgcom" and "wrjpgcom", two simple
|
||||
applications for inserting and extracting textual comments in JFIF files.
|
||||
|
||||
The emphasis in designing this software has been on achieving portability and
|
||||
flexibility, while also making it fast enough to be useful. In particular,
|
||||
the software is not intended to be read as a tutorial on JPEG. (See the
|
||||
REFERENCES section for introductory material.) Rather, it is intended to
|
||||
be reliable, portable, industrial-strength code. We do not claim to have
|
||||
achieved that goal in every aspect of the software, but we strive for it.
|
||||
|
||||
We welcome the use of this software as a component of commercial products.
|
||||
No royalty is required, but we do ask for an acknowledgement in product
|
||||
documentation, as described under LEGAL ISSUES.
|
||||
|
||||
|
||||
LEGAL ISSUES
|
||||
============
|
||||
|
||||
In plain English:
|
||||
|
||||
1. We don't promise that this software works. (But if you find any bugs,
|
||||
please let us know!)
|
||||
2. You can use this software for whatever you want. You don't have to pay us.
|
||||
3. You may not pretend that you wrote this software. If you use it in a
|
||||
program, you must acknowledge somewhere in your documentation that
|
||||
you've used the IJG code.
|
||||
|
||||
In legalese:
|
||||
|
||||
The authors make NO WARRANTY or representation, either express or implied,
|
||||
with respect to this software, its quality, accuracy, merchantability, or
|
||||
fitness for a particular purpose. This software is provided "AS IS", and you,
|
||||
its user, assume the entire risk as to its quality and accuracy.
|
||||
|
||||
This software is copyright (C) 1991-2018, Thomas G. Lane, Guido Vollbeding.
|
||||
All Rights Reserved except as specified below.
|
||||
|
||||
Permission is hereby granted to use, copy, modify, and distribute this
|
||||
software (or portions thereof) for any purpose, without fee, subject to these
|
||||
conditions:
|
||||
(1) If any part of the source code for this software is distributed, then this
|
||||
README file must be included, with this copyright and no-warranty notice
|
||||
unaltered; and any additions, deletions, or changes to the original files
|
||||
must be clearly indicated in accompanying documentation.
|
||||
(2) If only executable code is distributed, then the accompanying
|
||||
documentation must state that "this software is based in part on the work of
|
||||
the Independent JPEG Group".
|
||||
(3) Permission for use of this software is granted only if the user accepts
|
||||
full responsibility for any undesirable consequences; the authors accept
|
||||
NO LIABILITY for damages of any kind.
|
||||
|
||||
These conditions apply to any software derived from or based on the IJG code,
|
||||
not just to the unmodified library. If you use our work, you ought to
|
||||
acknowledge us.
|
||||
|
||||
Permission is NOT granted for the use of any IJG author's name or company name
|
||||
in advertising or publicity relating to this software or products derived from
|
||||
it. This software may be referred to only as "the Independent JPEG Group's
|
||||
software".
|
||||
|
||||
We specifically permit and encourage the use of this software as the basis of
|
||||
commercial products, provided that all warranty or liability claims are
|
||||
assumed by the product vendor.
|
||||
|
||||
|
||||
The Unix configuration script "configure" was produced with GNU Autoconf.
|
||||
It is copyright by the Free Software Foundation but is freely distributable.
|
||||
The same holds for its supporting scripts (config.guess, config.sub,
|
||||
ltmain.sh). Another support script, install-sh, is copyright by X Consortium
|
||||
but is also freely distributable.
|
||||
|
||||
The IJG distribution formerly included code to read and write GIF files.
|
||||
To avoid entanglement with the Unisys LZW patent (now expired), GIF reading
|
||||
support has been removed altogether, and the GIF writer has been simplified
|
||||
to produce "uncompressed GIFs". This technique does not use the LZW
|
||||
algorithm; the resulting GIF files are larger than usual, but are readable
|
||||
by all standard GIF decoders.
|
||||
|
||||
|
||||
REFERENCES
|
||||
==========
|
||||
|
||||
We recommend reading one or more of these references before trying to
|
||||
understand the innards of the JPEG software.
|
||||
|
||||
The best short technical introduction to the JPEG compression algorithm is
|
||||
Wallace, Gregory K. "The JPEG Still Picture Compression Standard",
|
||||
Communications of the ACM, April 1991 (vol. 34 no. 4), pp. 30-44.
|
||||
(Adjacent articles in that issue discuss MPEG motion picture compression,
|
||||
applications of JPEG, and related topics.) If you don't have the CACM issue
|
||||
handy, a PDF file containing a revised version of Wallace's article is
|
||||
available at http://www.ijg.org/files/Wallace.JPEG.pdf. The file (actually
|
||||
a preprint for an article that appeared in IEEE Trans. Consumer Electronics)
|
||||
omits the sample images that appeared in CACM, but it includes corrections
|
||||
and some added material. Note: the Wallace article is copyright ACM and IEEE,
|
||||
and it may not be used for commercial purposes.
|
||||
|
||||
A somewhat less technical, more leisurely introduction to JPEG can be found in
|
||||
"The Data Compression Book" by Mark Nelson and Jean-loup Gailly, published by
|
||||
M&T Books (New York), 2nd ed. 1996, ISBN 1-55851-434-1. This book provides
|
||||
good explanations and example C code for a multitude of compression methods
|
||||
including JPEG. It is an excellent source if you are comfortable reading C
|
||||
code but don't know much about data compression in general. The book's JPEG
|
||||
sample code is far from industrial-strength, but when you are ready to look
|
||||
at a full implementation, you've got one here...
|
||||
|
||||
The best currently available description of JPEG is the textbook "JPEG Still
|
||||
Image Data Compression Standard" by William B. Pennebaker and Joan L.
|
||||
Mitchell, published by Van Nostrand Reinhold, 1993, ISBN 0-442-01272-1.
|
||||
Price US$59.95, 638 pp. The book includes the complete text of the ISO JPEG
|
||||
standards (DIS 10918-1 and draft DIS 10918-2).
|
||||
Although this is by far the most detailed and comprehensive exposition of
|
||||
JPEG publicly available, we point out that it is still missing an explanation
|
||||
of the most essential properties and algorithms of the underlying DCT
|
||||
technology.
|
||||
If you think that you know about DCT-based JPEG after reading this book,
|
||||
then you are in delusion. The real fundamentals and corresponding potential
|
||||
of DCT-based JPEG are not publicly known so far, and that is the reason for
|
||||
all the mistaken developments taking place in the image coding domain.
|
||||
|
||||
The original JPEG standard is divided into two parts, Part 1 being the actual
|
||||
specification, while Part 2 covers compliance testing methods. Part 1 is
|
||||
titled "Digital Compression and Coding of Continuous-tone Still Images,
|
||||
Part 1: Requirements and guidelines" and has document numbers ISO/IEC IS
|
||||
10918-1, ITU-T T.81. Part 2 is titled "Digital Compression and Coding of
|
||||
Continuous-tone Still Images, Part 2: Compliance testing" and has document
|
||||
numbers ISO/IEC IS 10918-2, ITU-T T.83.
|
||||
IJG JPEG 8 introduced an implementation of the JPEG SmartScale extension
|
||||
which is specified in two documents: A contributed document at ITU and ISO
|
||||
with title "ITU-T JPEG-Plus Proposal for Extending ITU-T T.81 for Advanced
|
||||
Image Coding", April 2006, Geneva, Switzerland. The latest version of this
|
||||
document is Revision 3. And a contributed document ISO/IEC JTC1/SC29/WG1 N
|
||||
5799 with title "Evolution of JPEG", June/July 2011, Berlin, Germany.
|
||||
IJG JPEG 9 introduces a reversible color transform for improved lossless
|
||||
compression which is described in a contributed document ISO/IEC JTC1/SC29/
|
||||
WG1 N 6080 with title "JPEG 9 Lossless Coding", June/July 2012, Paris,
|
||||
France.
|
||||
|
||||
The JPEG standard does not specify all details of an interchangeable file
|
||||
format. For the omitted details we follow the "JFIF" conventions, version 2.
|
||||
JFIF version 1 has been adopted as Recommendation ITU-T T.871 (05/2011) :
|
||||
Information technology - Digital compression and coding of continuous-tone
|
||||
still images: JPEG File Interchange Format (JFIF). It is available as a
|
||||
free download in PDF file format from http://www.itu.int/rec/T-REC-T.871.
|
||||
A PDF file of the older JFIF document is available at
|
||||
http://www.w3.org/Graphics/JPEG/jfif3.pdf.
|
||||
|
||||
The TIFF 6.0 file format specification can be obtained by FTP from
|
||||
ftp://ftp.sgi.com/graphics/tiff/TIFF6.ps.gz. The JPEG incorporation scheme
|
||||
found in the TIFF 6.0 spec of 3-June-92 has a number of serious problems.
|
||||
IJG does not recommend use of the TIFF 6.0 design (TIFF Compression tag 6).
|
||||
Instead, we recommend the JPEG design proposed by TIFF Technical Note #2
|
||||
(Compression tag 7). Copies of this Note can be obtained from
|
||||
http://www.ijg.org/files/. It is expected that the next revision
|
||||
of the TIFF spec will replace the 6.0 JPEG design with the Note's design.
|
||||
Although IJG's own code does not support TIFF/JPEG, the free libtiff library
|
||||
uses our library to implement TIFF/JPEG per the Note.
|
||||
|
||||
|
||||
ARCHIVE LOCATIONS
|
||||
=================
|
||||
|
||||
The "official" archive site for this software is www.ijg.org.
|
||||
The most recent released version can always be found there in
|
||||
directory "files". This particular version will be archived as
|
||||
http://www.ijg.org/files/jpegsrc.v9c.tar.gz, and in Windows-compatible
|
||||
"zip" archive format as http://www.ijg.org/files/jpegsr9c.zip.
|
||||
|
||||
The JPEG FAQ (Frequently Asked Questions) article is a source of some
|
||||
general information about JPEG.
|
||||
It is available on the World Wide Web at http://www.faqs.org/faqs/jpeg-faq/
|
||||
and other news.answers archive sites, including the official news.answers
|
||||
archive at rtfm.mit.edu: ftp://rtfm.mit.edu/pub/usenet/news.answers/jpeg-faq/.
|
||||
If you don't have Web or FTP access, send e-mail to mail-server@rtfm.mit.edu
|
||||
with body
|
||||
send usenet/news.answers/jpeg-faq/part1
|
||||
send usenet/news.answers/jpeg-faq/part2
|
||||
|
||||
|
||||
ACKNOWLEDGMENTS
|
||||
===============
|
||||
|
||||
Thank to Juergen Bruder for providing me with a copy of the common DCT
|
||||
algorithm article, only to find out that I had come to the same result
|
||||
in a more direct and comprehensible way with a more generative approach.
|
||||
|
||||
Thank to Istvan Sebestyen and Joan L. Mitchell for inviting me to the
|
||||
ITU JPEG (Study Group 16) meeting in Geneva, Switzerland.
|
||||
|
||||
Thank to Thomas Wiegand and Gary Sullivan for inviting me to the
|
||||
Joint Video Team (MPEG & ITU) meeting in Geneva, Switzerland.
|
||||
|
||||
Thank to Thomas Richter and Daniel Lee for inviting me to the
|
||||
ISO/IEC JTC1/SC29/WG1 (previously known as JPEG, together with ITU-T SG16)
|
||||
meeting in Berlin, Germany.
|
||||
|
||||
Thank to John Korejwa and Massimo Ballerini for inviting me to
|
||||
fruitful consultations in Boston, MA and Milan, Italy.
|
||||
|
||||
Thank to Hendrik Elstner, Roland Fassauer, Simone Zuck, Guenther
|
||||
Maier-Gerber, Walter Stoeber, Fred Schmitz, and Norbert Braunagel
|
||||
for corresponding business development.
|
||||
|
||||
Thank to Nico Zschach and Dirk Stelling of the technical support team
|
||||
at the Digital Images company in Halle for providing me with extra
|
||||
equipment for configuration tests.
|
||||
|
||||
Thank to Richard F. Lyon (then of Foveon Inc.) for fruitful
|
||||
communication about JPEG configuration in Sigma Photo Pro software.
|
||||
|
||||
Thank to Andrew Finkenstadt for hosting the ijg.org site.
|
||||
|
||||
Thank to Thomas G. Lane for the original design and development of
|
||||
this singular software package.
|
||||
|
||||
Thank to Lars Goehler, Andreas Heinecke, Sebastian Fuss, Yvonne Roebert,
|
||||
Andrej Werner, and Ulf-Dietrich Braumann for support and public relations.
|
||||
|
||||
|
||||
FILE FORMAT WARS
|
||||
================
|
||||
|
||||
The ISO/IEC JTC1/SC29/WG1 standards committee (previously known as JPEG,
|
||||
together with ITU-T SG16) currently promotes different formats containing
|
||||
the name "JPEG" which is misleading because these formats are incompatible
|
||||
with original DCT-based JPEG and are based on faulty technologies.
|
||||
IJG therefore does not and will not support such momentary mistakes
|
||||
(see REFERENCES).
|
||||
There exist also distributions under the name "OpenJPEG" promoting such
|
||||
kind of formats which is misleading because they don't support original
|
||||
JPEG images.
|
||||
We have no sympathy for the promotion of inferior formats. Indeed, one of
|
||||
the original reasons for developing this free software was to help force
|
||||
convergence on common, interoperable format standards for JPEG files.
|
||||
Don't use an incompatible file format!
|
||||
(In any case, our decoder will remain capable of reading existing JPEG
|
||||
image files indefinitely.)
|
||||
|
||||
The ISO committee pretends to be "responsible for the popular JPEG" in their
|
||||
public reports which is not true because they don't respond to actual
|
||||
requirements for the maintenance of the original JPEG specification.
|
||||
Furthermore, the ISO committee pretends to "ensure interoperability" with
|
||||
their standards which is not true because their "standards" support only
|
||||
application-specific and proprietary use cases and contain mathematically
|
||||
incorrect code.
|
||||
|
||||
There are currently different distributions in circulation containing the
|
||||
name "libjpeg" which is misleading because they don't have the features and
|
||||
are incompatible with formats supported by actual IJG libjpeg distributions.
|
||||
One of those fakes is released by members of the ISO committee and just uses
|
||||
the name of libjpeg for misdirection of people, similar to the abuse of the
|
||||
name JPEG as described above, while having nothing in common with actual IJG
|
||||
libjpeg distributions and containing mathematically incorrect code.
|
||||
The other one claims to be a "derivative" or "fork" of the original libjpeg,
|
||||
but violates the license conditions as described under LEGAL ISSUES above
|
||||
and violates basic C programming properties.
|
||||
We have no sympathy for the release of misleading, incorrect and illegal
|
||||
distributions derived from obsolete code bases.
|
||||
Don't use an obsolete code base!
|
||||
|
||||
According to the UCC (Uniform Commercial Code) law, IJG has the lawful and
|
||||
legal right to foreclose on certain standardization bodies and other
|
||||
institutions or corporations that knowingly perform substantial and
|
||||
systematic deceptive acts and practices, fraud, theft, and damaging of the
|
||||
value of the people of this planet without their knowing, willing and
|
||||
intentional consent.
|
||||
The titles, ownership, and rights of these institutions and all their assets
|
||||
are now duly secured and held in trust for the free people of this planet.
|
||||
People of the planet, on every country, may have a financial interest in
|
||||
the assets of these former principals, agents, and beneficiaries of the
|
||||
foreclosed institutions and corporations.
|
||||
IJG asserts what is: that each man, woman, and child has unalienable value
|
||||
and rights granted and deposited in them by the Creator and not any one of
|
||||
the people is subordinate to any artificial principality, corporate fiction
|
||||
or the special interest of another without their appropriate knowing,
|
||||
willing and intentional consent made by contract or accommodation agreement.
|
||||
IJG expresses that which already was.
|
||||
The people have already determined and demanded that public administration
|
||||
entities, national governments, and their supporting judicial systems must
|
||||
be fully transparent, accountable, and liable.
|
||||
IJG has secured the value for all concerned free people of the planet.
|
||||
|
||||
A partial list of foreclosed institutions and corporations ("Hall of Shame")
|
||||
is currently prepared and will be published later.
|
||||
|
||||
|
||||
TO DO
|
||||
=====
|
||||
|
||||
Version 9 is the second release of a new generation JPEG standard
|
||||
to overcome the limitations of the original JPEG specification,
|
||||
and is the first true source reference JPEG codec.
|
||||
More features are being prepared for coming releases...
|
||||
|
||||
Please send bug reports, offers of help, etc. to jpeg-info@jpegclub.org.
|
BIN
libjpeg/bin/jpeg.lib
Normal file
BIN
libjpeg/bin/jpeg.lib
Normal file
Binary file not shown.
52
libjpeg/include/jconfig.h
Normal file
52
libjpeg/include/jconfig.h
Normal file
@ -0,0 +1,52 @@
|
||||
/* jconfig.vc --- jconfig.h for Microsoft Visual C++ on Windows 9x or NT. */
|
||||
/* This file also works for Borland C++ 32-bit (bcc32) on Windows 9x or NT. */
|
||||
/* see jconfig.txt for explanations */
|
||||
|
||||
#define HAVE_PROTOTYPES
|
||||
#define HAVE_UNSIGNED_CHAR
|
||||
#define HAVE_UNSIGNED_SHORT
|
||||
/* #define void char */
|
||||
/* #define const */
|
||||
#undef CHAR_IS_UNSIGNED
|
||||
#define HAVE_STDDEF_H
|
||||
#define HAVE_STDLIB_H
|
||||
#undef NEED_BSD_STRINGS
|
||||
#undef NEED_SYS_TYPES_H
|
||||
#undef NEED_FAR_POINTERS /* we presume a 32-bit flat memory model */
|
||||
#undef NEED_SHORT_EXTERNAL_NAMES
|
||||
#undef INCOMPLETE_TYPES_BROKEN
|
||||
|
||||
/* Define "boolean" as unsigned char, not enum, per Windows custom */
|
||||
#ifndef __RPCNDR_H__ /* don't conflict if rpcndr.h already read */
|
||||
typedef unsigned char boolean;
|
||||
#endif
|
||||
#ifndef FALSE /* in case these macros already exist */
|
||||
#define FALSE 0 /* values of boolean */
|
||||
#endif
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
#define HAVE_BOOLEAN /* prevent jmorecfg.h from redefining it */
|
||||
|
||||
|
||||
#ifdef JPEG_INTERNALS
|
||||
|
||||
#undef RIGHT_SHIFT_IS_UNSIGNED
|
||||
|
||||
#endif /* JPEG_INTERNALS */
|
||||
|
||||
#ifdef JPEG_CJPEG_DJPEG
|
||||
|
||||
#define BMP_SUPPORTED /* BMP image file format */
|
||||
#define GIF_SUPPORTED /* GIF image file format */
|
||||
#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */
|
||||
#undef RLE_SUPPORTED /* Utah RLE image file format */
|
||||
#define TARGA_SUPPORTED /* Targa image file format */
|
||||
|
||||
#define TWO_FILE_COMMANDLINE /* optional */
|
||||
#define USE_SETMODE /* Microsoft has setmode() */
|
||||
#undef NEED_SIGNAL_CATCHER
|
||||
#undef DONT_USE_B_MODE
|
||||
#undef PROGRESS_REPORT /* optional */
|
||||
|
||||
#endif /* JPEG_CJPEG_DJPEG */
|
446
libjpeg/include/jmorecfg.h
Normal file
446
libjpeg/include/jmorecfg.h
Normal file
@ -0,0 +1,446 @@
|
||||
/*
|
||||
* jmorecfg.h
|
||||
*
|
||||
* Copyright (C) 1991-1997, Thomas G. Lane.
|
||||
* Modified 1997-2013 by Guido Vollbeding.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
* This file contains additional configuration options that customize the
|
||||
* JPEG software for special applications or support machine-dependent
|
||||
* optimizations. Most users will not need to touch this file.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Define BITS_IN_JSAMPLE as either
|
||||
* 8 for 8-bit sample values (the usual setting)
|
||||
* 9 for 9-bit sample values
|
||||
* 10 for 10-bit sample values
|
||||
* 11 for 11-bit sample values
|
||||
* 12 for 12-bit sample values
|
||||
* Only 8, 9, 10, 11, and 12 bits sample data precision are supported for
|
||||
* full-feature DCT processing. Further depths up to 16-bit may be added
|
||||
* later for the lossless modes of operation.
|
||||
* Run-time selection and conversion of data precision will be added later
|
||||
* and are currently not supported, sorry.
|
||||
* Exception: The transcoding part (jpegtran) supports all settings in a
|
||||
* single instance, since it operates on the level of DCT coefficients and
|
||||
* not sample values. The DCT coefficients are of the same type (16 bits)
|
||||
* in all cases (see below).
|
||||
*/
|
||||
|
||||
#define BITS_IN_JSAMPLE 8 /* use 8, 9, 10, 11, or 12 */
|
||||
|
||||
|
||||
/*
|
||||
* Maximum number of components (color channels) allowed in JPEG image.
|
||||
* To meet the letter of the JPEG spec, set this to 255. However, darn
|
||||
* few applications need more than 4 channels (maybe 5 for CMYK + alpha
|
||||
* mask). We recommend 10 as a reasonable compromise; use 4 if you are
|
||||
* really short on memory. (Each allowed component costs a hundred or so
|
||||
* bytes of storage, whether actually used in an image or not.)
|
||||
*/
|
||||
|
||||
#define MAX_COMPONENTS 10 /* maximum number of image components */
|
||||
|
||||
|
||||
/*
|
||||
* Basic data types.
|
||||
* You may need to change these if you have a machine with unusual data
|
||||
* type sizes; for example, "char" not 8 bits, "short" not 16 bits,
|
||||
* or "long" not 32 bits. We don't care whether "int" is 16 or 32 bits,
|
||||
* but it had better be at least 16.
|
||||
*/
|
||||
|
||||
/* Representation of a single sample (pixel element value).
|
||||
* We frequently allocate large arrays of these, so it's important to keep
|
||||
* them small. But if you have memory to burn and access to char or short
|
||||
* arrays is very slow on your hardware, you might want to change these.
|
||||
*/
|
||||
|
||||
#if BITS_IN_JSAMPLE == 8
|
||||
/* JSAMPLE should be the smallest type that will hold the values 0..255.
|
||||
* You can use a signed char by having GETJSAMPLE mask it with 0xFF.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_UNSIGNED_CHAR
|
||||
|
||||
typedef unsigned char JSAMPLE;
|
||||
#define GETJSAMPLE(value) ((int) (value))
|
||||
|
||||
#else /* not HAVE_UNSIGNED_CHAR */
|
||||
|
||||
typedef char JSAMPLE;
|
||||
#ifdef CHAR_IS_UNSIGNED
|
||||
#define GETJSAMPLE(value) ((int) (value))
|
||||
#else
|
||||
#define GETJSAMPLE(value) ((int) (value) & 0xFF)
|
||||
#endif /* CHAR_IS_UNSIGNED */
|
||||
|
||||
#endif /* HAVE_UNSIGNED_CHAR */
|
||||
|
||||
#define MAXJSAMPLE 255
|
||||
#define CENTERJSAMPLE 128
|
||||
|
||||
#endif /* BITS_IN_JSAMPLE == 8 */
|
||||
|
||||
|
||||
#if BITS_IN_JSAMPLE == 9
|
||||
/* JSAMPLE should be the smallest type that will hold the values 0..511.
|
||||
* On nearly all machines "short" will do nicely.
|
||||
*/
|
||||
|
||||
typedef short JSAMPLE;
|
||||
#define GETJSAMPLE(value) ((int) (value))
|
||||
|
||||
#define MAXJSAMPLE 511
|
||||
#define CENTERJSAMPLE 256
|
||||
|
||||
#endif /* BITS_IN_JSAMPLE == 9 */
|
||||
|
||||
|
||||
#if BITS_IN_JSAMPLE == 10
|
||||
/* JSAMPLE should be the smallest type that will hold the values 0..1023.
|
||||
* On nearly all machines "short" will do nicely.
|
||||
*/
|
||||
|
||||
typedef short JSAMPLE;
|
||||
#define GETJSAMPLE(value) ((int) (value))
|
||||
|
||||
#define MAXJSAMPLE 1023
|
||||
#define CENTERJSAMPLE 512
|
||||
|
||||
#endif /* BITS_IN_JSAMPLE == 10 */
|
||||
|
||||
|
||||
#if BITS_IN_JSAMPLE == 11
|
||||
/* JSAMPLE should be the smallest type that will hold the values 0..2047.
|
||||
* On nearly all machines "short" will do nicely.
|
||||
*/
|
||||
|
||||
typedef short JSAMPLE;
|
||||
#define GETJSAMPLE(value) ((int) (value))
|
||||
|
||||
#define MAXJSAMPLE 2047
|
||||
#define CENTERJSAMPLE 1024
|
||||
|
||||
#endif /* BITS_IN_JSAMPLE == 11 */
|
||||
|
||||
|
||||
#if BITS_IN_JSAMPLE == 12
|
||||
/* JSAMPLE should be the smallest type that will hold the values 0..4095.
|
||||
* On nearly all machines "short" will do nicely.
|
||||
*/
|
||||
|
||||
typedef short JSAMPLE;
|
||||
#define GETJSAMPLE(value) ((int) (value))
|
||||
|
||||
#define MAXJSAMPLE 4095
|
||||
#define CENTERJSAMPLE 2048
|
||||
|
||||
#endif /* BITS_IN_JSAMPLE == 12 */
|
||||
|
||||
|
||||
/* Representation of a DCT frequency coefficient.
|
||||
* This should be a signed value of at least 16 bits; "short" is usually OK.
|
||||
* Again, we allocate large arrays of these, but you can change to int
|
||||
* if you have memory to burn and "short" is really slow.
|
||||
*/
|
||||
|
||||
typedef short JCOEF;
|
||||
|
||||
|
||||
/* Compressed datastreams are represented as arrays of JOCTET.
|
||||
* These must be EXACTLY 8 bits wide, at least once they are written to
|
||||
* external storage. Note that when using the stdio data source/destination
|
||||
* managers, this is also the data type passed to fread/fwrite.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_UNSIGNED_CHAR
|
||||
|
||||
typedef unsigned char JOCTET;
|
||||
#define GETJOCTET(value) (value)
|
||||
|
||||
#else /* not HAVE_UNSIGNED_CHAR */
|
||||
|
||||
typedef char JOCTET;
|
||||
#ifdef CHAR_IS_UNSIGNED
|
||||
#define GETJOCTET(value) (value)
|
||||
#else
|
||||
#define GETJOCTET(value) ((value) & 0xFF)
|
||||
#endif /* CHAR_IS_UNSIGNED */
|
||||
|
||||
#endif /* HAVE_UNSIGNED_CHAR */
|
||||
|
||||
|
||||
/* These typedefs are used for various table entries and so forth.
|
||||
* They must be at least as wide as specified; but making them too big
|
||||
* won't cost a huge amount of memory, so we don't provide special
|
||||
* extraction code like we did for JSAMPLE. (In other words, these
|
||||
* typedefs live at a different point on the speed/space tradeoff curve.)
|
||||
*/
|
||||
|
||||
/* UINT8 must hold at least the values 0..255. */
|
||||
|
||||
#ifdef HAVE_UNSIGNED_CHAR
|
||||
typedef unsigned char UINT8;
|
||||
#else /* not HAVE_UNSIGNED_CHAR */
|
||||
#ifdef CHAR_IS_UNSIGNED
|
||||
typedef char UINT8;
|
||||
#else /* not CHAR_IS_UNSIGNED */
|
||||
typedef short UINT8;
|
||||
#endif /* CHAR_IS_UNSIGNED */
|
||||
#endif /* HAVE_UNSIGNED_CHAR */
|
||||
|
||||
/* UINT16 must hold at least the values 0..65535. */
|
||||
|
||||
#ifdef HAVE_UNSIGNED_SHORT
|
||||
typedef unsigned short UINT16;
|
||||
#else /* not HAVE_UNSIGNED_SHORT */
|
||||
typedef unsigned int UINT16;
|
||||
#endif /* HAVE_UNSIGNED_SHORT */
|
||||
|
||||
/* INT16 must hold at least the values -32768..32767. */
|
||||
|
||||
#ifndef XMD_H /* X11/xmd.h correctly defines INT16 */
|
||||
typedef short INT16;
|
||||
#endif
|
||||
|
||||
/* INT32 must hold at least signed 32-bit values. */
|
||||
|
||||
#ifndef XMD_H /* X11/xmd.h correctly defines INT32 */
|
||||
#ifndef _BASETSD_H_ /* Microsoft defines it in basetsd.h */
|
||||
#ifndef _BASETSD_H /* MinGW is slightly different */
|
||||
#ifndef QGLOBAL_H /* Qt defines it in qglobal.h */
|
||||
typedef long INT32;
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Datatype used for image dimensions. The JPEG standard only supports
|
||||
* images up to 64K*64K due to 16-bit fields in SOF markers. Therefore
|
||||
* "unsigned int" is sufficient on all machines. However, if you need to
|
||||
* handle larger images and you don't mind deviating from the spec, you
|
||||
* can change this datatype.
|
||||
*/
|
||||
|
||||
typedef unsigned int JDIMENSION;
|
||||
|
||||
#define JPEG_MAX_DIMENSION 65500L /* a tad under 64K to prevent overflows */
|
||||
|
||||
|
||||
/* These macros are used in all function definitions and extern declarations.
|
||||
* You could modify them if you need to change function linkage conventions;
|
||||
* in particular, you'll need to do that to make the library a Windows DLL.
|
||||
* Another application is to make all functions global for use with debuggers
|
||||
* or code profilers that require it.
|
||||
*/
|
||||
|
||||
/* a function called through method pointers: */
|
||||
#define METHODDEF(type) static type
|
||||
/* a function used only in its module: */
|
||||
#define LOCAL(type) static type
|
||||
/* a function referenced thru EXTERNs: */
|
||||
#define GLOBAL(type) type
|
||||
/* a reference to a GLOBAL function: */
|
||||
#define EXTERN(type) extern type
|
||||
|
||||
|
||||
/* This macro is used to declare a "method", that is, a function pointer.
|
||||
* We want to supply prototype parameters if the compiler can cope.
|
||||
* Note that the arglist parameter must be parenthesized!
|
||||
* Again, you can customize this if you need special linkage keywords.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_PROTOTYPES
|
||||
#define JMETHOD(type,methodname,arglist) type (*methodname) arglist
|
||||
#else
|
||||
#define JMETHOD(type,methodname,arglist) type (*methodname) ()
|
||||
#endif
|
||||
|
||||
|
||||
/* The noreturn type identifier is used to declare functions
|
||||
* which cannot return.
|
||||
* Compilers can thus create more optimized code and perform
|
||||
* better checks for warnings and errors.
|
||||
* Static analyzer tools can make improved inferences about
|
||||
* execution paths and are prevented from giving false alerts.
|
||||
*
|
||||
* Unfortunately, the proposed specifications of corresponding
|
||||
* extensions in the Dec 2011 ISO C standard revision (C11),
|
||||
* GCC, MSVC, etc. are not viable.
|
||||
* Thus we introduce a user defined type to declare noreturn
|
||||
* functions at least for clarity. A proper compiler would
|
||||
* have a suitable noreturn type to match in place of void.
|
||||
*/
|
||||
|
||||
#ifndef HAVE_NORETURN_T
|
||||
typedef void noreturn_t;
|
||||
#endif
|
||||
|
||||
|
||||
/* Here is the pseudo-keyword for declaring pointers that must be "far"
|
||||
* on 80x86 machines. Most of the specialized coding for 80x86 is handled
|
||||
* by just saying "FAR *" where such a pointer is needed. In a few places
|
||||
* explicit coding is needed; see uses of the NEED_FAR_POINTERS symbol.
|
||||
*/
|
||||
|
||||
#ifndef FAR
|
||||
#ifdef NEED_FAR_POINTERS
|
||||
#define FAR far
|
||||
#else
|
||||
#define FAR
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* On a few systems, type boolean and/or its values FALSE, TRUE may appear
|
||||
* in standard header files. Or you may have conflicts with application-
|
||||
* specific header files that you want to include together with these files.
|
||||
* Defining HAVE_BOOLEAN before including jpeglib.h should make it work.
|
||||
*/
|
||||
|
||||
#ifndef HAVE_BOOLEAN
|
||||
#if defined FALSE || defined TRUE || defined QGLOBAL_H
|
||||
/* Qt3 defines FALSE and TRUE as "const" variables in qglobal.h */
|
||||
typedef int boolean;
|
||||
#ifndef FALSE /* in case these macros already exist */
|
||||
#define FALSE 0 /* values of boolean */
|
||||
#endif
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
#else
|
||||
typedef enum { FALSE = 0, TRUE = 1 } boolean;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* The remaining options affect code selection within the JPEG library,
|
||||
* but they don't need to be visible to most applications using the library.
|
||||
* To minimize application namespace pollution, the symbols won't be
|
||||
* defined unless JPEG_INTERNALS or JPEG_INTERNAL_OPTIONS has been defined.
|
||||
*/
|
||||
|
||||
#ifdef JPEG_INTERNALS
|
||||
#define JPEG_INTERNAL_OPTIONS
|
||||
#endif
|
||||
|
||||
#ifdef JPEG_INTERNAL_OPTIONS
|
||||
|
||||
|
||||
/*
|
||||
* These defines indicate whether to include various optional functions.
|
||||
* Undefining some of these symbols will produce a smaller but less capable
|
||||
* library. Note that you can leave certain source files out of the
|
||||
* compilation/linking process if you've #undef'd the corresponding symbols.
|
||||
* (You may HAVE to do that if your compiler doesn't like null source files.)
|
||||
*/
|
||||
|
||||
/* Capability options common to encoder and decoder: */
|
||||
|
||||
#define DCT_ISLOW_SUPPORTED /* slow but accurate integer algorithm */
|
||||
#define DCT_IFAST_SUPPORTED /* faster, less accurate integer method */
|
||||
#define DCT_FLOAT_SUPPORTED /* floating-point: accurate, fast on fast HW */
|
||||
|
||||
/* Encoder capability options: */
|
||||
|
||||
#define C_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */
|
||||
#define C_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */
|
||||
#define C_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/
|
||||
#define DCT_SCALING_SUPPORTED /* Input rescaling via DCT? (Requires DCT_ISLOW)*/
|
||||
#define ENTROPY_OPT_SUPPORTED /* Optimization of entropy coding parms? */
|
||||
/* Note: if you selected more than 8-bit data precision, it is dangerous to
|
||||
* turn off ENTROPY_OPT_SUPPORTED. The standard Huffman tables are only
|
||||
* good for 8-bit precision, so arithmetic coding is recommended for higher
|
||||
* precision. The Huffman encoder normally uses entropy optimization to
|
||||
* compute usable tables for higher precision. Otherwise, you'll have to
|
||||
* supply different default Huffman tables.
|
||||
* The exact same statements apply for progressive JPEG: the default tables
|
||||
* don't work for progressive mode. (This may get fixed, however.)
|
||||
*/
|
||||
#define INPUT_SMOOTHING_SUPPORTED /* Input image smoothing option? */
|
||||
|
||||
/* Decoder capability options: */
|
||||
|
||||
#define D_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */
|
||||
#define D_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */
|
||||
#define D_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/
|
||||
#define IDCT_SCALING_SUPPORTED /* Output rescaling via IDCT? (Requires DCT_ISLOW)*/
|
||||
#define SAVE_MARKERS_SUPPORTED /* jpeg_save_markers() needed? */
|
||||
#define BLOCK_SMOOTHING_SUPPORTED /* Block smoothing? (Progressive only) */
|
||||
#undef UPSAMPLE_SCALING_SUPPORTED /* Output rescaling at upsample stage? */
|
||||
#define UPSAMPLE_MERGING_SUPPORTED /* Fast path for sloppy upsampling? */
|
||||
#define QUANT_1PASS_SUPPORTED /* 1-pass color quantization? */
|
||||
#define QUANT_2PASS_SUPPORTED /* 2-pass color quantization? */
|
||||
|
||||
/* more capability options later, no doubt */
|
||||
|
||||
|
||||
/*
|
||||
* Ordering of RGB data in scanlines passed to or from the application.
|
||||
* If your application wants to deal with data in the order B,G,R, just
|
||||
* change these macros. You can also deal with formats such as R,G,B,X
|
||||
* (one extra byte per pixel) by changing RGB_PIXELSIZE. Note that changing
|
||||
* the offsets will also change the order in which colormap data is organized.
|
||||
* RESTRICTIONS:
|
||||
* 1. The sample applications cjpeg,djpeg do NOT support modified RGB formats.
|
||||
* 2. The color quantizer modules will not behave desirably if RGB_PIXELSIZE
|
||||
* is not 3 (they don't understand about dummy color components!). So you
|
||||
* can't use color quantization if you change that value.
|
||||
*/
|
||||
|
||||
#define RGB_RED 0 /* Offset of Red in an RGB scanline element */
|
||||
#define RGB_GREEN 1 /* Offset of Green */
|
||||
#define RGB_BLUE 2 /* Offset of Blue */
|
||||
#define RGB_PIXELSIZE 3 /* JSAMPLEs per RGB scanline element */
|
||||
|
||||
|
||||
/* Definitions for speed-related optimizations. */
|
||||
|
||||
|
||||
/* If your compiler supports inline functions, define INLINE
|
||||
* as the inline keyword; otherwise define it as empty.
|
||||
*/
|
||||
|
||||
#ifndef INLINE
|
||||
#ifdef __GNUC__ /* for instance, GNU C knows about inline */
|
||||
#define INLINE __inline__
|
||||
#endif
|
||||
#ifndef INLINE
|
||||
#define INLINE /* default is to define it as empty */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/* On some machines (notably 68000 series) "int" is 32 bits, but multiplying
|
||||
* two 16-bit shorts is faster than multiplying two ints. Define MULTIPLIER
|
||||
* as short on such a machine. MULTIPLIER must be at least 16 bits wide.
|
||||
*/
|
||||
|
||||
#ifndef MULTIPLIER
|
||||
#define MULTIPLIER int /* type for fastest integer multiply */
|
||||
#endif
|
||||
|
||||
|
||||
/* FAST_FLOAT should be either float or double, whichever is done faster
|
||||
* by your compiler. (Note that this type is only used in the floating point
|
||||
* DCT routines, so it only matters if you've defined DCT_FLOAT_SUPPORTED.)
|
||||
* Typically, float is faster in ANSI C compilers, while double is faster in
|
||||
* pre-ANSI compilers (because they insist on converting to double anyway).
|
||||
* The code below therefore chooses float if we have ANSI-style prototypes.
|
||||
*/
|
||||
|
||||
#ifndef FAST_FLOAT
|
||||
#ifdef HAVE_PROTOTYPES
|
||||
#define FAST_FLOAT float
|
||||
#else
|
||||
#define FAST_FLOAT double
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* JPEG_INTERNAL_OPTIONS */
|
1180
libjpeg/include/jpeglib.h
Normal file
1180
libjpeg/include/jpeglib.h
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user