text:
#include "SkBitmap.h"
#include "SkColorPriv.h"
#include "SkDither.h"
#include "SkFlattenable.h"
#include "SkImagePriv.h"
#include "SkMallocPixelRef.h"
#include "SkMask.h"
#include "SkOrderedReadBuffer.h"
#include "SkOrderedWriteBuffer.h"
#include "SkPixelRef.h"
#include "SkThread.h"
#include "SkUnPreMultiply.h"
#include "SkUtils.h"
#include "SkValidationUtils.h"
#include "SkPackBits.h"
#include <new>

static bool isPos32Bits(const Sk64& value) {
    return !value.isNeg() && value.is32();
}

struct MipLevel {
    void*       fPixels;
    uint32_t    fRowBytes;
    uint32_t    fWidth, fHeight;
};

struct SkBitmap::MipMap : SkNoncopyable {
    int32_t fRefCnt;
    int     fLevelCount;
//  MipLevel    fLevel[fLevelCount];
//  Pixels[]

    static MipMap* Alloc(int levelCount, size_t pixelSize) {
        if (levelCount < 0) {
            return NULL;
        }
        Sk64 size;
        size.setMul(levelCount + 1, sizeof(MipLevel));
        size.add(sizeof(MipMap));
        size.add(SkToS32(pixelSize));
        if (!isPos32Bits(size)) {
            return NULL;
        }
        MipMap* mm = (MipMap*)sk_malloc_throw(size.get32());
        mm->fRefCnt = 1;
        mm->fLevelCount = levelCount;
        return mm;
    }

    const MipLevel* levels() const { return (const MipLevel*)(this + 1); }
    MipLevel* levels() { return (MipLevel*)(this + 1); }

    const void* pixels() const { return levels() + fLevelCount; }
    void* pixels() { return levels() + fLevelCount; }

    void ref() {
        if (SK_MaxS32 == sk_atomic_inc(&fRefCnt)) {
            sk_throw();
        }
    }
    void unref() {
        SkASSERT(fRefCnt > 0);
        if (sk_atomic_dec(&fRefCnt) == 1) {
            sk_free(this);
        }
    }
};

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

SkBitmap::SkBitmap() {
    sk_bzero(this, sizeof(*this));
}

SkBitmap::SkBitmap(const SkBitmap& src) {
    SkDEBUGCODE(src.validate();)
    sk_bzero(this, sizeof(*this));
    *this = src;
    SkDEBUGCODE(this->validate();)
}

SkBitmap::~SkBitmap() {
    SkDEBUGCODE(this->validate();)
    this->freePixels();
}

SkBitmap& SkBitmap::operator=(const SkBitmap& src) {
    if (this != &src) {
        this->freePixels();
        memcpy(this, &src, sizeof(src));

        // inc src reference counts
        SkSafeRef(src.fPixelRef);
        SkSafeRef(src.fMipMap);

        // we reset our locks if we get blown away
        fPixelLockCount = 0;

        /*  The src could be in 3 states
            1. no pixelref, in which case we just copy/ref the pixels/ctable
            2. unlocked pixelref, pixels/ctable should be null
            3. locked pixelref, we should lock the ref again ourselves
        */
        if (NULL == fPixelRef) {
            // leave fPixels as it is
            SkSafeRef(fColorTable); // ref the user's ctable if present
        } else {    // we have a pixelref, so pixels/ctable reflect it
            // ignore the values from the memcpy
            fPixels = NULL;
            fColorTable = NULL;
            // Note that what to for genID is somewhat arbitrary. We have no
            // way to track changes to raw pixels across multiple SkBitmaps.
            // Would benefit from an SkRawPixelRef type created by
            // setPixels.
            // Just leave the memcpy'ed one but they'll get out of sync
            // as soon either is modified.
        }
    }

    SkDEBUGCODE(this->validate();)
    return *this;
}

void SkBitmap::swap(SkBitmap& other) {
    SkTSwap(fColorTable, other.fColorTable);
    SkTSwap(fPixelRef, other.fPixelRef);
    SkTSwap(fPixelRefOffset, other.fPixelRefOffset);
    SkTSwap(fPixelLockCount, other.fPixelLockCount);
    SkTSwap(fMipMap, other.fMipMap);
    SkTSwap(fPixels, other.fPixels);
    SkTSwap(fRowBytes, other.fRowBytes);
    SkTSwap(fWidth, other.fWidth);
    SkTSwap(fHeight, other.fHeight);
    SkTSwap(fConfig, other.fConfig);
    SkTSwap(fAlphaType, other.fAlphaType);
    SkTSwap(fFlags, other.fFlags);
    SkTSwap(fBytesPerPixel, other.fBytesPerPixel);

    SkDEBUGCODE(this->validate();)
}

void SkBitmap::reset() {
    this->freePixels();
    sk_bzero(this, sizeof(*this));
}

int SkBitmap::ComputeBytesPerPixel(SkBitmap::Config config) {
    int bpp;
    switch (config) {
        case kNo_Config:
            bpp = 0;   // not applicable
            break;
        case kA8_Config:
        case kIndex8_Config:
            bpp = 1;
            break;
        case kRGB_565_Config:
        case kARGB_4444_Config:
            bpp = 2;
            break;
        case kARGB_8888_Config:
            bpp = 4;
            break;
        default:
            SkDEBUGFAIL("unknown config");
            bpp = 0;   // error
            break;
    }
    return bpp;
}

size_t SkBitmap::ComputeRowBytes(Config c, int width) {
    if (width < 0) {
        return 0;
    }

    Sk64 rowBytes;
    rowBytes.setZero();

    switch (c) {
        case kNo_Config:
            break;
        case kA8_Config:
        case kIndex8_Config:
            rowBytes.set(width);
            break;
        case kRGB_565_Config:
        case kARGB_4444_Config:
            rowBytes.set(width);
            rowBytes.shiftLeft(1);
            break;
        case kARGB_8888_Config:
            rowBytes.set(width);
            rowBytes.shiftLeft(2);
            break;
        default:
            SkDEBUGFAIL("unknown config");
            break;
    }
    return isPos32Bits(rowBytes) ? rowBytes.get32() : 0;
}

Sk64 SkBitmap::ComputeSize64(Config c, int width, int height) {
    Sk64 size;
    size.setMul(SkToS32(SkBitmap::ComputeRowBytes(c, width)), height);
    return size;
}

size_t SkBitmap::ComputeSize(Config c, int width, int height) {
    Sk64 size = SkBitmap::ComputeSize64(c, width, height);
    return isPos32Bits(size) ? size.get32() : 0;
}

Sk64 SkBitmap::ComputeSafeSize64(Config config,
                                 uint32_t width,
                                 uint32_t height,
                                 size_t rowBytes) {
    Sk64 safeSize;
    safeSize.setZero();
    if (height > 0) {
        // TODO: Handle the case where the return value from
        // ComputeRowBytes is more than 31 bits.
        safeSize.set(SkToS32(ComputeRowBytes(config, width)));
        Sk64 sizeAllButLastRow;
        sizeAllButLastRow.setMul(height - 1, SkToS32(rowBytes));
        safeSize.add(sizeAllButLastRow);
    }
    SkASSERT(!safeSize.isNeg());
    return safeSize;
}

size_t SkBitmap::ComputeSafeSize(Config config,
                                 uint32_t width,
                                 uint32_t height,
                                 size_t rowBytes) {
    Sk64 safeSize = ComputeSafeSize64(config, width, height, rowBytes);
    return (safeSize.is32() ? safeSize.get32() : 0);
}

void SkBitmap::getBounds(SkRect* bounds) const {
    SkASSERT(bounds);
    bounds->set(0, 0,
                SkIntToScalar(fWidth), SkIntToScalar(fHeight));
}

void SkBitmap::getBounds(SkIRect* bounds) const {
    SkASSERT(bounds);
    bounds->set(0, 0, fWidth, fHeight);
}

///////////////////////////////////////////////////////////////////////////////

extern "C" void _ZN8SkBitmap9setConfigENS_6ConfigEiii(SkBitmap *bitmap,
        SkBitmap::Config c, int width, int height, int rowBytes) {
    bitmap->setConfig(c, width, height, (size_t) rowBytes);
}

static bool validate_alphaType(SkBitmap::Config config, SkAlphaType alphaType,
                               SkAlphaType* canonical = NULL) {
    switch (config) {
        case SkBitmap::kNo_Config:
            alphaType = kIgnore_SkAlphaType;
            break;
        case SkBitmap::kA8_Config:
            if (kUnpremul_SkAlphaType == alphaType) {
                alphaType = kPremul_SkAlphaType;
            }
            // fall-through
        case SkBitmap::kIndex8_Config:
        case SkBitmap::kARGB_4444_Config:
        case SkBitmap::kARGB_8888_Config:
            if (kIgnore_SkAlphaType == alphaType) {
                return false;
            }
            break;
        case SkBitmap::kRGB_565_Config:
            alphaType = kOpaque_SkAlphaType;
            break;
        default:
            return false;
    }
    if (canonical) {
        *canonical = alphaType;
    }
    return true;
}

bool SkBitmap::setConfig(Config config, int width, int height, size_t rowBytes,
                         SkAlphaType alphaType) {
    if ((width | height) < 0) {
        goto BAD_CONFIG;
    }
    if (rowBytes == 0) {
        rowBytes = SkBitmap::ComputeRowBytes(config, width);
        if (0 == rowBytes && kNo_Config != config && width > 0) {
            goto BAD_CONFIG;
        }
    }

    if (!validate_alphaType(config, alphaType, &alphaType)) {
        goto BAD_CONFIG;
    }

    this->freePixels();

    fConfig     = SkToU8(config);
    fAlphaType  = SkToU8(alphaType);
    fWidth      = width;
    fHeight     = height;
    fRowBytes   = SkToU32(rowBytes);

    fBytesPerPixel = (uint8_t)ComputeBytesPerPixel(config);

    SkDEBUGCODE(this->validate();)
    return true;

    // if we got here, we had an error, so we reset the bitmap to empty
BAD_CONFIG:
    this->reset();
    return false;
}

bool SkBitmap::setConfig(const SkImageInfo& info, size_t rowBytes) {
    return this->setConfig(SkImageInfoToBitmapConfig(info), info.fWidth,
                           info.fHeight, rowBytes, info.fAlphaType);
}

bool SkBitmap::setAlphaType(SkAlphaType alphaType) {
    if (!validate_alphaType(this->config(), alphaType, &alphaType)) {
        return false;
    }
    fAlphaType = SkToU8(alphaType);
    return true;
}

// Samsung libtvout compat
void SkBitmap::setIsOpaque(bool isOpaque) {
    this->setAlphaType(isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType);
}

