bool ReadHeader(File* file, Header& h) { byte header[14]; if (file->read(header, 14) != 14) { return false; } // check signature if (header[0] != 'B' || header[1] != 'M') { return false; } h.file_size = read32_le(header + 2); h.data_offset = read32_le(header + 10); return true; }
/********************************************************************************************************* ** 函数名称: armL2x0Disable ** 功能描述: 禁能 L2 CACHE 控制器 ** 输 入 : pl2cdrv 驱动结构 ** 输 出 : NONE ** 全局变量: ** 调用模块: *********************************************************************************************************/ static VOID armL2x0Disable (L2C_DRVIER *pl2cdrv) { while (read32_le(L2C_BASE(pl2cdrv) + L2C_CTRL) & 0x01) { armL2x0ClearAll(pl2cdrv); write32_le(0x00, L2C_BASE(pl2cdrv) + L2C_CTRL); } }
/********************************************************************************************************* ** 函数名称: armL2x0Enable ** 功能描述: 使能 L2 CACHE 控制器 ** 输 入 : pl2cdrv 驱动结构 ** 输 出 : NONE ** 全局变量: ** 调用模块: ** 注 意 : 如果有 lockdown 必须首先 unlock & invalidate 才能启动 L2. *********************************************************************************************************/ static VOID armL2x0Enable (L2C_DRVIER *pl2cdrv) { while (!(read32_le(L2C_BASE(pl2cdrv) + L2C_CTRL) & 0x01)) { write32_le(L2C_AUX(pl2cdrv), L2C_BASE(pl2cdrv) + L2C_AUX_CTRL); /* 有些处理器需要此操作 */ armL2x0InvalidateAll(pl2cdrv); write32_le(0x01, L2C_BASE(pl2cdrv) + L2C_CTRL); armL2x0Sync(pl2cdrv); } }
/********************************************************************************************************* ** 函数名称: armL2x0Init ** 功能描述: 初始化 L2 CACHE 控制器 ** 输 入 : pl2cdrv 驱动结构 ** uiInstruction 指令 CACHE 类型 ** uiData 数据 CACHE 类型 ** pcMachineName 机器名称 ** uiAux L2C_AUX_CTRL ** 输 出 : NONE ** 全局变量: ** 调用模块: *********************************************************************************************************/ VOID armL2x0Init (L2C_DRVIER *pl2cdrv, CACHE_MODE uiInstruction, CACHE_MODE uiData, CPCHAR pcMachineName, UINT32 uiAux) { pl2cdrv->L2CD_pfuncEnable = armL2x0Enable; pl2cdrv->L2CD_pfuncDisable = armL2x0Disable; pl2cdrv->L2CD_pfuncIsEnable = armL2x0IsEnable; pl2cdrv->L2CD_pfuncSync = armL2x0Sync; pl2cdrv->L2CD_pfuncFlush = armL2x0Flush; pl2cdrv->L2CD_pfuncFlushAll = armL2x0FlushAll; pl2cdrv->L2CD_pfuncInvalidate = armL2x0Invalidate; pl2cdrv->L2CD_pfuncInvalidateAll = armL2x0InvalidateAll; pl2cdrv->L2CD_pfuncClear = armL2x0Clear; pl2cdrv->L2CD_pfuncClearAll = armL2x0ClearAll; if (!(read32_le(L2C_BASE(pl2cdrv) + L2C_CTRL) & 0x01)) { write32_le(uiAux, L2C_BASE(pl2cdrv) + L2C_AUX_CTRL); /* l2x0 controller is disabled */ armL2x0InvalidateAll(pl2cdrv); } }
std::auto_ptr<Image> BMPFormat::read(byte_source* src, ImageFactory* factory, const options_map&) { char magick[2]; if (src->read(reinterpret_cast<byte*>(magick), 2) != 2) { throw CannotReadError("imread.bmp: File is empty"); } if (magick[0] != 'B' || magick[1] != 'M') { throw CannotReadError("imread.bmp: Magick number not matched (this might not be a BMP file)"); } const uint32_t size = read32_le(*src); (void)size; (void)read16_le(*src); (void)read16_le(*src); const uint32_t offset = read32_le(*src); const uint32_t header_size = read32_le(*src); (void)header_size; const uint32_t width = read32_le(*src); const uint32_t height = read32_le(*src); const uint16_t planes = read16_le(*src); if (planes != 1){ throw NotImplementedError("imread.bmp: planes should be 1"); } const uint16_t bitsppixel = read16_le(*src); const uint32_t compression = read32_le(*src); if (compression != 0) { throw NotImplementedError("imread.bmp: Only uncompressed bitmaps are supported"); } const uint32_t imsize = read32_le(*src); (void)imsize; const uint32_t hres = read32_le(*src); (void)hres; const uint32_t vres = read32_le(*src); (void)vres; const uint32_t n_colours = read32_le(*src); const uint32_t importantcolours = read32_le(*src); (void)importantcolours; if (bitsppixel != 8 && bitsppixel != 16 && bitsppixel != 24) { std::ostringstream out; out << "imread.bmp: Bits per pixel is " << bitsppixel << ". Only 8, 16, or 24 supported."; throw CannotReadError(out.str()); } const int depth = (bitsppixel == 16 ? -1 : 3); const int nbits = (bitsppixel == 16 ? 16 : 8); std::auto_ptr<Image> output(factory->create(nbits, height, width, depth)); std::vector<byte> color_table; if (bitsppixel <= 8) { const uint32_t table_size = (n_colours == 0 ? pow2(bitsppixel) : n_colours); color_table.resize(table_size*4); src->read_check(&color_table[0], table_size*4); } src->seek_absolute(offset); const int bytes_per_row = width * (bitsppixel/8); const int padding = (4 - (bytes_per_row % 4)) % 4; byte buf[4]; for (unsigned int r = 0; r != height; ++r) { byte* rowp = output->rowp_as<byte>(height-r-1); src->read_check(rowp, bytes_per_row); if (bitsppixel == 24) flippixels(rowp, width); else if (!color_table.empty()) color_expand(color_table, rowp, width); if (src->read(buf, padding) != unsigned(padding) && r != (height - 1)) { throw CannotReadError("File ended prematurely"); } } return output; }
void cf_salsa20_core(const uint8_t key0[16], const uint8_t key1[16], const uint8_t nonce[16], const uint8_t constant[16], uint8_t out[64]) { /* unpack sequence is: * * c0 * key0 * c1 * nonce * c2 * key1 * c3 * * where c0, c1, c2, c3 = constant */ uint32_t z0, z1, z2, z3, z4, z5, z6, z7, z8, z9, za, zb, zc, zd, ze, zf; uint32_t x0 = z0 = read32_le(constant + 0), x1 = z1 = read32_le(key0 + 0), x2 = z2 = read32_le(key0 + 4), x3 = z3 = read32_le(key0 + 8), x4 = z4 = read32_le(key0 + 12), x5 = z5 = read32_le(constant + 4), x6 = z6 = read32_le(nonce + 0), x7 = z7 = read32_le(nonce + 4), x8 = z8 = read32_le(nonce + 8), x9 = z9 = read32_le(nonce + 12), xa = za = read32_le(constant + 8), xb = zb = read32_le(key1 + 0), xc = zc = read32_le(key1 + 4), xd = zd = read32_le(key1 + 8), xe = ze = read32_le(key1 + 12), xf = zf = read32_le(constant + 12); #define QUARTER(v0, v1, v2, v3) \ v1 ^= rotl32(v0 + v3, 7); \ v2 ^= rotl32(v1 + v0, 9); \ v3 ^= rotl32(v2 + v1, 13);\ v0 ^= rotl32(v3 + v2, 18) #define ROW \ QUARTER(z0, z1, z2, z3); \ QUARTER(z5, z6, z7, z4); \ QUARTER(za, zb, z8, z9); \ QUARTER(zf, zc, zd, ze) #define COLUMN\ QUARTER(z0, z4, z8, zc); \ QUARTER(z5, z9, zd, z1); \ QUARTER(za, ze, z2, z6); \ QUARTER(zf, z3, z7, zb) for (int i = 0; i < 10; i++) { COLUMN; ROW; } x0 += z0; x1 += z1; x2 += z2; x3 += z3; x4 += z4; x5 += z5; x6 += z6; x7 += z7; x8 += z8; x9 += z9; xa += za; xb += zb; xc += zc; xd += zd; xe += ze; xf += zf; write32_le(x0, out + 0); write32_le(x1, out + 4); write32_le(x2, out + 8); write32_le(x3, out + 12); write32_le(x4, out + 16); write32_le(x5, out + 20); write32_le(x6, out + 24); write32_le(x7, out + 28); write32_le(x8, out + 32); write32_le(x9, out + 36); write32_le(xa, out + 40); write32_le(xb, out + 44); write32_le(xc, out + 48); write32_le(xd, out + 52); write32_le(xe, out + 56); write32_le(xf, out + 60); }
bool ReadInfoHeader(File* file, Header& h) { const int HEADER_READ_SIZE = 24; // read the only part of the header we need byte header[HEADER_READ_SIZE]; if (file->read(header, HEADER_READ_SIZE) != HEADER_READ_SIZE) { return false; } int size = read32_le(header + 0); int width; int height; int planes; int bpp; int compression; int image_size; if (size < 40) { // assume OS/2 bitmap if (size < 12) { return false; } h.os2 = true; width = read16_le(header + 4); height = read16_le(header + 6); planes = read16_le(header + 8); bpp = read16_le(header + 10); compression = 0; image_size = 0; } else { h.os2 = false; width = read32_le(header + 4); height = read32_le(header + 8); planes = read16_le(header + 12); bpp = read16_le(header + 14); compression = read32_le(header + 16); image_size = read32_le(header + 20); } // sanity check the info header if (planes != 1) { return false; } // adjust image_size // (if compression == 0 or 3, manually calculate image size) int line_size = 0; if (compression == 0 || compression == 3) { line_size = (width * bpp + 7) / 8; line_size = (line_size + 3) / 4 * 4; // 32-bit-aligned image_size = line_size * height; } h.width = width; h.height = height; h.bpp = bpp; h.compression = compression; h.pitch = line_size; h.image_size = image_size; // jump forward (backward in the OS/2 case :) to the palette data file->seek(size - HEADER_READ_SIZE, File::CURRENT); return true; }
bool ReadPalette(File* file, Header& h) { // initialize bit masks/shifts... just in case h.bf_red_mask = h.bf_red_shift = h.bf_red_rshift = 0; h.bf_green_mask = h.bf_green_shift = h.bf_green_rshift = 0; h.bf_blue_mask = h.bf_blue_shift = h.bf_blue_rshift = 0; // if we're not a palettized image, don't even read a palette if (h.bpp > 8) { h.palette_size = 0; // do we have bitfields? if (h.compression == 3) { auto_array<byte> bitfields(new byte[12]); if (file->read(bitfields, 12) != 12) { return false; } h.bf_red_mask = read32_le((byte*)bitfields); h.bf_green_mask = read32_le((byte*)bitfields + 4); h.bf_blue_mask = read32_le((byte*)bitfields + 8); // calculate shifts h.bf_red_shift = count_right_zeroes(h.bf_red_mask); h.bf_green_shift = count_right_zeroes(h.bf_green_mask); h.bf_blue_shift = count_right_zeroes(h.bf_blue_mask); h.bf_red_rshift = 8 - count_ones(h.bf_red_mask); h.bf_green_rshift = 8 - count_ones(h.bf_green_mask); h.bf_blue_rshift = 8 - count_ones(h.bf_blue_mask); // otherwise, set default bitfield entries } else { if (h.bpp == 16) { h.bf_red_mask = 0x7C00; h.bf_red_shift = 10; h.bf_red_rshift = 3; h.bf_green_mask = 0x03E0; h.bf_green_shift = 5; h.bf_green_rshift = 3; h.bf_blue_mask = 0x001F; h.bf_blue_shift = 0; h.bf_blue_rshift = 3; } else if (h.bpp == 32) { // these don't need any rshift h.bf_red_mask = 0x00FF0000; h.bf_red_shift = 16; h.bf_green_mask = 0x0000FF00; h.bf_green_shift = 8; h.bf_blue_mask = 0x000000FF; h.bf_blue_shift = 0; } } return true; } if (h.bpp <= 8) { h.palette_size = 1 << h.bpp; } else { h.palette_size = 0; return true; } h.palette = new BGR[h.palette_size]; // read the BMP color table const int buffer_size = h.palette_size * (h.os2 ? 3 : 4); auto_array<byte> buffer(new byte[buffer_size]); if (file->read(buffer, buffer_size) != buffer_size) { return false; } byte* in = buffer; BGR* out = h.palette; for (int i = 0; i < h.palette_size; ++i) { out->blue = *in++; out->green = *in++; out->red = *in++; if (!h.os2) { ++in; // skip alpha } ++out; } return true; }
/********************************************************************************************************* ** 函数名称: armL2x0Sync ** 功能描述: L2 CACHE 控制器同步 (理论上 PL310 不需要等待) ** 输 入 : pl2cdrv 驱动结构 ** 输 出 : NONE ** 全局变量: ** 调用模块: *********************************************************************************************************/ static VOID armL2x0Sync (L2C_DRVIER *pl2cdrv) { while (read32_le(L2C_BASE(pl2cdrv) + L2C_CACHE_SYNC) & 0x01); }
/********************************************************************************************************* ** 函数名称: armL2x0IsEnable ** 功能描述: 检查 L2 CACHE 控制器是否使能 ** 输 入 : pl2cdrv 驱动结构 ** 输 出 : 是否使能 ** 全局变量: ** 调用模块: *********************************************************************************************************/ static BOOL armL2x0IsEnable (L2C_DRVIER *pl2cdrv) { return (read32_le(L2C_BASE(pl2cdrv) + L2C_CTRL) & 0x01); }
/********************************************************************************************************* ** 函数名称: armPl310ClearAll ** 功能描述: L2 CACHE 控制器回写并无效所有数据 ** 输 入 : pl2cdrv 驱动结构 ** 输 出 : NONE ** 全局变量: ** 调用模块: *********************************************************************************************************/ static VOID armL2x0ClearAll (L2C_DRVIER *pl2cdrv) { write32_le(L2C_WAYMASK(pl2cdrv), L2C_BASE(pl2cdrv) + L2C_CLEAN_INV_WAY); while (read32_le(L2C_BASE(pl2cdrv) + L2C_CLEAN_INV_WAY)); armL2x0Sync(pl2cdrv); }
/********************************************************************************************************* ** 函数名称: armPl310ClearLine ** 功能描述: L2 CACHE 控制器回写并无效一行数据 ** 输 入 : pl2cdrv 驱动结构 ** ulPhyAddr 物理地址 ** 输 出 : NONE ** 全局变量: ** 调用模块: *********************************************************************************************************/ static VOID armL2x0ClearLine (L2C_DRVIER *pl2cdrv, addr_t ulPhyAddr) { while (read32_le(L2C_BASE(pl2cdrv) + L2C_CLEAN_INV_LINE_PA) & 1); write32_le((UINT32)ulPhyAddr, L2C_BASE(pl2cdrv) + L2C_CLEAN_INV_LINE_PA); }
/********************************************************************************************************* ** 函数名称: armPl310InvalidateAll ** 功能描述: L2 CACHE 控制器无效所有数据 ** 输 入 : pl2cdrv 驱动结构 ** 输 出 : NONE ** 全局变量: ** 调用模块: *********************************************************************************************************/ static VOID armL2x0InvalidateAll (L2C_DRVIER *pl2cdrv) { write32_le(L2C_WAYMASK(pl2cdrv), L2C_BASE(pl2cdrv) + L2C_INV_WAY); while (read32_le(L2C_BASE(pl2cdrv) + L2C_INV_WAY)); armL2x0Sync(pl2cdrv); }