| 2433 | }; |
| 2434 | |
| 2435 | uint8_t *read_tga(const uint8_t *pBuf, uint32_t buf_size, int &width, int &height, int &n_chans) |
| 2436 | { |
| 2437 | width = 0; |
| 2438 | height = 0; |
| 2439 | n_chans = 0; |
| 2440 | |
| 2441 | if (buf_size <= sizeof(tga_header)) |
| 2442 | return nullptr; |
| 2443 | |
| 2444 | const tga_header &hdr = *reinterpret_cast<const tga_header *>(pBuf); |
| 2445 | |
| 2446 | if ((!hdr.m_width) || (!hdr.m_height) || (hdr.m_width > MAX_TGA_IMAGE_SIZE) || (hdr.m_height > MAX_TGA_IMAGE_SIZE)) |
| 2447 | return nullptr; |
| 2448 | |
| 2449 | if (hdr.m_desc >> 6) |
| 2450 | return nullptr; |
| 2451 | |
| 2452 | // Simple validation |
| 2453 | if ((hdr.m_cmap != 0) && (hdr.m_cmap != 1)) |
| 2454 | return nullptr; |
| 2455 | |
| 2456 | if (hdr.m_cmap) |
| 2457 | { |
| 2458 | if ((hdr.m_cmap_bpp == 0) || (hdr.m_cmap_bpp > 32)) |
| 2459 | return nullptr; |
| 2460 | |
| 2461 | // Nobody implements CMapFirst correctly, so we're not supporting it. Never seen it used, either. |
| 2462 | if (hdr.m_cmap_first != 0) |
| 2463 | return nullptr; |
| 2464 | } |
| 2465 | |
| 2466 | const bool x_flipped = (hdr.m_desc & 0x10) != 0; |
| 2467 | const bool y_flipped = (hdr.m_desc & 0x20) == 0; |
| 2468 | |
| 2469 | bool rle_flag = false; |
| 2470 | int file_image_type = hdr.m_type; |
| 2471 | if (file_image_type > 8) |
| 2472 | { |
| 2473 | file_image_type -= 8; |
| 2474 | rle_flag = true; |
| 2475 | } |
| 2476 | |
| 2477 | const tga_image_type image_type = static_cast<tga_image_type>(file_image_type); |
| 2478 | |
| 2479 | switch (file_image_type) |
| 2480 | { |
| 2481 | case cITRGB: |
| 2482 | if (hdr.m_depth == 8) |
| 2483 | return nullptr; |
| 2484 | break; |
| 2485 | case cITPalettized: |
| 2486 | if ((hdr.m_depth != 8) || (hdr.m_cmap != 1) || (hdr.m_cmap_len == 0)) |
| 2487 | return nullptr; |
| 2488 | break; |
| 2489 | case cITGrayscale: |
| 2490 | if ((hdr.m_cmap != 0) || (hdr.m_cmap_len != 0)) |
| 2491 | return nullptr; |
| 2492 | if ((hdr.m_depth != 8) && (hdr.m_depth != 16)) |
no test coverage detected