void SkBitmap::updatePixelsFromRef() const {
    if (NULL != fPixelRef) {
        if (fPixelLockCount > 0) {
            SkASSERT(fPixelRef->isLocked());

            void* p = fPixelRef->pixels();
            if (NULL != p) {
                p = (char*)p + fPixelRefOffset;
            }
            fPixels = p;
            SkRefCnt_SafeAssign(fColorTable, fPixelRef->colorTable());
        } else {
            SkASSERT(0 == fPixelLockCount);
            fPixels = NULL;
            if (fColorTable) {
                fColorTable->unref();
                fColorTable = NULL;
            }
        }
    }
}

static bool config_to_colorType(SkBitmap::Config config, SkColorType* ctOut) {
    SkColorType ct;
    switch (config) {
        case SkBitmap::kA8_Config:
            ct = kAlpha_8_SkColorType;
            break;
        case SkBitmap::kIndex8_Config:
            ct = kIndex_8_SkColorType;
            break;
        case SkBitmap::kRGB_565_Config:
            ct = kRGB_565_SkColorType;
            break;
        case SkBitmap::kARGB_4444_Config:
            ct = kARGB_4444_SkColorType;
            break;
        case SkBitmap::kARGB_8888_Config:
            ct = kPMColor_SkColorType;
            break;
        case SkBitmap::kNo_Config:
        default:
            return false;
    }
    if (ctOut) {
        *ctOut = ct;
    }
    return true;
}

bool SkBitmap::asImageInfo(SkImageInfo* info) const {
    SkColorType ct;
    if (!config_to_colorType(this->config(), &ct)) {
        return false;
    }
    if (info) {
        info->fWidth = fWidth;
        info->fHeight = fHeight;
        info->fAlphaType = this->alphaType();
        info->fColorType = ct;
    }
    return true;
}

SkPixelRef* SkBitmap::setPixelRef(SkPixelRef* pr, size_t offset) {
    // do this first, we that we never have a non-zero offset with a null ref
    if (NULL == pr) {
        offset = 0;
    }

    if (fPixelRef != pr || fPixelRefOffset != offset) {
        if (fPixelRef != pr) {
            this->freePixels();
            SkASSERT(NULL == fPixelRef);

            SkSafeRef(pr);
            fPixelRef = pr;
        }
        fPixelRefOffset = offset;
        this->updatePixelsFromRef();
    }

    SkDEBUGCODE(this->validate();)
    return pr;
}

void SkBitmap::lockPixels() const {
    if (NULL != fPixelRef && 0 == sk_atomic_inc(&fPixelLockCount)) {
        fPixelRef->lockPixels();
        this->updatePixelsFromRef();
    }
    SkDEBUGCODE(this->validate();)
}

void SkBitmap::unlockPixels() const {
    SkASSERT(NULL == fPixelRef || fPixelLockCount > 0);

    if (NULL != fPixelRef && 1 == sk_atomic_dec(&fPixelLockCount)) {
        fPixelRef->unlockPixels();
        this->updatePixelsFromRef();
    }
    SkDEBUGCODE(this->validate();)
}

bool SkBitmap::lockPixelsAreWritable() const {
    return (fPixelRef) ? fPixelRef->lockPixelsAreWritable() : false;
}

void SkBitmap::setPixels(void* p, SkColorTable* ctable) {
    if (NULL == p) {
        this->setPixelRef(NULL, 0);
        return;
    }

    SkImageInfo info;
    if (!this->asImageInfo(&info)) {
        this->setPixelRef(NULL, 0);
        return;
    }

    SkPixelRef* pr = SkMallocPixelRef::NewDirect(info, p, fRowBytes, ctable);
    if (NULL == pr) {
        this->setPixelRef(NULL, 0);
        return;
    }

    this->setPixelRef(pr)->unref();

    // since we're already allocated, we lockPixels right away
    this->lockPixels();
    SkDEBUGCODE(this->validate();)
}

bool SkBitmap::allocPixels(Allocator* allocator, SkColorTable* ctable) {
    HeapAllocator stdalloc;

    if (NULL == allocator) {
        allocator = &stdalloc;
    }
    return allocator->allocPixelRef(this, ctable);
}

void SkBitmap::freePixels() {
    // if we're gonna free the pixels, we certainly need to free the mipmap
    this->freeMipMap();

    if (fColorTable) {
        fColorTable->unref();
        fColorTable = NULL;
    }

    if (NULL != fPixelRef) {
        if (fPixelLockCount > 0) {
            fPixelRef->unlockPixels();
        }
        fPixelRef->unref();
        fPixelRef = NULL;
        fPixelRefOffset = 0;
    }
    fPixelLockCount = 0;
    fPixels = NULL;
}

void SkBitmap::freeMipMap() {
    if (fMipMap) {
        fMipMap->unref();
        fMipMap = NULL;
    }
}

uint32_t SkBitmap::getGenerationID() const {
    return (fPixelRef) ? fPixelRef->getGenerationID() : 0;
}

void SkBitmap::notifyPixelsChanged() const {
    SkASSERT(!this->isImmutable());
    if (fPixelRef) {
        fPixelRef->notifyPixelsChanged();
    }
}

GrTexture* SkBitmap::getTexture() const {
    return fPixelRef ? fPixelRef->getTexture() : NULL;
}

///////////////////////////////////////////////////////////////////////////////

/** We explicitly use the same allocator for our pixels that SkMask does,
 so that we can freely assign memory allocated by one class to the other.
 */
bool SkBitmap::HeapAllocator::allocPixelRef(SkBitmap* dst,
                                            SkColorTable* ctable) {
    SkImageInfo info;
    if (!dst->asImageInfo(&info)) {
//        SkDebugf("unsupported config for info %d\n", dst->config());
        return false;
    }

    SkPixelRef* pr = SkMallocPixelRef::NewAllocate(info, dst->rowBytes(),
                                                   ctable);
    if (NULL == pr) {
        return false;
    }

    dst->setPixelRef(pr, 0)->unref();
    // since we're already allocated, we lockPixels right away
    dst->lockPixels();
    return true;
}

///////////////////////////////////////////////////////////////////////////////

size_t SkBitmap::getSafeSize() const {
    // This is intended to be a size_t version of ComputeSafeSize64(), just
    // faster. The computation is meant to be identical.
    return (fHeight ? ((fHeight - 1) * fRowBytes) +
            ComputeRowBytes(this->config(), fWidth): 0);
}

Sk64 SkBitmap::getSafeSize64() const {
    return ComputeSafeSize64(this->config(), fWidth, fHeight, fRowBytes);
}

bool SkBitmap::copyPixelsTo(void* const dst, size_t dstSize,
                            size_t dstRowBytes, bool preserveDstPad) const {

    if (0 == dstRowBytes) {
        dstRowBytes = fRowBytes;
    }

    if (dstRowBytes < ComputeRowBytes(this->config(), fWidth) ||
        dst == NULL || (getPixels() == NULL && pixelRef() == NULL))
        return false;

    if (!preserveDstPad && static_cast<uint32_t>(dstRowBytes) == fRowBytes) {
        size_t safeSize = this->getSafeSize();
        if (safeSize > dstSize || safeSize == 0)
            return false;
        else {
            SkAutoLockPixels lock(*this);
            // This implementation will write bytes beyond the end of each row,
            // excluding the last row, if the bitmap's stride is greater than
            // strictly required by the current config.
            memcpy(dst, getPixels(), safeSize);

            return true;
        }
    } else {
        // If destination has different stride than us, then copy line by line.
        if (ComputeSafeSize(this->config(), fWidth, fHeight, dstRowBytes) >
            dstSize)
            return false;
        else {
            // Just copy what we need on each line.
            size_t rowBytes = ComputeRowBytes(this->config(), fWidth);
            SkAutoLockPixels lock(*this);
            const uint8_t* srcP = reinterpret_cast<const uint8_t*>(getPixels());
            uint8_t* dstP = reinterpret_cast<uint8_t*>(dst);
            for (uint32_t row = 0; row < fHeight;
                 row++, srcP += fRowBytes, dstP += dstRowBytes) {
                memcpy(dstP, srcP, rowBytes);
            }

            return true;
        }
    }
}

///////////////////////////////////////////////////////////////////////////////

bool SkBitmap::isImmutable() const {
    return fPixelRef ? fPixelRef->isImmutable() :
        fFlags & kImageIsImmutable_Flag;
}

void SkBitmap::setImmutable() {
    if (fPixelRef) {
        fPixelRef->setImmutable();
    } else {
        fFlags |= kImageIsImmutable_Flag;
    }
}

bool SkBitmap::isVolatile() const {
    return (fFlags & kImageIsVolatile_Flag) != 0;
}

void SkBitmap::setIsVolatile(bool isVolatile) {
    if (isVolatile) {
        fFlags |= kImageIsVolatile_Flag;
    } else {
        fFlags &= ~kImageIsVolatile_Flag;
    }
}

void* SkBitmap::getAddr(int x, int y) const {
    SkASSERT((unsigned)x < (unsigned)this->width());
    SkASSERT((unsigned)y < (unsigned)this->height());

    char* base = (char*)this->getPixels();
    if (base) {
        base += y * this->rowBytes();
        switch (this->config()) {
            case SkBitmap::kARGB_8888_Config:
                base += x << 2;
                break;
            case SkBitmap::kARGB_4444_Config:
            case SkBitmap::kRGB_565_Config:
                base += x << 1;
                break;
            case SkBitmap::kA8_Config:
            case SkBitmap::kIndex8_Config:
                base += x;
                break;
                break;
            default:
                SkDEBUGFAIL("Can't return addr for config");
                base = NULL;
                break;
        }
    }
    return base;
}

SkColor SkBitmap::getColor(int x, int y) const {
    SkASSERT((unsigned)x < (unsigned)this->width());
    SkASSERT((unsigned)y < (unsigned)this->height());

    switch (this->config()) {
        case SkBitmap::kA8_Config: {
            uint8_t* addr = this->getAddr8(x, y);
            return SkColorSetA(0, addr[0]);
        }
        case SkBitmap::kIndex8_Config: {
            SkPMColor c = this->getIndex8Color(x, y);
            return SkUnPreMultiply::PMColorToColor(c);
        }
        case SkBitmap::kRGB_565_Config: {
            uint16_t* addr = this->getAddr16(x, y);
            return SkPixel16ToColor(addr[0]);
        }
        case SkBitmap::kARGB_4444_Config: {
            uint16_t* addr = this->getAddr16(x, y);
            SkPMColor c = SkPixel4444ToPixel32(addr[0]);
            return SkUnPreMultiply::PMColorToColor(c);
        }
        case SkBitmap::kARGB_8888_Config: {
            uint32_t* addr = this->getAddr32(x, y);
            return SkUnPreMultiply::PMColorToColor(addr[0]);
        }
        case kNo_Config:
        default:
            SkASSERT(false);
            return 0;
    }
    SkASSERT(false);  // Not reached.
    return 0;
}

