//-----------------------------------------------------------------// bool read(utils::file_io& fin) { size_t s = waves_.size(); if(zero_.bits() == 24) { for(size_t i = 0; i < s; ++i) { if(fin.read(&waves_[i], zero_.size()) != zero_.size()) return false; } } else { if(fin.read(&waves_[0], zero_.size(), s) != s) return false; } return true; }
/*----------------------------------------------------------------------/ / インデックス・カラー(無圧縮 1, 4, 8 ビット) 形式の画像データを展開 / /----------------------------------------------------------------------*/ bool read_idx_(utils::file_io& fin, const bmp_info& bmp) { size_t stride = bmp.width * bmp.depth; if(stride & 7) stride += 8; stride >>= 3; if(stride & 3) stride += 4 - (stride & 3); char tmp[stride]; char* buf = tmp; short d; vtx::spos pos; if(bmp.topdown) { pos.y = 0; d = 1; } else { pos.y = bmp.height - 1; d = -1; } for(int h = 0; h < bmp.height; ++h) { if(fin.read(buf, 1, stride) != stride) { return false; } int depth = 0; for(pos.x = 0; pos.x < bmp.width; ++pos.x) { unsigned char idx = buf[depth / 8]; if(bmp.depth == 4) { if(~pos.x & 1) idx >>= 4; idx &= 15; } else if(bmp.depth == 1) { idx >>= (~pos.x & 3); idx &= 1; } depth += bmp.depth; render_idx_(pos.x, pos.y, idx); }
//-----------------------------------------------------------------// bool jpeg_io::probe(utils::file_io& fin) { unsigned char sig[2]; long pos = fin.tell(); size_t l = fin.read(sig, 1, 2); fin.seek(pos, utils::file_io::seek::set); if(l == 2) { if(sig[0] == 0xff && sig[1] == 0xd8) { return true; } } return false; }
/*----------------------------------------------------------/ / bmp ファイルヘッダーのみ展開して、情報を得る / /----------------------------------------------------------*/ static bool read_header_bmp_(utils::file_io& fin, bmp_info& bmp) { uint8_t bfh[FILEHED_SIZE + BMPV5HED_SIZE]; uint8_t *const bih = bfh + FILEHED_SIZE; // skip MAC-Binary header がある場合を考えてヘッダーを特定 for(int i = 0; i < 512; i++) { if(fin.read(bfh, (FILEHED_SIZE + BIHSIZE_SIZE), 1) != 1) { return false; } if(mgetwl_(bfh + BFH_WTYPE) == BMP_SIGNATURE) break; if(i != 0) { return false; } if(fin.read(bfh, (128 - FILEHED_SIZE - BIHSIZE_SIZE), 1) != 1) { return false; } } bmp.offbits = mgetdwl_(bfh + BFH_DOFFBITS); bmp.bihsize = mgetdwl_(bfh + BFH_DBIHSIZE); bmp.skip = bmp.offbits - bmp.bihsize - FILEHED_SIZE; if(bmp.bihsize < COREHED_SIZE || bmp.bihsize > BMPV5HED_SIZE || bmp.offbits < (bmp.bihsize + FILEHED_SIZE)) { return false; } if(fin.read((bih + BIHSIZE_SIZE), (bmp.bihsize - BIHSIZE_SIZE), 1) != 1) { return false; } bmp.topdown = false; if(bmp.bihsize >= INFOHED_SIZE) { // [Windows] style BMP bmp.width = mgetdwl_(bih + BIH_LWIDTH); bmp.height = mgetdwl_(bih + BIH_LHEIGHT); bmp.depth = mgetwl_(bih + BIH_WBITCOUNT); bmp.compression = mgetdwl_(bih + BIH_DCOMPRESSION); bmp.palette_size = RGBQUAD_SIZE; if(static_cast<int>(bmp.height) < 0) { bmp.height = -static_cast<int>(bmp.height); bmp.topdown = true; } } else { // [OS/2] style BMP bmp.width = mgetwl_(bih + BCH_WWIDTH); bmp.height = mgetwl_(bih + BCH_WHEIGHT); bmp.depth = mgetwl_(bih + BCH_WBITCOUNT); bmp.compression = BI_RGB; bmp.palette_size = RGBTRIPLE_SIZE; } if(bmp.width <= 0 || bmp.width >= BMP_MAX_WIDTH) { return false; } if(bmp.height <= 0 || bmp.height >= BMP_MAX_HEIGHT) { return false; } bmp.alpha_chanel = false; switch(bmp.compression) { case BI_RGB: if(bmp.depth != 1 && bmp.depth != 4 && bmp.depth != 8 && bmp.depth != 16 && bmp.depth != 24 && bmp.depth != 32) { return false; } // RGB565 16bits color if(bmp.depth == 16) { bmp.color_mask.a = 0x0000; bmp.color_mask.r = 0x7C00; bmp.color_mask.g = 0x03E0; bmp.color_mask.b = 0x001F; bmp.compression = BI_BITFIELDS; } break; case BI_BITFIELDS: if(bmp.depth != 16 && bmp.depth != 32) { return false; } if(bmp.bihsize < INFOHED_SIZE + 12) { if(bmp.skip < (INFOHED_SIZE + 12 - bmp.bihsize)) { return false; } if(fin.read((bih + bmp.bihsize), (INFOHED_SIZE + 12 - bmp.bihsize), 1) != 1) { return false; } bmp.skip -= (INFOHED_SIZE + 12 - bmp.bihsize); } bmp.color_mask.a = 0x00000000; bmp.color_mask.r = mgetdwl_(bih + B4H_DREDMASK); bmp.color_mask.g = mgetdwl_(bih + B4H_DGREENMASK); bmp.color_mask.b = mgetdwl_(bih + B4H_DBLUEMASK); if(bmp.depth == 32 && bmp.bihsize >= (INFOHED_SIZE + 16)) { bmp.color_mask.a = mgetdwl_(bih + B4H_DALPHAMASK); if(bmp.color_mask.a != 0) { bmp.alpha_chanel = true; } } if(bmp.depth == 32 && bmp.color_mask.b == 0x000000FF && bmp.color_mask.g == 0x0000FF00 && bmp.color_mask.r == 0x00FF0000 && (bmp.color_mask.a == 0xFF000000 || bmp.color_mask.a == 0x00000000)) { bmp.compression = BI_RGB; } break; case BI_RLE8: if(bmp.depth != 8) { return false; } break; case BI_RLE4: if(bmp.depth != 4) { return false; } break; default: return false; } return true; }