//-----------------------------------------------------------------// bool write(utils::file_io& fout) { size_t s = waves_.size(); if(zero_.bits() == 24) { for(auto w : waves_) { if(fout.write(&w, zero_.size()) != zero_.size()) return false; } } else { if(fout.write(&waves_[0], zero_.size(), s) != s) return false; } return true; }
//-----------------------------------------------------------------// 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; }
//-----------------------------------------------------------------// 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; }
/*----------------------------------------------------------------------/ / インデックス・カラー(無圧縮 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 devrec::load(utils::file_io& fin) { long fs = fin.get_file_size(); m_record.resize(fs / rec_pad_size); for(unsigned int i = 0; i < m_record.size(); ++i) { m_record[i].read(fin); } #ifdef __PPU__ utils::file_io::reorder_memory(&m_record[0], fs, "ssbb"); #endif m_get_pos = 0; return true; }
//-----------------------------------------------------------------// uint32_t sound::load(utils::file_io& fin, const std::string& ext) { if(!snd_files_.load(fin, ext)) { fin.close(); return 0; } uint32_t no = 0; const audio aif = snd_files_.get_audio(); if(aif) { al::audio_io::wave_handle wh = audio_io_.create_wave(aif); if(wh) { no = ses_.size(); ses_.push_back(wh); } } return no; }
bool load_(utils::file_io& fio) { area_.min_ = 0xffffffff; area_.max_ = 0x00000000; uint32_t value = 0; uint32_t type = 0; uint32_t length = 0; uint32_t address = 0; uint32_t sum = 0; int vcnt = 0; bool toend = false; int mode = 0; while(1) { char ch; if(!fio.get_char(ch)) { break; } if(ch == ' ') { } else if(ch == 0x0d || ch == 0x0a) { if(toend) break; } else if(mode == 0 && ch == 'S') { mode = 1; value = vcnt = 0; } else if(ch >= '0' && ch <= '9') { value <<= 4; value |= ch - '0'; ++vcnt; } else if(ch >= 'A' && ch <= 'F') { value <<= 4; value |= ch - 'A' + 10; ++vcnt; } else { std::cerr << "S format illegual character: '"; if(ch >= 0x20 && ch <= 0x7f) { std::cerr << ch; } else { std::cerr << boost::format("0x%02X") % static_cast<int>(ch); } std::cerr << "'" << std::endl; return false; } if(mode == 1) { // タイプ取得 if(vcnt == 1) { type = value; mode = 2; value = vcnt = 0; } } else if(mode == 2) { // レングス取得 if(vcnt == 2) { length = value; sum = value; mode = 3; value = vcnt = 0; } } else if(mode == 3) { // アドレス取得 int alen = 0; if(type == 0) { alen = 4; } else if(type == 1) { alen = 4; } else if(type == 2) { alen = 6; } else if(type == 3) { alen = 8; } else if(type == 5) { alen = 4; } else if(type == 7) { alen = 8; } else if(type == 8) { alen = 6; } else if(type == 9) { alen = 4; } else { return false; } if(vcnt == alen) { address = value; if(type >= 1 && type <= 3) { if(area_.min_ > address) area_.min_ = address; } alen >>= 1; length -= alen; length -= 1; // SUM の分サイズを引く while(alen > 0) { sum += value; value >>= 8; --alen; } if(type >= 1 && type <= 3) { mode = 4; } else if(type >= 7 && type <= 9) { exec_ = value; mode = 5; } else { mode = 4; } value = vcnt = 0; } } else if(mode == 4) { // データ・レコード
//-----------------------------------------------------------------// bool jpeg_io::info(utils::file_io& fin, img::img_info& fo) { if(!probe(fin)) { return false; } struct jpeg_decompress_struct cinfo; struct jpeg_error_mgr errmgr; long pos = fin.tell(); // エラーのハンドリング cinfo.err = jpeg_std_error(&errmgr); errmgr.error_exit = error_exit_task; // 構造体の初期設定 jpeg_create_decompress(&cinfo); // file_io クラス設定 fio_jpeg_file_io_src(&cinfo, &fin); // ファイルの情報ヘッダの読込み error_code_ = 0; jpeg_read_header(&cinfo, TRUE); fin.seek(pos, utils::file_io::seek::set); if(error_code_) { /// std::endl << "JPEG decode error: 'header'(" << static_cast<int>(error_code_) << ")" << std::endl; jpeg_destroy_decompress(&cinfo); return false; } fo.width = cinfo.output_width; fo.height = cinfo.output_height; fo.mipmap_level = 0; fo.multi_level = 0; fo.i_depth = 0; if(cinfo.output_components == 4) { fo.r_depth = 8; fo.g_depth = 8; fo.b_depth = 8; fo.a_depth = 8; fo.grayscale = false; } else if(cinfo.output_components == 3) { fo.r_depth = 8; fo.g_depth = 8; fo.b_depth = 8; fo.a_depth = 0; fo.grayscale = false; } else if(cinfo.output_components == 2) { fo.r_depth = 8; fo.g_depth = 8; fo.b_depth = 8; fo.a_depth = 8; fo.grayscale = true; } else if(cinfo.output_components == 1) { fo.r_depth = 8; fo.g_depth = 8; fo.b_depth = 8; fo.a_depth = 0; fo.grayscale = true; } else { fo.r_depth = 0; fo.g_depth = 0; fo.b_depth = 0; fo.a_depth = 0; fo.grayscale = false; return false; } return true; }
/*----------------------------------------------------------/ / 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; }