bool SkBitmap::ComputeIsOpaque(const SkBitmap& bm) {
    SkAutoLockPixels alp(bm);
    if (!bm.getPixels()) {
        return false;
    }

    const int height = bm.height();
    const int width = bm.width();

    switch (bm.config()) {
        case SkBitmap::kA8_Config: {
            unsigned a = 0xFF;
            for (int y = 0; y < height; ++y) {
                const uint8_t* row = bm.getAddr8(0, y);
                for (int x = 0; x < width; ++x) {
                    a &= row[x];
                }
                if (0xFF != a) {
                    return false;
                }
            }
            return true;
        } break;
        case SkBitmap::kIndex8_Config: {
            SkAutoLockColors alc(bm);
            const SkPMColor* table = alc.colors();
            if (!table) {
                return false;
            }
            SkPMColor c = (SkPMColor)~0;
            for (int i = bm.getColorTable()->count() - 1; i >= 0; --i) {
                c &= table[i];
            }
            return 0xFF == SkGetPackedA32(c);
        } break;
        case SkBitmap::kRGB_565_Config:
            return true;
            break;
        case SkBitmap::kARGB_4444_Config: {
            unsigned c = 0xFFFF;
            for (int y = 0; y < height; ++y) {
                const SkPMColor16* row = bm.getAddr16(0, y);
                for (int x = 0; x < width; ++x) {
                    c &= row[x];
                }
                if (0xF != SkGetPackedA4444(c)) {
                    return false;
                }
            }
            return true;
        } break;
        case SkBitmap::kARGB_8888_Config: {
            SkPMColor c = (SkPMColor)~0;
            for (int y = 0; y < height; ++y) {
                const SkPMColor* row = bm.getAddr32(0, y);
                for (int x = 0; x < width; ++x) {
                    c &= row[x];
                }
                if (0xFF != SkGetPackedA32(c)) {
                    return false;
                }
            }
            return true;
        }
        default:
            break;
    }
    return false;
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

static uint16_t pack_8888_to_4444(unsigned a, unsigned r, unsigned g, unsigned b) {
    unsigned pixel = (SkA32To4444(a) << SK_A4444_SHIFT) |
                     (SkR32To4444(r) << SK_R4444_SHIFT) |
                     (SkG32To4444(g) << SK_G4444_SHIFT) |
                     (SkB32To4444(b) << SK_B4444_SHIFT);
    return SkToU16(pixel);
}

void SkBitmap::internalErase(const SkIRect& area,
                             U8CPU a, U8CPU r, U8CPU g, U8CPU b) const {
#ifdef SK_DEBUG
    SkDEBUGCODE(this->validate();)
    SkASSERT(!area.isEmpty());
    {
        SkIRect total = { 0, 0, this->width(), this->height() };
        SkASSERT(total.contains(area));
    }
#endif

    if (kNo_Config == fConfig || kIndex8_Config == fConfig) {
        return;
    }

    SkAutoLockPixels alp(*this);
    // perform this check after the lock call
    if (!this->readyToDraw()) {
        return;
    }

    int height = area.height();
    const int width = area.width();
    const int rowBytes = fRowBytes;

    // make rgb premultiplied
    if (255 != a) {
        r = SkAlphaMul(r, a);
        g = SkAlphaMul(g, a);
        b = SkAlphaMul(b, a);
    }

    switch (fConfig) {
        case kA8_Config: {
            uint8_t* p = this->getAddr8(area.fLeft, area.fTop);
            while (--height >= 0) {
                memset(p, a, width);
                p += rowBytes;
            }
            break;
        }
        case kARGB_4444_Config:
        case kRGB_565_Config: {
            uint16_t* p = this->getAddr16(area.fLeft, area.fTop);;
            uint16_t v;

            if (kARGB_4444_Config == fConfig) {
                v = pack_8888_to_4444(a, r, g, b);
            } else {
                v = SkPackRGB16(r >> (8 - SK_R16_BITS),
                                g >> (8 - SK_G16_BITS),
                                b >> (8 - SK_B16_BITS));
            }
            while (--height >= 0) {
                sk_memset16(p, v, width);
                p = (uint16_t*)((char*)p + rowBytes);
            }
            break;
        }
        case kARGB_8888_Config: {
            uint32_t* p = this->getAddr32(area.fLeft, area.fTop);
            uint32_t  v = SkPackARGB32(a, r, g, b);

            while (--height >= 0) {
                sk_memset32(p, v, width);
                p = (uint32_t*)((char*)p + rowBytes);
            }
            break;
        }
    }

    this->notifyPixelsChanged();
}

void SkBitmap::eraseARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) const {
    SkIRect area = { 0, 0, this->width(), this->height() };
    if (!area.isEmpty()) {
        this->internalErase(area, a, r, g, b);
    }
}

void SkBitmap::eraseArea(const SkIRect& rect, SkColor c) const {
    SkIRect area = { 0, 0, this->width(), this->height() };
    if (area.intersect(rect)) {
        this->internalErase(area, SkColorGetA(c), SkColorGetR(c),
                            SkColorGetG(c), SkColorGetB(c));
    }
}

//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////

#define SUB_OFFSET_FAILURE  ((size_t)-1)

/**
 *  Based on the Config and rowBytes() of bm, return the offset into an SkPixelRef of the pixel at
 *  (x, y).
 *  Note that the SkPixelRef does not need to be set yet. deepCopyTo takes advantage of this fact.
 *  Also note that (x, y) may be outside the range of (0 - width(), 0 - height()), so long as it is
 *  within the bounds of the SkPixelRef being used.
 */
static size_t get_sub_offset(const SkBitmap& bm, int x, int y) {
    switch (bm.config()) {
        case SkBitmap::kA8_Config:
        case SkBitmap:: kIndex8_Config:
            // x is fine as is for the calculation
            break;

        case SkBitmap::kRGB_565_Config:
        case SkBitmap::kARGB_4444_Config:
            x <<= 1;
            break;

        case SkBitmap::kARGB_8888_Config:
            x <<= 2;
            break;

        case SkBitmap::kNo_Config:
        default:
            return SUB_OFFSET_FAILURE;
    }
    return y * bm.rowBytes() + x;
}

/**
 *  Using the pixelRefOffset(), rowBytes(), and Config of bm, determine the (x, y) coordinate of the
 *  upper left corner of bm relative to its SkPixelRef.
 *  x and y must be non-NULL.
 */
bool get_upper_left_from_offset(SkBitmap::Config config, size_t offset, size_t rowBytes,
                                   int32_t* x, int32_t* y);
bool get_upper_left_from_offset(SkBitmap::Config config, size_t offset, size_t rowBytes,
                                   int32_t* x, int32_t* y) {
    SkASSERT(x != NULL && y != NULL);
    if (0 == offset) {
        *x = *y = 0;
        return true;
    }
    // Use integer division to find the correct y position.
    // The remainder will be the x position, after we reverse get_sub_offset.
    SkTDivMod(offset, rowBytes, y, x);
    switch (config) {
        case SkBitmap::kA8_Config:
            // Fall through.
        case SkBitmap::kIndex8_Config:
            // x is unmodified
            break;

        case SkBitmap::kRGB_565_Config:
            // Fall through.
        case SkBitmap::kARGB_4444_Config:
            *x >>= 1;
            break;

        case SkBitmap::kARGB_8888_Config:
            *x >>= 2;
            break;

        case SkBitmap::kNo_Config:
            // Fall through.
        default:
            return false;
    }
    return true;
}

static bool get_upper_left_from_offset(const SkBitmap& bm, int32_t* x, int32_t* y) {
    return get_upper_left_from_offset(bm.config(), bm.pixelRefOffset(), bm.rowBytes(), x, y);
}

bool SkBitmap::extractSubset(SkBitmap* result, const SkIRect& subset) const {
    SkDEBUGCODE(this->validate();)

    if (NULL == result || NULL == fPixelRef) {
        return false;   // no src pixels
    }

    SkIRect srcRect, r;
    srcRect.set(0, 0, this->width(), this->height());
    if (!r.intersect(srcRect, subset)) {
        return false;   // r is empty (i.e. no intersection)
    }

    if (fPixelRef->getTexture() != NULL) {
        // Do a deep copy
        SkPixelRef* pixelRef = fPixelRef->deepCopy(this->config(), &subset);
        if (pixelRef != NULL) {
            SkBitmap dst;
            dst.setConfig(this->config(), subset.width(), subset.height(), 0,
                          this->alphaType());
            dst.setIsVolatile(this->isVolatile());
            dst.setPixelRef(pixelRef)->unref();
            SkDEBUGCODE(dst.validate());
            result->swap(dst);
            return true;
        }
    }

    // If the upper left of the rectangle was outside the bounds of this SkBitmap, we should have
    // exited above.
    SkASSERT(static_cast<unsigned>(r.fLeft) < static_cast<unsigned>(this->width()));
    SkASSERT(static_cast<unsigned>(r.fTop) < static_cast<unsigned>(this->height()));

    size_t offset = get_sub_offset(*this, r.fLeft, r.fTop);
    if (SUB_OFFSET_FAILURE == offset) {
        return false;   // config not supported
    }

    SkBitmap dst;
    dst.setConfig(this->config(), r.width(), r.height(), this->rowBytes(),
                  this->alphaType());
    dst.setIsVolatile(this->isVolatile());

    if (fPixelRef) {
        // share the pixelref with a custom offset
        dst.setPixelRef(fPixelRef, fPixelRefOffset + offset);
    }
    SkDEBUGCODE(dst.validate();)

    // we know we're good, so commit to result
    result->swap(dst);
    return true;
}

///////////////////////////////////////////////////////////////////////////////

#include "SkCanvas.h"
#include "SkPaint.h"

bool SkBitmap::canCopyTo(Config dstConfig) const {
    if (this->config() == kNo_Config) {
        return false;
    }

    bool sameConfigs = (this->config() == dstConfig);
    switch (dstConfig) {
        case kA8_Config:
        case kRGB_565_Config:
        case kARGB_8888_Config:
            break;
        case kIndex8_Config:
            if (!sameConfigs) {
                return false;
            }
            break;
        case kARGB_4444_Config:
            return sameConfigs || kARGB_8888_Config == this->config();
        default:
            return false;
    }
    return true;
}

