Home | History | Annotate | Download | only in core
      1 /*
      2  * Copyright 2010 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #include "SkImageInfo.h"
      9 #include "SkReadBuffer.h"
     10 #include "SkWriteBuffer.h"
     11 
     12 static bool profile_type_is_valid(SkColorProfileType profileType) {
     13     return (profileType >= 0) && (profileType <= kLastEnum_SkColorProfileType);
     14 }
     15 
     16 static bool alpha_type_is_valid(SkAlphaType alphaType) {
     17     return (alphaType >= 0) && (alphaType <= kLastEnum_SkAlphaType);
     18 }
     19 
     20 static bool color_type_is_valid(SkColorType colorType) {
     21     return (colorType >= 0) && (colorType <= kLastEnum_SkColorType);
     22 }
     23 
     24 void SkImageInfo::unflatten(SkReadBuffer& buffer) {
     25     fWidth = buffer.read32();
     26     fHeight = buffer.read32();
     27 
     28     uint32_t packed = buffer.read32();
     29     SkASSERT(0 == (packed >> 24));
     30     fProfileType = (SkColorProfileType)((packed >> 16) & 0xFF);
     31     fAlphaType = (SkAlphaType)((packed >> 8) & 0xFF);
     32     fColorType = (SkColorType)((packed >> 0) & 0xFF);
     33     buffer.validate(profile_type_is_valid(fProfileType) &&
     34                     alpha_type_is_valid(fAlphaType) &&
     35                     color_type_is_valid(fColorType));
     36 }
     37 
     38 void SkImageInfo::flatten(SkWriteBuffer& buffer) const {
     39     buffer.write32(fWidth);
     40     buffer.write32(fHeight);
     41 
     42     SkASSERT(0 == (fProfileType & ~0xFF));
     43     SkASSERT(0 == (fAlphaType & ~0xFF));
     44     SkASSERT(0 == (fColorType & ~0xFF));
     45     uint32_t packed = (fProfileType << 16) | (fAlphaType << 8) | fColorType;
     46     buffer.write32(packed);
     47 }
     48 
     49 bool SkColorTypeValidateAlphaType(SkColorType colorType, SkAlphaType alphaType,
     50                                   SkAlphaType* canonical) {
     51     switch (colorType) {
     52         case kUnknown_SkColorType:
     53             alphaType = kUnknown_SkAlphaType;
     54             break;
     55         case kAlpha_8_SkColorType:
     56             if (kUnpremul_SkAlphaType == alphaType) {
     57                 alphaType = kPremul_SkAlphaType;
     58             }
     59             // fall-through
     60         case kIndex_8_SkColorType:
     61         case kARGB_4444_SkColorType:
     62         case kRGBA_8888_SkColorType:
     63         case kBGRA_8888_SkColorType:
     64         case kRGBA_F16_SkColorType:
     65             if (kUnknown_SkAlphaType == alphaType) {
     66                 return false;
     67             }
     68             break;
     69         case kRGB_565_SkColorType:
     70         case kGray_8_SkColorType:
     71             alphaType = kOpaque_SkAlphaType;
     72             break;
     73         default:
     74             return false;
     75     }
     76     if (canonical) {
     77         *canonical = alphaType;
     78     }
     79     return true;
     80 }
     81 
     82 ///////////////////////////////////////////////////////////////////////////////////////////////////
     83 
     84 #include "SkReadPixelsRec.h"
     85 
     86 bool SkReadPixelsRec::trim(int srcWidth, int srcHeight) {
     87     switch (fInfo.colorType()) {
     88         case kUnknown_SkColorType:
     89         case kIndex_8_SkColorType:
     90             return false;
     91         default:
     92             break;
     93     }
     94     if (nullptr == fPixels || fRowBytes < fInfo.minRowBytes()) {
     95         return false;
     96     }
     97     if (0 == fInfo.width() || 0 == fInfo.height()) {
     98         return false;
     99     }
    100 
    101     int x = fX;
    102     int y = fY;
    103     SkIRect srcR = SkIRect::MakeXYWH(x, y, fInfo.width(), fInfo.height());
    104     if (!srcR.intersect(0, 0, srcWidth, srcHeight)) {
    105         return false;
    106     }
    107 
    108     // if x or y are negative, then we have to adjust pixels
    109     if (x > 0) {
    110         x = 0;
    111     }
    112     if (y > 0) {
    113         y = 0;
    114     }
    115     // here x,y are either 0 or negative
    116     fPixels = ((char*)fPixels - y * fRowBytes - x * fInfo.bytesPerPixel());
    117     // the intersect may have shrunk info's logical size
    118     fInfo = fInfo.makeWH(srcR.width(), srcR.height());
    119     fX = srcR.x();
    120     fY = srcR.y();
    121 
    122     return true;
    123 }
    124 
    125