2015-03-03 16:59:20 +00:00
|
|
|
/*
|
|
|
|
* Copyright 2015 Google Inc.
|
|
|
|
*
|
|
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
|
|
* found in the LICENSE file.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef SkCodec_DEFINED
|
|
|
|
#define SkCodec_DEFINED
|
|
|
|
|
SkCodec no longer inherits from SkImageGenerator.
SkImageGenerator makes some assumptions that are not necessarily valid
for SkCodec. For example, SkCodec does not assume that it can always be
rewound.
We also have an ongoing question of what an SkCodec should report as
its default settings (i.e. the return from getInfo). It makes sense for
an SkCodec to report that its pixels are unpremultiplied, if that is
the case for the underlying data, but if a client of SkImageGenerator
uses the default settings (as many do), they will receive
unpremultiplied pixels which cannot (currently) be drawn with Skia. We
may ultimately decide to revisit SkCodec reporting an SkImageInfo, but
I have left it unchanged for now.
Import features of SkImageGenerator used by SkCodec into SkCodec.
I have left SkImageGenerator unchanged for now, but it no longer needs
Result or Options. This will require changes to Chromium.
Manually handle the lifetime of fScanlineDecoder, so SkScanlineDecoder.h
can include SkCodec.h (where Result is), and SkCodec.h does not need
to include it (to delete fScanlineDecoder).
In many places, make the following simple changes:
- Now include SkScanlineDecoder.h, which is no longer included by
SkCodec.h
- Use the enums in SkCodec, rather than SkImageGenerator
- Stop including SkImageGenerator.h where no longer needed
Review URL: https://codereview.chromium.org/1220733013
2015-07-09 15:16:03 +00:00
|
|
|
#include "SkColor.h"
|
2015-03-20 18:55:55 +00:00
|
|
|
#include "SkEncodedFormat.h"
|
2015-03-03 16:59:20 +00:00
|
|
|
#include "SkImageInfo.h"
|
|
|
|
#include "SkSize.h"
|
2015-03-18 17:50:37 +00:00
|
|
|
#include "SkStream.h"
|
2015-03-03 16:59:20 +00:00
|
|
|
#include "SkTemplates.h"
|
|
|
|
#include "SkTypes.h"
|
|
|
|
|
|
|
|
class SkData;
|
SkCodec no longer inherits from SkImageGenerator.
SkImageGenerator makes some assumptions that are not necessarily valid
for SkCodec. For example, SkCodec does not assume that it can always be
rewound.
We also have an ongoing question of what an SkCodec should report as
its default settings (i.e. the return from getInfo). It makes sense for
an SkCodec to report that its pixels are unpremultiplied, if that is
the case for the underlying data, but if a client of SkImageGenerator
uses the default settings (as many do), they will receive
unpremultiplied pixels which cannot (currently) be drawn with Skia. We
may ultimately decide to revisit SkCodec reporting an SkImageInfo, but
I have left it unchanged for now.
Import features of SkImageGenerator used by SkCodec into SkCodec.
I have left SkImageGenerator unchanged for now, but it no longer needs
Result or Options. This will require changes to Chromium.
Manually handle the lifetime of fScanlineDecoder, so SkScanlineDecoder.h
can include SkCodec.h (where Result is), and SkCodec.h does not need
to include it (to delete fScanlineDecoder).
In many places, make the following simple changes:
- Now include SkScanlineDecoder.h, which is no longer included by
SkCodec.h
- Use the enums in SkCodec, rather than SkImageGenerator
- Stop including SkImageGenerator.h where no longer needed
Review URL: https://codereview.chromium.org/1220733013
2015-07-09 15:16:03 +00:00
|
|
|
class SkScanlineDecoder;
|
2015-03-03 16:59:20 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Abstraction layer directly on top of an image codec.
|
|
|
|
*/
|
SkCodec no longer inherits from SkImageGenerator.
SkImageGenerator makes some assumptions that are not necessarily valid
for SkCodec. For example, SkCodec does not assume that it can always be
rewound.
We also have an ongoing question of what an SkCodec should report as
its default settings (i.e. the return from getInfo). It makes sense for
an SkCodec to report that its pixels are unpremultiplied, if that is
the case for the underlying data, but if a client of SkImageGenerator
uses the default settings (as many do), they will receive
unpremultiplied pixels which cannot (currently) be drawn with Skia. We
may ultimately decide to revisit SkCodec reporting an SkImageInfo, but
I have left it unchanged for now.
Import features of SkImageGenerator used by SkCodec into SkCodec.
I have left SkImageGenerator unchanged for now, but it no longer needs
Result or Options. This will require changes to Chromium.
Manually handle the lifetime of fScanlineDecoder, so SkScanlineDecoder.h
can include SkCodec.h (where Result is), and SkCodec.h does not need
to include it (to delete fScanlineDecoder).
In many places, make the following simple changes:
- Now include SkScanlineDecoder.h, which is no longer included by
SkCodec.h
- Use the enums in SkCodec, rather than SkImageGenerator
- Stop including SkImageGenerator.h where no longer needed
Review URL: https://codereview.chromium.org/1220733013
2015-07-09 15:16:03 +00:00
|
|
|
class SkCodec : SkNoncopyable {
|
2015-03-03 16:59:20 +00:00
|
|
|
public:
|
|
|
|
/**
|
|
|
|
* If this stream represents an encoded image that we know how to decode,
|
|
|
|
* return an SkCodec that can decode it. Otherwise return NULL.
|
|
|
|
*
|
|
|
|
* If NULL is returned, the stream is deleted immediately. Otherwise, the
|
|
|
|
* SkCodec takes ownership of it, and will delete it when done with it.
|
|
|
|
*/
|
|
|
|
static SkCodec* NewFromStream(SkStream*);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* If this data represents an encoded image that we know how to decode,
|
|
|
|
* return an SkCodec that can decode it. Otherwise return NULL.
|
|
|
|
*
|
|
|
|
* Will take a ref if it returns a codec, else will not affect the data.
|
|
|
|
*/
|
|
|
|
static SkCodec* NewFromData(SkData*);
|
|
|
|
|
SkCodec no longer inherits from SkImageGenerator.
SkImageGenerator makes some assumptions that are not necessarily valid
for SkCodec. For example, SkCodec does not assume that it can always be
rewound.
We also have an ongoing question of what an SkCodec should report as
its default settings (i.e. the return from getInfo). It makes sense for
an SkCodec to report that its pixels are unpremultiplied, if that is
the case for the underlying data, but if a client of SkImageGenerator
uses the default settings (as many do), they will receive
unpremultiplied pixels which cannot (currently) be drawn with Skia. We
may ultimately decide to revisit SkCodec reporting an SkImageInfo, but
I have left it unchanged for now.
Import features of SkImageGenerator used by SkCodec into SkCodec.
I have left SkImageGenerator unchanged for now, but it no longer needs
Result or Options. This will require changes to Chromium.
Manually handle the lifetime of fScanlineDecoder, so SkScanlineDecoder.h
can include SkCodec.h (where Result is), and SkCodec.h does not need
to include it (to delete fScanlineDecoder).
In many places, make the following simple changes:
- Now include SkScanlineDecoder.h, which is no longer included by
SkCodec.h
- Use the enums in SkCodec, rather than SkImageGenerator
- Stop including SkImageGenerator.h where no longer needed
Review URL: https://codereview.chromium.org/1220733013
2015-07-09 15:16:03 +00:00
|
|
|
virtual ~SkCodec();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return the ImageInfo associated with this codec.
|
|
|
|
*/
|
|
|
|
const SkImageInfo& getInfo() const { return fInfo; }
|
|
|
|
|
2015-03-03 16:59:20 +00:00
|
|
|
/**
|
|
|
|
* Return a size that approximately supports the desired scale factor.
|
|
|
|
* The codec may not be able to scale efficiently to the exact scale
|
|
|
|
* factor requested, so return a size that approximates that scale.
|
|
|
|
*/
|
2015-03-18 17:50:37 +00:00
|
|
|
SkISize getScaledDimensions(float desiredScale) const {
|
|
|
|
return this->onGetScaledDimensions(desiredScale);
|
|
|
|
}
|
2015-03-03 16:59:20 +00:00
|
|
|
|
2015-03-20 18:55:55 +00:00
|
|
|
/**
|
|
|
|
* Format of the encoded data.
|
|
|
|
*/
|
|
|
|
SkEncodedFormat getEncodedFormat() const { return this->onGetEncodedFormat(); }
|
|
|
|
|
SkCodec no longer inherits from SkImageGenerator.
SkImageGenerator makes some assumptions that are not necessarily valid
for SkCodec. For example, SkCodec does not assume that it can always be
rewound.
We also have an ongoing question of what an SkCodec should report as
its default settings (i.e. the return from getInfo). It makes sense for
an SkCodec to report that its pixels are unpremultiplied, if that is
the case for the underlying data, but if a client of SkImageGenerator
uses the default settings (as many do), they will receive
unpremultiplied pixels which cannot (currently) be drawn with Skia. We
may ultimately decide to revisit SkCodec reporting an SkImageInfo, but
I have left it unchanged for now.
Import features of SkImageGenerator used by SkCodec into SkCodec.
I have left SkImageGenerator unchanged for now, but it no longer needs
Result or Options. This will require changes to Chromium.
Manually handle the lifetime of fScanlineDecoder, so SkScanlineDecoder.h
can include SkCodec.h (where Result is), and SkCodec.h does not need
to include it (to delete fScanlineDecoder).
In many places, make the following simple changes:
- Now include SkScanlineDecoder.h, which is no longer included by
SkCodec.h
- Use the enums in SkCodec, rather than SkImageGenerator
- Stop including SkImageGenerator.h where no longer needed
Review URL: https://codereview.chromium.org/1220733013
2015-07-09 15:16:03 +00:00
|
|
|
/**
|
|
|
|
* Used to describe the result of a call to getPixels().
|
|
|
|
*
|
|
|
|
* Result is the union of possible results from subclasses.
|
|
|
|
*/
|
|
|
|
enum Result {
|
|
|
|
/**
|
|
|
|
* General return value for success.
|
|
|
|
*/
|
|
|
|
kSuccess,
|
|
|
|
/**
|
|
|
|
* The input is incomplete. A partial image was generated.
|
|
|
|
*/
|
|
|
|
kIncompleteInput,
|
|
|
|
/**
|
|
|
|
* The generator cannot convert to match the request, ignoring
|
|
|
|
* dimensions.
|
|
|
|
*/
|
|
|
|
kInvalidConversion,
|
|
|
|
/**
|
|
|
|
* The generator cannot scale to requested size.
|
|
|
|
*/
|
|
|
|
kInvalidScale,
|
|
|
|
/**
|
|
|
|
* Parameters (besides info) are invalid. e.g. NULL pixels, rowBytes
|
|
|
|
* too small, etc.
|
|
|
|
*/
|
|
|
|
kInvalidParameters,
|
|
|
|
/**
|
|
|
|
* The input did not contain a valid image.
|
|
|
|
*/
|
|
|
|
kInvalidInput,
|
|
|
|
/**
|
|
|
|
* Fulfilling this request requires rewinding the input, which is not
|
|
|
|
* supported for this input.
|
|
|
|
*/
|
|
|
|
kCouldNotRewind,
|
|
|
|
/**
|
|
|
|
* This method is not implemented by this generator.
|
|
|
|
*/
|
|
|
|
kUnimplemented,
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Whether or not the memory passed to getPixels is zero initialized.
|
|
|
|
*/
|
|
|
|
enum ZeroInitialized {
|
|
|
|
/**
|
|
|
|
* The memory passed to getPixels is zero initialized. The SkCodec
|
|
|
|
* may take advantage of this by skipping writing zeroes.
|
|
|
|
*/
|
|
|
|
kYes_ZeroInitialized,
|
|
|
|
/**
|
|
|
|
* The memory passed to getPixels has not been initialized to zero,
|
|
|
|
* so the SkCodec must write all zeroes to memory.
|
|
|
|
*
|
|
|
|
* This is the default. It will be used if no Options struct is used.
|
|
|
|
*/
|
|
|
|
kNo_ZeroInitialized,
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Additional options to pass to getPixels.
|
|
|
|
*/
|
|
|
|
struct Options {
|
|
|
|
Options()
|
|
|
|
: fZeroInitialized(kNo_ZeroInitialized) {}
|
|
|
|
|
|
|
|
ZeroInitialized fZeroInitialized;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Decode into the given pixels, a block of memory of size at
|
|
|
|
* least (info.fHeight - 1) * rowBytes + (info.fWidth *
|
|
|
|
* bytesPerPixel)
|
|
|
|
*
|
|
|
|
* Repeated calls to this function should give the same results,
|
|
|
|
* allowing the PixelRef to be immutable.
|
|
|
|
*
|
|
|
|
* @param info A description of the format (config, size)
|
|
|
|
* expected by the caller. This can simply be identical
|
|
|
|
* to the info returned by getInfo().
|
|
|
|
*
|
|
|
|
* This contract also allows the caller to specify
|
|
|
|
* different output-configs, which the implementation can
|
|
|
|
* decide to support or not.
|
|
|
|
*
|
|
|
|
* A size that does not match getInfo() implies a request
|
|
|
|
* to scale. If the generator cannot perform this scale,
|
|
|
|
* it will return kInvalidScale.
|
|
|
|
*
|
|
|
|
* If info is kIndex8_SkColorType, then the caller must provide storage for up to 256
|
|
|
|
* SkPMColor values in ctable. On success the generator must copy N colors into that storage,
|
|
|
|
* (where N is the logical number of table entries) and set ctableCount to N.
|
|
|
|
*
|
|
|
|
* If info is not kIndex8_SkColorType, then the last two parameters may be NULL. If ctableCount
|
|
|
|
* is not null, it will be set to 0.
|
|
|
|
*
|
|
|
|
* @return Result kSuccess, or another value explaining the type of failure.
|
|
|
|
*/
|
|
|
|
Result getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, const Options*,
|
|
|
|
SkPMColor ctable[], int* ctableCount);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Simplified version of getPixels() that asserts that info is NOT kIndex8_SkColorType and
|
|
|
|
* uses the default Options.
|
|
|
|
*/
|
|
|
|
Result getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes);
|
|
|
|
|
2015-03-25 18:11:52 +00:00
|
|
|
/**
|
Allow creating multiple scanline decoders.
Make getScanlineDecoder return a new object each time, which is
owned by the caller, and independent from any existing scanline
decoders and the SkCodec itself.
Since the SkCodec already contains the entire state machine, and it
is used by the scanline decoders, simply create a new SkCodec which
is now owned by the scanline decoder.
Move code that cleans up after using a scanline decoder into its
destructor
One side effect is that creating the first scanline decoder requires
a duplication of the stream and re-reading the header. (With some
more complexity/changes, we could pass the state machine to the
scanline decoder and make the SkCodec recreate its own state machine
instead.) The typical client of the scanline decoder (region decoder)
uses an SkMemoryStream, so the duplication is cheap, although we
should consider the extra time to reread the header/recreate the state
machine. (If/when we use the scanline decoder for other purposes,
where the stream may not be cheaply duplicated, we should consider
passing the state machine.)
One (intended) result of this change is that a client can create a
new scanline decoder in a new thread, and decode different pieces of
the image simultaneously.
In SkPngCodec::decodePalette, use fBitDepth rather than a parameter.
Review URL: https://codereview.chromium.org/1230033004
2015-07-10 19:07:02 +00:00
|
|
|
* Create a new object which can be used to decode individual scanlines.
|
2015-03-25 18:11:52 +00:00
|
|
|
*
|
Allow creating multiple scanline decoders.
Make getScanlineDecoder return a new object each time, which is
owned by the caller, and independent from any existing scanline
decoders and the SkCodec itself.
Since the SkCodec already contains the entire state machine, and it
is used by the scanline decoders, simply create a new SkCodec which
is now owned by the scanline decoder.
Move code that cleans up after using a scanline decoder into its
destructor
One side effect is that creating the first scanline decoder requires
a duplication of the stream and re-reading the header. (With some
more complexity/changes, we could pass the state machine to the
scanline decoder and make the SkCodec recreate its own state machine
instead.) The typical client of the scanline decoder (region decoder)
uses an SkMemoryStream, so the duplication is cheap, although we
should consider the extra time to reread the header/recreate the state
machine. (If/when we use the scanline decoder for other purposes,
where the stream may not be cheaply duplicated, we should consider
passing the state machine.)
One (intended) result of this change is that a client can create a
new scanline decoder in a new thread, and decode different pieces of
the image simultaneously.
In SkPngCodec::decodePalette, use fBitDepth rather than a parameter.
Review URL: https://codereview.chromium.org/1230033004
2015-07-10 19:07:02 +00:00
|
|
|
* The returned object has its own state, independent of the SkCodec, or any
|
|
|
|
* previously spawned SkScanlineDecoders. At creation, it will be ready to
|
|
|
|
* return the first scanline.
|
2015-03-25 18:11:52 +00:00
|
|
|
*
|
|
|
|
* @param dstInfo Info of the destination. If the dimensions do not match
|
|
|
|
* those of getInfo, this implies a scale.
|
2015-04-29 14:38:43 +00:00
|
|
|
* @param options Contains decoding options, including if memory is zero
|
|
|
|
* initialized.
|
|
|
|
* @param ctable A pointer to a color table. When dstInfo.colorType() is
|
|
|
|
* kIndex8, this should be non-NULL and have enough storage for 256
|
|
|
|
* colors. The color table will be populated after decoding the palette.
|
|
|
|
* @param ctableCount A pointer to the size of the color table. When
|
|
|
|
* dstInfo.colorType() is kIndex8, this should be non-NULL. It will
|
|
|
|
* be modified to the true size of the color table (<= 256) after
|
|
|
|
* decoding the palette.
|
2015-03-25 18:11:52 +00:00
|
|
|
* @return New SkScanlineDecoder, or NULL on failure.
|
|
|
|
*
|
Allow creating multiple scanline decoders.
Make getScanlineDecoder return a new object each time, which is
owned by the caller, and independent from any existing scanline
decoders and the SkCodec itself.
Since the SkCodec already contains the entire state machine, and it
is used by the scanline decoders, simply create a new SkCodec which
is now owned by the scanline decoder.
Move code that cleans up after using a scanline decoder into its
destructor
One side effect is that creating the first scanline decoder requires
a duplication of the stream and re-reading the header. (With some
more complexity/changes, we could pass the state machine to the
scanline decoder and make the SkCodec recreate its own state machine
instead.) The typical client of the scanline decoder (region decoder)
uses an SkMemoryStream, so the duplication is cheap, although we
should consider the extra time to reread the header/recreate the state
machine. (If/when we use the scanline decoder for other purposes,
where the stream may not be cheaply duplicated, we should consider
passing the state machine.)
One (intended) result of this change is that a client can create a
new scanline decoder in a new thread, and decode different pieces of
the image simultaneously.
In SkPngCodec::decodePalette, use fBitDepth rather than a parameter.
Review URL: https://codereview.chromium.org/1230033004
2015-07-10 19:07:02 +00:00
|
|
|
* NOTE: This requires duplicating the SkStream.
|
2015-03-25 18:11:52 +00:00
|
|
|
*/
|
2015-04-29 14:38:43 +00:00
|
|
|
SkScanlineDecoder* getScanlineDecoder(const SkImageInfo& dstInfo, const Options* options,
|
|
|
|
SkPMColor ctable[], int* ctableCount);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Simplified version of getScanlineDecoder() that asserts that info is NOT
|
|
|
|
* kIndex8_SkColorType and uses the default Options.
|
|
|
|
*/
|
2015-03-25 18:11:52 +00:00
|
|
|
SkScanlineDecoder* getScanlineDecoder(const SkImageInfo& dstInfo);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Some images may initially report that they have alpha due to the format
|
|
|
|
* of the encoded data, but then never use any colors which have alpha
|
|
|
|
* less than 100%. This function can be called *after* decoding to
|
|
|
|
* determine if such an image truly had alpha. Calling it before decoding
|
|
|
|
* is undefined.
|
|
|
|
* FIXME: see skbug.com/3582.
|
|
|
|
*/
|
|
|
|
bool reallyHasAlpha() const {
|
|
|
|
return this->onReallyHasAlpha();
|
|
|
|
}
|
|
|
|
|
2015-03-03 16:59:20 +00:00
|
|
|
protected:
|
|
|
|
SkCodec(const SkImageInfo&, SkStream*);
|
|
|
|
|
|
|
|
virtual SkISize onGetScaledDimensions(float /* desiredScale */) const {
|
|
|
|
// By default, scaling is not supported.
|
2015-03-26 13:29:03 +00:00
|
|
|
return this->getInfo().dimensions();
|
2015-03-03 16:59:20 +00:00
|
|
|
}
|
|
|
|
|
2015-03-20 18:55:55 +00:00
|
|
|
virtual SkEncodedFormat onGetEncodedFormat() const = 0;
|
|
|
|
|
SkCodec no longer inherits from SkImageGenerator.
SkImageGenerator makes some assumptions that are not necessarily valid
for SkCodec. For example, SkCodec does not assume that it can always be
rewound.
We also have an ongoing question of what an SkCodec should report as
its default settings (i.e. the return from getInfo). It makes sense for
an SkCodec to report that its pixels are unpremultiplied, if that is
the case for the underlying data, but if a client of SkImageGenerator
uses the default settings (as many do), they will receive
unpremultiplied pixels which cannot (currently) be drawn with Skia. We
may ultimately decide to revisit SkCodec reporting an SkImageInfo, but
I have left it unchanged for now.
Import features of SkImageGenerator used by SkCodec into SkCodec.
I have left SkImageGenerator unchanged for now, but it no longer needs
Result or Options. This will require changes to Chromium.
Manually handle the lifetime of fScanlineDecoder, so SkScanlineDecoder.h
can include SkCodec.h (where Result is), and SkCodec.h does not need
to include it (to delete fScanlineDecoder).
In many places, make the following simple changes:
- Now include SkScanlineDecoder.h, which is no longer included by
SkCodec.h
- Use the enums in SkCodec, rather than SkImageGenerator
- Stop including SkImageGenerator.h where no longer needed
Review URL: https://codereview.chromium.org/1220733013
2015-07-09 15:16:03 +00:00
|
|
|
virtual Result onGetPixels(const SkImageInfo& info,
|
|
|
|
void* pixels, size_t rowBytes, const Options&,
|
|
|
|
SkPMColor ctable[], int* ctableCount) = 0;
|
|
|
|
|
2015-03-25 18:11:52 +00:00
|
|
|
/**
|
|
|
|
* Override if your codec supports scanline decoding.
|
|
|
|
*
|
|
|
|
* @param dstInfo Info of the destination. If the dimensions do not match
|
|
|
|
* those of getInfo, this implies a scale.
|
2015-04-29 14:38:43 +00:00
|
|
|
* @param options Contains decoding options, including if memory is zero
|
|
|
|
* initialized.
|
|
|
|
* @param ctable A pointer to a color table. When dstInfo.colorType() is
|
|
|
|
* kIndex8, this should be non-NULL and have enough storage for 256
|
|
|
|
* colors. The color table will be populated after decoding the palette.
|
|
|
|
* @param ctableCount A pointer to the size of the color table. When
|
|
|
|
* dstInfo.colorType() is kIndex8, this should be non-NULL. It will
|
|
|
|
* be modified to the true size of the color table (<= 256) after
|
|
|
|
* decoding the palette.
|
Allow creating multiple scanline decoders.
Make getScanlineDecoder return a new object each time, which is
owned by the caller, and independent from any existing scanline
decoders and the SkCodec itself.
Since the SkCodec already contains the entire state machine, and it
is used by the scanline decoders, simply create a new SkCodec which
is now owned by the scanline decoder.
Move code that cleans up after using a scanline decoder into its
destructor
One side effect is that creating the first scanline decoder requires
a duplication of the stream and re-reading the header. (With some
more complexity/changes, we could pass the state machine to the
scanline decoder and make the SkCodec recreate its own state machine
instead.) The typical client of the scanline decoder (region decoder)
uses an SkMemoryStream, so the duplication is cheap, although we
should consider the extra time to reread the header/recreate the state
machine. (If/when we use the scanline decoder for other purposes,
where the stream may not be cheaply duplicated, we should consider
passing the state machine.)
One (intended) result of this change is that a client can create a
new scanline decoder in a new thread, and decode different pieces of
the image simultaneously.
In SkPngCodec::decodePalette, use fBitDepth rather than a parameter.
Review URL: https://codereview.chromium.org/1230033004
2015-07-10 19:07:02 +00:00
|
|
|
* @return New SkScanlineDecoder on success, NULL otherwise. The caller is
|
|
|
|
* responsible for deleting the returned object.
|
2015-03-25 18:11:52 +00:00
|
|
|
*/
|
2015-04-29 14:38:43 +00:00
|
|
|
virtual SkScanlineDecoder* onGetScanlineDecoder(const SkImageInfo& dstInfo,
|
|
|
|
const Options& options,
|
|
|
|
SkPMColor ctable[],
|
|
|
|
int* ctableCount) {
|
2015-03-25 18:11:52 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual bool onReallyHasAlpha() const { return false; }
|
|
|
|
|
2015-03-27 19:16:53 +00:00
|
|
|
enum RewindState {
|
|
|
|
kRewound_RewindState,
|
|
|
|
kNoRewindNecessary_RewindState,
|
|
|
|
kCouldNotRewind_RewindState
|
|
|
|
};
|
2015-03-03 16:59:20 +00:00
|
|
|
/**
|
|
|
|
* If the stream was previously read, attempt to rewind.
|
|
|
|
* @returns:
|
2015-03-27 19:16:53 +00:00
|
|
|
* kRewound if the stream needed to be rewound, and the
|
|
|
|
* rewind succeeded.
|
|
|
|
* kNoRewindNecessary if the stream did not need to be
|
|
|
|
* rewound.
|
|
|
|
* kCouldNotRewind if the stream needed to be rewound, and
|
|
|
|
* rewind failed.
|
|
|
|
*
|
2015-03-03 16:59:20 +00:00
|
|
|
* Subclasses MUST call this function before reading the stream (e.g. in
|
|
|
|
* onGetPixels). If it returns false, onGetPixels should return
|
|
|
|
* kCouldNotRewind.
|
|
|
|
*/
|
2015-03-27 19:16:53 +00:00
|
|
|
RewindState SK_WARN_UNUSED_RESULT rewindIfNeeded();
|
2015-03-03 16:59:20 +00:00
|
|
|
|
2015-07-01 13:50:35 +00:00
|
|
|
/**
|
2015-03-16 18:55:18 +00:00
|
|
|
* Get method for the input stream
|
|
|
|
*/
|
|
|
|
SkStream* stream() {
|
|
|
|
return fStream.get();
|
|
|
|
}
|
|
|
|
|
2015-03-03 16:59:20 +00:00
|
|
|
private:
|
SkCodec no longer inherits from SkImageGenerator.
SkImageGenerator makes some assumptions that are not necessarily valid
for SkCodec. For example, SkCodec does not assume that it can always be
rewound.
We also have an ongoing question of what an SkCodec should report as
its default settings (i.e. the return from getInfo). It makes sense for
an SkCodec to report that its pixels are unpremultiplied, if that is
the case for the underlying data, but if a client of SkImageGenerator
uses the default settings (as many do), they will receive
unpremultiplied pixels which cannot (currently) be drawn with Skia. We
may ultimately decide to revisit SkCodec reporting an SkImageInfo, but
I have left it unchanged for now.
Import features of SkImageGenerator used by SkCodec into SkCodec.
I have left SkImageGenerator unchanged for now, but it no longer needs
Result or Options. This will require changes to Chromium.
Manually handle the lifetime of fScanlineDecoder, so SkScanlineDecoder.h
can include SkCodec.h (where Result is), and SkCodec.h does not need
to include it (to delete fScanlineDecoder).
In many places, make the following simple changes:
- Now include SkScanlineDecoder.h, which is no longer included by
SkCodec.h
- Use the enums in SkCodec, rather than SkImageGenerator
- Stop including SkImageGenerator.h where no longer needed
Review URL: https://codereview.chromium.org/1220733013
2015-07-09 15:16:03 +00:00
|
|
|
const SkImageInfo fInfo;
|
|
|
|
SkAutoTDelete<SkStream> fStream;
|
|
|
|
bool fNeedsRewind;
|
2015-03-03 16:59:20 +00:00
|
|
|
};
|
|
|
|
#endif // SkCodec_DEFINED
|