changeset 33 | 3e2da88830cd |
parent 30 | 5dc02b23752f |
child 37 | 758a864f9613 |
30:5dc02b23752f | 33:3e2da88830cd |
---|---|
56 #include <math.h> |
56 #include <math.h> |
57 #include <private/qdrawhelper_p.h> |
57 #include <private/qdrawhelper_p.h> |
58 #include <private/qmemrotate_p.h> |
58 #include <private/qmemrotate_p.h> |
59 #include <private/qpixmapdata_p.h> |
59 #include <private/qpixmapdata_p.h> |
60 #include <private/qimagescale_p.h> |
60 #include <private/qimagescale_p.h> |
61 #include <private/qsimd_p.h> |
|
61 |
62 |
62 #include <qhash.h> |
63 #include <qhash.h> |
63 |
64 |
64 #include <private/qpaintengine_raster_p.h> |
65 #include <private/qpaintengine_raster_p.h> |
65 |
66 |
207 default: |
208 default: |
208 numColors = 0; |
209 numColors = 0; |
209 break; |
210 break; |
210 } |
211 } |
211 |
212 |
212 const int bytes_per_line = ((width * depth + 31) >> 5) << 2; // bytes per scanline (must be multiple of 8) |
213 const int bytes_per_line = ((width * depth + 31) >> 5) << 2; // bytes per scanline (must be multiple of 4) |
213 |
214 |
214 // sanity check for potential overflows |
215 // sanity check for potential overflows |
215 if (INT_MAX/depth < width |
216 if (INT_MAX/depth < width |
216 || bytes_per_line <= 0 |
217 || bytes_per_line <= 0 |
217 || height <= 0 |
218 || height <= 0 |
270 { |
271 { |
271 bool has_alpha_pixels = false; |
272 bool has_alpha_pixels = false; |
272 |
273 |
273 switch (format) { |
274 switch (format) { |
274 |
275 |
276 case QImage::Format_Mono: |
|
277 case QImage::Format_MonoLSB: |
|
275 case QImage::Format_Indexed8: |
278 case QImage::Format_Indexed8: |
276 has_alpha_pixels = has_alpha_clut; |
279 has_alpha_pixels = has_alpha_clut; |
277 break; |
280 break; |
278 |
281 |
279 case QImage::Format_ARGB32: |
282 case QImage::Format_ARGB32: |
2270 Internal routines for converting image depth. |
2273 Internal routines for converting image depth. |
2271 *****************************************************************************/ |
2274 *****************************************************************************/ |
2272 |
2275 |
2273 typedef void (*Image_Converter)(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags); |
2276 typedef void (*Image_Converter)(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags); |
2274 |
2277 |
2278 typedef bool (*InPlace_Image_Converter)(QImageData *data, Qt::ImageConversionFlags); |
|
2279 |
|
2275 static void convert_ARGB_to_ARGB_PM(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) |
2280 static void convert_ARGB_to_ARGB_PM(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) |
2276 { |
2281 { |
2277 Q_ASSERT(src->format == QImage::Format_ARGB32); |
2282 Q_ASSERT(src->format == QImage::Format_ARGB32); |
2278 Q_ASSERT(dest->format == QImage::Format_ARGB32_Premultiplied); |
2283 Q_ASSERT(dest->format == QImage::Format_ARGB32_Premultiplied); |
2279 Q_ASSERT(src->width == dest->width); |
2284 Q_ASSERT(src->width == dest->width); |
2291 ++src_data; |
2296 ++src_data; |
2292 ++dest_data; |
2297 ++dest_data; |
2293 } |
2298 } |
2294 src_data += src_pad; |
2299 src_data += src_pad; |
2295 dest_data += dest_pad; |
2300 dest_data += dest_pad; |
2301 } |
|
2302 } |
|
2303 |
|
2304 static bool convert_ARGB_to_ARGB_PM_inplace(QImageData *data, Qt::ImageConversionFlags) |
|
2305 { |
|
2306 Q_ASSERT(data->format == QImage::Format_ARGB32); |
|
2307 |
|
2308 const int pad = (data->bytes_per_line >> 2) - data->width; |
|
2309 QRgb *rgb_data = (QRgb *) data->data; |
|
2310 |
|
2311 for (int i = 0; i < data->height; ++i) { |
|
2312 const QRgb *end = rgb_data + data->width; |
|
2313 while (rgb_data < end) { |
|
2314 *rgb_data = PREMUL(*rgb_data); |
|
2315 ++rgb_data; |
|
2316 } |
|
2317 rgb_data += pad; |
|
2318 } |
|
2319 data->format = QImage::Format_ARGB32_Premultiplied; |
|
2320 return true; |
|
2321 } |
|
2322 |
|
2323 static bool convert_indexed8_to_ARGB_PM_inplace(QImageData *data, Qt::ImageConversionFlags) |
|
2324 { |
|
2325 Q_ASSERT(data->format == QImage::Format_Indexed8); |
|
2326 const int depth = 32; |
|
2327 |
|
2328 const int dst_bytes_per_line = ((data->width * depth + 31) >> 5) << 2; |
|
2329 const int nbytes = dst_bytes_per_line * data->height; |
|
2330 uchar *const newData = (uchar *)realloc(data->data, nbytes); |
|
2331 if (!newData) |
|
2332 return false; |
|
2333 |
|
2334 data->data = newData; |
|
2335 |
|
2336 // start converting from the end because the end image is bigger than the source |
|
2337 uchar *src_data = newData + data->nbytes; // end of src |
|
2338 quint32 *dest_data = (quint32 *) (newData + nbytes); // end of dest > end of src |
|
2339 const int width = data->width; |
|
2340 const int src_pad = data->bytes_per_line - width; |
|
2341 const int dest_pad = (dst_bytes_per_line >> 2) - width; |
|
2342 if (data->colortable.size() == 0) { |
|
2343 data->colortable.resize(256); |
|
2344 for (int i = 0; i < 256; ++i) |
|
2345 data->colortable[i] = qRgb(i, i, i); |
|
2346 } else { |
|
2347 for (int i = 0; i < data->colortable.size(); ++i) |
|
2348 data->colortable[i] = PREMUL(data->colortable.at(i)); |
|
2349 |
|
2350 // Fill the rest of the table in case src_data > colortable.size() |
|
2351 const int oldSize = data->colortable.size(); |
|
2352 const QRgb lastColor = data->colortable.at(oldSize - 1); |
|
2353 data->colortable.insert(oldSize, 256 - oldSize, lastColor); |
|
2354 } |
|
2355 |
|
2356 for (int i = 0; i < data->height; ++i) { |
|
2357 src_data -= src_pad; |
|
2358 dest_data -= dest_pad; |
|
2359 for (int pixI = 0; pixI < width; ++pixI) { |
|
2360 --src_data; |
|
2361 --dest_data; |
|
2362 *dest_data = data->colortable.at(*src_data); |
|
2363 } |
|
2364 } |
|
2365 |
|
2366 data->colortable = QVector<QRgb>(); |
|
2367 data->format = QImage::Format_ARGB32_Premultiplied; |
|
2368 data->bytes_per_line = dst_bytes_per_line; |
|
2369 data->depth = depth; |
|
2370 data->nbytes = nbytes; |
|
2371 |
|
2372 return true; |
|
2373 } |
|
2374 |
|
2375 static bool convert_indexed8_to_RGB_inplace(QImageData *data, Qt::ImageConversionFlags) |
|
2376 { |
|
2377 Q_ASSERT(data->format == QImage::Format_Indexed8); |
|
2378 const int depth = 32; |
|
2379 |
|
2380 const int dst_bytes_per_line = ((data->width * depth + 31) >> 5) << 2; |
|
2381 const int nbytes = dst_bytes_per_line * data->height; |
|
2382 uchar *const newData = (uchar *)realloc(data->data, nbytes); |
|
2383 if (!newData) |
|
2384 return false; |
|
2385 |
|
2386 data->data = newData; |
|
2387 |
|
2388 // start converting from the end because the end image is bigger than the source |
|
2389 uchar *src_data = newData + data->nbytes; |
|
2390 quint32 *dest_data = (quint32 *) (newData + nbytes); |
|
2391 const int width = data->width; |
|
2392 const int src_pad = data->bytes_per_line - width; |
|
2393 const int dest_pad = (dst_bytes_per_line >> 2) - width; |
|
2394 if (data->colortable.size() == 0) { |
|
2395 data->colortable.resize(256); |
|
2396 for (int i = 0; i < 256; ++i) |
|
2397 data->colortable[i] = qRgb(i, i, i); |
|
2398 } else { |
|
2399 // Fill the rest of the table in case src_data > colortable.size() |
|
2400 const int oldSize = data->colortable.size(); |
|
2401 const QRgb lastColor = data->colortable.at(oldSize - 1); |
|
2402 data->colortable.insert(oldSize, 256 - oldSize, lastColor); |
|
2403 } |
|
2404 |
|
2405 for (int i = 0; i < data->height; ++i) { |
|
2406 src_data -= src_pad; |
|
2407 dest_data -= dest_pad; |
|
2408 for (int pixI = 0; pixI < width; ++pixI) { |
|
2409 --src_data; |
|
2410 --dest_data; |
|
2411 *dest_data = (quint32) data->colortable.at(*src_data); |
|
2412 } |
|
2413 } |
|
2414 |
|
2415 data->colortable = QVector<QRgb>(); |
|
2416 data->format = QImage::Format_RGB32; |
|
2417 data->bytes_per_line = dst_bytes_per_line; |
|
2418 data->depth = depth; |
|
2419 data->nbytes = nbytes; |
|
2420 |
|
2421 return true; |
|
2422 } |
|
2423 |
|
2424 static bool convert_indexed8_to_RGB16_inplace(QImageData *data, Qt::ImageConversionFlags) |
|
2425 { |
|
2426 Q_ASSERT(data->format == QImage::Format_Indexed8); |
|
2427 const int depth = 16; |
|
2428 |
|
2429 const int dst_bytes_per_line = ((data->width * depth + 31) >> 5) << 2; |
|
2430 const int nbytes = dst_bytes_per_line * data->height; |
|
2431 uchar *const newData = (uchar *)realloc(data->data, nbytes); |
|
2432 if (!newData) |
|
2433 return false; |
|
2434 |
|
2435 data->data = newData; |
|
2436 |
|
2437 // start converting from the end because the end image is bigger than the source |
|
2438 uchar *src_data = newData + data->nbytes; |
|
2439 quint16 *dest_data = (quint16 *) (newData + nbytes); |
|
2440 const int width = data->width; |
|
2441 const int src_pad = data->bytes_per_line - width; |
|
2442 const int dest_pad = (dst_bytes_per_line >> 1) - width; |
|
2443 |
|
2444 quint16 colorTableRGB16[256]; |
|
2445 if (data->colortable.isEmpty()) { |
|
2446 for (int i = 0; i < 256; ++i) |
|
2447 colorTableRGB16[i] = qt_colorConvert<quint16, quint32>(qRgb(i, i, i), 0); |
|
2448 } else { |
|
2449 // 1) convert the existing colors to RGB16 |
|
2450 const int tableSize = data->colortable.size(); |
|
2451 for (int i = 0; i < tableSize; ++i) |
|
2452 colorTableRGB16[i] = qt_colorConvert<quint16, quint32>(data->colortable.at(i), 0); |
|
2453 data->colortable = QVector<QRgb>(); |
|
2454 |
|
2455 // 2) fill the rest of the table in case src_data > colortable.size() |
|
2456 const quint16 lastColor = colorTableRGB16[tableSize - 1]; |
|
2457 for (int i = tableSize; i < 256; ++i) |
|
2458 colorTableRGB16[i] = lastColor; |
|
2459 } |
|
2460 |
|
2461 for (int i = 0; i < data->height; ++i) { |
|
2462 src_data -= src_pad; |
|
2463 dest_data -= dest_pad; |
|
2464 for (int pixI = 0; pixI < width; ++pixI) { |
|
2465 --src_data; |
|
2466 --dest_data; |
|
2467 *dest_data = colorTableRGB16[*src_data]; |
|
2468 } |
|
2469 } |
|
2470 |
|
2471 data->format = QImage::Format_RGB16; |
|
2472 data->bytes_per_line = dst_bytes_per_line; |
|
2473 data->depth = depth; |
|
2474 data->nbytes = nbytes; |
|
2475 |
|
2476 return true; |
|
2477 } |
|
2478 |
|
2479 static bool convert_RGB_to_RGB16_inplace(QImageData *data, Qt::ImageConversionFlags) |
|
2480 { |
|
2481 Q_ASSERT(data->format == QImage::Format_RGB32); |
|
2482 const int depth = 16; |
|
2483 |
|
2484 const int dst_bytes_per_line = ((data->width * depth + 31) >> 5) << 2; |
|
2485 const int src_bytes_per_line = data->bytes_per_line; |
|
2486 quint32 *src_data = (quint32 *) data->data; |
|
2487 quint16 *dst_data = (quint16 *) data->data; |
|
2488 |
|
2489 for (int i = 0; i < data->height; ++i) { |
|
2490 qt_memconvert(dst_data, src_data, data->width); |
|
2491 src_data = (quint32 *) (((char*)src_data) + src_bytes_per_line); |
|
2492 dst_data = (quint16 *) (((char*)dst_data) + dst_bytes_per_line); |
|
2493 } |
|
2494 data->format = QImage::Format_RGB16; |
|
2495 data->bytes_per_line = dst_bytes_per_line; |
|
2496 data->depth = depth; |
|
2497 data->nbytes = dst_bytes_per_line * data->height; |
|
2498 uchar *const newData = (uchar *)realloc(data->data, data->nbytes); |
|
2499 if (newData) { |
|
2500 data->data = newData; |
|
2501 return true; |
|
2502 } else { |
|
2503 return false; |
|
2296 } |
2504 } |
2297 } |
2505 } |
2298 |
2506 |
2299 static void convert_ARGB_PM_to_ARGB(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) |
2507 static void convert_ARGB_PM_to_ARGB(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) |
2300 { |
2508 { |
3443 0, |
3651 0, |
3444 0 |
3652 0 |
3445 } // Format_ARGB4444_Premultiplied |
3653 } // Format_ARGB4444_Premultiplied |
3446 }; |
3654 }; |
3447 |
3655 |
3656 static InPlace_Image_Converter inplace_converter_map[QImage::NImageFormats][QImage::NImageFormats] = |
|
3657 { |
|
3658 { |
|
3659 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 |
|
3660 }, |
|
3661 { |
|
3662 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 |
|
3663 }, // Format_Mono |
|
3664 { |
|
3665 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 |
|
3666 }, // Format_MonoLSB |
|
3667 { |
|
3668 0, |
|
3669 0, |
|
3670 0, |
|
3671 0, |
|
3672 0, |
|
3673 convert_indexed8_to_RGB_inplace, |
|
3674 convert_indexed8_to_ARGB_PM_inplace, |
|
3675 convert_indexed8_to_RGB16_inplace, |
|
3676 0, |
|
3677 0, |
|
3678 0, |
|
3679 0, |
|
3680 0, |
|
3681 0, |
|
3682 0, |
|
3683 0, |
|
3684 }, // Format_Indexed8 |
|
3685 { |
|
3686 0, |
|
3687 0, |
|
3688 0, |
|
3689 0, |
|
3690 0, |
|
3691 0, |
|
3692 0, |
|
3693 convert_RGB_to_RGB16_inplace, |
|
3694 0, |
|
3695 0, |
|
3696 0, |
|
3697 0, |
|
3698 0, |
|
3699 0, |
|
3700 0, |
|
3701 0, |
|
3702 }, // Format_ARGB32 |
|
3703 { |
|
3704 0, |
|
3705 0, |
|
3706 0, |
|
3707 0, |
|
3708 0, |
|
3709 0, |
|
3710 convert_ARGB_to_ARGB_PM_inplace, |
|
3711 0, |
|
3712 0, |
|
3713 0, |
|
3714 0, |
|
3715 0, |
|
3716 0, |
|
3717 0, |
|
3718 0, |
|
3719 0, |
|
3720 }, // Format_ARGB32 |
|
3721 { |
|
3722 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 |
|
3723 }, // Format_ARGB32_Premultiplied |
|
3724 { |
|
3725 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 |
|
3726 }, // Format_RGB16 |
|
3727 { |
|
3728 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 |
|
3729 }, // Format_ARGB8565_Premultiplied |
|
3730 { |
|
3731 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 |
|
3732 }, // Format_RGB666 |
|
3733 { |
|
3734 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 |
|
3735 }, // Format_ARGB6666_Premultiplied |
|
3736 { |
|
3737 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 |
|
3738 }, // Format_RGB555 |
|
3739 { |
|
3740 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 |
|
3741 }, // Format_ARGB8555_Premultiplied |
|
3742 { |
|
3743 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 |
|
3744 }, // Format_RGB888 |
|
3745 { |
|
3746 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 |
|
3747 }, // Format_RGB444 |
|
3748 { |
|
3749 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 |
|
3750 } // Format_ARGB4444_Premultiplied |
|
3751 }; |
|
3752 |
|
3753 void qInitImageConversions() |
|
3754 { |
|
3755 const uint features = qDetectCPUFeatures(); |
|
3756 Q_UNUSED(features); |
|
3757 |
|
3758 #ifdef QT_HAVE_SSE2 |
|
3759 if (features & SSE2) { |
|
3760 extern bool convert_ARGB_to_ARGB_PM_inplace_sse2(QImageData *data, Qt::ImageConversionFlags); |
|
3761 inplace_converter_map[QImage::Format_ARGB32][QImage::Format_ARGB32_Premultiplied] = convert_ARGB_to_ARGB_PM_inplace_sse2; |
|
3762 } |
|
3763 #endif |
|
3764 } |
|
3765 |
|
3448 /*! |
3766 /*! |
3449 Returns a copy of the image in the given \a format. |
3767 Returns a copy of the image in the given \a format. |
3450 |
3768 |
3451 The specified image conversion \a flags control how the image data |
3769 The specified image conversion \a flags control how the image data |
3452 is handled during the conversion process. |
3770 is handled during the conversion process. |
3795 else |
4113 else |
3796 *(s + (x >> 3)) |= (1 << (7-(x & 7))); |
4114 *(s + (x >> 3)) |= (1 << (7-(x & 7))); |
3797 } |
4115 } |
3798 break; |
4116 break; |
3799 case Format_Indexed8: |
4117 case Format_Indexed8: |
3800 if (index_or_rgb > (uint)d->colortable.size()) { |
4118 if (index_or_rgb >= (uint)d->colortable.size()) { |
3801 qWarning("QImage::setPixel: Index %d out of range", index_or_rgb); |
4119 qWarning("QImage::setPixel: Index %d out of range", index_or_rgb); |
3802 return; |
4120 return; |
3803 } |
4121 } |
3804 s[x] = index_or_rgb; |
4122 s[x] = index_or_rgb; |
3805 break; |
4123 break; |
4206 #define PIX(x,y) (*((QRgb*)scanLine(y)+x) & 0x00ffffff) |
4524 #define PIX(x,y) (*((QRgb*)scanLine(y)+x) & 0x00ffffff) |
4207 |
4525 |
4208 int w = width(); |
4526 int w = width(); |
4209 int h = height(); |
4527 int h = height(); |
4210 QImage m(w, h, Format_MonoLSB); |
4528 QImage m(w, h, Format_MonoLSB); |
4529 QIMAGE_SANITYCHECK_MEMORY(m); |
|
4211 m.setColorCount(2); |
4530 m.setColorCount(2); |
4212 m.setColor(0, QColor(Qt::color0).rgba()); |
4531 m.setColor(0, QColor(Qt::color0).rgba()); |
4213 m.setColor(1, QColor(Qt::color1).rgba()); |
4532 m.setColor(1, QColor(Qt::color1).rgba()); |
4214 m.fill(0xff); |
4533 m.fill(0xff); |
4215 |
4534 |
4298 QImage QImage::createMaskFromColor(QRgb color, Qt::MaskMode mode) const |
4617 QImage QImage::createMaskFromColor(QRgb color, Qt::MaskMode mode) const |
4299 { |
4618 { |
4300 if (!d) |
4619 if (!d) |
4301 return QImage(); |
4620 return QImage(); |
4302 QImage maskImage(size(), QImage::Format_MonoLSB); |
4621 QImage maskImage(size(), QImage::Format_MonoLSB); |
4622 QIMAGE_SANITYCHECK_MEMORY(maskImage); |
|
4303 maskImage.fill(0); |
4623 maskImage.fill(0); |
4304 uchar *s = maskImage.bits(); |
4624 uchar *s = maskImage.bits(); |
4305 |
4625 |
4306 if (depth() == 32) { |
4626 if (depth() == 32) { |
4307 for (int h = 0; h < d->height; h++) { |
4627 for (int h = 0; h < d->height; h++) { |
4358 |
4678 |
4359 int w = d->width; |
4679 int w = d->width; |
4360 int h = d->height; |
4680 int h = d->height; |
4361 // Create result image, copy colormap |
4681 // Create result image, copy colormap |
4362 QImage result(d->width, d->height, d->format); |
4682 QImage result(d->width, d->height, d->format); |
4683 QIMAGE_SANITYCHECK_MEMORY(result); |
|
4363 |
4684 |
4364 // check if we ran out of of memory.. |
4685 // check if we ran out of of memory.. |
4365 if (!result.d) |
4686 if (!result.d) |
4366 return QImage(); |
4687 return QImage(); |
4367 |
4688 |
4495 break; |
4816 break; |
4496 case Format_RGB32: |
4817 case Format_RGB32: |
4497 case Format_ARGB32: |
4818 case Format_ARGB32: |
4498 case Format_ARGB32_Premultiplied: |
4819 case Format_ARGB32_Premultiplied: |
4499 res = QImage(d->width, d->height, d->format); |
4820 res = QImage(d->width, d->height, d->format); |
4821 QIMAGE_SANITYCHECK_MEMORY(res); |
|
4500 for (int i = 0; i < d->height; i++) { |
4822 for (int i = 0; i < d->height; i++) { |
4501 uint *q = (uint*)res.scanLine(i); |
4823 uint *q = (uint*)res.scanLine(i); |
4502 uint *p = (uint*)scanLine(i); |
4824 uint *p = (uint*)scanLine(i); |
4503 uint *end = p + d->width; |
4825 uint *end = p + d->width; |
4504 while (p < end) { |
4826 while (p < end) { |
4508 } |
4830 } |
4509 } |
4831 } |
4510 break; |
4832 break; |
4511 case Format_RGB16: |
4833 case Format_RGB16: |
4512 res = QImage(d->width, d->height, d->format); |
4834 res = QImage(d->width, d->height, d->format); |
4835 QIMAGE_SANITYCHECK_MEMORY(res); |
|
4513 for (int i = 0; i < d->height; i++) { |
4836 for (int i = 0; i < d->height; i++) { |
4514 ushort *q = (ushort*)res.scanLine(i); |
4837 ushort *q = (ushort*)res.scanLine(i); |
4515 const ushort *p = (const ushort*)scanLine(i); |
4838 const ushort *p = (const ushort*)scanLine(i); |
4516 const ushort *end = p + d->width; |
4839 const ushort *end = p + d->width; |
4517 while (p < end) { |
4840 while (p < end) { |
4521 } |
4844 } |
4522 } |
4845 } |
4523 break; |
4846 break; |
4524 case Format_ARGB8565_Premultiplied: |
4847 case Format_ARGB8565_Premultiplied: |
4525 res = QImage(d->width, d->height, d->format); |
4848 res = QImage(d->width, d->height, d->format); |
4849 QIMAGE_SANITYCHECK_MEMORY(res); |
|
4526 for (int i = 0; i < d->height; i++) { |
4850 for (int i = 0; i < d->height; i++) { |
4527 quint8 *p = (quint8*)scanLine(i); |
4851 quint8 *p = (quint8*)scanLine(i); |
4528 const quint8 *end = p + d->width * sizeof(qargb8565); |
4852 const quint8 *end = p + d->width * sizeof(qargb8565); |
4529 while (p < end) { |
4853 while (p < end) { |
4530 quint16 *q = reinterpret_cast<quint16*>(p + 1); |
4854 quint16 *q = reinterpret_cast<quint16*>(p + 1); |
4533 } |
4857 } |
4534 } |
4858 } |
4535 break; |
4859 break; |
4536 case Format_RGB666: |
4860 case Format_RGB666: |
4537 res = QImage(d->width, d->height, d->format); |
4861 res = QImage(d->width, d->height, d->format); |
4862 QIMAGE_SANITYCHECK_MEMORY(res); |
|
4538 for (int i = 0; i < d->height; i++) { |
4863 for (int i = 0; i < d->height; i++) { |
4539 qrgb666 *q = reinterpret_cast<qrgb666*>(res.scanLine(i)); |
4864 qrgb666 *q = reinterpret_cast<qrgb666*>(res.scanLine(i)); |
4540 const qrgb666 *p = reinterpret_cast<const qrgb666*>(scanLine(i)); |
4865 const qrgb666 *p = reinterpret_cast<const qrgb666*>(scanLine(i)); |
4541 const qrgb666 *end = p + d->width; |
4866 const qrgb666 *end = p + d->width; |
4542 while (p < end) { |
4867 while (p < end) { |
4545 } |
4870 } |
4546 } |
4871 } |
4547 break; |
4872 break; |
4548 case Format_ARGB6666_Premultiplied: |
4873 case Format_ARGB6666_Premultiplied: |
4549 res = QImage(d->width, d->height, d->format); |
4874 res = QImage(d->width, d->height, d->format); |
4875 QIMAGE_SANITYCHECK_MEMORY(res); |
|
4550 for (int i = 0; i < d->height; i++) { |
4876 for (int i = 0; i < d->height; i++) { |
4551 qargb6666 *q = reinterpret_cast<qargb6666*>(res.scanLine(i)); |
4877 qargb6666 *q = reinterpret_cast<qargb6666*>(res.scanLine(i)); |
4552 const qargb6666 *p = reinterpret_cast<const qargb6666*>(scanLine(i)); |
4878 const qargb6666 *p = reinterpret_cast<const qargb6666*>(scanLine(i)); |
4553 const qargb6666 *end = p + d->width; |
4879 const qargb6666 *end = p + d->width; |
4554 while (p < end) { |
4880 while (p < end) { |
4557 } |
4883 } |
4558 } |
4884 } |
4559 break; |
4885 break; |
4560 case Format_RGB555: |
4886 case Format_RGB555: |
4561 res = QImage(d->width, d->height, d->format); |
4887 res = QImage(d->width, d->height, d->format); |
4888 QIMAGE_SANITYCHECK_MEMORY(res); |
|
4562 for (int i = 0; i < d->height; i++) { |
4889 for (int i = 0; i < d->height; i++) { |
4563 ushort *q = (ushort*)res.scanLine(i); |
4890 ushort *q = (ushort*)res.scanLine(i); |
4564 const ushort *p = (const ushort*)scanLine(i); |
4891 const ushort *p = (const ushort*)scanLine(i); |
4565 const ushort *end = p + d->width; |
4892 const ushort *end = p + d->width; |
4566 while (p < end) { |
4893 while (p < end) { |
4570 } |
4897 } |
4571 } |
4898 } |
4572 break; |
4899 break; |
4573 case Format_ARGB8555_Premultiplied: |
4900 case Format_ARGB8555_Premultiplied: |
4574 res = QImage(d->width, d->height, d->format); |
4901 res = QImage(d->width, d->height, d->format); |
4902 QIMAGE_SANITYCHECK_MEMORY(res); |
|
4575 for (int i = 0; i < d->height; i++) { |
4903 for (int i = 0; i < d->height; i++) { |
4576 quint8 *p = (quint8*)scanLine(i); |
4904 quint8 *p = (quint8*)scanLine(i); |
4577 const quint8 *end = p + d->width * sizeof(qargb8555); |
4905 const quint8 *end = p + d->width * sizeof(qargb8555); |
4578 while (p < end) { |
4906 while (p < end) { |
4579 quint16 *q = reinterpret_cast<quint16*>(p + 1); |
4907 quint16 *q = reinterpret_cast<quint16*>(p + 1); |
4582 } |
4910 } |
4583 } |
4911 } |
4584 break; |
4912 break; |
4585 case Format_RGB888: |
4913 case Format_RGB888: |
4586 res = QImage(d->width, d->height, d->format); |
4914 res = QImage(d->width, d->height, d->format); |
4915 QIMAGE_SANITYCHECK_MEMORY(res); |
|
4587 for (int i = 0; i < d->height; i++) { |
4916 for (int i = 0; i < d->height; i++) { |
4588 quint8 *q = reinterpret_cast<quint8*>(res.scanLine(i)); |
4917 quint8 *q = reinterpret_cast<quint8*>(res.scanLine(i)); |
4589 const quint8 *p = reinterpret_cast<const quint8*>(scanLine(i)); |
4918 const quint8 *p = reinterpret_cast<const quint8*>(scanLine(i)); |
4590 const quint8 *end = p + d->width * sizeof(qrgb888); |
4919 const quint8 *end = p + d->width * sizeof(qrgb888); |
4591 while (p < end) { |
4920 while (p < end) { |
4597 } |
4926 } |
4598 } |
4927 } |
4599 break; |
4928 break; |
4600 case Format_RGB444: |
4929 case Format_RGB444: |
4601 res = QImage(d->width, d->height, d->format); |
4930 res = QImage(d->width, d->height, d->format); |
4931 QIMAGE_SANITYCHECK_MEMORY(res); |
|
4602 for (int i = 0; i < d->height; i++) { |
4932 for (int i = 0; i < d->height; i++) { |
4603 quint8 *q = reinterpret_cast<quint8*>(res.scanLine(i)); |
4933 quint8 *q = reinterpret_cast<quint8*>(res.scanLine(i)); |
4604 const quint8 *p = reinterpret_cast<const quint8*>(scanLine(i)); |
4934 const quint8 *p = reinterpret_cast<const quint8*>(scanLine(i)); |
4605 const quint8 *end = p + d->width * sizeof(qrgb444); |
4935 const quint8 *end = p + d->width * sizeof(qrgb444); |
4606 while (p < end) { |
4936 while (p < end) { |
4611 } |
4941 } |
4612 } |
4942 } |
4613 break; |
4943 break; |
4614 case Format_ARGB4444_Premultiplied: |
4944 case Format_ARGB4444_Premultiplied: |
4615 res = QImage(d->width, d->height, d->format); |
4945 res = QImage(d->width, d->height, d->format); |
4946 QIMAGE_SANITYCHECK_MEMORY(res); |
|
4616 for (int i = 0; i < d->height; i++) { |
4947 for (int i = 0; i < d->height; i++) { |
4617 quint8 *q = reinterpret_cast<quint8*>(res.scanLine(i)); |
4948 quint8 *q = reinterpret_cast<quint8*>(res.scanLine(i)); |
4618 const quint8 *p = reinterpret_cast<const quint8*>(scanLine(i)); |
4949 const quint8 *p = reinterpret_cast<const quint8*>(scanLine(i)); |
4619 const quint8 *end = p + d->width * sizeof(qargb4444); |
4950 const quint8 *end = p + d->width * sizeof(qargb4444); |
4620 while (p < end) { |
4951 while (p < end) { |
4810 |
5141 |
4811 Writes the given \a image to the given \a stream as a PNG image, |
5142 Writes the given \a image to the given \a stream as a PNG image, |
4812 or as a BMP image if the stream's version is 1. Note that writing |
5143 or as a BMP image if the stream's version is 1. Note that writing |
4813 the stream to a file will not produce a valid image file. |
5144 the stream to a file will not produce a valid image file. |
4814 |
5145 |
4815 \sa QImage::save(), {Format of the QDataStream Operators} |
5146 \sa QImage::save(), {Serializing Qt Data Types} |
4816 */ |
5147 */ |
4817 |
5148 |
4818 QDataStream &operator<<(QDataStream &s, const QImage &image) |
5149 QDataStream &operator<<(QDataStream &s, const QImage &image) |
4819 { |
5150 { |
4820 if (s.version() >= 5) { |
5151 if (s.version() >= 5) { |
4836 \relates QImage |
5167 \relates QImage |
4837 |
5168 |
4838 Reads an image from the given \a stream and stores it in the given |
5169 Reads an image from the given \a stream and stores it in the given |
4839 \a image. |
5170 \a image. |
4840 |
5171 |
4841 \sa QImage::load(), {Format of the QDataStream Operators} |
5172 \sa QImage::load(), {Serializing Qt Data Types} |
4842 */ |
5173 */ |
4843 |
5174 |
4844 QDataStream &operator>>(QDataStream &s, QImage &image) |
5175 QDataStream &operator>>(QDataStream &s, QImage &image) |
4845 { |
5176 { |
4846 if (s.version() >= 5) { |
5177 if (s.version() >= 5) { |
6259 const QRect mapped = matrix.mapRect(rect).toAlignedRect(); |
6590 const QRect mapped = matrix.mapRect(rect).toAlignedRect(); |
6260 const QPoint delta = mapped.topLeft(); |
6591 const QPoint delta = mapped.topLeft(); |
6261 return matrix * QTransform().translate(-delta.x(), -delta.y()); |
6592 return matrix * QTransform().translate(-delta.x(), -delta.y()); |
6262 } |
6593 } |
6263 |
6594 |
6595 bool QImageData::convertInPlace(QImage::Format newFormat, Qt::ImageConversionFlags flags) |
|
6596 { |
|
6597 if (format == newFormat) |
|
6598 return true; |
|
6599 |
|
6600 const InPlace_Image_Converter *const converterPtr = &inplace_converter_map[format][newFormat]; |
|
6601 InPlace_Image_Converter converter = *converterPtr; |
|
6602 if (converter) |
|
6603 return converter(this, flags); |
|
6604 else |
|
6605 return false; |
|
6606 } |
|
6264 |
6607 |
6265 /*! |
6608 /*! |
6266 \typedef QImage::DataPtr |
6609 \typedef QImage::DataPtr |
6267 \internal |
6610 \internal |
6268 */ |
6611 */ |