48 #include <private/qsimd_p.h> 60 #if defined(Q_OS_WIN) && defined(Q_CC_GNU) 61 # if defined(__RPCNDR_H__) && !defined(boolean) 62 typedef unsigned char boolean;
67 #define XMD_H // shut JPEGlib up 68 #if defined(Q_OS_UNIXWARE) 69 # define HAVE_BOOLEAN // libjpeg under Unixware seems to need this 73 # undef const // remove crazy C hackery in jconfig.h 77 #if defined(JPEG_TRUE) && !defined(HAVE_BOOLEAN) 79 typedef JPEG_boolean boolean;
87 for (
int i = 0; i < len; ++i) {
88 *dst++ =
qRgb(src[0], src[1], src[2]);
101 #if defined(Q_C_CALLBACKS) 108 char buffer[JMSG_LENGTH_MAX];
109 (*cinfo->err->format_message)(cinfo, buffer);
114 #if defined(Q_C_CALLBACKS) 131 #if defined(Q_C_CALLBACKS) 148 src->next_input_byte = src->
buffer;
153 src->next_input_byte = src->
buffer;
154 src->
buffer[0] = (JOCTET) 0xFF;
155 src->
buffer[1] = (JOCTET) JPEG_EOI;
156 src->bytes_in_buffer = 2;
158 src->bytes_in_buffer = num_read;
174 while (num_bytes > (
long) src->bytes_in_buffer) {
175 num_bytes -= (long) src->bytes_in_buffer;
181 src->next_input_byte += (size_t) num_bytes;
182 src->bytes_in_buffer -= (size_t) num_bytes;
193 #if defined(Q_C_CALLBACKS) 202 jpeg_source_mgr::resync_to_restart = jpeg_resync_to_restart;
204 this->device = device;
207 next_input_byte = buffer;
213 (void) jpeg_calc_output_dimensions(cinfo);
215 w = cinfo->output_width;
216 h = cinfo->output_height;
220 #define HIGH_QUALITY_THRESHOLD 50 226 switch (cinfo->output_components) {
238 cinfo->output_scanline = cinfo->output_height;
246 switch (info->output_components) {
259 *dest =
QImage(size, format);
263 for (
int i = 0; i < 256; i++)
277 int quality = inQuality;
284 if (!scaledClipRect.
isEmpty()) {
287 clipRect = scaledClipRect;
288 scaledClipRect =
QRect();
289 }
else if (scaledSize.
isEmpty()) {
293 scaledClipRect =
QRect();
294 }
else if (clipRect.
isEmpty()) {
297 if ((info->image_width % scaledSize.
width()) == 0 &&
298 (info->image_height % scaledSize.
height()) == 0) {
299 int x = scaledClipRect.
x() * info->image_width /
301 int y = scaledClipRect.
y() * info->image_height /
303 int width = (scaledClipRect.
right() + 1) *
304 info->image_width / scaledSize.
width() - x;
305 int height = (scaledClipRect.
bottom() + 1) *
306 info->image_height / scaledSize.
height() - y;
307 clipRect =
QRect(x, y, width, height);
308 scaledSize = scaledClipRect.
size();
309 scaledClipRect =
QRect();
321 qMin(info->image_width / scaledSize.
width(),
322 info->image_height / scaledSize.
height());
328 if (info->scale_denom < 2) {
329 info->scale_denom = 1;
330 }
else if (info->scale_denom < 4) {
331 info->scale_denom = 2;
332 }
else if (info->scale_denom < 8) {
333 info->scale_denom = 4;
335 info->scale_denom = 8;
342 while (info->scale_denom > 1 &&
343 ((clipRect.
x() % info->scale_denom) != 0 ||
344 (clipRect.
y() % info->scale_denom) != 0 ||
345 (clipRect.
width() % info->scale_denom) != 0 ||
346 (clipRect.
height() % info->scale_denom) != 0)) {
347 info->scale_denom /= 2;
354 info->dct_method = JDCT_IFAST;
355 info->do_fancy_upsampling =
FALSE;
358 (void) jpeg_calc_output_dimensions(info);
361 QRect imageRect(0, 0, info->output_width, info->output_height);
365 }
else if (info->scale_denom == info->scale_num) {
370 clip =
QRect(clipRect.
x() / int(info->scale_denom),
371 clipRect.
y() / int(info->scale_denom),
372 clipRect.
width() / int(info->scale_denom),
373 clipRect.
height() / int(info->scale_denom));
382 bool quickGray = (info->output_components == 1 &&
391 JSAMPARRAY rows = (info->mem->alloc_sarray)
392 ((j_common_ptr)
info, JPOOL_IMAGE,
393 info->output_width * info->output_components, 1);
395 (void) jpeg_start_decompress(info);
397 while (info->output_scanline < info->output_height) {
398 int y = int(info->output_scanline) - clip.
y();
402 (void) jpeg_read_scanlines(info, rows, 1);
407 if (info->output_components == 3) {
408 uchar *in = rows[0] + clip.
x() * 3;
411 }
else if (info->out_color_space == JCS_CMYK) {
413 uchar *in = rows[0] + clip.
x() * 4;
415 for (
int i = 0; i < clip.
width(); ++i) {
417 *out++ =
qRgb(k * in[0] / 255, k * in[1] / 255,
421 }
else if (info->output_components == 1) {
424 rows[0] + clip.
x(), clip.
width());
429 (void) jpeg_start_decompress(info);
430 while (info->output_scanline < info->output_height) {
432 (void) jpeg_read_scanlines(info, &row, 1);
436 if (info->output_scanline == info->output_height)
437 (void) jpeg_finish_decompress(info);
439 if (info->density_unit == 1) {
442 }
else if (info->density_unit == 2) {
447 if (scaledSize.
isValid() && scaledSize != clip.
size()) {
452 *outImage = outImage->
copy(scaledClipRect);
453 return !outImage->
isNull();
469 #if defined(Q_C_CALLBACKS) 483 (*cinfo->err->error_exit)((j_common_ptr)cinfo);
485 dest->next_output_byte = dest->
buffer;
486 dest->free_in_buffer =
max_buf;
498 (*cinfo->err->error_exit)((j_common_ptr)cinfo);
501 #if defined(Q_C_CALLBACKS) 510 this->device = device;
511 next_output_byte = buffer;
518 bool success =
false;
521 struct jpeg_compress_struct cinfo;
522 JSAMPROW row_pointer[1];
528 cinfo.err = jpeg_std_error(&jerr);
536 jpeg_create_compress(&cinfo);
538 cinfo.dest = iod_dest;
540 cinfo.image_width = image.
width();
541 cinfo.image_height = image.
height();
549 for (
int i = image.
colorCount(); gray && i--;) {
550 gray = gray & (
qRed(cmap[i]) ==
qGreen(cmap[i]) &&
553 cinfo.input_components = gray ? 1 : 3;
554 cinfo.in_color_space = gray ? JCS_GRAYSCALE : JCS_RGB;
557 cinfo.input_components = 3;
558 cinfo.in_color_space = JCS_RGB;
561 jpeg_set_defaults(&cinfo);
567 if (diffInch < diffCm) {
568 cinfo.density_unit = 1;
572 cinfo.density_unit = 2;
578 int quality = sourceQuality >= 0 ?
qMin(sourceQuality,100) : 75;
579 jpeg_set_quality(&cinfo, quality,
TRUE );
580 jpeg_start_compress(&cinfo,
TRUE);
582 row_pointer[0] =
new uchar[cinfo.image_width*cinfo.input_components];
583 int w = cinfo.image_width;
584 while (cinfo.next_scanline < cinfo.image_height) {
585 uchar *row = row_pointer[0];
592 for (
int i=0; i<w; i++) {
593 bool bit = !!(*(data + (i >> 3)) & (1 << (i & 7)));
594 row[i] =
qRed(cmap[bit]);
597 for (
int i=0; i<w; i++) {
598 bool bit = !!(*(data + (i >> 3)) & (1 << (7 -(i & 7))));
599 row[i] =
qRed(cmap[bit]);
605 for (
int i=0; i<w; i++) {
606 bool bit = !!(*(data + (i >> 3)) & (1 << (i & 7)));
607 *row++ =
qRed(cmap[bit]);
608 *row++ =
qGreen(cmap[bit]);
609 *row++ =
qBlue(cmap[bit]);
612 for (
int i=0; i<w; i++) {
613 bool bit = !!(*(data + (i >> 3)) & (1 << (7 -(i & 7))));
614 *row++ =
qRed(cmap[bit]);
615 *row++ =
qGreen(cmap[bit]);
616 *row++ =
qBlue(cmap[bit]);
624 for (
int i=0; i<w; i++) {
625 *row =
qRed(cmap[*pix]);
630 for (
int i=0; i<w; i++) {
631 *row++ =
qRed(cmap[*pix]);
632 *row++ =
qGreen(cmap[*pix]);
633 *row++ =
qBlue(cmap[*pix]);
639 memcpy(row, image.
constScanLine(cinfo.next_scanline), w * 3);
646 for (
int i=0; i<w; i++) {
649 *row++ =
qBlue(*rgb);
659 for (
int i=0; i<w; i++) {
662 *row++ =
qBlue(*rgb);
668 jpeg_write_scanlines(&cinfo, row_pointer, 1);
671 jpeg_finish_compress(&cinfo);
672 jpeg_destroy_compress(&cinfo);
675 jpeg_destroy_compress(&cinfo);
680 delete [] row_pointer[0];
694 : quality(75), iod_src(0), state(Ready), q(qq)
701 jpeg_destroy_decompress(&
info);
716 struct jpeg_decompress_struct
info;
735 jpeg_create_decompress(&
info);
737 info.err = jpeg_std_error(&err);
740 if (!setjmp(err.setjmp_buffer)) {
741 (void) jpeg_read_header(&
info,
TRUE);
746 size =
QSize(width, height);
758 else if(state ==
Error)
766 readJpegHeader(q->device());
768 if(state == ReadHeader)
770 bool success =
read_jpeg_image(image, scaledSize, scaledClipRect, clipRect, quality, &
info, &err);
771 state = success ? Ready :
Error;
784 #if defined(QT_HAVE_NEON) 790 #endif // QT_HAVE_NEON 791 #if defined(QT_HAVE_SSSE3) 795 if (features &
SSSE3)
797 #endif // QT_HAVE_SSSE3 821 qWarning(
"QJpegHandler::canRead() called with no device");
826 if (device->
peek(buffer, 2) != 2)
828 return uchar(buffer[0]) == 0xff &&
uchar(buffer[1]) == 0xd8;
835 return d->
read(image);
The QVariant class acts like a union for the most common Qt data types.
T qobject_cast(QObject *object)
#define HIGH_QUALITY_THRESHOLD
Format
The following image formats are available in Qt.
void setFormat(const QByteArray &format)
Sets the format of the QImageIOHandler to format.
QImage copy(const QRect &rect=QRect()) const
Returns a sub-area of the image as a new image.
void setColor(int i, QRgb c)
Sets the color at the given index in the color table, to the given to colorValue. ...
static void my_error_exit(j_common_ptr cinfo)
static mach_timebase_info_data_t info
Q_DECL_CONSTEXPR const T & qMin(const T &a, const T &b)
#define QT_END_NAMESPACE
This macro expands to.
const QByteArray & data() const
Returns the data contained in the buffer.
bool isNull() const
Returns true if it is a null image, otherwise returns false.
The QByteArray class provides an array of bytes.
virtual qint64 pos() const
For random-access devices, this function returns the position that data is written to or read from...
bool canRead() const
Returns true if an image can be read from the device (i.
int width() const
Returns the width of the rectangle.
qint64 pos() const
Reimplemented Function
QRect intersected(const QRect &other) const
Returns the intersection of this rectangle and the given rectangle.
int dotsPerMeterY() const
Returns the number of pixels that fit vertically in a physical meter.
The QBuffer class provides a QIODevice interface for a QByteArray.
int height() const
Returns the height of the rectangle.
int bottom() const
Returns the y-coordinate of the rectangle's bottom edge.
Q_DECL_CONSTEXPR T qAbs(const T &t)
Format format() const
Returns the format of the image.
Q_GUI_EXPORT_INLINE int qRed(QRgb rgb)
int toInt(bool *ok=0) const
Returns the variant as an int if the variant has type() Int , Bool , ByteArray , Char ...
qint64 read(char *data, qint64 maxlen)
Reads at most maxSize bytes from the device into data, and returns the number of bytes read...
bool read(QImage *image)
Read an image from the device, and stores it in image.
int width() const
Returns the width.
void setColorCount(int)
Resizes the color table to contain colorCount entries.
void setOption(ImageOption option, const QVariant &value)
Sets the option option with the value value.
static bool ensureValidImage(QImage *dest, struct jpeg_decompress_struct *info, const QSize &size)
#define QT_BEGIN_NAMESPACE
This macro expands to.
static void qt_term_destination(j_compress_ptr cinfo)
static bool write_jpeg_image(const QImage &image, QIODevice *device, int sourceQuality)
static void qt_skip_input_data(j_decompress_ptr cinfo, long num_bytes)
ImageOption
This enum describes the different options supported by QImageIOHandler.
QSize size() const
Returns the size of the rectangle.
qint64 peek(char *data, qint64 maxlen)
Reads at most maxSize bytes from the device into data, without side effects (i.
Q_CORE_EXPORT void qWarning(const char *,...)
The QImage class provides a hardware-independent image representation that allows direct access to th...
static const char * data(const QByteArray &arr)
#define FALSE
Synonym for false.
void setDotsPerMeterY(int)
Sets the number of pixels that fit vertically in a physical meter, to y.
The State element defines configurations of objects and properties.
void(QT_FASTCALL * Rgb888ToRgb32Converter)(quint32 *dst, const uchar *src, int len)
Q_GUI_EXPORT_INLINE int qBlue(QRgb rgb)
QSize toSize() const
Returns the variant as a QSize if the variant has type() Size ; otherwise returns an invalid QSize...
my_jpeg_destination_mgr(QIODevice *)
virtual bool isSequential() const
Returns true if this device is sequential; otherwise returns false.
QSize size() const
Returns the size of the image, i.
const uchar * constScanLine(int) const
Returns a pointer to the pixel data at the scanline with index i.
#define TRUE
Synonym for true.
const char * constData() const
Returns a pointer to the data stored in the byte array.
bool isEmpty() const
Returns true if the rectangle is empty, otherwise returns false.
QRgb qRgb(int r, int g, int b)
Returns the ARGB quadruplet (255, {r}, {g}, {b}).
bool write(const QImage &image)
Writes the image image to the assigned device.
int width() const
Returns the width of the image.
static boolean qt_fill_input_buffer(j_decompress_ptr cinfo)
my_jpeg_source_mgr(QIODevice *device)
QImage convertToFormat(Format f, Qt::ImageConversionFlags flags=Qt::AutoColor) const Q_REQUIRED_RESULT
Returns a copy of the image in the given format.
static void qt_init_source(j_decompress_ptr)
int right() const
Returns the x-coordinate of the rectangle's right edge.
void setDotsPerMeterX(int)
Sets the number of pixels that fit horizontally in a physical meter, to x.
int y() const
Returns the y-coordinate of the rectangle's top edge.
int colorCount() const
Returns the size of the color table for the image.
uint qDetectCPUFeatures()
QRect toRect() const
Returns the variant as a QRect if the variant has type() Rect ; otherwise returns an invalid QRect...
int x() const
Returns the x-coordinate of the rectangle's left edge.
QByteArray name() const
Use format() instead.
Q_GUI_EXPORT_INLINE QRgb qRgb(int r, int g, int b)
int height() const
Returns the height.
if(void) toggleToolbarShown
The QRect class defines a rectangle in the plane using integer precision.
bool isValid() const
Returns true if both the width and height is equal to or greater than 0; otherwise returns false...
QIODevice * device() const
Returns the device currently assigned to the QImageIOHandler.
int height() const
Returns the height of the image.
int size() const
Returns the number of bytes in this byte array.
Q_GUI_EXPORT_INLINE int qGreen(QRgb rgb)
static bool read_jpeg_size(int &w, int &h, j_decompress_ptr cinfo)
The QSize class defines the size of a two-dimensional object using integer point precision.
static boolean qt_empty_output_buffer(j_compress_ptr cinfo)
static void qt_term_source(j_decompress_ptr cinfo)
struct my_jpeg_source_mgr * iod_src
static bool read_jpeg_image(QImage *outImage, QSize scaledSize, QRect scaledClipRect, QRect clipRect, int inQuality, j_decompress_ptr info, struct my_error_mgr *err)
bool isEmpty() const
Returns true if either of the width and height is less than or equal to 0; otherwise returns false...
qint64 write(const char *data, qint64 len)
Writes at most maxSize bytes of data from data to the device.
static Rgb888ToRgb32Converter rgb888ToRgb32ConverterPtr
QImage scaled(int w, int h, Qt::AspectRatioMode aspectMode=Qt::IgnoreAspectRatio, Qt::TransformationMode mode=Qt::FastTransformation) const
void translate(int dx, int dy)
Moves the rectangle dx along the x axis and dy along the y axis, relative to the current position...
The QIODevice class is the base interface class of all I/O devices in Qt.
static void qt_init_destination(j_compress_ptr)
void QT_FASTCALL convert_rgb888_to_rgb32_C(quint32 *dst, const uchar *src, int len)
bool readJpegHeader(QIODevice *)
#define Q_UNUSED(x)
Indicates to the compiler that the parameter with the specified name is not used in the body of a fun...
virtual bool seek(qint64 pos)
For random-access devices, this function sets the current position to pos, returning true on success...
int dotsPerMeterX() const
Returns the number of pixels that fit horizontally in a physical meter.
const QBuffer * memDevice
QVector< QRgb > colorTable() const
Returns a list of the colors contained in the image's color table, or an empty list if the image does...
static bool read_jpeg_format(QImage::Format &format, j_decompress_ptr cinfo)
Q_DECL_CONSTEXPR int qRound(qreal d)
bool supportsOption(ImageOption option) const
Returns true if the QImageIOHandler supports the option option; otherwise returns false...
uchar * scanLine(int)
Returns a pointer to the pixel data at the scanline with index i.
QVariant option(ImageOption option) const
Returns the value assigned to option as a QVariant.
QJpegHandlerPrivate(QJpegHandler *qq)
QPoint topLeft() const
Returns the position of the rectangle's top-left corner.