Ejemplo n.º 1
0
void RescaleImage::Get(RGBA *tgt)
{
	if(y < 0 || offsets >= vert.End()) {
		memset(tgt, 0, sizeof(RGBA) * tsz.cx);
		return;
	}
	offset += *offsets++;
	ASSERT(offset >= 0 && offset + segspan <= size.cy);
	if(bigseg) {
		row_proc(&row_buffers[0 * cx4], GetLine(offset + 0 * step), horz);
		row_proc(&row_buffers[1 * cx4], GetLine(offset + 1 * step), horz);
		row_proc(&row_buffers[2 * cx4], GetLine(offset + 2 * step), horz);
		row_proc(&row_buffers[3 * cx4], GetLine(offset + 3 * step), horz);
		BltAASet4Fix(tgt, &row_buffers[0 * cx4], &row_buffers[1 * cx4],
			              &row_buffers[2 * cx4], &row_buffers[3 * cx4], tsz.cx);
	}
	else {
		int endoff = offset + segment;
		for(int next = first + full; next < endoff; next++) {
			if(full >= segment)
				first++;
			else
				full++;
			row_proc(&row_buffers[next % segment * cx4], GetLine(next), horz);
		}
		while(first > offset) {
			if(full < segment)
				full++;
			--first;
			row_proc(&row_buffers[first % segment * cx4], GetLine(first), horz);
		}
		ASSERT(offset >= first && endoff <= first + full);
		switch(segment) {
		case 1:
			BltAAFix2(tgt, &row_buffers[offset % segment * cx4], tsz.cx);
			offsets++;
			break;
		case 2:
			if(offsets[0] == 0)
				BltAAFix2(tgt, &row_buffers[(offset + 1) % segment * cx4], tsz.cx);
			else
			if(offsets[1] == 0)
				BltAAFix2(tgt, &row_buffers[offset % segment * cx4], tsz.cx);
			else
				BltAASet2Fix(tgt, &row_buffers[(offset + 0) % segment * cx4], offsets[0],
					              &row_buffers[(offset + 1) % segment * cx4], offsets[1],
					         tsz.cx);
			offsets += 2;
			break;
		case 3:
			BltAASet3Fix(tgt,
			             &row_buffers[(offset + 0) % segment * cx4], offsets[0],
			             &row_buffers[(offset + 1) % segment * cx4], offsets[1],
			             &row_buffers[(offset + 2) % segment * cx4], offsets[2], tsz.cx);
			offsets += 3;
			break;
		default:
			NEVER();
			break;
		}
	}
}
Ejemplo n.º 2
0
bool GReadBitmapFromFile(const char path[], GBitmap* bitmap) {
    FILE* file = fopen(path, "rb");
    if (NULL == file) {
        return always_false();
    }
    GAutoFClose afc(file);

    uint8_t signature[SIGNATURE_BYTES];
    if (SIGNATURE_BYTES != fread(signature, 1, SIGNATURE_BYTES, file)) {
        return always_false();
    }
    if (png_sig_cmp(signature, 0, SIGNATURE_BYTES)) {
        return always_false();
    }
        
    png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
                                                 NULL, NULL, NULL);
    if (NULL == png_ptr) {
        return always_false();
    }
    
    png_infop info_ptr = png_create_info_struct(png_ptr);
    if (NULL == info_ptr) {
        png_destroy_read_struct(&png_ptr, NULL, NULL);
        return always_false();
    }
    
    GAutoPNGReader reader(png_ptr, info_ptr);
    
    if (setjmp(png_jmpbuf(png_ptr))) {
        return always_false();
    }
    
    png_init_io(png_ptr, file);
    png_set_sig_bytes(png_ptr, SIGNATURE_BYTES);
    png_read_info(png_ptr, info_ptr);

    png_uint_32 width, height;
    int bitDepth, colorType;
    png_get_IHDR(png_ptr, info_ptr, &width, &height, &bitDepth, &colorType,
                 NULL, NULL, NULL);

    if (8 != bitDepth) {
        return always_false();   // TODO: handle other formats
    }
    if (png_set_interlace_handling(png_ptr) > 1) {
        return always_false();   // TODO: support interleave
    }

    swizzle_row_proc row_proc = NULL;
    switch (colorType) {
        case PNG_COLOR_TYPE_RGB:
            row_proc = swizzle_rgb_row;
            break;
        case PNG_COLOR_TYPE_RGB_ALPHA:
            row_proc = swizzle_rgba_row;
            break;
        default:
            return always_false();
    }

    png_read_update_info(png_ptr, info_ptr);

    GAutoFree rowStorage(malloc(png_get_rowbytes(png_ptr, info_ptr)));
    png_bytep srcRow = (png_bytep)rowStorage.get();
    if (!srcRow) {
        return always_false();
    }

    GAutoFree pixelStorage(malloc(height * width * 4));
    GPixel* dstRow = (GPixel*)pixelStorage.get();
    if (NULL == dstRow) {
        return always_false();
    }

    for (int y = 0; y < height; y++) {
        uint8_t* tmp = srcRow;
        png_read_rows(png_ptr, &tmp, NULL, 1);
        row_proc(dstRow, srcRow, width);
        dstRow += width;
    }

    bitmap->fWidth = width;
    bitmap->fHeight = height;
    bitmap->fRowBytes = width * 4;
    bitmap->fPixels = (GPixel*)pixelStorage.detach();
    return true;
}