bool SkBitmap::copyTo(SkBitmap* dst, Config dstConfig, Allocator* alloc) const {
    if (!this->canCopyTo(dstConfig)) {
        return false;
    }

    // if we have a texture, first get those pixels
    SkBitmap tmpSrc;
    const SkBitmap* src = this;

    if (fPixelRef) {
        SkIRect subset;
        if (get_upper_left_from_offset(*this, &subset.fLeft, &subset.fTop)) {
            subset.fRight = subset.fLeft + fWidth;
            subset.fBottom = subset.fTop + fHeight;
            if (fPixelRef->readPixels(&tmpSrc, &subset)) {
                SkASSERT(tmpSrc.width() == this->width());
                SkASSERT(tmpSrc.height() == this->height());

                // did we get lucky and we can just return tmpSrc?
                if (tmpSrc.config() == dstConfig && NULL == alloc) {
                    dst->swap(tmpSrc);
                    if (dst->pixelRef() && this->config() == dstConfig) {
                        // TODO(scroggo): fix issue 1742
                        dst->pixelRef()->cloneGenID(*fPixelRef);
                    }
                    return true;
                }

                // fall through to the raster case
                src = &tmpSrc;
            }
        }
    }

    // we lock this now, since we may need its colortable
    SkAutoLockPixels srclock(*src);
    if (!src->readyToDraw()) {
        return false;
    }

    SkBitmap tmpDst;
    tmpDst.setConfig(dstConfig, src->width(), src->height(), 0,
                     src->alphaType());

    // allocate colortable if srcConfig == kIndex8_Config
    SkColorTable* ctable = (dstConfig == kIndex8_Config) ?
    new SkColorTable(*src->getColorTable()) : NULL;
    SkAutoUnref au(ctable);
    if (!tmpDst.allocPixels(alloc, ctable)) {
        return false;
    }

    if (!tmpDst.readyToDraw()) {
        // allocator/lock failed
        return false;
    }

    /* do memcpy for the same configs cases, else use drawing
    */
    if (src->config() == dstConfig) {
        if (tmpDst.getSize() == src->getSize()) {
            memcpy(tmpDst.getPixels(), src->getPixels(), src->getSafeSize());
            SkPixelRef* pixelRef = tmpDst.pixelRef();
            if (NULL != pixelRef && NULL != fPixelRef) {
                // TODO(scroggo): fix issue 1742
                pixelRef->cloneGenID(*fPixelRef);
            }
        } else {
            const char* srcP = reinterpret_cast<const char*>(src->getPixels());
            char* dstP = reinterpret_cast<char*>(tmpDst.getPixels());
            // to be sure we don't read too much, only copy our logical pixels
            size_t bytesToCopy = tmpDst.width() * tmpDst.bytesPerPixel();
            for (int y = 0; y < tmpDst.height(); y++) {
                memcpy(dstP, srcP, bytesToCopy);
                srcP += src->rowBytes();
                dstP += tmpDst.rowBytes();
            }
        }
    } else if (SkBitmap::kARGB_4444_Config == dstConfig
               && SkBitmap::kARGB_8888_Config == src->config()) {
        SkASSERT(src->height() == tmpDst.height());
        SkASSERT(src->width() == tmpDst.width());
        for (int y = 0; y < src->height(); ++y) {
            SkPMColor16* SK_RESTRICT dstRow = (SkPMColor16*) tmpDst.getAddr16(0, y);
            SkPMColor* SK_RESTRICT srcRow = (SkPMColor*) src->getAddr32(0, y);
            DITHER_4444_SCAN(y);
            for (int x = 0; x < src->width(); ++x) {
                dstRow[x] = SkDitherARGB32To4444(srcRow[x],
                                                 DITHER_VALUE(x));
            }
        }
    } else {
        // Always clear the dest in case one of the blitters accesses it
        // TODO: switch the allocation of tmpDst to call sk_calloc_throw
        tmpDst.eraseColor(SK_ColorTRANSPARENT);

        SkCanvas canvas(tmpDst);
        SkPaint  paint;

        paint.setDither(true);
        canvas.drawBitmap(*src, 0, 0, &paint);
    }

    dst->swap(tmpDst);
    return true;
}

bool SkBitmap::deepCopyTo(SkBitmap* dst, Config dstConfig) const {
    if (!this->canCopyTo(dstConfig)) {
        return false;
    }

    // If we have a PixelRef, and it supports deep copy, use it.
    // Currently supported only by texture-backed bitmaps.
    if (fPixelRef) {
        SkPixelRef* pixelRef = fPixelRef->deepCopy(dstConfig);
        if (pixelRef) {
            uint32_t rowBytes;
            if (dstConfig == fConfig) {
                // TODO(scroggo): fix issue 1742
                pixelRef->cloneGenID(*fPixelRef);
                // Use the same rowBytes as the original.
                rowBytes = fRowBytes;
            } else {
                // With the new config, an appropriate fRowBytes will be computed by setConfig.
                rowBytes = 0;
            }
            dst->setConfig(dstConfig, fWidth, fHeight, rowBytes);

            size_t pixelRefOffset;
            if (0 == fPixelRefOffset || dstConfig == fConfig) {
                // Use the same offset as the original.
                pixelRefOffset = fPixelRefOffset;
            } else {
                // Find the correct offset in the new config. This needs to be done after calling
                // setConfig so dst's fConfig and fRowBytes have been set properly.
                int32_t x, y;
                if (!get_upper_left_from_offset(*this, &x, &y)) {
                    return false;
                }
                pixelRefOffset = get_sub_offset(*dst, x, y);
                if (SUB_OFFSET_FAILURE == pixelRefOffset) {
                    return false;
                }
            }
            dst->setPixelRef(pixelRef, pixelRefOffset)->unref();
            return true;
        }
    }

    if (this->getTexture()) {
        return false;
    } else {
        return this->copyTo(dst, dstConfig, NULL);
    }
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

static void downsampleby2_proc32(SkBitmap* dst, int x, int y,
                                 const SkBitmap& src) {
    x <<= 1;
    y <<= 1;
    const SkPMColor* p = src.getAddr32(x, y);
    const SkPMColor* baseP = p;
    SkPMColor c, ag, rb;

    c = *p; ag = (c >> 8) & 0xFF00FF; rb = c & 0xFF00FF;
    if (x < src.width() - 1) {
        p += 1;
    }
    c = *p; ag += (c >> 8) & 0xFF00FF; rb += c & 0xFF00FF;

    p = baseP;
    if (y < src.height() - 1) {
        p += src.rowBytes() >> 2;
    }
    c = *p; ag += (c >> 8) & 0xFF00FF; rb += c & 0xFF00FF;
    if (x < src.width() - 1) {
        p += 1;
    }
    c = *p; ag += (c >> 8) & 0xFF00FF; rb += c & 0xFF00FF;

    *dst->getAddr32(x >> 1, y >> 1) =
        ((rb >> 2) & 0xFF00FF) | ((ag << 6) & 0xFF00FF00);
}

static inline uint32_t expand16(U16CPU c) {
    return (c & ~SK_G16_MASK_IN_PLACE) | ((c & SK_G16_MASK_IN_PLACE) << 16);
}

// returns dirt in the top 16bits, but we don't care, since we only
// store the low 16bits.
static inline U16CPU pack16(uint32_t c) {
    return (c & ~SK_G16_MASK_IN_PLACE) | ((c >> 16) & SK_G16_MASK_IN_PLACE);
}

static void downsampleby2_proc16(SkBitmap* dst, int x, int y,
                                 const SkBitmap& src) {
    x <<= 1;
    y <<= 1;
    const uint16_t* p = src.getAddr16(x, y);
    const uint16_t* baseP = p;
    SkPMColor       c;

    c = expand16(*p);
    if (x < src.width() - 1) {
        p += 1;
    }
    c += expand16(*p);

    p = baseP;
    if (y < src.height() - 1) {
        p += src.rowBytes() >> 1;
    }
    c += expand16(*p);
    if (x < src.width() - 1) {
        p += 1;
    }
    c += expand16(*p);

    *dst->getAddr16(x >> 1, y >> 1) = (uint16_t)pack16(c >> 2);
}

static uint32_t expand4444(U16CPU c) {
    return (c & 0xF0F) | ((c & ~0xF0F) << 12);
}

static U16CPU collaps4444(uint32_t c) {
    return (c & 0xF0F) | ((c >> 12) & ~0xF0F);
}

static void downsampleby2_proc4444(SkBitmap* dst, int x, int y,
                                   const SkBitmap& src) {
    x <<= 1;
    y <<= 1;
    const uint16_t* p = src.getAddr16(x, y);
    const uint16_t* baseP = p;
    uint32_t        c;

    c = expand4444(*p);
    if (x < src.width() - 1) {
        p += 1;
    }
    c += expand4444(*p);

    p = baseP;
    if (y < src.height() - 1) {
        p += src.rowBytes() >> 1;
    }
    c += expand4444(*p);
    if (x < src.width() - 1) {
        p += 1;
    }
    c += expand4444(*p);

    *dst->getAddr16(x >> 1, y >> 1) = (uint16_t)collaps4444(c >> 2);
}

void SkBitmap::buildMipMap(bool forceRebuild) {
    if (forceRebuild)
        this->freeMipMap();
    else if (fMipMap)
        return; // we're already built

    SkASSERT(NULL == fMipMap);

    void (*proc)(SkBitmap* dst, int x, int y, const SkBitmap& src);

    const SkBitmap::Config config = this->config();

    switch (config) {
        case kARGB_8888_Config:
            proc = downsampleby2_proc32;
            break;
        case kRGB_565_Config:
            proc = downsampleby2_proc16;
            break;
        case kARGB_4444_Config:
            proc = downsampleby2_proc4444;
            break;
        case kIndex8_Config:
        case kA8_Config:
        default:
            return; // don't build mipmaps for these configs
    }

    SkAutoLockPixels alp(*this);
    if (!this->readyToDraw()) {
        return;
    }

    // whip through our loop to compute the exact size needed
    size_t  size = 0;
    int     maxLevels = 0;
    {
        int width = this->width();
        int height = this->height();
        for (;;) {
            width >>= 1;
            height >>= 1;
            if (0 == width || 0 == height) {
                break;
            }
            size += ComputeRowBytes(config, width) * height;
            maxLevels += 1;
        }
    }

    // nothing to build
    if (0 == maxLevels) {
        return;
    }

    SkBitmap srcBM(*this);
    srcBM.lockPixels();
    if (!srcBM.readyToDraw()) {
        return;
    }

    MipMap* mm = MipMap::Alloc(maxLevels, size);
    if (NULL == mm) {
        return;
    }

    MipLevel*   level = mm->levels();
    uint8_t*    addr = (uint8_t*)mm->pixels();
    int         width = this->width();
    int         height = this->height();
    uint32_t    rowBytes;
    SkBitmap    dstBM;

    for (int i = 0; i < maxLevels; i++) {
        width >>= 1;
        height >>= 1;
        rowBytes = SkToU32(ComputeRowBytes(config, width));

        level[i].fPixels   = addr;
        level[i].fWidth    = width;
        level[i].fHeight   = height;
        level[i].fRowBytes = rowBytes;

        dstBM.setConfig(config, width, height, rowBytes);
        dstBM.setPixels(addr);

        srcBM.lockPixels();
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                proc(&dstBM, x, y, srcBM);
            }
        }
        srcBM.unlockPixels();

        srcBM = dstBM;
        addr += height * rowBytes;
    }
    SkASSERT(addr == (uint8_t*)mm->pixels() + size);
    fMipMap = mm;
}

bool SkBitmap::hasMipMap() const {
    return fMipMap != NULL;
}

