| 29 | namespace label_image { |
| 30 | |
| 31 | std::vector<uint8_t> decode_bmp(const uint8_t* input, int row_size, int width, |
| 32 | int height, int channels, bool top_down) { |
| 33 | std::vector<uint8_t> output(height * width * channels); |
| 34 | for (int i = 0; i < height; i++) { |
| 35 | int src_pos; |
| 36 | int dst_pos; |
| 37 | |
| 38 | for (int j = 0; j < width; j++) { |
| 39 | if (!top_down) { |
| 40 | src_pos = ((height - 1 - i) * row_size) + j * channels; |
| 41 | } else { |
| 42 | src_pos = i * row_size + j * channels; |
| 43 | } |
| 44 | |
| 45 | dst_pos = (i * width + j) * channels; |
| 46 | |
| 47 | switch (channels) { |
| 48 | case 1: |
| 49 | output[dst_pos] = input[src_pos]; |
| 50 | break; |
| 51 | case 3: |
| 52 | // BGR -> RGB |
| 53 | output[dst_pos] = input[src_pos + 2]; |
| 54 | output[dst_pos + 1] = input[src_pos + 1]; |
| 55 | output[dst_pos + 2] = input[src_pos]; |
| 56 | break; |
| 57 | case 4: |
| 58 | // BGRA -> RGBA |
| 59 | output[dst_pos] = input[src_pos + 2]; |
| 60 | output[dst_pos + 1] = input[src_pos + 1]; |
| 61 | output[dst_pos + 2] = input[src_pos]; |
| 62 | output[dst_pos + 3] = input[src_pos + 3]; |
| 63 | break; |
| 64 | default: |
| 65 | LOG(FATAL) << "Unexpected number of channels: " << channels; |
| 66 | break; |
| 67 | } |
| 68 | } |
| 69 | } |
| 70 | return output; |
| 71 | } |
| 72 | |
| 73 | std::vector<uint8_t> read_bmp(const std::string& input_bmp_name, int* width, |
| 74 | int* height, int* channels, Settings* s) { |