Changeset View
Changeset View
Standalone View
Standalone View
src/imageformats/tga.cpp
Context not available. | |||||
178 | { | 178 | { | ||
---|---|---|---|---|---|
179 | // Create image. | 179 | // Create image. | ||
180 | img = QImage(tga.width, tga.height, QImage::Format_RGB32); | 180 | img = QImage(tga.width, tga.height, QImage::Format_RGB32); | ||
181 | if (img.isNull()) { | ||||
182 | qWarning() << "Failed to allocate image, invalid dimensions?" << QSize(tga.width, tga.height); | ||||
183 | return false; | ||||
184 | } | ||||
181 | 185 | | |||
182 | TgaHeaderInfo info(tga); | 186 | TgaHeaderInfo info(tga); | ||
183 | 187 | | |||
Context not available. | |||||
186 | // However alpha exists only in the 32 bit format. | 190 | // However alpha exists only in the 32 bit format. | ||
187 | if ((tga.pixel_size == 32) && (tga.flags & 0xf)) { | 191 | if ((tga.pixel_size == 32) && (tga.flags & 0xf)) { | ||
188 | img = QImage(tga.width, tga.height, QImage::Format_ARGB32); | 192 | img = QImage(tga.width, tga.height, QImage::Format_ARGB32); | ||
193 | if (img.isNull()) { | ||||
194 | qWarning() << "Failed to allocate image, invalid dimensions?" << QSize(tga.width, tga.height); | ||||
195 | return false; | ||||
196 | } | ||||
189 | 197 | | |||
190 | if (numAlphaBits > 8) { | 198 | if (numAlphaBits > 8) { | ||
191 | return false; | 199 | return false; | ||
Context not available. | |||||
229 | if (info.rle) { | 237 | if (info.rle) { | ||
230 | // Decode image. | 238 | // Decode image. | ||
231 | char *dst = (char *)image; | 239 | char *dst = (char *)image; | ||
240 | char *imgEnd = dst + size; | ||||
232 | qint64 num = size; | 241 | qint64 num = size; | ||
233 | 242 | | |||
234 | while (num > 0) { | 243 | while (num > 0 && valid) { | ||
235 | if (s.atEnd()) { | 244 | if (s.atEnd()) { | ||
236 | valid = false; | 245 | valid = false; | ||
237 | break; | 246 | break; | ||
Context not available. | |||||
257 | memset(&pixel[dataRead], 0, pixel_size - dataRead); | 266 | memset(&pixel[dataRead], 0, pixel_size - dataRead); | ||
258 | } | 267 | } | ||
259 | do { | 268 | do { | ||
269 | if (dst + pixel_size > imgEnd) { | ||||
270 | qWarning() << "Trying to write out of bounds!" << ptrdiff_t(dst) << (ptrdiff_t(imgEnd) - ptrdiff_t(pixel_size)); | ||||
271 | valid = false; | ||||
272 | break; | ||||
273 | } | ||||
274 | | ||||
260 | memcpy(dst, pixel, pixel_size); | 275 | memcpy(dst, pixel, pixel_size); | ||
261 | dst += pixel_size; | 276 | dst += pixel_size; | ||
262 | } while (--count); | 277 | } while (--count); | ||
Context not available. | |||||
268 | free(image); | 283 | free(image); | ||
269 | return false; | 284 | return false; | ||
270 | } | 285 | } | ||
286 | | ||||
287 | | ||||
271 | if ((uint)dataRead < count) { | 288 | if ((uint)dataRead < count) { | ||
272 | memset(&dst[dataRead], 0, count - dataRead); | 289 | const size_t toCopy = count - dataRead; | ||
290 | if (&dst[dataRead] + toCopy > imgEnd) { | ||||
291 | qWarning() << "Trying to write out of bounds!" << ptrdiff_t(image) << ptrdiff_t(&dst[dataRead]);; | ||||
292 | valid = false; | ||||
293 | break; | ||||
294 | } | ||||
295 | | ||||
296 | memset(&dst[dataRead], 0, toCopy); | ||||
273 | } | 297 | } | ||
274 | dst += count; | 298 | dst += count; | ||
275 | } | 299 | } | ||
Context not available. |