int SkBitmap::extractMipLevel(SkBitmap* dst, SkFixed sx, SkFixed sy) {
    if (NULL == fMipMap) {
        return 0;
    }

    int level = ComputeMipLevel(sx, sy) >> 16;
    SkASSERT(level >= 0);
    if (level <= 0) {
        return 0;
    }

    if (level >= fMipMap->fLevelCount) {
        level = fMipMap->fLevelCount - 1;
    }
    if (dst) {
        const MipLevel& mip = fMipMap->levels()[level - 1];
        dst->setConfig((SkBitmap::Config)this->config(),
                       mip.fWidth, mip.fHeight, mip.fRowBytes);
        dst->setPixels(mip.fPixels);
    }
    return level;
}

SkFixed SkBitmap::ComputeMipLevel(SkFixed sx, SkFixed sy) {
    sx = SkAbs32(sx);
    sy = SkAbs32(sy);
    if (sx < sy) {
        sx = sy;
    }
    if (sx < SK_Fixed1) {
        return 0;
    }
    int clz = SkCLZ(sx);
    SkASSERT(clz >= 1 && clz <= 15);
    return SkIntToFixed(15 - clz) + ((unsigned)(sx << (clz + 1)) >> 16);
}

///////////////////////////////////////////////////////////////////////////////

static bool GetBitmapAlpha(const SkBitmap& src, uint8_t* SK_RESTRICT alpha,
                           int alphaRowBytes) {
    SkASSERT(alpha != NULL);
    SkASSERT(alphaRowBytes >= src.width());

    SkBitmap::Config config = src.config();
    int              w = src.width();
    int              h = src.height();
    size_t           rb = src.rowBytes();

    SkAutoLockPixels alp(src);
    if (!src.readyToDraw()) {
        // zero out the alpha buffer and return
        while (--h >= 0) {
            memset(alpha, 0, w);
            alpha += alphaRowBytes;
        }
        return false;
    }

    if (SkBitmap::kA8_Config == config && !src.isOpaque()) {
        const uint8_t* s = src.getAddr8(0, 0);
        while (--h >= 0) {
            memcpy(alpha, s, w);
            s += rb;
            alpha += alphaRowBytes;
        }
    } else if (SkBitmap::kARGB_8888_Config == config && !src.isOpaque()) {
        const SkPMColor* SK_RESTRICT s = src.getAddr32(0, 0);
        while (--h >= 0) {
            for (int x = 0; x < w; x++) {
                alpha[x] = SkGetPackedA32(s[x]);
            }
            s = (const SkPMColor*)((const char*)s + rb);
            alpha += alphaRowBytes;
        }
    } else if (SkBitmap::kARGB_4444_Config == config && !src.isOpaque()) {
        const SkPMColor16* SK_RESTRICT s = src.getAddr16(0, 0);
        while (--h >= 0) {
            for (int x = 0; x < w; x++) {
                alpha[x] = SkPacked4444ToA32(s[x]);
            }
            s = (const SkPMColor16*)((const char*)s + rb);
            alpha += alphaRowBytes;
        }
    } else if (SkBitmap::kIndex8_Config == config && !src.isOpaque()) {
        SkColorTable* ct = src.getColorTable();
        if (ct) {
            const SkPMColor* SK_RESTRICT table = ct->lockColors();
            const uint8_t* SK_RESTRICT s = src.getAddr8(0, 0);
            while (--h >= 0) {
                for (int x = 0; x < w; x++) {
                    alpha[x] = SkGetPackedA32(table[s[x]]);
                }
                s += rb;
                alpha += alphaRowBytes;
            }
            ct->unlockColors();
        }
    } else {    // src is opaque, so just fill alpha[] with 0xFF
        memset(alpha, 0xFF, h * alphaRowBytes);
    }
    return true;
}

#include "SkPaint.h"
#include "SkMaskFilter.h"
#include "SkMatrix.h"

bool SkBitmap::extractAlpha(SkBitmap* dst, const SkPaint* paint,
                            Allocator *allocator, SkIPoint* offset) const {
    SkDEBUGCODE(this->validate();)

    SkBitmap    tmpBitmap;
    SkMatrix    identity;
    SkMask      srcM, dstM;

    srcM.fBounds.set(0, 0, this->width(), this->height());
    srcM.fRowBytes = SkAlign4(this->width());
    srcM.fFormat = SkMask::kA8_Format;

    SkMaskFilter* filter = paint ? paint->getMaskFilter() : NULL;

    // compute our (larger?) dst bounds if we have a filter
    if (NULL != filter) {
        identity.reset();
        srcM.fImage = NULL;
        if (!filter->filterMask(&dstM, srcM, identity, NULL)) {
            goto NO_FILTER_CASE;
        }
        dstM.fRowBytes = SkAlign4(dstM.fBounds.width());
    } else {
    NO_FILTER_CASE:
        tmpBitmap.setConfig(SkBitmap::kA8_Config, this->width(), this->height(),
                       srcM.fRowBytes);
        if (!tmpBitmap.allocPixels(allocator, NULL)) {
            // Allocation of pixels for alpha bitmap failed.
            SkDebugf("extractAlpha failed to allocate (%d,%d) alpha bitmap\n",
                    tmpBitmap.width(), tmpBitmap.height());
            return false;
        }
        GetBitmapAlpha(*this, tmpBitmap.getAddr8(0, 0), srcM.fRowBytes);
        if (offset) {
            offset->set(0, 0);
        }
        tmpBitmap.swap(*dst);
        return true;
    }
    srcM.fImage = SkMask::AllocImage(srcM.computeImageSize());
    SkAutoMaskFreeImage srcCleanup(srcM.fImage);

    GetBitmapAlpha(*this, srcM.fImage, srcM.fRowBytes);
    if (!filter->filterMask(&dstM, srcM, identity, NULL)) {
        goto NO_FILTER_CASE;
    }
    SkAutoMaskFreeImage dstCleanup(dstM.fImage);

    tmpBitmap.setConfig(SkBitmap::kA8_Config, dstM.fBounds.width(),
                   dstM.fBounds.height(), dstM.fRowBytes);
    if (!tmpBitmap.allocPixels(allocator, NULL)) {
        // Allocation of pixels for alpha bitmap failed.
        SkDebugf("extractAlpha failed to allocate (%d,%d) alpha bitmap\n",
                tmpBitmap.width(), tmpBitmap.height());
        return false;
    }
    memcpy(tmpBitmap.getPixels(), dstM.fImage, dstM.computeImageSize());
    if (offset) {
        offset->set(dstM.fBounds.fLeft, dstM.fBounds.fTop);
    }
    SkDEBUGCODE(tmpBitmap.validate();)

    tmpBitmap.swap(*dst);
    return true;
}

///////////////////////////////////////////////////////////////////////////////

enum {
    SERIALIZE_PIXELTYPE_NONE,
    SERIALIZE_PIXELTYPE_REF_DATA
};

void SkBitmap::flatten(SkFlattenableWriteBuffer& buffer) const {
    buffer.writeInt(fWidth);
    buffer.writeInt(fHeight);
    buffer.writeInt(fRowBytes);
    buffer.writeInt(fConfig);
    buffer.writeInt(fAlphaType);

    if (fPixelRef) {
        if (fPixelRef->getFactory()) {
            buffer.writeInt(SERIALIZE_PIXELTYPE_REF_DATA);
            buffer.writeUInt(SkToU32(fPixelRefOffset));
            buffer.writeFlattenable(fPixelRef);
            return;
        }
        // if we get here, we can't record the pixels
        buffer.writeInt(SERIALIZE_PIXELTYPE_NONE);
    } else {
        buffer.writeInt(SERIALIZE_PIXELTYPE_NONE);
    }
}

void SkBitmap::unflatten(SkFlattenableReadBuffer& buffer) {
    this->reset();

    int width = buffer.readInt();
    int height = buffer.readInt();
    int rowBytes = buffer.readInt();
    Config config = (Config)buffer.readInt();
    SkAlphaType alphaType = (SkAlphaType)buffer.readInt();
    buffer.validate((width >= 0) && (height >= 0) && (rowBytes >= 0) &&
                    SkIsValidConfig(config) && validate_alphaType(config, alphaType));

    bool configIsValid = this->setConfig(config, width, height, rowBytes, alphaType);
    // Note : Using (fRowBytes >= (fWidth * fBytesPerPixel)) in the following test can create false
    //        positives if the multiplication causes an integer overflow. Use the division instead.
    buffer.validate(configIsValid && (fBytesPerPixel > 0) &&
                    ((fRowBytes / fBytesPerPixel) >= fWidth));

    int reftype = buffer.readInt();
    if (buffer.validate((SERIALIZE_PIXELTYPE_REF_DATA == reftype) ||
                        (SERIALIZE_PIXELTYPE_NONE == reftype))) {
        switch (reftype) {
            case SERIALIZE_PIXELTYPE_REF_DATA: {
                size_t offset = buffer.readUInt();
                SkPixelRef* pr = buffer.readPixelRef();
                if (!buffer.validate((NULL == pr) ||
                       (pr->getAllocatedSizeInBytes() >= (offset + this->getSafeSize())))) {
                    offset = 0;
                }
                SkSafeUnref(this->setPixelRef(pr, offset));
                break;
            }
            case SERIALIZE_PIXELTYPE_NONE:
                break;
            default:
                SkDEBUGFAIL("unrecognized pixeltype in serialized data");
                sk_throw();
        }
    }
}

///////////////////////////////////////////////////////////////////////////////

SkBitmap::RLEPixels::RLEPixels(int width, int height) {
    fHeight = height;
    fYPtrs = (uint8_t**)sk_calloc_throw(height * sizeof(uint8_t*));
}

SkBitmap::RLEPixels::~RLEPixels() {
    sk_free(fYPtrs);
}

///////////////////////////////////////////////////////////////////////////////

#ifdef SK_DEBUG
void SkBitmap::validate() const {
    SkASSERT(fConfig < kConfigCount);
    SkASSERT(fRowBytes >= (unsigned)ComputeRowBytes((Config)fConfig, fWidth));
    uint8_t allFlags = kImageIsOpaque_Flag | kImageIsVolatile_Flag | kImageIsImmutable_Flag;
#ifdef SK_BUILD_FOR_ANDROID
    allFlags |= kHasHardwareMipMap_Flag;
#endif
    SkASSERT(fFlags <= allFlags);
    SkASSERT(fPixelLockCount >= 0);
    SkASSERT(NULL == fColorTable || (unsigned)fColorTable->getRefCnt() < 10000);
    SkASSERT((uint8_t)ComputeBytesPerPixel((Config)fConfig) == fBytesPerPixel);

#if 0   // these asserts are not thread-correct, so disable for now
    if (fPixelRef) {
        if (fPixelLockCount > 0) {
            SkASSERT(fPixelRef->isLocked());
        } else {
            SkASSERT(NULL == fPixels);
            SkASSERT(NULL == fColorTable);
        }
    }
#endif
}
#endif

