105245900bf6d49068b1668da1b38890a41e09bc5scroggo/* 205245900bf6d49068b1668da1b38890a41e09bc5scroggo * Copyright 2015 Google Inc. 305245900bf6d49068b1668da1b38890a41e09bc5scroggo * 405245900bf6d49068b1668da1b38890a41e09bc5scroggo * Use of this source code is governed by a BSD-style license that can be 505245900bf6d49068b1668da1b38890a41e09bc5scroggo * found in the LICENSE file. 605245900bf6d49068b1668da1b38890a41e09bc5scroggo */ 705245900bf6d49068b1668da1b38890a41e09bc5scroggo 805245900bf6d49068b1668da1b38890a41e09bc5scroggo#ifndef SkScanlineDecoder_DEFINED 905245900bf6d49068b1668da1b38890a41e09bc5scroggo#define SkScanlineDecoder_DEFINED 1005245900bf6d49068b1668da1b38890a41e09bc5scroggo 1105245900bf6d49068b1668da1b38890a41e09bc5scroggo#include "SkTypes.h" 1205245900bf6d49068b1668da1b38890a41e09bc5scroggo#include "SkTemplates.h" 1305245900bf6d49068b1668da1b38890a41e09bc5scroggo#include "SkImageGenerator.h" 1405245900bf6d49068b1668da1b38890a41e09bc5scroggo#include "SkImageInfo.h" 1505245900bf6d49068b1668da1b38890a41e09bc5scroggo 1605245900bf6d49068b1668da1b38890a41e09bc5scroggoclass SkScanlineDecoder : public SkNoncopyable { 1705245900bf6d49068b1668da1b38890a41e09bc5scroggopublic: 1805245900bf6d49068b1668da1b38890a41e09bc5scroggo // Note for implementations: An SkScanlineDecoder will be deleted by (and 1905245900bf6d49068b1668da1b38890a41e09bc5scroggo // therefore *before*) its associated SkCodec, in case the order matters. 2005245900bf6d49068b1668da1b38890a41e09bc5scroggo virtual ~SkScanlineDecoder() {} 2105245900bf6d49068b1668da1b38890a41e09bc5scroggo 2205245900bf6d49068b1668da1b38890a41e09bc5scroggo /** 2305245900bf6d49068b1668da1b38890a41e09bc5scroggo * Write the next countLines scanlines into dst. 2405245900bf6d49068b1668da1b38890a41e09bc5scroggo * 2505245900bf6d49068b1668da1b38890a41e09bc5scroggo * @param dst Must be non-null, and large enough to hold countLines 2605245900bf6d49068b1668da1b38890a41e09bc5scroggo * scanlines of size rowBytes. 2705245900bf6d49068b1668da1b38890a41e09bc5scroggo * @param countLines Number of lines to write. 2805245900bf6d49068b1668da1b38890a41e09bc5scroggo * @param rowBytes Number of bytes per row. Must be large enough to hold 2905245900bf6d49068b1668da1b38890a41e09bc5scroggo * a scanline based on the SkImageInfo used to create this object. 3005245900bf6d49068b1668da1b38890a41e09bc5scroggo */ 3105245900bf6d49068b1668da1b38890a41e09bc5scroggo SkImageGenerator::Result getScanlines(void* dst, int countLines, size_t rowBytes) { 3205245900bf6d49068b1668da1b38890a41e09bc5scroggo if ((rowBytes < fDstInfo.minRowBytes() && countLines > 1 ) || countLines <= 0 3305245900bf6d49068b1668da1b38890a41e09bc5scroggo || fCurrScanline + countLines > fDstInfo.height()) { 3405245900bf6d49068b1668da1b38890a41e09bc5scroggo return SkImageGenerator::kInvalidParameters; 3505245900bf6d49068b1668da1b38890a41e09bc5scroggo } 3605245900bf6d49068b1668da1b38890a41e09bc5scroggo const SkImageGenerator::Result result = this->onGetScanlines(dst, countLines, rowBytes); 3705245900bf6d49068b1668da1b38890a41e09bc5scroggo this->checkForFinish(countLines); 3805245900bf6d49068b1668da1b38890a41e09bc5scroggo return result; 3905245900bf6d49068b1668da1b38890a41e09bc5scroggo } 4005245900bf6d49068b1668da1b38890a41e09bc5scroggo 4105245900bf6d49068b1668da1b38890a41e09bc5scroggo /** 4205245900bf6d49068b1668da1b38890a41e09bc5scroggo * Skip count scanlines. 4305245900bf6d49068b1668da1b38890a41e09bc5scroggo * 4405245900bf6d49068b1668da1b38890a41e09bc5scroggo * The default version just calls onGetScanlines and discards the dst. 4505245900bf6d49068b1668da1b38890a41e09bc5scroggo * NOTE: If skipped lines are the only lines with alpha, this default 4605245900bf6d49068b1668da1b38890a41e09bc5scroggo * will make reallyHasAlpha return true, when it could have returned 4705245900bf6d49068b1668da1b38890a41e09bc5scroggo * false. 4805245900bf6d49068b1668da1b38890a41e09bc5scroggo */ 4905245900bf6d49068b1668da1b38890a41e09bc5scroggo SkImageGenerator::Result skipScanlines(int countLines) { 5005245900bf6d49068b1668da1b38890a41e09bc5scroggo if (fCurrScanline + countLines > fDstInfo.height()) { 5105245900bf6d49068b1668da1b38890a41e09bc5scroggo // Arguably, we could just skip the scanlines which are remaining, 5205245900bf6d49068b1668da1b38890a41e09bc5scroggo // and return kSuccess. We choose to return invalid so the client 5305245900bf6d49068b1668da1b38890a41e09bc5scroggo // can catch their bug. 5405245900bf6d49068b1668da1b38890a41e09bc5scroggo return SkImageGenerator::kInvalidParameters; 5505245900bf6d49068b1668da1b38890a41e09bc5scroggo } 5605245900bf6d49068b1668da1b38890a41e09bc5scroggo const SkImageGenerator::Result result = this->onSkipScanlines(countLines); 5705245900bf6d49068b1668da1b38890a41e09bc5scroggo this->checkForFinish(countLines); 5805245900bf6d49068b1668da1b38890a41e09bc5scroggo return result; 5905245900bf6d49068b1668da1b38890a41e09bc5scroggo } 6005245900bf6d49068b1668da1b38890a41e09bc5scroggo 6105245900bf6d49068b1668da1b38890a41e09bc5scroggo /** 6205245900bf6d49068b1668da1b38890a41e09bc5scroggo * Some images may initially report that they have alpha due to the format 6305245900bf6d49068b1668da1b38890a41e09bc5scroggo * of the encoded data, but then never use any colors which have alpha 6405245900bf6d49068b1668da1b38890a41e09bc5scroggo * less than 100%. This function can be called *after* decoding to 6505245900bf6d49068b1668da1b38890a41e09bc5scroggo * determine if such an image truly had alpha. Calling it before decoding 6605245900bf6d49068b1668da1b38890a41e09bc5scroggo * is undefined. 6705245900bf6d49068b1668da1b38890a41e09bc5scroggo * FIXME: see skbug.com/3582. 6805245900bf6d49068b1668da1b38890a41e09bc5scroggo */ 6905245900bf6d49068b1668da1b38890a41e09bc5scroggo bool reallyHasAlpha() const { 7005245900bf6d49068b1668da1b38890a41e09bc5scroggo return this->onReallyHasAlpha(); 7105245900bf6d49068b1668da1b38890a41e09bc5scroggo } 7205245900bf6d49068b1668da1b38890a41e09bc5scroggo 7305245900bf6d49068b1668da1b38890a41e09bc5scroggoprotected: 7405245900bf6d49068b1668da1b38890a41e09bc5scroggo SkScanlineDecoder(const SkImageInfo& requested) 7505245900bf6d49068b1668da1b38890a41e09bc5scroggo : fDstInfo(requested) 7605245900bf6d49068b1668da1b38890a41e09bc5scroggo , fCurrScanline(0) {} 7705245900bf6d49068b1668da1b38890a41e09bc5scroggo 7805245900bf6d49068b1668da1b38890a41e09bc5scroggo virtual bool onReallyHasAlpha() const { return false; } 7905245900bf6d49068b1668da1b38890a41e09bc5scroggo 8097fdea6c4393cf0102d7eee5790782509fb4f57bmsarett const SkImageInfo& dstInfo() const { return fDstInfo; } 8197fdea6c4393cf0102d7eee5790782509fb4f57bmsarett 8205245900bf6d49068b1668da1b38890a41e09bc5scroggoprivate: 8305245900bf6d49068b1668da1b38890a41e09bc5scroggo const SkImageInfo fDstInfo; 8405245900bf6d49068b1668da1b38890a41e09bc5scroggo int fCurrScanline; 8505245900bf6d49068b1668da1b38890a41e09bc5scroggo 8605245900bf6d49068b1668da1b38890a41e09bc5scroggo // Naive default version just calls onGetScanlines on temp memory. 8705245900bf6d49068b1668da1b38890a41e09bc5scroggo virtual SkImageGenerator::Result onSkipScanlines(int countLines) { 8805245900bf6d49068b1668da1b38890a41e09bc5scroggo SkAutoMalloc storage(fDstInfo.minRowBytes()); 8905245900bf6d49068b1668da1b38890a41e09bc5scroggo // Note that we pass 0 to rowBytes so we continue to use the same memory. 9005245900bf6d49068b1668da1b38890a41e09bc5scroggo // Also note that while getScanlines checks that rowBytes is big enough, 9105245900bf6d49068b1668da1b38890a41e09bc5scroggo // onGetScanlines bypasses that check. 9205245900bf6d49068b1668da1b38890a41e09bc5scroggo // Calling the virtual method also means we do not double count 9305245900bf6d49068b1668da1b38890a41e09bc5scroggo // countLines. 9405245900bf6d49068b1668da1b38890a41e09bc5scroggo return this->onGetScanlines(storage.get(), countLines, 0); 9505245900bf6d49068b1668da1b38890a41e09bc5scroggo } 9605245900bf6d49068b1668da1b38890a41e09bc5scroggo 9705245900bf6d49068b1668da1b38890a41e09bc5scroggo virtual SkImageGenerator::Result onGetScanlines(void* dst, int countLines, 9805245900bf6d49068b1668da1b38890a41e09bc5scroggo size_t rowBytes) = 0; 9905245900bf6d49068b1668da1b38890a41e09bc5scroggo 10005245900bf6d49068b1668da1b38890a41e09bc5scroggo /** 10105245900bf6d49068b1668da1b38890a41e09bc5scroggo * Called after any set of scanlines read/skipped. Updates fCurrScanline, 10205245900bf6d49068b1668da1b38890a41e09bc5scroggo * and, if we are at the end, calls onFinish(). 10305245900bf6d49068b1668da1b38890a41e09bc5scroggo */ 10405245900bf6d49068b1668da1b38890a41e09bc5scroggo void checkForFinish(int countLines) { 10505245900bf6d49068b1668da1b38890a41e09bc5scroggo fCurrScanline += countLines; 10605245900bf6d49068b1668da1b38890a41e09bc5scroggo if (fCurrScanline >= fDstInfo.height()) { 10705245900bf6d49068b1668da1b38890a41e09bc5scroggo this->onFinish(); 10805245900bf6d49068b1668da1b38890a41e09bc5scroggo } 10905245900bf6d49068b1668da1b38890a41e09bc5scroggo } 11005245900bf6d49068b1668da1b38890a41e09bc5scroggo 11105245900bf6d49068b1668da1b38890a41e09bc5scroggo /** 11205245900bf6d49068b1668da1b38890a41e09bc5scroggo * This function will be called after reading/skipping all scanlines to do 11305245900bf6d49068b1668da1b38890a41e09bc5scroggo * any necessary cleanups. 11405245900bf6d49068b1668da1b38890a41e09bc5scroggo */ 11505245900bf6d49068b1668da1b38890a41e09bc5scroggo virtual void onFinish() {} // Default does nothing. 11605245900bf6d49068b1668da1b38890a41e09bc5scroggo}; 11705245900bf6d49068b1668da1b38890a41e09bc5scroggo#endif // SkScanlineDecoder_DEFINED 118