@@ -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
@@ -903,13 +903,42 @@ DDSInput::seek_subimage(int subimage, int miplevel)
903903 m_spec.attribute (" textureformat" , " Plain Texture" );
904904 }
905905
906+ // Check validity of resolutions.
907+ if (m_dds.caps .flags2 & DDS_CAPS2_CUBEMAP) {
908+ // cube maps must be square and each face can be up to 16384x16384
909+ // (currently). But remember that they are stored in a 3x2 or 1x6
910+ // layout.
911+ #ifdef DDS_3X2_CUBE_MAP_LAYOUT
912+ if (!check_open (m_spec, { 0 , 16384 * 3 , 0 , 16384 * 2 , 0 , 1 , 0 , 4 }))
913+ return false ;
914+ #else
915+ if (!check_open (m_spec, { 0 , 16384 , 0 , 16384 * 6 , 0 , 1 , 0 , 4 }))
916+ return false ;
917+ #endif
918+ if (m_spec.full_width != m_spec.full_height ) {
919+ errorfmt (
920+ " Invalid cube map layout: width {} does not match height {}" ,
921+ m_spec.full_width , m_spec.full_height );
922+ return false ;
923+ }
924+ } else if (m_dds.caps .flags2 & DDS_CAPS2_VOLUME) {
925+ // volume textures are limited to 4096x4096x4096 (currently)
926+ if (!check_open (m_spec, { 0 , 4096 , 0 , 4096 , 0 , 4096 , 0 , 4 })) {
927+ return false ;
928+ }
929+ } else {
930+ // 2D textures can be up to 32768x32768
931+ if (!check_open (m_spec, { 0 , 32768 , 0 , 32768 , 0 , 1 , 0 , 4 }))
932+ return false ;
933+ }
934+
906935 m_subimage = subimage;
907936 m_miplevel = miplevel;
908937 return true ;
909938}
910939
911940bool
912- DDSInput::internal_readimg (unsigned char * dst, int w, int h, int d)
941+ DDSInput::internal_readimg (unsigned char * dst, size_t w, size_t h, size_t d)
913942{
914943 if (m_compression != Compression::None) {
915944 // compressed image
@@ -920,15 +949,15 @@ DDSInput::internal_readimg(unsigned char* dst, int w, int h, int d)
920949 if (!ioread (tmp.get (), bufsize, 1 ))
921950 return false ;
922951 // decompress image
923- DecompressImage (dst, w, h , tmp.get (), m_compression, m_dds. fmt ,
924- threads ());
952+ DecompressImage (dst, int (w), int (h) , tmp.get (), m_compression,
953+ m_dds. fmt , threads ());
925954 tmp.reset ();
926955 // correct pre-multiplied alpha, if necessary
927956 if (m_compression == Compression::DXT2
928957 || m_compression == Compression::DXT4) {
929- int k;
930- for (int y = 0 ; y < h; y++) {
931- for (int x = 0 ; x < w; x++) {
958+ size_t k;
959+ for (size_t y = 0 ; y < h; y++) {
960+ for (size_t x = 0 ; x < w; x++) {
932961 k = (y * w + x) * 4 ;
933962 if (dst[k + 3 ]) {
934963 dst[k + 0 ] = (unsigned char )((int )dst[k + 0 ] * 255
@@ -961,12 +990,12 @@ DDSInput::internal_readimg(unsigned char* dst, int w, int h, int d)
961990 }
962991
963992 std::unique_ptr<uint8_t []> tmp (new uint8_t [w * m_Bpp]);
964- for (int z = 0 ; z < d; z++) {
965- for (int y = 0 ; y < h; y++) {
993+ for (size_t z = 0 ; z < d; z++) {
994+ for (size_t y = 0 ; y < h; y++) {
966995 if (!ioread (tmp.get (), w, m_Bpp))
967996 return false ;
968997 size_t k = (z * h * w + y * w) * m_spec.nchannels ;
969- for (int x = 0 ; x < w; x++, k += m_spec.nchannels ) {
998+ for (size_t x = 0 ; x < w; x++, k += m_spec.nchannels ) {
970999 uint32_t pixel = 0 ;
9711000 memcpy (&pixel, tmp.get () + x * m_Bpp, m_Bpp);
9721001 for (int ch = 0 ; ch < m_spec.nchannels ; ++ch) {
@@ -992,8 +1021,8 @@ DDSInput::readimg_scanlines()
9921021 m_buf.resize (m_spec.scanline_bytes () * m_spec.height * m_spec.depth
9931022 /* / (1 << m_miplevel)*/ );
9941023
995- return internal_readimg (&m_buf[0 ], m_spec.width , m_spec. height ,
996- m_spec.depth );
1024+ return internal_readimg (&m_buf[0 ], size_t ( m_spec.width ) ,
1025+ size_t ( m_spec.height ), size_t (m_spec. depth ) );
9971026}
9981027
9991028
@@ -1003,8 +1032,9 @@ DDSInput::readimg_tiles()
10031032{
10041033 // resize destination buffer
10051034 OIIO_ASSERT (m_buf.size () >= m_spec.tile_bytes ());
1006- return internal_readimg (&m_buf[0 ], m_spec.tile_width , m_spec.tile_height ,
1007- m_spec.tile_depth );
1035+ return internal_readimg (&m_buf[0 ], size_t (m_spec.tile_width ),
1036+ size_t (m_spec.tile_height ),
1037+ size_t (m_spec.tile_depth ));
10081038}
10091039
10101040
@@ -1032,8 +1062,9 @@ DDSInput::read_native_scanline(int subimage, int miplevel, int y, int z,
10321062 if (m_buf.empty ())
10331063 readimg_scanlines ();
10341064
1035- size_t size = spec ().scanline_bytes ();
1036- memcpy (data, &m_buf[0 ] + z * m_spec.height * size + y * size, size);
1065+ size_t size = spec ().scanline_bytes ();
1066+ size_t offset = size_t (z) * m_spec.height * size + size_t (y) * size;
1067+ memcpy (data, &m_buf[0 ] + offset, size);
10371068 return true ;
10381069}
10391070
@@ -1075,10 +1106,10 @@ DDSInput::read_native_tile(int subimage, int miplevel, int x, int y, int z,
10751106 || z % m_spec.tile_width )
10761107 return false ;
10771108 if (m_buf.empty () || x != lastx || y != lasty || z != lastz) {
1078- lastx = x;
1079- lasty = y;
1080- lastz = z;
1081- unsigned int w = 0 , h = 0 , d = 0 ;
1109+ lastx = x;
1110+ lasty = y;
1111+ lastz = z;
1112+ size_t w = 0 , h = 0 , d = 0 ;
10821113#ifdef DDS_3X2_CUBE_MAP_LAYOUT
10831114 internal_seek_subimage (((x / m_spec.tile_width ) << 1 )
10841115 + y / m_spec.tile_height ,
0 commit comments