#ifdef SK_DEVELOPER
void SkBitmap::toString(SkString* str) const {

    static const char* gConfigNames[kConfigCount] = {
        "NONE", "A8", "INDEX8", "565", "4444", "8888"
    };

    str->appendf("bitmap: ((%d, %d) %s", this->width(), this->height(),
                 gConfigNames[this->config()]);

    str->append(" (");
    if (this->isOpaque()) {
        str->append("opaque");
    } else {
        str->append("transparent");
    }
    if (this->isImmutable()) {
        str->append(", immutable");
    } else {
        str->append(", not-immutable");
    }
    str->append(")");

    SkPixelRef* pr = this->pixelRef();
    if (NULL == pr) {
        // show null or the explicit pixel address (rare)
        str->appendf(" pixels:%p", this->getPixels());
    } else {
        const char* uri = pr->getURI();
        if (NULL != uri) {
            str->appendf(" uri:\"%s\"", uri);
        } else {
            str->appendf(" pixelref:%p", pr);
        }
    }

    str->append(")");
}
#endif


text:
Travel - Discover
Ten Of The Most Beautiful Places Of The World!
Santorini island - Greece
We live in a world blessed with sights that are beautiful beyond words. Every human being probably dreams of visiting at least one of those places in their lifetime. Living in modern cities with high-rise buildings, we tend to miss out on what Mother Nature has to offer as well as some of the most incredible man-made structures built throughout the course of history.
Look at the places below, and you will see beauty that ...
... fills the eye and warms the heart. It wouldn't be appropriate or humanly possible to just pick a few places from the huge collection of amazing sights around the world and call them the "best."
They say that "beauty is in the eye of the beholder," and there are perhaps other places that have touched your heart. For this reason, we do not claim the places included in our list are the best, but ratheramong the vast collection of the most beautiful places of the world.
Skardu Valley – Pakistan
Photo by bogavanterojo
Photo by NotMicroButSoft
Skardu Valley is part of the Baltistan. Baltistan is spread over an area of 26,000 square kilometres – just right below the jagged and glaciated ramparts of the Karakoram. Once part of Laddakh, it was known as Tibet-i-Khurd – Little Tibet. Archaeological exploration has proven that it was encompassed by the Silk Trade Route.
Shangrila – Pakistan
Shangrila Resort Skardu, also known as "Heaven on Earth", is nestled amongst some of the world's highest peaks. It encircles the heart shaped "Kachura Lake" and is surrounded by fruit laden orchards and flower filled gardens.
Lake Saiful Muluk – Pakistan
Photo by Fahd Murtaza
Lake Saiful Muluk is a lake located at the northern end of the Kaghan Valley near Naran. A fairy tale called Saiful Muluk, written by the famous sufi poet Mian Muhammad Bakhsh, is associated with the lake. It is the story of prince of Persia who fell in love with a fairy princess at the lake. The impact of the lake beauty is of such extent that people believe that fairies come down to lake in full moon.
The Grand Canyon, United States
A steep gorge by the Colorado River, Arizona in the United States, the Grand Canyon has some truly enjoyable scenery. It is 277 miles in length, 4 to 18 miles in width, and about a mile deep. Scientists believe that the canyon was created by the Colorado River over a six million year period.
Native Americans built settlements in the caves within the canyon before the emigration of Europeans. It was also considered to be a site of pilgrimage by the Pueblo people. The first recorded visit to the Grand Canyon by the Europeans was in 1869. Although it is not the deepest canyon in the world, it is known for its extremely large size and beautifully intricate landscape. The Grand Canyon National Park is said to be one of the first national parks in the United States and it attracts more than five million visitors a year. Weather conditions in the Grand Canyon vary greatly between seasons as well as varying at different elevations. While winter snow is experienced by the higher forested rims, the inner gorge has a desert temperature because of the low elevation.
The Great Barrier Reef, Australia
One of the natural wonders of the world, the Great Barrier Reef off the east coast of Australia is the world's largest coral reef. It has the distinction of being placed in the World Heritage as well as the National Heritage lists.
With more than 600 islands and coral cays, the reef covers more than 300,000 sq. km. Corals make up the reefs and cays and are responsible for a huge variety of sea life in the reef — green turtles, several varieties of whales and dolphins, the dugong, about 4000 types of mollusks, 1500 different species of fish, as well as beautifully colored bird life encompassing at least 200 species. The Great Reef Marine Park is a huge tourist attraction with millions of tourists visiting the area each year. Sporting activities include reef sailing, scuba diving, and snorkeling, amongst others.
Aptly called "Heaven on earth," this beautiful town at the tip of the African continent, with small roads surrounded by huge mountains, makes a person feel small; showing how marvelous and dominating nature can actually be.
The Cape Dutch style buildings depict the architectural heritage of the place. Beauty abounds in the black clouds that seem to pay homage to Table Mountain at all times. Cape Point, Signal Hill, Chapman's Peak Drive, Victoria & Alfred Waterfront, Robben Island, Rhodes Memorial, and the beaches are some of the famous tourist attractions. Located on the shore of Table Bay, Cape Town is famous for its natural floral kingdom as well as its harbor. This town is one of the most popular tourist attractions of South Africa with its wine tasting day trips, whale watching, and dolphin watching.
The Taj Mahal in India is one of the wonders of the world and is one of the most beautiful mausoleums constructed by the Mughal emperor, Shah Jahan, in memory of his favorite queen, Mumtaz Mahal. Located in Agra, white marble was used in the construction of this symbol of love, and the Taj Mahal is considered to be the pinnacle of Mughal architecture.
As the story goes, the emperor was grief-stricken when he lost his beloved third wife, Mumtaz Mahal. It took thousands of craftsmen and artisans, and about twenty years to construct it. The masons, stone cutters, carvers, inlayers, calligraphers, painters, and others were brought from throughout the entire empire as well as from Iran and Central Asia. Semi-precious stones were used for inlay ornamentation. It later became the mausoleum of Shah Jahan too. This is a huge tourist attraction with one to two million tourists visiting it every year.
Canadian Rockies, Canada
The majestic Canadian Rockies are the Canadian segment of the North American Rocky Mountains. They are a visitor's wonderland and the playground for western Canada. They are older than the American Rockies and are formed from over thrusting.
The Canadian Rockies house five national parks, and four of those national parks (along with other provincial parks) combine to form a single UNESCO World Heritage Site that consists of beautiful mountain landscapes, lakes, canyons, waterfalls, glaciers, peaks, limestone caves, and fossils. Mount Robson is the highest peak of the Canadian Rockies and climbing it is considered a challenge. These beautiful mountains are a haven for hikers and walkers alike.
Machu Picchu, Peru
Machu Picchu in Peru, which means 'Old Peak," is one of the most enigmatic ancient sites in the world. According to legend, Machu Picchu was long ago considered to be a sacred place. The credit for the creation of the extraordinary city goes to the Inca people who have erected many stone structures and turned the place into a work of art.
Two thousand feet above the Urubamba river, these ruins consist of baths, temples, palaces, and about 150 houses, all very well preserved. These gray granite structures, some of which weigh more than 50 tons, are so perfectly sculpted that they are nothing less than works of architectural genius. They were rediscovered by a Yale archaeologist in 1911. The ethereal beauty, workmanship, and history of the place attracts millions of tourists each year.
The Pyramids, Egypt
The Egyptian pyramids are massive monuments with a square base and four triangular sides rising up to a point. There is still a lot of curiosity (and many theories) as to how the pyramids were actually constructed.
It is generally believed that the Egyptians began constructing them after 2700 B.C. and that they were built as tombs for the pharaohs. The most well-known (and the largest) pyramids of Egypt are the Pyramids at Giza which are said to be the largest ever built. It's said that the Great Pyramid at Giza took 23 years to complete, using a work force of around 30,000 people. About 118 pyramids have been identified, and they are popular and intriguing to tourists and home researchers alike.
Described by the UNESCO as "one of the most precious cultural properties of man's cultural heritage", Petra is an archeological site on the slope of Mount Hor. It is one of the new wonders of the world and is famous for its rock-cut architecture.
This site was kept hidden until 1812 when it was discovered by a Swiss explorer. It was said to have been prepared by God for the Jewish people. Petra once flourished under the Roman empire but a rapid decline began with the Arabian trade being taken elsewhere. Then an earthquake caused a great deal of destruction. Tourists frequent the place to get a glimpse of the ruins of this beautiful city.
Great Wall of China, China
One of the seven wonders of the world, the Great Wall of China is a man-made structure that was constructed over two thousand years ago and took about 100 years to complete. The vastness of this project brings to light the immense capabilities of man.
The constructions started in the 5th Century B.C. It is actually not a single wall, but rather many walls put together, and it stretches over 4,000 miles. It was constructed to protect the Chinese Empire from the Xiongnu people in the north. The wall was initially built of stone, grass, earth, and wood, but bricks were used once the production started. It is believed that about 2-3 million Chinese died during the construction project.
The Iguazu Waterfalls, Argentina-Brazil Border
Heralded as the most beautiful waterfalls in the world, the Iguazu Waterfalls are a true wonder of nature. They are located at the border of Argentina, Brazil, and Paraguay. While the Argentinean side allows visitors to walk right around the water or explore the National Park, the Brazilian side is known for its panoramic views and splendor.
First Lady Eleanor Roosevelt is believed to have exclaimed upon seeing these falls, "poor Niagara." The area surrounding the falls provides ample opportunities for rock climbing as well as water sports. Iguazu has the distinction of having a greater annual flow than any other waterfall in the world.
With all of these, and many more beautiful places that exist in our world, we surrounded by choices. The only way to decide on the places to visit is to follow your heart. While some may love the tranquility of water, others may bury themselves deep in architectural miracles, ancient sites, or the serenity of a small town.
Ετικέτες Ten Of The Most Beautiful Places Of The World
Traveling together
What you lOOking for?
Beautiful Greece - Twenty (20) pictures
Γνωρίστε την Ελάτεια: Μία γραφική κωμόπολη στην καρδιά της Φθιώτιδας!
To καλύτερο ξενοδοχείο της Ευρώπης βρίσκεται στη Σαντορίνη (φωτο)
Τροχόσπιτα για όλα τα… βαλάντια!
ΦΩΤΟ-Μια σπάνια φάλαινα
Ελλάδα Χειμερινές διακοπές Χριστούγεννα Amsterdam Australia Brasil Brazil Greece Iceland India Mexico National Archaeological Museum of Athens New York Thailand Travel Tips Vietnam
tweet- fb
fb pop
Εικόνες θέματος από wingmar. Από το Blogger.

redpajama_set_name: RedPajamaCommonCrawl


