| OLD | NEW |
| 1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
| 6 | 6 |
| 7 #include "core/fxcodec/lbmp/fx_bmp.h" | 7 #include "core/fxcodec/lbmp/fx_bmp.h" |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 | 10 |
| 11 namespace { | 11 namespace { |
| 12 | 12 |
| 13 const size_t kBmpCoreHeaderSize = 12; | 13 const size_t kBmpCoreHeaderSize = 12; |
| 14 const size_t kBmpInfoHeaderSize = 40; | 14 const size_t kBmpInfoHeaderSize = 40; |
| 15 | 15 |
| 16 // TODO(thestig): Replace with FXDWORD_GET_LSBFIRST? | 16 // TODO(thestig): Replace with FXDWORD_GET_LSBFIRST? |
| 17 FX_DWORD GetDWord_LSBFirst(uint8_t* p) { | 17 uint32_t GetDWord_LSBFirst(uint8_t* p) { |
| 18 return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); | 18 return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); |
| 19 } | 19 } |
| 20 | 20 |
| 21 void SetDWord_LSBFirst(uint8_t* p, FX_DWORD v) { | 21 void SetDWord_LSBFirst(uint8_t* p, uint32_t v) { |
| 22 p[0] = (uint8_t)v; | 22 p[0] = (uint8_t)v; |
| 23 p[1] = (uint8_t)(v >> 8); | 23 p[1] = (uint8_t)(v >> 8); |
| 24 p[2] = (uint8_t)(v >> 16); | 24 p[2] = (uint8_t)(v >> 16); |
| 25 p[3] = (uint8_t)(v >> 24); | 25 p[3] = (uint8_t)(v >> 24); |
| 26 } | 26 } |
| 27 } // namespace | 27 } // namespace |
| 28 | 28 |
| 29 uint16_t GetWord_LSBFirst(uint8_t* p) { | 29 uint16_t GetWord_LSBFirst(uint8_t* p) { |
| 30 return p[0] | (p[1] << 8); | 30 return p[0] | (p[1] << 8); |
| 31 } | 31 } |
| (...skipping 26 matching lines...) Expand all Loading... |
| 58 FX_Free(bmp_ptr->out_row_buffer); | 58 FX_Free(bmp_ptr->out_row_buffer); |
| 59 } | 59 } |
| 60 FX_Free(bmp_ptr->pal_ptr); | 60 FX_Free(bmp_ptr->pal_ptr); |
| 61 FX_Free(bmp_ptr->bmp_header_ptr); | 61 FX_Free(bmp_ptr->bmp_header_ptr); |
| 62 FX_Free(bmp_ptr); | 62 FX_Free(bmp_ptr); |
| 63 } | 63 } |
| 64 int32_t bmp_read_header(bmp_decompress_struct_p bmp_ptr) { | 64 int32_t bmp_read_header(bmp_decompress_struct_p bmp_ptr) { |
| 65 if (bmp_ptr == NULL) { | 65 if (bmp_ptr == NULL) { |
| 66 return 0; | 66 return 0; |
| 67 } | 67 } |
| 68 FX_DWORD skip_size_org = bmp_ptr->skip_size; | 68 uint32_t skip_size_org = bmp_ptr->skip_size; |
| 69 if (bmp_ptr->decode_status == BMP_D_STATUS_HEADER) { | 69 if (bmp_ptr->decode_status == BMP_D_STATUS_HEADER) { |
| 70 ASSERT(sizeof(BmpFileHeader) == 14); | 70 ASSERT(sizeof(BmpFileHeader) == 14); |
| 71 BmpFileHeader* bmp_header_ptr = NULL; | 71 BmpFileHeader* bmp_header_ptr = NULL; |
| 72 if (bmp_read_data(bmp_ptr, (uint8_t**)&bmp_header_ptr, 14) == NULL) { | 72 if (bmp_read_data(bmp_ptr, (uint8_t**)&bmp_header_ptr, 14) == NULL) { |
| 73 return 2; | 73 return 2; |
| 74 } | 74 } |
| 75 bmp_ptr->bmp_header_ptr->bfType = | 75 bmp_ptr->bmp_header_ptr->bfType = |
| 76 GetWord_LSBFirst((uint8_t*)&bmp_header_ptr->bfType); | 76 GetWord_LSBFirst((uint8_t*)&bmp_header_ptr->bfType); |
| 77 bmp_ptr->bmp_header_ptr->bfOffBits = | 77 bmp_ptr->bmp_header_ptr->bfOffBits = |
| 78 GetDWord_LSBFirst((uint8_t*)&bmp_header_ptr->bfOffBits); | 78 GetDWord_LSBFirst((uint8_t*)&bmp_header_ptr->bfOffBits); |
| 79 bmp_ptr->data_size = GetDWord_LSBFirst((uint8_t*)&bmp_header_ptr->bfSize); | 79 bmp_ptr->data_size = GetDWord_LSBFirst((uint8_t*)&bmp_header_ptr->bfSize); |
| 80 if (bmp_ptr->bmp_header_ptr->bfType != BMP_SIGNATURE) { | 80 if (bmp_ptr->bmp_header_ptr->bfType != BMP_SIGNATURE) { |
| 81 bmp_error(bmp_ptr, "Not A Bmp Image"); | 81 bmp_error(bmp_ptr, "Not A Bmp Image"); |
| 82 return 0; | 82 return 0; |
| 83 } | 83 } |
| 84 if (bmp_ptr->avail_in < sizeof(FX_DWORD)) { | 84 if (bmp_ptr->avail_in < sizeof(uint32_t)) { |
| 85 bmp_ptr->skip_size = skip_size_org; | 85 bmp_ptr->skip_size = skip_size_org; |
| 86 return 2; | 86 return 2; |
| 87 } | 87 } |
| 88 bmp_ptr->img_ifh_size = | 88 bmp_ptr->img_ifh_size = |
| 89 GetDWord_LSBFirst(bmp_ptr->next_in + bmp_ptr->skip_size); | 89 GetDWord_LSBFirst(bmp_ptr->next_in + bmp_ptr->skip_size); |
| 90 bmp_ptr->pal_type = 0; | 90 bmp_ptr->pal_type = 0; |
| 91 static_assert(sizeof(BmpCoreHeader) == kBmpCoreHeaderSize, | 91 static_assert(sizeof(BmpCoreHeader) == kBmpCoreHeaderSize, |
| 92 "BmpCoreHeader has wrong size"); | 92 "BmpCoreHeader has wrong size"); |
| 93 static_assert(sizeof(BmpInfoHeader) == kBmpInfoHeaderSize, | 93 static_assert(sizeof(BmpInfoHeader) == kBmpInfoHeaderSize, |
| 94 "BmpInfoHeader has wrong size"); | 94 "BmpInfoHeader has wrong size"); |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 175 } | 175 } |
| 176 } | 176 } |
| 177 ASSERT(bmp_ptr->width > 0); | 177 ASSERT(bmp_ptr->width > 0); |
| 178 ASSERT(bmp_ptr->compress_flag <= BMP_BITFIELDS); | 178 ASSERT(bmp_ptr->compress_flag <= BMP_BITFIELDS); |
| 179 switch (bmp_ptr->bitCounts) { | 179 switch (bmp_ptr->bitCounts) { |
| 180 case 1: | 180 case 1: |
| 181 case 4: | 181 case 4: |
| 182 case 8: | 182 case 8: |
| 183 case 16: | 183 case 16: |
| 184 case 24: { | 184 case 24: { |
| 185 if (bmp_ptr->color_used > ((FX_DWORD)1) << bmp_ptr->bitCounts) { | 185 if (bmp_ptr->color_used > ((uint32_t)1) << bmp_ptr->bitCounts) { |
| 186 bmp_error(bmp_ptr, "The Bmp File Is Corrupt"); | 186 bmp_error(bmp_ptr, "The Bmp File Is Corrupt"); |
| 187 return 0; | 187 return 0; |
| 188 } | 188 } |
| 189 } | 189 } |
| 190 case 32: { | 190 case 32: { |
| 191 if (bmp_ptr->width <= 0 || bmp_ptr->compress_flag > BMP_BITFIELDS) { | 191 if (bmp_ptr->width <= 0 || bmp_ptr->compress_flag > BMP_BITFIELDS) { |
| 192 bmp_error(bmp_ptr, "The Bmp File Is Corrupt"); | 192 bmp_error(bmp_ptr, "The Bmp File Is Corrupt"); |
| 193 return 0; | 193 return 0; |
| 194 } | 194 } |
| 195 } break; | 195 } break; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 220 FXSYS_memset(bmp_ptr->out_row_buffer, 0, bmp_ptr->out_row_bytes); | 220 FXSYS_memset(bmp_ptr->out_row_buffer, 0, bmp_ptr->out_row_bytes); |
| 221 bmp_save_decoding_status(bmp_ptr, BMP_D_STATUS_PAL); | 221 bmp_save_decoding_status(bmp_ptr, BMP_D_STATUS_PAL); |
| 222 } | 222 } |
| 223 if (bmp_ptr->decode_status == BMP_D_STATUS_PAL) { | 223 if (bmp_ptr->decode_status == BMP_D_STATUS_PAL) { |
| 224 skip_size_org = bmp_ptr->skip_size; | 224 skip_size_org = bmp_ptr->skip_size; |
| 225 if (bmp_ptr->compress_flag == BMP_BITFIELDS) { | 225 if (bmp_ptr->compress_flag == BMP_BITFIELDS) { |
| 226 if (bmp_ptr->bitCounts != 16 && bmp_ptr->bitCounts != 32) { | 226 if (bmp_ptr->bitCounts != 16 && bmp_ptr->bitCounts != 32) { |
| 227 bmp_error(bmp_ptr, "The Bmp File Is Corrupt"); | 227 bmp_error(bmp_ptr, "The Bmp File Is Corrupt"); |
| 228 return 0; | 228 return 0; |
| 229 } | 229 } |
| 230 FX_DWORD* mask; | 230 uint32_t* mask; |
| 231 if (bmp_read_data(bmp_ptr, (uint8_t**)&mask, 3 * sizeof(FX_DWORD)) == | 231 if (bmp_read_data(bmp_ptr, (uint8_t**)&mask, 3 * sizeof(uint32_t)) == |
| 232 NULL) { | 232 NULL) { |
| 233 bmp_ptr->skip_size = skip_size_org; | 233 bmp_ptr->skip_size = skip_size_org; |
| 234 return 2; | 234 return 2; |
| 235 } | 235 } |
| 236 bmp_ptr->mask_red = GetDWord_LSBFirst((uint8_t*)&mask[0]); | 236 bmp_ptr->mask_red = GetDWord_LSBFirst((uint8_t*)&mask[0]); |
| 237 bmp_ptr->mask_green = GetDWord_LSBFirst((uint8_t*)&mask[1]); | 237 bmp_ptr->mask_green = GetDWord_LSBFirst((uint8_t*)&mask[1]); |
| 238 bmp_ptr->mask_blue = GetDWord_LSBFirst((uint8_t*)&mask[2]); | 238 bmp_ptr->mask_blue = GetDWord_LSBFirst((uint8_t*)&mask[2]); |
| 239 if (bmp_ptr->mask_red & bmp_ptr->mask_green || | 239 if (bmp_ptr->mask_red & bmp_ptr->mask_green || |
| 240 bmp_ptr->mask_red & bmp_ptr->mask_blue || | 240 bmp_ptr->mask_red & bmp_ptr->mask_blue || |
| 241 bmp_ptr->mask_green & bmp_ptr->mask_blue) { | 241 bmp_ptr->mask_green & bmp_ptr->mask_blue) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 252 bmp_ptr->mask_green = 0x03E0; | 252 bmp_ptr->mask_green = 0x03E0; |
| 253 bmp_ptr->mask_blue = 0x001F; | 253 bmp_ptr->mask_blue = 0x001F; |
| 254 } | 254 } |
| 255 bmp_ptr->pal_num = 0; | 255 bmp_ptr->pal_num = 0; |
| 256 if (bmp_ptr->bitCounts < 16) { | 256 if (bmp_ptr->bitCounts < 16) { |
| 257 bmp_ptr->pal_num = 1 << bmp_ptr->bitCounts; | 257 bmp_ptr->pal_num = 1 << bmp_ptr->bitCounts; |
| 258 if (bmp_ptr->color_used != 0) { | 258 if (bmp_ptr->color_used != 0) { |
| 259 bmp_ptr->pal_num = bmp_ptr->color_used; | 259 bmp_ptr->pal_num = bmp_ptr->color_used; |
| 260 } | 260 } |
| 261 uint8_t* src_pal_ptr = NULL; | 261 uint8_t* src_pal_ptr = NULL; |
| 262 FX_DWORD src_pal_size = bmp_ptr->pal_num * (bmp_ptr->pal_type ? 3 : 4); | 262 uint32_t src_pal_size = bmp_ptr->pal_num * (bmp_ptr->pal_type ? 3 : 4); |
| 263 if (bmp_read_data(bmp_ptr, (uint8_t**)&src_pal_ptr, src_pal_size) == | 263 if (bmp_read_data(bmp_ptr, (uint8_t**)&src_pal_ptr, src_pal_size) == |
| 264 NULL) { | 264 NULL) { |
| 265 bmp_ptr->skip_size = skip_size_org; | 265 bmp_ptr->skip_size = skip_size_org; |
| 266 return 2; | 266 return 2; |
| 267 } | 267 } |
| 268 FX_Free(bmp_ptr->pal_ptr); | 268 FX_Free(bmp_ptr->pal_ptr); |
| 269 bmp_ptr->pal_ptr = FX_Alloc(FX_DWORD, bmp_ptr->pal_num); | 269 bmp_ptr->pal_ptr = FX_Alloc(uint32_t, bmp_ptr->pal_num); |
| 270 int32_t src_pal_index = 0; | 270 int32_t src_pal_index = 0; |
| 271 if (bmp_ptr->pal_type == BMP_PAL_OLD) { | 271 if (bmp_ptr->pal_type == BMP_PAL_OLD) { |
| 272 while (src_pal_index < bmp_ptr->pal_num) { | 272 while (src_pal_index < bmp_ptr->pal_num) { |
| 273 bmp_ptr->pal_ptr[src_pal_index++] = BMP_PAL_ENCODE( | 273 bmp_ptr->pal_ptr[src_pal_index++] = BMP_PAL_ENCODE( |
| 274 0x00, src_pal_ptr[2], src_pal_ptr[1], src_pal_ptr[0]); | 274 0x00, src_pal_ptr[2], src_pal_ptr[1], src_pal_ptr[0]); |
| 275 src_pal_ptr += 3; | 275 src_pal_ptr += 3; |
| 276 } | 276 } |
| 277 } else { | 277 } else { |
| 278 while (src_pal_index < bmp_ptr->pal_num) { | 278 while (src_pal_index < bmp_ptr->pal_num) { |
| 279 bmp_ptr->pal_ptr[src_pal_index++] = BMP_PAL_ENCODE( | 279 bmp_ptr->pal_ptr[src_pal_index++] = BMP_PAL_ENCODE( |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 381 bmp_ptr->out_row_buffer); | 381 bmp_ptr->out_row_buffer); |
| 382 } | 382 } |
| 383 bmp_save_decoding_status(bmp_ptr, BMP_D_STATUS_TAIL); | 383 bmp_save_decoding_status(bmp_ptr, BMP_D_STATUS_TAIL); |
| 384 return 1; | 384 return 1; |
| 385 } | 385 } |
| 386 int32_t bmp_decode_rle8(bmp_decompress_struct_p bmp_ptr) { | 386 int32_t bmp_decode_rle8(bmp_decompress_struct_p bmp_ptr) { |
| 387 uint8_t* first_byte_ptr = NULL; | 387 uint8_t* first_byte_ptr = NULL; |
| 388 uint8_t* second_byte_ptr = NULL; | 388 uint8_t* second_byte_ptr = NULL; |
| 389 bmp_ptr->col_num = 0; | 389 bmp_ptr->col_num = 0; |
| 390 while (TRUE) { | 390 while (TRUE) { |
| 391 FX_DWORD skip_size_org = bmp_ptr->skip_size; | 391 uint32_t skip_size_org = bmp_ptr->skip_size; |
| 392 if (bmp_read_data(bmp_ptr, &first_byte_ptr, 1) == NULL) { | 392 if (bmp_read_data(bmp_ptr, &first_byte_ptr, 1) == NULL) { |
| 393 return 2; | 393 return 2; |
| 394 } | 394 } |
| 395 switch (*first_byte_ptr) { | 395 switch (*first_byte_ptr) { |
| 396 case RLE_MARKER: { | 396 case RLE_MARKER: { |
| 397 if (bmp_read_data(bmp_ptr, &first_byte_ptr, 1) == NULL) { | 397 if (bmp_read_data(bmp_ptr, &first_byte_ptr, 1) == NULL) { |
| 398 bmp_ptr->skip_size = skip_size_org; | 398 bmp_ptr->skip_size = skip_size_org; |
| 399 return 2; | 399 return 2; |
| 400 } | 400 } |
| 401 switch (*first_byte_ptr) { | 401 switch (*first_byte_ptr) { |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 483 } | 483 } |
| 484 } | 484 } |
| 485 bmp_error(bmp_ptr, "Any Uncontrol Error"); | 485 bmp_error(bmp_ptr, "Any Uncontrol Error"); |
| 486 return 0; | 486 return 0; |
| 487 } | 487 } |
| 488 int32_t bmp_decode_rle4(bmp_decompress_struct_p bmp_ptr) { | 488 int32_t bmp_decode_rle4(bmp_decompress_struct_p bmp_ptr) { |
| 489 uint8_t* first_byte_ptr = NULL; | 489 uint8_t* first_byte_ptr = NULL; |
| 490 uint8_t* second_byte_ptr = NULL; | 490 uint8_t* second_byte_ptr = NULL; |
| 491 bmp_ptr->col_num = 0; | 491 bmp_ptr->col_num = 0; |
| 492 while (TRUE) { | 492 while (TRUE) { |
| 493 FX_DWORD skip_size_org = bmp_ptr->skip_size; | 493 uint32_t skip_size_org = bmp_ptr->skip_size; |
| 494 if (bmp_read_data(bmp_ptr, &first_byte_ptr, 1) == NULL) { | 494 if (bmp_read_data(bmp_ptr, &first_byte_ptr, 1) == NULL) { |
| 495 return 2; | 495 return 2; |
| 496 } | 496 } |
| 497 switch (*first_byte_ptr) { | 497 switch (*first_byte_ptr) { |
| 498 case RLE_MARKER: { | 498 case RLE_MARKER: { |
| 499 if (bmp_read_data(bmp_ptr, &first_byte_ptr, 1) == NULL) { | 499 if (bmp_read_data(bmp_ptr, &first_byte_ptr, 1) == NULL) { |
| 500 bmp_ptr->skip_size = skip_size_org; | 500 bmp_ptr->skip_size = skip_size_org; |
| 501 return 2; | 501 return 2; |
| 502 } | 502 } |
| 503 switch (*first_byte_ptr) { | 503 switch (*first_byte_ptr) { |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 601 } | 601 } |
| 602 } | 602 } |
| 603 } | 603 } |
| 604 } | 604 } |
| 605 } | 605 } |
| 606 bmp_error(bmp_ptr, "Any Uncontrol Error"); | 606 bmp_error(bmp_ptr, "Any Uncontrol Error"); |
| 607 return 0; | 607 return 0; |
| 608 } | 608 } |
| 609 uint8_t* bmp_read_data(bmp_decompress_struct_p bmp_ptr, | 609 uint8_t* bmp_read_data(bmp_decompress_struct_p bmp_ptr, |
| 610 uint8_t** des_buf_pp, | 610 uint8_t** des_buf_pp, |
| 611 FX_DWORD data_size) { | 611 uint32_t data_size) { |
| 612 if (bmp_ptr == NULL || bmp_ptr->avail_in < bmp_ptr->skip_size + data_size) { | 612 if (bmp_ptr == NULL || bmp_ptr->avail_in < bmp_ptr->skip_size + data_size) { |
| 613 return NULL; | 613 return NULL; |
| 614 } | 614 } |
| 615 *des_buf_pp = bmp_ptr->next_in + bmp_ptr->skip_size; | 615 *des_buf_pp = bmp_ptr->next_in + bmp_ptr->skip_size; |
| 616 bmp_ptr->skip_size += data_size; | 616 bmp_ptr->skip_size += data_size; |
| 617 return *des_buf_pp; | 617 return *des_buf_pp; |
| 618 } | 618 } |
| 619 void bmp_save_decoding_status(bmp_decompress_struct_p bmp_ptr, int32_t status) { | 619 void bmp_save_decoding_status(bmp_decompress_struct_p bmp_ptr, int32_t status) { |
| 620 bmp_ptr->decode_status = status; | 620 bmp_ptr->decode_status = status; |
| 621 bmp_ptr->next_in += bmp_ptr->skip_size; | 621 bmp_ptr->next_in += bmp_ptr->skip_size; |
| 622 bmp_ptr->avail_in -= bmp_ptr->skip_size; | 622 bmp_ptr->avail_in -= bmp_ptr->skip_size; |
| 623 bmp_ptr->skip_size = 0; | 623 bmp_ptr->skip_size = 0; |
| 624 } | 624 } |
| 625 void bmp_input_buffer(bmp_decompress_struct_p bmp_ptr, | 625 void bmp_input_buffer(bmp_decompress_struct_p bmp_ptr, |
| 626 uint8_t* src_buf, | 626 uint8_t* src_buf, |
| 627 FX_DWORD src_size) { | 627 uint32_t src_size) { |
| 628 bmp_ptr->next_in = src_buf; | 628 bmp_ptr->next_in = src_buf; |
| 629 bmp_ptr->avail_in = src_size; | 629 bmp_ptr->avail_in = src_size; |
| 630 bmp_ptr->skip_size = 0; | 630 bmp_ptr->skip_size = 0; |
| 631 } | 631 } |
| 632 FX_DWORD bmp_get_avail_input(bmp_decompress_struct_p bmp_ptr, | 632 uint32_t bmp_get_avail_input(bmp_decompress_struct_p bmp_ptr, |
| 633 uint8_t** avial_buf_ptr) { | 633 uint8_t** avial_buf_ptr) { |
| 634 if (avial_buf_ptr) { | 634 if (avial_buf_ptr) { |
| 635 *avial_buf_ptr = NULL; | 635 *avial_buf_ptr = NULL; |
| 636 if (bmp_ptr->avail_in > 0) { | 636 if (bmp_ptr->avail_in > 0) { |
| 637 *avial_buf_ptr = bmp_ptr->next_in; | 637 *avial_buf_ptr = bmp_ptr->next_in; |
| 638 } | 638 } |
| 639 } | 639 } |
| 640 return bmp_ptr->avail_in; | 640 return bmp_ptr->avail_in; |
| 641 } | 641 } |
| 642 bmp_compress_struct_p bmp_create_compress() { | 642 bmp_compress_struct_p bmp_create_compress() { |
| 643 bmp_compress_struct_p bmp_ptr; | 643 bmp_compress_struct_p bmp_ptr; |
| 644 bmp_ptr = FX_Alloc(bmp_compress_struct, 1); | 644 bmp_ptr = FX_Alloc(bmp_compress_struct, 1); |
| 645 if (bmp_ptr) { | 645 if (bmp_ptr) { |
| 646 FXSYS_memset(bmp_ptr, 0, sizeof(bmp_compress_struct)); | 646 FXSYS_memset(bmp_ptr, 0, sizeof(bmp_compress_struct)); |
| 647 } | 647 } |
| 648 return bmp_ptr; | 648 return bmp_ptr; |
| 649 } | 649 } |
| 650 void bmp_destroy_compress(bmp_compress_struct_p bmp_ptr) { | 650 void bmp_destroy_compress(bmp_compress_struct_p bmp_ptr) { |
| 651 if (bmp_ptr) { | 651 if (bmp_ptr) { |
| 652 if (bmp_ptr->src_free && bmp_ptr->src_buf) { | 652 if (bmp_ptr->src_free && bmp_ptr->src_buf) { |
| 653 FX_Free(bmp_ptr->src_buf); | 653 FX_Free(bmp_ptr->src_buf); |
| 654 } | 654 } |
| 655 FX_Free(bmp_ptr); | 655 FX_Free(bmp_ptr); |
| 656 } | 656 } |
| 657 } | 657 } |
| 658 static void WriteFileHeader(BmpFileHeaderPtr head_ptr, uint8_t* dst_buf) { | 658 static void WriteFileHeader(BmpFileHeaderPtr head_ptr, uint8_t* dst_buf) { |
| 659 FX_DWORD offset; | 659 uint32_t offset; |
| 660 offset = 0; | 660 offset = 0; |
| 661 SetWord_LSBFirst(&dst_buf[offset], head_ptr->bfType); | 661 SetWord_LSBFirst(&dst_buf[offset], head_ptr->bfType); |
| 662 offset += 2; | 662 offset += 2; |
| 663 SetDWord_LSBFirst(&dst_buf[offset], head_ptr->bfSize); | 663 SetDWord_LSBFirst(&dst_buf[offset], head_ptr->bfSize); |
| 664 offset += 4; | 664 offset += 4; |
| 665 SetWord_LSBFirst(&dst_buf[offset], head_ptr->bfReserved1); | 665 SetWord_LSBFirst(&dst_buf[offset], head_ptr->bfReserved1); |
| 666 offset += 2; | 666 offset += 2; |
| 667 SetWord_LSBFirst(&dst_buf[offset], head_ptr->bfReserved2); | 667 SetWord_LSBFirst(&dst_buf[offset], head_ptr->bfReserved2); |
| 668 offset += 2; | 668 offset += 2; |
| 669 SetDWord_LSBFirst(&dst_buf[offset], head_ptr->bfOffBits); | 669 SetDWord_LSBFirst(&dst_buf[offset], head_ptr->bfOffBits); |
| 670 offset += 4; | 670 offset += 4; |
| 671 } | 671 } |
| 672 static void WriteInfoHeader(BmpInfoHeaderPtr info_head_ptr, uint8_t* dst_buf) { | 672 static void WriteInfoHeader(BmpInfoHeaderPtr info_head_ptr, uint8_t* dst_buf) { |
| 673 FX_DWORD offset; | 673 uint32_t offset; |
| 674 offset = sizeof(BmpFileHeader); | 674 offset = sizeof(BmpFileHeader); |
| 675 SetDWord_LSBFirst(&dst_buf[offset], info_head_ptr->biSize); | 675 SetDWord_LSBFirst(&dst_buf[offset], info_head_ptr->biSize); |
| 676 offset += 4; | 676 offset += 4; |
| 677 SetDWord_LSBFirst(&dst_buf[offset], info_head_ptr->biWidth); | 677 SetDWord_LSBFirst(&dst_buf[offset], info_head_ptr->biWidth); |
| 678 offset += 4; | 678 offset += 4; |
| 679 SetDWord_LSBFirst(&dst_buf[offset], info_head_ptr->biHeight); | 679 SetDWord_LSBFirst(&dst_buf[offset], info_head_ptr->biHeight); |
| 680 offset += 4; | 680 offset += 4; |
| 681 SetWord_LSBFirst(&dst_buf[offset], info_head_ptr->biPlanes); | 681 SetWord_LSBFirst(&dst_buf[offset], info_head_ptr->biPlanes); |
| 682 offset += 2; | 682 offset += 2; |
| 683 SetWord_LSBFirst(&dst_buf[offset], info_head_ptr->biBitCount); | 683 SetWord_LSBFirst(&dst_buf[offset], info_head_ptr->biBitCount); |
| 684 offset += 2; | 684 offset += 2; |
| 685 SetDWord_LSBFirst(&dst_buf[offset], info_head_ptr->biCompression); | 685 SetDWord_LSBFirst(&dst_buf[offset], info_head_ptr->biCompression); |
| 686 offset += 4; | 686 offset += 4; |
| 687 SetDWord_LSBFirst(&dst_buf[offset], info_head_ptr->biSizeImage); | 687 SetDWord_LSBFirst(&dst_buf[offset], info_head_ptr->biSizeImage); |
| 688 offset += 4; | 688 offset += 4; |
| 689 SetDWord_LSBFirst(&dst_buf[offset], info_head_ptr->biXPelsPerMeter); | 689 SetDWord_LSBFirst(&dst_buf[offset], info_head_ptr->biXPelsPerMeter); |
| 690 offset += 4; | 690 offset += 4; |
| 691 SetDWord_LSBFirst(&dst_buf[offset], info_head_ptr->biYPelsPerMeter); | 691 SetDWord_LSBFirst(&dst_buf[offset], info_head_ptr->biYPelsPerMeter); |
| 692 offset += 4; | 692 offset += 4; |
| 693 SetDWord_LSBFirst(&dst_buf[offset], info_head_ptr->biClrUsed); | 693 SetDWord_LSBFirst(&dst_buf[offset], info_head_ptr->biClrUsed); |
| 694 offset += 4; | 694 offset += 4; |
| 695 SetDWord_LSBFirst(&dst_buf[offset], info_head_ptr->biClrImportant); | 695 SetDWord_LSBFirst(&dst_buf[offset], info_head_ptr->biClrImportant); |
| 696 offset += 4; | 696 offset += 4; |
| 697 } | 697 } |
| 698 static void bmp_encode_bitfields(bmp_compress_struct_p bmp_ptr, | 698 static void bmp_encode_bitfields(bmp_compress_struct_p bmp_ptr, |
| 699 uint8_t*& dst_buf, | 699 uint8_t*& dst_buf, |
| 700 FX_DWORD& dst_size) { | 700 uint32_t& dst_size) { |
| 701 if (bmp_ptr->info_header.biBitCount != 16 && | 701 if (bmp_ptr->info_header.biBitCount != 16 && |
| 702 bmp_ptr->info_header.biBitCount != 32) { | 702 bmp_ptr->info_header.biBitCount != 32) { |
| 703 return; | 703 return; |
| 704 } | 704 } |
| 705 FX_DWORD size, dst_pos, i; | 705 uint32_t size, dst_pos, i; |
| 706 size = bmp_ptr->src_pitch * bmp_ptr->src_row * | 706 size = bmp_ptr->src_pitch * bmp_ptr->src_row * |
| 707 bmp_ptr->info_header.biBitCount / 16; | 707 bmp_ptr->info_header.biBitCount / 16; |
| 708 dst_pos = bmp_ptr->file_header.bfOffBits; | 708 dst_pos = bmp_ptr->file_header.bfOffBits; |
| 709 dst_size += size; | 709 dst_size += size; |
| 710 dst_buf = FX_Realloc(uint8_t, dst_buf, dst_size); | 710 dst_buf = FX_Realloc(uint8_t, dst_buf, dst_size); |
| 711 if (dst_buf == NULL) { | 711 if (dst_buf == NULL) { |
| 712 return; | 712 return; |
| 713 } | 713 } |
| 714 FXSYS_memset(&dst_buf[dst_pos], 0, size); | 714 FXSYS_memset(&dst_buf[dst_pos], 0, size); |
| 715 FX_DWORD mask_red; | 715 uint32_t mask_red; |
| 716 FX_DWORD mask_green; | 716 uint32_t mask_green; |
| 717 FX_DWORD mask_blue; | 717 uint32_t mask_blue; |
| 718 mask_red = 0x7C00; | 718 mask_red = 0x7C00; |
| 719 mask_green = 0x03E0; | 719 mask_green = 0x03E0; |
| 720 mask_blue = 0x001F; | 720 mask_blue = 0x001F; |
| 721 if (bmp_ptr->info_header.biCompression == BMP_BITFIELDS) { | 721 if (bmp_ptr->info_header.biCompression == BMP_BITFIELDS) { |
| 722 if (bmp_ptr->bit_type == BMP_BIT_565) { | 722 if (bmp_ptr->bit_type == BMP_BIT_565) { |
| 723 mask_red = 0xF800; | 723 mask_red = 0xF800; |
| 724 mask_green = 0x07E0; | 724 mask_green = 0x07E0; |
| 725 mask_blue = 0x001F; | 725 mask_blue = 0x001F; |
| 726 } | 726 } |
| 727 if (bmp_ptr->info_header.biBitCount == 32) { | 727 if (bmp_ptr->info_header.biBitCount == 32) { |
| (...skipping 30 matching lines...) Expand all Loading... |
| 758 red_bits -= 8; | 758 red_bits -= 8; |
| 759 i = 0; | 759 i = 0; |
| 760 for (int32_t row_num = bmp_ptr->src_row - 1; row_num > -1; row_num--, i = 0) { | 760 for (int32_t row_num = bmp_ptr->src_row - 1; row_num > -1; row_num--, i = 0) { |
| 761 while (i < bmp_ptr->src_width * bmp_ptr->src_bpp / 8) { | 761 while (i < bmp_ptr->src_width * bmp_ptr->src_bpp / 8) { |
| 762 uint8_t b = bmp_ptr->src_buf[row_num * bmp_ptr->src_pitch + i++]; | 762 uint8_t b = bmp_ptr->src_buf[row_num * bmp_ptr->src_pitch + i++]; |
| 763 uint8_t g = bmp_ptr->src_buf[row_num * bmp_ptr->src_pitch + i++]; | 763 uint8_t g = bmp_ptr->src_buf[row_num * bmp_ptr->src_pitch + i++]; |
| 764 uint8_t r = bmp_ptr->src_buf[row_num * bmp_ptr->src_pitch + i++]; | 764 uint8_t r = bmp_ptr->src_buf[row_num * bmp_ptr->src_pitch + i++]; |
| 765 if (bmp_ptr->src_bpp == 32) { | 765 if (bmp_ptr->src_bpp == 32) { |
| 766 i++; | 766 i++; |
| 767 } | 767 } |
| 768 FX_DWORD pix_val = 0; | 768 uint32_t pix_val = 0; |
| 769 pix_val |= (b >> blue_bits) & mask_blue; | 769 pix_val |= (b >> blue_bits) & mask_blue; |
| 770 pix_val |= (g << green_bits) & mask_green; | 770 pix_val |= (g << green_bits) & mask_green; |
| 771 pix_val |= (r << red_bits) & mask_red; | 771 pix_val |= (r << red_bits) & mask_red; |
| 772 if (bmp_ptr->info_header.biBitCount == 16) { | 772 if (bmp_ptr->info_header.biBitCount == 16) { |
| 773 SetWord_LSBFirst(&dst_buf[dst_pos], pix_val); | 773 SetWord_LSBFirst(&dst_buf[dst_pos], pix_val); |
| 774 dst_pos += 2; | 774 dst_pos += 2; |
| 775 } else { | 775 } else { |
| 776 SetDWord_LSBFirst(&dst_buf[dst_pos], pix_val); | 776 SetDWord_LSBFirst(&dst_buf[dst_pos], pix_val); |
| 777 dst_pos += 4; | 777 dst_pos += 4; |
| 778 } | 778 } |
| 779 } | 779 } |
| 780 } | 780 } |
| 781 dst_size = dst_pos; | 781 dst_size = dst_pos; |
| 782 } | 782 } |
| 783 | 783 |
| 784 static void bmp_encode_rgb(bmp_compress_struct_p bmp_ptr, | 784 static void bmp_encode_rgb(bmp_compress_struct_p bmp_ptr, |
| 785 uint8_t*& dst_buf, | 785 uint8_t*& dst_buf, |
| 786 FX_DWORD& dst_size) { | 786 uint32_t& dst_size) { |
| 787 if (bmp_ptr->info_header.biBitCount == 16) { | 787 if (bmp_ptr->info_header.biBitCount == 16) { |
| 788 bmp_encode_bitfields(bmp_ptr, dst_buf, dst_size); | 788 bmp_encode_bitfields(bmp_ptr, dst_buf, dst_size); |
| 789 return; | 789 return; |
| 790 } | 790 } |
| 791 FX_DWORD size, dst_pos; | 791 uint32_t size, dst_pos; |
| 792 FX_DWORD dst_pitch = | 792 uint32_t dst_pitch = |
| 793 (bmp_ptr->src_width * bmp_ptr->info_header.biBitCount + 31) / 32 * 4; | 793 (bmp_ptr->src_width * bmp_ptr->info_header.biBitCount + 31) / 32 * 4; |
| 794 size = dst_pitch * bmp_ptr->src_row; | 794 size = dst_pitch * bmp_ptr->src_row; |
| 795 dst_pos = bmp_ptr->file_header.bfOffBits; | 795 dst_pos = bmp_ptr->file_header.bfOffBits; |
| 796 dst_size += size; | 796 dst_size += size; |
| 797 dst_buf = FX_Realloc(uint8_t, dst_buf, dst_size); | 797 dst_buf = FX_Realloc(uint8_t, dst_buf, dst_size); |
| 798 if (dst_buf == NULL) { | 798 if (dst_buf == NULL) { |
| 799 return; | 799 return; |
| 800 } | 800 } |
| 801 FXSYS_memset(&dst_buf[dst_pos], 0, size); | 801 FXSYS_memset(&dst_buf[dst_pos], 0, size); |
| 802 for (int32_t row_num = bmp_ptr->src_row - 1; row_num > -1; row_num--) { | 802 for (int32_t row_num = bmp_ptr->src_row - 1; row_num > -1; row_num--) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 813 while (num < len) { | 813 while (num < len) { |
| 814 if (buf[num - 1] != buf[num] || num == 0xFF) { | 814 if (buf[num - 1] != buf[num] || num == 0xFF) { |
| 815 break; | 815 break; |
| 816 } | 816 } |
| 817 num++; | 817 num++; |
| 818 } | 818 } |
| 819 return num; | 819 return num; |
| 820 } | 820 } |
| 821 static void bmp_encode_rle8(bmp_compress_struct_p bmp_ptr, | 821 static void bmp_encode_rle8(bmp_compress_struct_p bmp_ptr, |
| 822 uint8_t*& dst_buf, | 822 uint8_t*& dst_buf, |
| 823 FX_DWORD& dst_size) { | 823 uint32_t& dst_size) { |
| 824 FX_DWORD size, dst_pos, index; | 824 uint32_t size, dst_pos, index; |
| 825 uint8_t rle[2] = {0}; | 825 uint8_t rle[2] = {0}; |
| 826 size = bmp_ptr->src_pitch * bmp_ptr->src_row * 2; | 826 size = bmp_ptr->src_pitch * bmp_ptr->src_row * 2; |
| 827 dst_pos = bmp_ptr->file_header.bfOffBits; | 827 dst_pos = bmp_ptr->file_header.bfOffBits; |
| 828 dst_size += size; | 828 dst_size += size; |
| 829 dst_buf = FX_Realloc(uint8_t, dst_buf, dst_size); | 829 dst_buf = FX_Realloc(uint8_t, dst_buf, dst_size); |
| 830 if (dst_buf == NULL) { | 830 if (dst_buf == NULL) { |
| 831 return; | 831 return; |
| 832 } | 832 } |
| 833 FXSYS_memset(&dst_buf[dst_pos], 0, size); | 833 FXSYS_memset(&dst_buf[dst_pos], 0, size); |
| 834 for (int32_t row_num = bmp_ptr->src_row - 1, i = 0; row_num > -1;) { | 834 for (int32_t row_num = bmp_ptr->src_row - 1, i = 0; row_num > -1;) { |
| (...skipping 26 matching lines...) Expand all Loading... |
| 861 while (num < len) { | 861 while (num < len) { |
| 862 if (buf[num - 2] != buf[num] || num == 0xFF) { | 862 if (buf[num - 2] != buf[num] || num == 0xFF) { |
| 863 break; | 863 break; |
| 864 } | 864 } |
| 865 num++; | 865 num++; |
| 866 } | 866 } |
| 867 return num; | 867 return num; |
| 868 } | 868 } |
| 869 static void bmp_encode_rle4(bmp_compress_struct_p bmp_ptr, | 869 static void bmp_encode_rle4(bmp_compress_struct_p bmp_ptr, |
| 870 uint8_t*& dst_buf, | 870 uint8_t*& dst_buf, |
| 871 FX_DWORD& dst_size) { | 871 uint32_t& dst_size) { |
| 872 FX_DWORD size, dst_pos, index; | 872 uint32_t size, dst_pos, index; |
| 873 uint8_t rle[2] = {0}; | 873 uint8_t rle[2] = {0}; |
| 874 size = bmp_ptr->src_pitch * bmp_ptr->src_row; | 874 size = bmp_ptr->src_pitch * bmp_ptr->src_row; |
| 875 dst_pos = bmp_ptr->file_header.bfOffBits; | 875 dst_pos = bmp_ptr->file_header.bfOffBits; |
| 876 dst_size += size; | 876 dst_size += size; |
| 877 dst_buf = FX_Realloc(uint8_t, dst_buf, dst_size); | 877 dst_buf = FX_Realloc(uint8_t, dst_buf, dst_size); |
| 878 if (dst_buf == NULL) { | 878 if (dst_buf == NULL) { |
| 879 return; | 879 return; |
| 880 } | 880 } |
| 881 FXSYS_memset(&dst_buf[dst_pos], 0, size); | 881 FXSYS_memset(&dst_buf[dst_pos], 0, size); |
| 882 for (int32_t row_num = bmp_ptr->src_row - 1, i = 0; row_num > -1; | 882 for (int32_t row_num = bmp_ptr->src_row - 1, i = 0; row_num > -1; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 900 dst_buf[dst_pos++] = rle[0]; | 900 dst_buf[dst_pos++] = rle[0]; |
| 901 dst_buf[dst_pos++] = rle[1]; | 901 dst_buf[dst_pos++] = rle[1]; |
| 902 } | 902 } |
| 903 } | 903 } |
| 904 dst_buf[dst_pos++] = RLE_MARKER; | 904 dst_buf[dst_pos++] = RLE_MARKER; |
| 905 dst_buf[dst_pos++] = RLE_EOI; | 905 dst_buf[dst_pos++] = RLE_EOI; |
| 906 dst_size = dst_pos; | 906 dst_size = dst_pos; |
| 907 } | 907 } |
| 908 FX_BOOL bmp_encode_image(bmp_compress_struct_p bmp_ptr, | 908 FX_BOOL bmp_encode_image(bmp_compress_struct_p bmp_ptr, |
| 909 uint8_t*& dst_buf, | 909 uint8_t*& dst_buf, |
| 910 FX_DWORD& dst_size) { | 910 uint32_t& dst_size) { |
| 911 FX_DWORD head_size = sizeof(BmpFileHeader) + sizeof(BmpInfoHeader); | 911 uint32_t head_size = sizeof(BmpFileHeader) + sizeof(BmpInfoHeader); |
| 912 FX_DWORD pal_size = sizeof(FX_DWORD) * bmp_ptr->pal_num; | 912 uint32_t pal_size = sizeof(uint32_t) * bmp_ptr->pal_num; |
| 913 if (bmp_ptr->info_header.biClrUsed > 0 && | 913 if (bmp_ptr->info_header.biClrUsed > 0 && |
| 914 bmp_ptr->info_header.biClrUsed < bmp_ptr->pal_num) { | 914 bmp_ptr->info_header.biClrUsed < bmp_ptr->pal_num) { |
| 915 pal_size = sizeof(FX_DWORD) * bmp_ptr->info_header.biClrUsed; | 915 pal_size = sizeof(uint32_t) * bmp_ptr->info_header.biClrUsed; |
| 916 } | 916 } |
| 917 dst_size = head_size + sizeof(FX_DWORD) * bmp_ptr->pal_num; | 917 dst_size = head_size + sizeof(uint32_t) * bmp_ptr->pal_num; |
| 918 dst_buf = FX_TryAlloc(uint8_t, dst_size); | 918 dst_buf = FX_TryAlloc(uint8_t, dst_size); |
| 919 if (dst_buf == NULL) { | 919 if (dst_buf == NULL) { |
| 920 return FALSE; | 920 return FALSE; |
| 921 } | 921 } |
| 922 FXSYS_memset(dst_buf, 0, dst_size); | 922 FXSYS_memset(dst_buf, 0, dst_size); |
| 923 bmp_ptr->file_header.bfOffBits = head_size; | 923 bmp_ptr->file_header.bfOffBits = head_size; |
| 924 if (bmp_ptr->pal_ptr && pal_size) { | 924 if (bmp_ptr->pal_ptr && pal_size) { |
| 925 FXSYS_memcpy(&dst_buf[head_size], bmp_ptr->pal_ptr, pal_size); | 925 FXSYS_memcpy(&dst_buf[head_size], bmp_ptr->pal_ptr, pal_size); |
| 926 bmp_ptr->file_header.bfOffBits += pal_size; | 926 bmp_ptr->file_header.bfOffBits += pal_size; |
| 927 } | 927 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 939 case BMP_RLE4: | 939 case BMP_RLE4: |
| 940 bmp_encode_rle4(bmp_ptr, dst_buf, dst_size); | 940 bmp_encode_rle4(bmp_ptr, dst_buf, dst_size); |
| 941 break; | 941 break; |
| 942 default: | 942 default: |
| 943 break; | 943 break; |
| 944 } | 944 } |
| 945 bmp_ptr->file_header.bfSize = dst_size; | 945 bmp_ptr->file_header.bfSize = dst_size; |
| 946 WriteFileHeader(&bmp_ptr->file_header, dst_buf); | 946 WriteFileHeader(&bmp_ptr->file_header, dst_buf); |
| 947 return TRUE; | 947 return TRUE; |
| 948 } | 948 } |
| OLD | NEW |