QImage/QPixmap size limitations?

前端 未结 4 2011
粉色の甜心
粉色の甜心 2020-12-03 17:54

Are there any known size/space limitation of QPixmap and/or QImage objects documented? I did not find any useful information regarding this. I\'m c

相关标签:
4条回答
  • 2020-12-03 18:23

    Both are limited to 32767x32767 pixels. That is, you can think of them as using a signed 16-bit value for both the X and Y resolution.

    No axis can ever exceed 32767 pixels, even if the other axis is only 1 pixel. Operating system "bitness" does not affect the limitation. The underlying system may run into other limits, such as memory as you mentioned, before such a huge image can be created.

    You can see an example of this limitation in the following source code: http://git.zx2c4.com/qt/plain/src/gui/image/qpixmap_x11.cpp

    if (uint(w) >= 32768 || uint(h) >= 32768) {
        w = h = 0;
        is_null = true;
        return;
    }
    
    0 讨论(0)
  • 2020-12-03 18:24

    I actually had occasion to look into this at one time. Do a search in the source code of qimage.cpp for "sanity check for potential overflows" and you can see the checks that Qt is doing. Basically,

    • The number of bytes required (width * height * depth_for_format) must be less than INT_MAX.
    • It must be able to malloc those bytes at the point you are creating the QImage instance.
    0 讨论(0)
  • 2020-12-03 18:27

    Are you building a 64 bit app? If not, you are going to run into memory issues very quickly. On Windows, even if the machine has 16GB ram, a 32 bit process will be limited to 2GB (Unless it is LARGEADDRESSAWARE then 3GB). A 16000x16000 image will be just under 1 GB, so you'll only be able to allocate enough memory for 1, maybe 2 if you are very lucky.

    With a 64 bit app you should be able to allocate enough memory for several images.

    0 讨论(0)
  • 2020-12-03 18:44

    Building on the answer by @charles-burns, here is relevant source code for QImage:

    QImageData *d = 0;
    
    if (format == QImage::Format_Invalid)
        return d;
    
    const int depth = qt_depthForFormat(format);
    const int calc_bytes_per_line = ((width * depth + 31)/32) * 4;
    const int min_bytes_per_line = (width * depth + 7)/8;
    
    if (bpl <= 0)
        bpl = calc_bytes_per_line;
    
    if (width <= 0 || height <= 0 || !data
        || INT_MAX/sizeof(uchar *) < uint(height)
        || INT_MAX/uint(depth) < uint(width)
        || bpl <= 0
        || height <= 0
        || bpl < min_bytes_per_line
        || INT_MAX/uint(bpl) < uint(height))
        return d;                                        // invalid parameter(s)
    

    So here, bpl is the number of bytes per line, which is effectively width * depth_in_bytes. Using algebra on that final invalid test:

    • INT_MAX/uint(bpl) < uint(height)
    • INT_MAX < uint(height) * uint(bpl)
    • INT_MAX < height * width * depth_in_bytes

    So, your image size in total must be less than 2147483647 (for 32-bit ints).

    0 讨论(0)
提交回复
热议问题