void BmpImage::toGrayscale() { if (bitsPerPixel != 8 && bitsPerPixel != 24) return; int w = rowBytes(); int avg; if (bitsPerPixel == 24) { ByteBuffer* bmpBuffer = new ByteBuffer(bitmapSize, bmpBits); BinaryReader* reader = new BinaryReader(bmpBuffer); byte blue, green, red; for (unsigned int i = 0; i < height; i++) { for (unsigned int j = 0; j < width; j++) { blue = reader->readByte(i*w+j*3); green = reader->readByte(i*w+j*3+1); red = reader->readByte(i*w+j*3+2); avg = (red + green + blue)/3; avg = (avg << 16) | (avg << 8) | (avg); bmpBuffer->seek(i*w+j*3); bmpBuffer->addRGB(avg); } } bmpBits = bmpBuffer->getBytes(); return; } int colorTableIndex; for (unsigned int i = 0; i < height; i++) { for (unsigned int j = 0; j < width; j++) { colorTableIndex = bmpBits[i*w+j]; avg = (colorPalette[colorTableIndex] & 0x00FF0000) >> 16; avg += (colorPalette[colorTableIndex] & 0x0000FF00) >> 8; avg += (colorPalette[colorTableIndex] & 0x000000FF); avg /= 3; bmpBits[i*w+j] = avg; } } for (int k = 0; k < colorPaletteSize; k++) { colorPalette[k] = (k << 16) | (k << 8) | (k); } }
void SkGlyph::expandA8ToLCD() const { SkASSERT(fMaskFormat == SkMask::kHorizontalLCD_Format || fMaskFormat == SkMask::kVerticalLCD_Format); #if defined(SK_SUPPORT_LCDTEXT) uint8_t* input = reinterpret_cast<uint8_t*>(fImage); uint32_t* output = reinterpret_cast<uint32_t*>(input + SkAlign4(rowBytes() * fHeight)); if (fMaskFormat == SkMask::kHorizontalLCD_Format) { for (unsigned y = 0; y < fHeight; ++y) { const uint8_t* inputRow = input; *output++ = 0; // make the extra column on the left clear for (unsigned x = 0; x < fWidth; ++x) { const uint8_t alpha = *inputRow++; *output++ = SkPackARGB32(alpha, alpha, alpha, alpha); } *output++ = 0; input += rowBytes(); } } else { const unsigned outputRowBytes = sizeof(uint32_t) * fWidth; memset(output, 0, outputRowBytes); output += fWidth; for (unsigned y = 0; y < fHeight; ++y) { const uint8_t* inputRow = input; for (unsigned x = 0; x < fWidth; ++x) { const uint8_t alpha = *inputRow++; *output++ = SkPackARGB32(alpha, alpha, alpha, alpha); } input += rowBytes(); } memset(output, 0, outputRowBytes); output += fWidth; } #else #endif }
bool BmpImage::init() { initValuesToDefault(); BinaryReader* reader = new BinaryReader(this->image); reader->reset(); /* read the file data header */ // read the type of the file reader->seek(FILE_TYPE_OFFSET); fileType = reader->readWord(); switch (fileType) { case BMPBITMAP: break; case BMPARRAY: case BMPCLRICON: case BMPCLRPOINTER: case BMPICON: case BMPPOINTER: return false; default: { fileType = NOT_BMP; // exception should be thrown return false; } } // read the file size in bytes fileSize = reader->readDword(); // read the two hot spots, reserved 1 & reserved 2 Xhot = reader->readWord(); Yhot = reader->readWord(); bitmapOffset = reader->readDword(); /* read the bitmap header now */ headerSize = reader->readDword(); if (headerSize < BMPOLDANYHDRSIZE || (headerSize > BMPNEWOS2HDRSIZE && headerSize != BMPNEWWINV4HDRSIZE)) { fileType = NOT_BMP; // exception should be thrown return false; } // read the rest of the header and the palette if any if (headerSize == BMPOLDANYHDRSIZE) // we have an old BMP file format { version = BMPOLD; width = (word) reader->readWord(); height = (word) reader->readWord(); planes = reader->readWord(); bitsPerPixel = reader->readWord(); if (bitsPerPixel != 1 || bitsPerPixel != 4 || bitsPerPixel != 8 || bitsPerPixel != 24) { fileType = NOT_BMP; // exception should be thrown return false; } colorPaletteSize = bitsPerPixel == 24 ? 0 : 1 << bitsPerPixel; int numberOfEntries = (bitmapOffset - BMPFILEHDRSIZE - BMPOLDANYHDRSIZE) / BMPOLDPALETTESIZE; if (colorPaletteSize != numberOfEntries) { fileType = NOT_BMP; // exception should be thrown return false; } // read the palette if (colorPaletteSize != 0) { colorPalette = new unsigned long[colorPaletteSize]; for (int i = 0; i < colorPaletteSize; i++) { colorPalette[i] = reader->readRGB(); } } bitmapSize = rowBytes() * height; } else // new BMP file format { switch (headerSize) { case BMPNEWWINHDRSIZE: { version = BMPWINNEW; break; } case BMPNEWOS2HDRSIZE: { version = BMPOS2NEW; break; } case BMPNEWWINV4HDRSIZE: { version = BMPWIN4NEW; break; } default: { version = BMPUNKNOWN; break; } } width = reader->readDword(); height = reader->readDword(); planes = reader->readWord(); bitsPerPixel = reader->readWord(); compression = reader->readDword(); bitmapSize = reader->readDword(); horizResolution = (long) reader->readDword(); vertResolution = (long) reader->readDword(); colorsUsed = reader->readDword(); colorsImportant = reader->readDword(); bitmapSize = (bitmapSize) ? bitmapSize : rowBytes() * height; // if the image is an OS2 bitmap if (headerSize == BMPNEWOS2HDRSIZE) { units = reader->readWord(); reserved = reader->readWord(); recording = reader->readWord(); rendering = reader->readWord(); size1 = reader->readDword(); size2 = reader->readDword(); identifier = reader->readDword(); } // read the palette // seek to the color palette reader->seek(BMPFILEHDRSIZE + headerSize); // rle compression not supported if (compression == 3 && (bitsPerPixel == 16 || bitsPerPixel == 32)) { // should throw exception return false; } // compute the number of color table entries colorPaletteSize = bitsPerPixel > 8 ? 0 : 1 << bitsPerPixel; int numberOfEntries = (bitmapOffset - BMPFILEHDRSIZE - headerSize) / BMPNEWPALETTESIZE; if (colorPaletteSize != numberOfEntries) { fileType = NOT_BMP; // exception should be thrown return false; } // read the palette if (colorPaletteSize != 0) { colorPalette = new unsigned long[colorPaletteSize]; for (int i = 0; i < colorPaletteSize; i++) { colorPalette[i] = reader->readDword(); } } } // shold read the data bits & lose the padding bmpBits = &image->getBytes()[bitmapOffset]; // calculate the file size if not given if (fileSize == 0) { fileSize = BMPFILEHDRSIZE; fileSize += headerSize; int paletteSize = (version == BMPOLD) ? BMPOLDPALETTESIZE : BMPNEWPALETTESIZE; fileSize += colorPaletteSize*paletteSize; fileSize += bitmapSize; } delete reader; return true; }
void pngRead(const std::string& file, ImageBuffer<RGBA8>& image) { // open file FILE* fp = nullptr; try { fp = fopen(file.c_str(), "rb"); if(!fp) throw; // check if it's a png, 8 is the maximum size that can be checked png_byte header[8]; fread(header, 1, 8, fp); if(png_sig_cmp(header, 0, 8)) throw; // try to create read struct png_structp pStruct = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if(!pStruct) throw; // try to create info struct png_infop pInfo = png_create_info_struct(pStruct); if(!pInfo) throw; // read info png_init_io(pStruct, fp); png_set_sig_bytes(pStruct, 8); png_read_info(pStruct, pInfo); int width = png_get_image_width(pStruct, pInfo); int height = png_get_image_height(pStruct, pInfo); png_byte colorType = png_get_color_type(pStruct, pInfo); png_byte bitDepth = png_get_bit_depth(pStruct, pInfo); png_byte channels = png_get_channels(pStruct, pInfo); png_read_update_info(pStruct, pInfo); // read data std::vector<std::vector<png_byte>> rowBytes(height); std::vector<png_byte*> rowPointers(height); png_size_t rowByteCount = png_get_rowbytes(pStruct, pInfo); for(int y = 0; y < height; y++) { rowBytes[y].resize(rowByteCount); rowPointers[y] = rowBytes[y].data(); } png_read_image(pStruct, rowPointers.data()); if(colorType == PNG_COLOR_TYPE_RGB) { image.setSize(width, height); for(int y = 0; y < height; y++) { png_byte* pBytes = rowPointers[y]; for(int x = 0; x < width; x++, pBytes += 3) { image(x, y) = {pBytes[0], pBytes[1], pBytes[2], 255}; } } } else if(colorType == PNG_COLOR_TYPE_RGBA) { image.setSize(width, height); for(int y = 0; y < height; y++) { png_byte* pBytes = rowPointers[y]; for(int x = 0; x < width; x++, pBytes += 4) { image(x, y) = {pBytes[0], pBytes[1], pBytes[2], pBytes[3]}; } } } else { throw; } } catch(...) { // File couldn't be loaded or read. assert(0); if(fp) fclose(fp); } }