@@ -97,11 +97,11 @@ class DDSInput final : public ImageInput {
9797
9898 // / Helper function: performs the actual file seeking.
9999 // /
100- void internal_seek_subimage (int cubeface, int miplevel, unsigned int & w,
101- unsigned int & h, unsigned int & d);
100+ void internal_seek_subimage (int cubeface, int miplevel, size_t & w,
101+ size_t & h, size_t & d);
102102
103103 // / Helper function: performs the actual pixel decoding.
104- bool internal_readimg (unsigned char * dst, int w, int h, int d);
104+ bool internal_readimg (unsigned char * dst, size_t w, size_t h, size_t d);
105105
106106 static bool validate_signature (uint32_t signature);
107107};
@@ -671,8 +671,8 @@ DDSInput::calc_shifts(uint32_t mask, uint32_t& count, uint32_t& right)
671671// NOTE: This function has no sanity checks! It's a private method and relies
672672// on the input being correct and valid!
673673void
674- DDSInput::internal_seek_subimage (int cubeface, int miplevel, unsigned int & w,
675- unsigned int & h, unsigned int & d)
674+ DDSInput::internal_seek_subimage (int cubeface, int miplevel, size_t & w,
675+ size_t & h, size_t & d)
676676{
677677 // early out for cubemaps that don't contain the requested face
678678 if (m_dds.caps .flags2 & DDS_CAPS2_CUBEMAP
@@ -683,10 +683,10 @@ DDSInput::internal_seek_subimage(int cubeface, int miplevel, unsigned int& w,
683683 // we can easily calculate the offsets because both compressed and
684684 // uncompressed images have predictable length
685685 // calculate the offset; start with after the header
686- unsigned int ofs = sizeof (dds_header);
686+ size_t ofs = sizeof (dds_header);
687687 if (m_dds.fmt .fourCC == DDS_4CC_DX10)
688688 ofs += sizeof (dds_header_dx10);
689- unsigned int len;
689+ size_t len;
690690 // this loop is used to iterate over cube map sides, or run once in the
691691 // case of ordinary 2D or 3D images
692692 for (int j = 0 ; j <= cubeface; j++) {
@@ -754,7 +754,7 @@ DDSInput::seek_subimage(int subimage, int miplevel)
754754 m_buf.clear ();
755755
756756 // for cube maps, the seek will be performed when reading a tile instead
757- unsigned int w = 0 , h = 0 , d = 0 ;
757+ size_t w = 0 , h = 0 , d = 0 ;
758758 TypeDesc::BASETYPE basetype = GetBaseType (m_compression);
759759 if (m_dds.caps .flags2 & DDS_CAPS2_CUBEMAP) {
760760 // calc sizes separately for cube maps
@@ -896,13 +896,42 @@ DDSInput::seek_subimage(int subimage, int miplevel)
896896 m_spec.attribute (" textureformat" , " Plain Texture" );
897897 }
898898
899+ // Check validity of resolutions.
900+ if (m_dds.caps .flags2 & DDS_CAPS2_CUBEMAP) {
901+ // cube maps must be square and each face can be up to 16384x16384
902+ // (currently). But remember that they are stored in a 3x2 or 1x6
903+ // layout.
904+ #ifdef DDS_3X2_CUBE_MAP_LAYOUT
905+ if (!check_open (m_spec, { 0 , 16384 * 3 , 0 , 16384 * 2 , 0 , 1 , 0 , 4 }))
906+ return false ;
907+ #else
908+ if (!check_open (m_spec, { 0 , 16384 , 0 , 16384 * 6 , 0 , 1 , 0 , 4 }))
909+ return false ;
910+ #endif
911+ if (m_spec.full_width != m_spec.full_height ) {
912+ errorfmt (
913+ " Invalid cube map layout: width {} does not match height {}" ,
914+ m_spec.full_width , m_spec.full_height );
915+ return false ;
916+ }
917+ } else if (m_dds.caps .flags2 & DDS_CAPS2_VOLUME) {
918+ // volume textures are limited to 4096x4096x4096 (currently)
919+ if (!check_open (m_spec, { 0 , 4096 , 0 , 4096 , 0 , 4096 , 0 , 4 })) {
920+ return false ;
921+ }
922+ } else {
923+ // 2D textures can be up to 32768x32768
924+ if (!check_open (m_spec, { 0 , 32768 , 0 , 32768 , 0 , 1 , 0 , 4 }))
925+ return false ;
926+ }
927+
899928 m_subimage = subimage;
900929 m_miplevel = miplevel;
901930 return true ;
902931}
903932
904933bool
905- DDSInput::internal_readimg (unsigned char * dst, int w, int h, int d)
934+ DDSInput::internal_readimg (unsigned char * dst, size_t w, size_t h, size_t d)
906935{
907936 if (m_compression != Compression::None) {
908937 // compressed image
@@ -913,15 +942,15 @@ DDSInput::internal_readimg(unsigned char* dst, int w, int h, int d)
913942 if (!ioread (tmp.get (), bufsize, 1 ))
914943 return false ;
915944 // decompress image
916- DecompressImage (dst, w, h , tmp.get (), m_compression, m_dds. fmt ,
917- threads ());
945+ DecompressImage (dst, int (w), int (h) , tmp.get (), m_compression,
946+ m_dds. fmt , threads ());
918947 tmp.reset ();
919948 // correct pre-multiplied alpha, if necessary
920949 if (m_compression == Compression::DXT2
921950 || m_compression == Compression::DXT4) {
922- int k;
923- for (int y = 0 ; y < h; y++) {
924- for (int x = 0 ; x < w; x++) {
951+ size_t k;
952+ for (size_t y = 0 ; y < h; y++) {
953+ for (size_t x = 0 ; x < w; x++) {
925954 k = (y * w + x) * 4 ;
926955 if (dst[k + 3 ]) {
927956 dst[k + 0 ] = (unsigned char )((int )dst[k + 0 ] * 255
@@ -954,12 +983,12 @@ DDSInput::internal_readimg(unsigned char* dst, int w, int h, int d)
954983 }
955984
956985 std::unique_ptr<uint8_t []> tmp (new uint8_t [w * m_Bpp]);
957- for (int z = 0 ; z < d; z++) {
958- for (int y = 0 ; y < h; y++) {
986+ for (size_t z = 0 ; z < d; z++) {
987+ for (size_t y = 0 ; y < h; y++) {
959988 if (!ioread (tmp.get (), w, m_Bpp))
960989 return false ;
961990 size_t k = (z * h * w + y * w) * m_spec.nchannels ;
962- for (int x = 0 ; x < w; x++, k += m_spec.nchannels ) {
991+ for (size_t x = 0 ; x < w; x++, k += m_spec.nchannels ) {
963992 uint32_t pixel = 0 ;
964993 memcpy (&pixel, tmp.get () + x * m_Bpp, m_Bpp);
965994 for (int ch = 0 ; ch < m_spec.nchannels ; ++ch) {
@@ -985,8 +1014,8 @@ DDSInput::readimg_scanlines()
9851014 m_buf.resize (m_spec.scanline_bytes () * m_spec.height * m_spec.depth
9861015 /* / (1 << m_miplevel)*/ );
9871016
988- return internal_readimg (&m_buf[0 ], m_spec.width , m_spec. height ,
989- m_spec.depth );
1017+ return internal_readimg (&m_buf[0 ], size_t ( m_spec.width ) ,
1018+ size_t ( m_spec.height ), size_t (m_spec. depth ) );
9901019}
9911020
9921021
@@ -996,8 +1025,9 @@ DDSInput::readimg_tiles()
9961025{
9971026 // resize destination buffer
9981027 OIIO_ASSERT (m_buf.size () >= m_spec.tile_bytes ());
999- return internal_readimg (&m_buf[0 ], m_spec.tile_width , m_spec.tile_height ,
1000- m_spec.tile_depth );
1028+ return internal_readimg (&m_buf[0 ], size_t (m_spec.tile_width ),
1029+ size_t (m_spec.tile_height ),
1030+ size_t (m_spec.tile_depth ));
10011031}
10021032
10031033
@@ -1025,8 +1055,9 @@ DDSInput::read_native_scanline(int subimage, int miplevel, int y, int z,
10251055 if (m_buf.empty ())
10261056 readimg_scanlines ();
10271057
1028- size_t size = spec ().scanline_bytes ();
1029- memcpy (data, &m_buf[0 ] + z * m_spec.height * size + y * size, size);
1058+ size_t size = spec ().scanline_bytes ();
1059+ size_t offset = size_t (z) * m_spec.height * size + size_t (y) * size;
1060+ memcpy (data, &m_buf[0 ] + offset, size);
10301061 return true ;
10311062}
10321063
@@ -1051,10 +1082,10 @@ DDSInput::read_native_tile(int subimage, int miplevel, int x, int y, int z,
10511082 || z % m_spec.tile_width )
10521083 return false ;
10531084 if (m_buf.empty () || x != lastx || y != lasty || z != lastz) {
1054- lastx = x;
1055- lasty = y;
1056- lastz = z;
1057- unsigned int w = 0 , h = 0 , d = 0 ;
1085+ lastx = x;
1086+ lasty = y;
1087+ lastz = z;
1088+ size_t w = 0 , h = 0 , d = 0 ;
10581089#ifdef DDS_3X2_CUBE_MAP_LAYOUT
10591090 internal_seek_subimage (((x / m_spec.tile_width ) << 1 )
10601091 + y / m_spec.tile_height ,
0 commit comments