text:
Back to Marronebio.com
About Marrone
Marrone Bio Innovations Announces The Netherlands as New Rapporteur Member State for Sakalia
|In Press Releases
|By Web Master
Move taken in response to BREXIT
DAVIS, Calif., Feb. 20, 2018 (GLOBE NEWSWIRE) — Marrone Bio Innovations, Inc. (NASDAQ:MBII) (MBI), a leading provider of bio-based pest management and plant health products for agriculture, turf and ornamental and water treatment markets, announces that the Dutch Board for the Authorisation of Plant Protection Products and Biocides(Ctgb) has agreed to serve as the new European Union (EU) Rapporteur Member State for Sakalia™, a novel biofungicide that is derived from Giant Knotweed (Reynoutria sachalinensis), a plant native to Asia, where is it commonly sold and consumed as food. Giant Knotweed is also ubiquitous to Europe and North America, where it was introduced for fodder and ornamental uses and where extracts are sold and consumed as dietary supplements.
In response to recent guidance from the European Commission that applicants for the approval of plant protection products should consider the impact of pending BREXIT negotiations, MBI announced today that the Netherlands has agreed to serve as the Rapporteur Member State (RMS) for the review and approval of Sakalia for European market entry. As RMS, Ctgb will provide guidance and advice to MBI on addressing EU approval for plant protection products.
"The Netherlands has an established and respected expertise specifically in helping companies, like MBI, with biologically-based pest management products to successfully navigate an EU regulatory process that is not tailored to unique characteristics of plant-extract based and microbially-based pesticides. Currently, MBI is working with Ctgb as RMS for Grandevo®, our Chromobacterium subtsugae-based microbial insecticide, miticide and nematicide, and we look forward to further guidance and collaboration with the Netherlands on pursuing the approval of Sakalia in the European Union," stated Keith Pitts, Chief Sustainability Officer of Marrone Bio Innovations.
Previously, the United Kingdom's Chemicals Review Directorate (CRD) had served at the RMS for Sakalia. However, expected deadlines for the United Kingdom's exit from the European Union necessitated ending the current CRD-supported submission and submitting Sakalia to the EU review process with support from a new European Union member state. MBI requested a voluntary withdrawal of the pending UK-sponsored dossier. The voluntary withdrawal was approved via European Commission administrative action in late January. MBI will be working closely with CRD, which has previously recommended Sakalia for approval in the EU, to secure market entry in the United Kingdom.
In European field trials, Sakalia has demonstrated efficacy against several diseases on a wide variety of crops, including:
Cucurbitaceae(cucumber, melon, zucchini): powdery mildew (Erysiphe cichoracearum, Leveillula taurica, Podosphaera xanthii, Sphaerotheca fuliginea), downy mildew (Pseudoperonospora cubensis).
Solanaceae (Tomato, pepper, aubergine): powdery mildew (Oidium neolycopersici, Leveillula taurica), grey mould (Botrytis cinerea), late blight (Phytophthora infestans).
Lettuce: downy mildew (Bremia lactucae), grey mould (Botrytis cinerea).
Strawberry: powdery mildew (Podosphaera macularis).
Grape: grey mould (Botrytis cinerea), powdery mildew (Erysiphe necator).
Stone fruit(apricot, peach):Monilinia spp. (Monilinia laxa, Monilinia fructigena), powdery mildew (Podosphaera leucotricha, Sphaerotheca pannosa).
Pome fruit(apple, pear): powdery mildew (Podosphaera leucotricha).
Sakalia has a novel, multifaceted "Induced Systemic Resistance Response" mode of action (a unique P5 FRAC code) that makes this biofungicide an excellent resistance management and integrated disease management tool for growers. The formulation is also USDA National Organic Program, OMRI (US and Canada) and Control Union certified for use in organic farming, making Sakalia an excellent tool for both conventional and organic farmers. EcoCert certification is anticipated upon product approval in the European Union.
Syngenta is the exclusive distributor of Sakalia in Europe and holds ownership of the Sakalia product name. In other markets, the formulation is marketed as Regalia® Maxx. The formulation is registered in more than 25 countries, including major agricultural markets in the United States, Canada, Mexico, Brazil, Chile, South Africa, Turkey, Morocco and Tunisia. In countries where approved, Regalia Maxx has received "minimal risk" to humans and the environment designations, including MRL (pesticide residue) exempt status, zero day pre-harvest intervals and minimally-restricted worker re-entry intervals. New application efforts are also underway in Australia, New Zealand, the Philippines, China, Vietnam and Kenya. On average, approvals for Regalia Maxx have taken 18 months in countries where it is now marketed and sold.
About Marrone Bio Innovations
BIO WITH BITE.
Marrone Bio Innovations, Inc. (NASDAQ:MBII) strives to lead the movement to a more sustainable world through the discovery, development and promotion of biological products for pest management and plant health. MBI's effective and environmentally responsible pest management solutions help customers operate more sustainably while uniquely improving plant health and increasing crop yields. MBI's currently available commercial products are Regalia®, Grandevo®, Venerate®, Majestene®, Haven® StargusTM, AmplitudeTM, ZeltoTM and Zequanox®. MBI also distributes Bio-tam 2.0® for Isagro USA and Jet-Ag® for Jet Harvest in most regions of the U.S.
Marrone Bio Innovations is dedicated to pioneering smart biopesticide solutions that support a better tomorrow for both farmers, turf managers and consumers around the globe. For more information, please visit www.marronebio.com.
Marrone Bio Innovations Forward Looking Statements
This press release contains forward-looking statements that involve substantial risks and uncertainties. All statements, other than statements of historical facts, included in this press release regarding strategy, future operations and plans, including assumptions underlying such statements, are forward-looking statements, and should not be relied upon as representing MBI's views as of any subsequent date. Examples of such statements include statements regarding the potential of Sakalia and Regalia in international markets, market projections, including the potential benefits of Sakalia and Regalia, and MBI's plans for expanding additional label uses and international expansion. Such forward-looking statements are based on information available to the Company as of the date of this release and involve a number of risks and uncertainties, some beyond the Company's control, that could cause actual results to differ materially from those anticipated by these forward-looking statements, including consumer, regulatory and other factors affecting demand for the MBI's products, any difficulty in marketing MBI's products in its target markets inside and outside the United States, competition in the market for pest management products, lack of understanding of bio-based pest management products by customers and growers. Additional information that could lead to material changes in MBI's performance is contained in its filings with the SEC. MBI is under no obligation to, and expressly disclaims any responsibility to, update or alter forward-looking statements contained in this release, whether as a result of current information, future events or otherwise.
Marrone Bio Innovations Contacts:
Pam Marrone, CEO and Founder
Keith Pitts, CSO and SVP-Regulatory and Government Affairs
Email: Info@marronebio.com
MBI Investor Relations:
Greg Falesnik
MZ Group – MZ North America
MBII@mzgroup.us
www.mzgroup.us
Categories Select Category Articles Blog Events & Presentations Interviews & Presentations Podcasts Press Releases Videos
Marrone Bio Innovations Hires New Territory Sales Managers in California and Florida
Weed Management in 2050: Perspectives on the Future of Weed Science
Receive company press releases and relevant media items via email when they occur.
Marrone Bio Innovations, Inc. (NASDAQ: MBII) (MBI) leads the movement to a more sustainable world through the discovery, development and promotion of biological products for pest management and plant health. Our effective and environmentally responsible solutions help customers operate more sustainably while controlling pests, improving plant health, and increasing crop yields.
Terms & Conditions | Patents & Trademarks
© Marrone Bio Innovations. All rights reserved.


text:
Galway Diary
Fr Peter Daly - 'The warmest expression of our unbounded gratitude.'
Week III
Ronnie O'Gorman Galway Advertiser, Thu, Sep 01, 2016
To show the esteem with which Fr Peter Daly was held by the Galway Town Commissioners, 'a full length portrait was ordered from Mr Haverty, the expense of the same not to exceed £25.' No doubt the angelic and thoughtful look of the subject appealed to Daly.
Described as a 'turbulent priest', and 'the dominant public figure in Galway during the 1850s', who was 'a stubborn, abrasive, guileful and egotistical populist,'* Fr Peter Daly was the principle mover and shaker behind Galway's drive to become the main transatlantic port for traffic to America in the 1850s. As chairman of both the Town Commissioners and the Harbour Board, he supported J O Lever's Galway Line, which was to run three state-of-the-art steam-sailing ships between Galway and New York, from a grandiose harbour to be built off Furbo. Passengers from Britain, and all over Ireland, would be delivered to the terminal by train. It was to be the most comfortable, and shortest, route to America.
Unfortunately, on its maiden voyage, the Indian Empire, the line's first ship, while entering Galway Bay, was briefly stranded on the Margaretta Rock while under the directions of two local pilots, Patrick Wallace and Henry Burbridge. It was generally believed that the pilots were bribed by Liverpool interests, to stop Galway stealing their monopoly of the Atlantic trade. While languishing in prison one of the pilots, Partrick Wallace, was poisoned and died.
The ship was quickly refloated, and resumed its transatlantic passage. But damage to the project had been done. In August 1858 Daly decided to lead a party of Galway's great and good to visit the British prime minister, the Earl of Derby, in person, and ask for funds to build the new harbour.
Who was this Fr Peter Daly? Was he a man of contradictions, who was fighting to improve the lot of the citizens of Galway, and had to sometimes use intemperate language and methods to achieve these ends; or was he simply a greedy, exploitative, man, who gained financially from his businesses and land holdings as the town grew more prosperous?
He quickly made his mark when as a young parish priest of St Nicholas North (Market Street ), he single-handedly exacerbated the division between Catholics and Protestants over the question of the religious affiliation of a man near death. Apparently there was some doubt whether the poor man was Catholic or Protestant. There was such a struggle for his soul between Daly and the Protestant minister, that the mayor and sheriffs had to be summoned to quell the row.
Evidently pleased with the publicity by proclaiming himself a Catholic champion, he threw himself into open fights against proselytising. He led a large number of like-minded Catholics to vigorously oppose a meeting in Loughrea of the London Hibernian Society for Establishing Schools and Circulating Holy Sriptures. He scattered them.
The event was celebrated by Anthony O' Raftery in his poem (in Irish ), The Gathering of Catholics in Loughrea:
'And Loughrea shall defeat them, and beat their rascality,
We have lost our good Clayton but Daly's as bad for them
Their bible's mendacious, we'll shame them and sadden them...'
Ruthless landlord
His initial popularity led to his appointment to the Town Commissioners and the Harbour Board where he basked in the glory of substantial achievements. He was behind many positive developments for Galway. He was responsible for bringing the Sisters of Charity and later the Mercy Sisters to the town. He was heavily involved in bringing the railway to Galway, the building of O'Brien's bridge, and for building churches in Moycullen, Barna, and Bushy Park (where he is buried ), organising soup kitchens for Famine relief, and the opening of the Magdalen Asylum.
But he was a ruthless landlord. He bought Blackrock House and lands in Salthill, and other property at Sea Road and at Gortatleva, where he built a second house, which he called Villa Albano. He farmed extensively. He evicted tenants without mercy or compensation. The local press particularly condemned his eviction of a poor widow with five children, 'the youngest she carried at her breast'. He scorned criticism, and had to power to ban newspapers covering public meetings. He acquired massive wealth.
Inevitably, although his supporters never wavered in their devotion to him, antagonism grew between him and his clerical colleagues, and some fellow members of the public boards. Suspended from ecclesiastical office by Bishop MacEvilly for repeated displays of temper, insulting and bad language, he appealed to Rome (where his earlier anti proselytising and church building had been noted with some satisfaction ), at the 'injustice' of his suspension. More significantly, he appealed to Archbishop of Tuam, the mighty Catholic champion of his day, John McHale, who re-instated Daly over MacEvilly's head.
Daly's offer
In London Daly was not bashful in displaying his wealth. Lord Derby did not display much enthusiasm for the delegation nor the Galway translantic project. James Mitchell tells us that:'the prime minister, expressed the fear that Galway, as a port, would have many passengers but relatively little cargo.
When Lord Derby referred to the loan of £150,000, sought by the delegation for the constructing of the new harbour, he asked what security would Galway offer against it?
Peter Daly stepped forward and said: "If the government will accept my own personal security there will not be the least difficulty in giving it."
When Daly's offer was heard in Galway the Galway Express criticised the priest's offer. But so pleased and excited were Daly's supporters on the Town Commissioners and Harbour Board that they banned the Galway Express from attending and reporting their meetings in the future.
In the meantime they passed a resolution stating, with unusual wit and playfulness on the ship owner's name, 'the warmest expression of our unbounded gratitude...not only for his (Daly's ) unceasing exertions for the advancement of the interests of Galway, but for the mighty 'Lever' which he has put on to raise her to future greatness...'
You can hear them all laughing...
More next week.
NOTES: Desmond McCabe, Dictionary of Irish Biography; and John Cunningham, Galway 1790-1914: A Town Tormented by the Sea.
I was originally taking the story of the Indian Empire stuck on the Margareta Rock, and J O Lever's attempts to establish a Galway route to New York, from Ray Burke's excellent Joyce County - Galway and James Joyce, (published recently by Currach Press ). The author traces influences that Joyce absorbed during his two visits to Galway in 1909 and 1912, which Joyce reproduced, with all his inimitable subtlety, in his writings. But I got side-tracked when the extraordinary Peter Daly walked on to the stage.
I am leaning on Rev Dr James Mitchell's, (one of Galway's finest historians ), extended essay on Daly from the Journal of The Galway Archaeological and Historical Society, Volume 39, pages 27 - 114.
Daly America New York Ireland United Kingdom Galway Minister Archbishop head Chairman Mayor Peter Daly priest Galway Bay author James Joyce Liverpool Rome Bishop Galway Archaeological and Historical Society John Cunningham John McHale Prime Minister The Galway Express Patrick Wallace Integrated Mining Briens Bridge Joyce County Currach Press Ray Burke Henry Burbridge Harbour Board Villa Albano young parish priest Blackrock House Raftery James Mitchell Galway Express Desmond McCabe London Hibernian Society Town Commissioners and Harbour Board turbulent priest
Did a midsummer murder silence a guilty pilot?
Did Liverpool scuttle Galway's Atlantic dream?
The west of Ireland lacks civilisation - But it has poetry
'The old lady was a holy terror'
GBC - A Galway tradition for eighty years.
'Today the Somme is a peaceful but sullen place.'
'Have you news of my boy Jack?'
'Too late now to retrieve a fallen dream..'
Dying for Home Rule
A day talked about in sadness and horror
'Deep humiliation and bitterness'
Thirty years of mayhem and magic
The extraordinary Fr Peter Daly walks on to the Galway Stage
For a while Galway dreamed of greatness
Justice at last for the Indian Empire incident?
A hero's welcome in New York for first Galway Line ship
A Galway story that intrigued James Joyce
Australia offered some relief for Famine orphan girls
The end of the Galway Line?


JamesEdition makes it easy to find Ranger tugs yachts you're looking for, we feature Ranger tugs for sale by dealerships around the world. Our search technology instantly finds Ranger tugs for sale from our database of thousands of luxury and exotic yachts. Compare prices on Ranger tugs, read specifications and descriptions and see Ranger tugs images from our global listings. JamesEdition is the world's smartest online marketplace for new and used premium yachts.


text:
Bankster - USA
Senator Dodd Doubles Down on a Losing Bet
Watching the devolution of the bank reform bill in the U.S. Senate has been painful. Banking Chairman Chris Dodd's original proposal unveiled last year had numerous strengths, most significantly the removal of bank supervisory authority from the Federal Reserve. Dodd had decided that the Fed had done such a lousy job ignoring the housing bubble and failing to crack down on predatory lending in the mortgage market that it shouldn't be given a second chance.
But a second chance for this unpopular and failed institution is currently in the works. In an effort to please Republicans and achieve a bipartisan bill, Dodd is not only going to let the Fed keep its bank supervision and rule making authority, he wants to give it authority over the proposed Consumer Financial Projection Agency (CFPA).
How would this work exactly? The CFPA issues strong rules cracking down on credit card abuses one week and the Fed issues contrary rules the next? Moreover, if I were the Fed chairman, I would insist on veto power over any agency under my jurisdiction.
This ill-conceived idea may be enough to kill public support for the financial reform proposal in the Senate. The bill has always been more remarkable for what it lacked than what it contained. This point was made clear by an astounding interview with a Wall Street insider in a little-known trade publication called Welling@Weeden.
Long before the 2008 financial crisis, the blueprint for the crisis was laid by the Fed's weak-kneed response to another derivative-fueled disaster involving a massive hedge fund called Long Term Capital Management (LTCM), whose collapse in 1998 threatened the entire financial system. The Fed organized a massive private bailout, but did not take concrete action to address the underlying causes. The failure of the government to crack down on derivative abuses lead directly to the current crisis. Today, the former lawyer for LTCM says that by once again not getting to the heart of the matter, Congress is busily laying the groundwork for the next catastrophe.
"What strikes me now, looking back, is how nothing was changed; no lessons were applied. Even though the lessons were obvious in 1998," says James Rickards, former LTCM lawyer who negotiated the firm's emergency bailout. Risk models needed to be fixed; leverage needed to be slashed; derivatives had to be pulled out of the shadow market and cleared through clearing houses and regulation needed to be ramped up. But the government "did just the opposite" says Rickards, launching into a string of deregulatory moves that made banks bigger and ensured that derivatives would remain unregulated. According to Rickards, "the U.S. stared near-catastrophe in the eye, with LTCM, and decided to double down.""
Today, Rickard says the risks are even greater. Globalization has "scaled up" the financial system and the level of risk, "so now when [the system] fails, it fails catastrophically on a much greater scale than we have ever seen before." If anything, there is greater concentration on Wall Street, and the only difference is that "the Fed has printed so much money, and Treasury has spent so much money, that they have papered over the problem temporarily."
What is needed? While the current Senate bill does kick the can to regulators to set higher capital requirements and lower leverage ratios, it lacks critical elements. In Rickard's opinion, we need to break up the big banks by reinstating Glass-Steagall protections and the Volcker rule, let them be investment or commercial, but not both; fix the conflict of interest in the ratings agencies and create competition for them; liquidate Fannie Mae and Freddie Mac and get back to a private housing market; and most importantly, make sure that every derivative is regulated and traded in a clearing house.
The Dodd bill does none of these things. Not one. Once again, the Senate is doubling down on a bad bet and the blueprint for the next crisis is being laid as Dodd busily negotiates away the bill's best provisions to achieve bipartisan support.
© 2010 Bankster
Mary Bottari is the Director of the Center for Media and Democracy's Real Economy Project and editor of their www.BanksterUSA.org site.


UnitedHealthcare is giving away more than 150 health and wellness prizes to members who register and enter the 2013 myuhc.com registration sweepstakes!
UnitedHealthcare is giving away more than 150 health and wellness prizes to members who register and enter the 2013 myuhc.com registration sweepstakes between April 25 and Aug. 31. These prizes include daily, weekly and monthly giveaways of Sports Authority® gift cards of $100, $200 or $500, as well as the grand prize, a four-day, three-night package for two to Miraval® Resort & Spa in Tucson, Ariz.
Member Flier: You can promote the sweepstakes with your employees by distributing the flier, which includes a list of prizes, instructions on how to enter and some key benefits of myuhc.com.
Member Flier – Spanish: Spanish version of the member flier listed above.
Member Poster: Similar to the member flier, you can display the poster in break rooms, conference rooms, etc. Printed copies can be requested via your UnitedHealthcare strategic account executive.
Intranet, Newsletter and Email Copy: You can copy and paste this text into their internal communications to promote the sweepstakes.
Banner Ads: You can use banner ads of various sizes on their intranet to generate awareness of the sweepstakes and drive registration.
Sweepstakes promotional period 4/25/2013 - 8/31/2013. Members who are already registered can enter the sweepstakes at http://promos.welcometouhc.com/myuhc. Complete sweepstakes rules and prize details can be found when registering at myuhc.com or by visiting http://promos.welcometouhc.com/myuhc.
Sports Authority is a registered trademark owned by The Sports Authority, Inc. Miraval is a registered trademark owned by Miraval Resort Tucson, LLC.


Re: Screen flickering when using camera?
Screen flickering when using camera?
It looks like some kind of noise that flickers when you're using the camera phone. Is this happening to you guys too? If not, maybe its my phone is defective?
Hmm, that's kind of odd and shouldn't be happening. What model Galaxy Note do you have? Did this just start all of the sudden or after a recent update? Lastly, is this only happening through the stock camera application? Or all applications that utilize the camera?
By the way, welcome to our Support Community!
Hi, I just got this phone. Sorry, not screen flickering... its more like noise flickering, in darker areas.
Ah, I have a better idea of what you're talking about now, thisisandrew. Do you have the Note 8? If you're connected to headphones or a bluetooth speaker, do you hear the flickering sound?
Hey just checking in to see if this has been resolved. If not, please give us a reply back and let us know. If you can give us more info in regards to Amanda's post, that would be great. Thanks for posting.
Thank you for checking up on this, but I think this issue happens across all phone devices. Its more of a noise static when there's dark areas. You can test this when you cover your camera to give it a darker shadow on the screen, I don't know why this happens to all phones. I even checked on the iPhone and it does it too. It might be because everything's digitalized, and can't get a crisp image in its dark.
I would like to hear your thoughts about this, if you're able to test this out. I just think its more noticeable on the Samsung Note 8 because of the large screen.
Hey there! How are things? You still getting the noise flickering?
I see what you are saying. Yes, I see the same thing on my camera when taking a picture in the dark. The good news is that static noise does not transfer over with the photo. I think that this is just the way the phone renders the image on the screen when looking through the camera lens in the dark. I am using an iPhone 7 Plus by the way.
I just wanted to swing by to see if you had any other questions for us. I also have an iPhone 7 Plus and can confirm what Chris said above.