mirror of
https://gitee.com/houstudio/Cdroid.git
synced 2024-12-05 05:37:53 +08:00
modify animatedimagedrawable,animation bydefault is stopped at creation
This commit is contained in:
parent
6e47e8a2a6
commit
49d48de586
@ -28,6 +28,7 @@ AnimatedImageDrawable::AnimatedImageDrawable(cdroid::Context*ctx,const std::stri
|
||||
LOGD("decoder=%p res=%s",mAnimatedImageState->mDecoder,res.c_str());
|
||||
ImageDecoder*decoder = ImageDecoder::create(ctx,res);
|
||||
mAnimatedImageState->mDecoder = decoder;
|
||||
decoder->load();
|
||||
#if ENABLE(DMABLIT)
|
||||
GFXCreateSurface(0,&mImageHandler,decoder->getWidth(),decoder->getHeight(),0,0);
|
||||
GFXLockSurface(mImageHandler,(void**)&buffer,&pitch);
|
||||
@ -82,8 +83,8 @@ int AnimatedImageDrawable::getAlpha()const{
|
||||
}
|
||||
|
||||
void AnimatedImageDrawable::draw(Canvas& canvas){
|
||||
if (!mStarting) {
|
||||
mStarting = true;
|
||||
if (mStarting) {
|
||||
mStarting = false;
|
||||
postOnAnimationStart();
|
||||
}
|
||||
canvas.save();
|
||||
@ -177,6 +178,7 @@ void AnimatedImageDrawable::postOnAnimationStart(){
|
||||
callback.onAnimationStart(*this);
|
||||
}
|
||||
});
|
||||
//todo post callback
|
||||
}
|
||||
|
||||
void AnimatedImageDrawable::postOnAnimationEnd(){
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <cdlog.h>
|
||||
#include "png.h" /* original (unpatched) libpng is ok */
|
||||
//REF:https://github.com/xxyyboy/img_apng2webp/blob/main/apng2png/apng2webp.c
|
||||
//https://gitee.com/mirrors_line/apng-drawable.git
|
||||
namespace cdroid {
|
||||
|
||||
#define APNG_DISPOSE_OP_NONE 0
|
||||
@ -16,23 +17,112 @@ namespace cdroid {
|
||||
#define APNG_BLEND_OP_SOURCE 0
|
||||
#define APNG_BLEND_OP_OVER 1
|
||||
|
||||
APNGDecoder::APNGDecoder() {
|
||||
struct PRIVATE{
|
||||
png_structp png_ptr;
|
||||
png_infop info_ptr;
|
||||
};
|
||||
APNGDecoder::APNGDecoder(std::unique_ptr<std::istream>stm):ImageDecoder(std::move(stm)) {
|
||||
mPrivate = new PRIVATE();
|
||||
}
|
||||
|
||||
APNGDecoder::~APNGDecoder() {
|
||||
}
|
||||
|
||||
int APNGDecoder::readImage(Cairo::RefPtr<Cairo::ImageSurface>image,int frameIndex) {
|
||||
png_uint_16 delay_num , delay_den;
|
||||
png_byte dispose_op , blend_op;
|
||||
//ImageFrame* frame = new ImageFrame;
|
||||
png_structp png_ptr =mPrivate->png_ptr;
|
||||
png_infop info_ptr=mPrivate->info_ptr;
|
||||
|
||||
png_read_frame_head(png_ptr, info_ptr);
|
||||
uint8_t*frame_pixels;
|
||||
uint32_t frame_width,frame_height,frame_x,frame_y;
|
||||
png_get_next_frame_fcTL(png_ptr, info_ptr, &frame_width, &frame_height, &frame_x, &frame_y,
|
||||
&delay_num, &delay_den, &dispose_op, &blend_op);
|
||||
//frame->disposalMethod = (dispose_op<<8)|blend_op;
|
||||
//frame->duration = delay_num * 1000 / (delay_den ? delay_den : 1000);// Convert to milliseconds
|
||||
frame_pixels = new uint8_t[frame_width * frame_height * 4];
|
||||
|
||||
std::vector<png_bytep> row_pointers(frame_height);
|
||||
/*if(ifrm==0){
|
||||
memset(frame_pixels,0,frame_width * frame_height * 4);
|
||||
}else{
|
||||
switch(snap->disposalMethod>>8){
|
||||
case APNG_DISPOSE_OP_PREVIOUS:memcpy(frame_pixels,snap->pixels,frame->width*frame->height*4);break;
|
||||
case APNG_DISPOSE_OP_BACKGROUND:memset(frame_pixels,0,frame->width * frame->height * 4);break;
|
||||
case APNG_DISPOSE_OP_NONE:break;
|
||||
}
|
||||
}*/
|
||||
for (png_uint_32 y = 0; y < frame_height; ++y) {
|
||||
row_pointers[y] = frame_pixels + y* frame_width * 4;
|
||||
}
|
||||
png_read_image(png_ptr, row_pointers.data());
|
||||
/*if((dispose_op==APNG_DISPOSE_OP_PREVIOUS)&&((snap->disposalMethod>>8)!=APNG_DISPOSE_OP_PREVIOUS)){
|
||||
memcpy(snap->pixels,frame->pixels,frame->width * frame->height * 4);
|
||||
}*/
|
||||
LOGV("FRAME[%d](%d,%d,%d,%d)op=%d/%d",frameIndex,frame_x,frame_y,frame_width,frame_height,dispose_op,blend_op);
|
||||
//snap->disposalMethod=(dispose_op<<8)|blend_op;
|
||||
//mFrames.push_back(frame);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void istream_png_reader(png_structp png_ptr, png_bytep png_data, png_size_t data_size){
|
||||
std::istream* is = (std::istream*)(png_get_io_ptr(png_ptr));
|
||||
is->read(reinterpret_cast<char*>(png_data), data_size);
|
||||
};
|
||||
}
|
||||
|
||||
int APNGDecoder::load(std::istream&istream) {
|
||||
return 0;
|
||||
int APNGDecoder::load() {
|
||||
png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||
if (!png_ptr) {
|
||||
std::cerr << "Error creating read struct" << std::endl;
|
||||
return false;
|
||||
}
|
||||
png_infop info_ptr = png_create_info_struct(png_ptr);
|
||||
if (!info_ptr) {
|
||||
std::cerr << "Error creating info struct" << std::endl;
|
||||
png_destroy_read_struct(&png_ptr, NULL, NULL);
|
||||
return false;
|
||||
}
|
||||
mPrivate->png_ptr = png_ptr;
|
||||
mPrivate->info_ptr= info_ptr;
|
||||
if (setjmp(png_jmpbuf(png_ptr))) {
|
||||
std::cerr << "Error during libpng init_io" << std::endl;
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
|
||||
return false;
|
||||
}
|
||||
|
||||
png_set_read_fn(png_ptr,(void*)istream.get(),istream_png_reader);
|
||||
png_read_info(png_ptr, info_ptr);
|
||||
|
||||
int bit_depth, color_type;
|
||||
png_get_IHDR(png_ptr, info_ptr,(uint32_t*)&mImageWidth, (uint32_t*)&mImageHeight, &bit_depth, &color_type, NULL, NULL, NULL);
|
||||
|
||||
if (color_type == PNG_COLOR_TYPE_PALETTE) {
|
||||
png_set_palette_to_rgb(png_ptr);
|
||||
}
|
||||
|
||||
if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) {
|
||||
png_set_expand_gray_1_2_4_to_8(png_ptr);
|
||||
}
|
||||
|
||||
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
|
||||
png_set_tRNS_to_alpha(png_ptr);
|
||||
}
|
||||
|
||||
if (bit_depth == 16) {
|
||||
png_set_strip_16(png_ptr);
|
||||
}
|
||||
|
||||
if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
|
||||
png_set_gray_to_rgb(png_ptr);
|
||||
}
|
||||
|
||||
png_set_bgr(png_ptr);
|
||||
png_set_filler(png_ptr, 0xFF, PNG_FILLER_AFTER);
|
||||
png_read_update_info(png_ptr, info_ptr);
|
||||
color_type = png_get_color_type(png_ptr, info_ptr);
|
||||
|
||||
mFrameCount = png_get_num_frames(png_ptr, info_ptr);
|
||||
return mFrameCount;
|
||||
}
|
||||
}/*namesapce*/
|
||||
|
@ -7,21 +7,19 @@
|
||||
|
||||
namespace cdroid{
|
||||
|
||||
typedef struct {
|
||||
struct PRIVATE{
|
||||
std::vector<int>delays;
|
||||
GifFileType*gif;
|
||||
}GIFPrivate;
|
||||
|
||||
GIFDecoder::GIFDecoder(){
|
||||
GIFPrivate*priv = new GIFPrivate;
|
||||
priv->gif=nullptr;
|
||||
mPrivate=priv;
|
||||
GIFDecoder::GIFDecoder(std::unique_ptr<std::istream>stm):ImageDecoder(std::move(stm)){
|
||||
mPrivate = new PRIVATE;
|
||||
mPrivate->gif=nullptr;
|
||||
}
|
||||
|
||||
GIFDecoder::~GIFDecoder(){
|
||||
GIFPrivate*priv=(GIFPrivate*)mPrivate;
|
||||
DGifCloseFile((GifFileType*)priv->gif,nullptr);
|
||||
delete priv;
|
||||
DGifCloseFile(mPrivate->gif,nullptr);
|
||||
delete mPrivate;
|
||||
}
|
||||
|
||||
#define ARGB(a, r, g, b) ( ((a) & 0xff) << 24 ) | ( ((r) & 0xff) << 16 ) | ( ((g) & 0xff) << 8 ) | ((b) & 0xff)
|
||||
@ -36,17 +34,17 @@ static int GIFRead(GifFileType *gifFile, GifByteType *buff, int rdlen){
|
||||
return is->gcount();
|
||||
}
|
||||
|
||||
static int gifDrawFrame(GifFileType*gif,int¤t_frame,size_t pxstride,uint8_t *pixels,bool force_DISPOSE_1);
|
||||
static int gifDrawFrame(GifFileType*gif,int current_frame,size_t pxstride,uint8_t *pixels,bool force_DISPOSE_1);
|
||||
|
||||
int GIFDecoder::load(std::istream&is){
|
||||
int GIFDecoder::load(){
|
||||
int err;
|
||||
GifFileType*gifFileType = DGifOpen(&is,GIFRead,&err);
|
||||
GifFileType*gifFileType = DGifOpen(istream.get(),GIFRead,&err);
|
||||
LOGE_IF(gifFileType==nullptr,"git load failed");
|
||||
if(gifFileType==nullptr)return 0;
|
||||
DGifSlurp(gifFileType);
|
||||
|
||||
mFrameCount = gifFileType->ImageCount;
|
||||
((GIFPrivate*)mPrivate)->gif = gifFileType;
|
||||
mPrivate->gif = gifFileType;
|
||||
mImageWidth = gifFileType->SWidth;
|
||||
mImageHeight= gifFileType->SHeight;
|
||||
LOGD("GIF %d frames loaded size(%dx%d)",mFrameCount,mImageWidth,mImageHeight);
|
||||
@ -54,20 +52,18 @@ int GIFDecoder::load(std::istream&is){
|
||||
}
|
||||
|
||||
int GIFDecoder::readImage(Cairo::RefPtr<Cairo::ImageSurface>image,int frameIndex){
|
||||
GIFPrivate*priv=(GIFPrivate*)mPrivate;
|
||||
const int duration=gifDrawFrame(priv->gif,frameIndex,image->get_stride(),image->get_data(),false);
|
||||
if(priv->delays.size()<frameIndex+1){
|
||||
priv->delays.push_back(duration);
|
||||
const int duration = gifDrawFrame(mPrivate->gif,frameIndex,image->get_stride(),image->get_data(),false);
|
||||
if(frameIndex>=mPrivate->delays.size()){
|
||||
mPrivate->delays.push_back(duration);
|
||||
}
|
||||
return duration;
|
||||
}
|
||||
|
||||
int GIFDecoder::getFrameDuration(int frameIndex)const{
|
||||
GIFPrivate*priv=(GIFPrivate*)mPrivate;
|
||||
return priv->delays.at(frameIndex);
|
||||
return mPrivate->delays.at(frameIndex);
|
||||
}
|
||||
|
||||
static int gifDrawFrame(GifFileType*gif,int¤t_frame,size_t pxstride,uint8_t *pixels,bool force_DISPOSE_1) {
|
||||
static int gifDrawFrame(GifFileType*gif,int current_frame,size_t pxstride,uint8_t *pixels,bool force_DISPOSE_1) {
|
||||
GifColorType *bg;
|
||||
GifColorType *color;
|
||||
SavedImage *frame;
|
||||
|
@ -1,6 +1,5 @@
|
||||
#include <memory>
|
||||
#include <cstring>
|
||||
#include <fstream>
|
||||
#include <drawables/drawable.h>
|
||||
#include <drawables/bitmapdrawable.h>
|
||||
#include <drawables/ninepatchdrawable.h>
|
||||
@ -11,12 +10,13 @@
|
||||
|
||||
namespace cdroid{
|
||||
|
||||
ImageDecoder::ImageDecoder(){
|
||||
ImageDecoder::ImageDecoder(std::unique_ptr<std::istream>stm){
|
||||
mImageWidth = -1;
|
||||
mImageHeight= -1;
|
||||
mFrameCount = 0;
|
||||
mScale = 1.f;
|
||||
mPrivate = nullptr;
|
||||
istream = std::move(stm);
|
||||
}
|
||||
|
||||
ImageDecoder::~ImageDecoder(){
|
||||
@ -97,25 +97,25 @@ ImageDecoder*ImageDecoder::create(Context*ctx,const std::string&resourceId){
|
||||
constexpr unsigned lengthOfLongestSignature = 14; /* To wit: "RIFF????WEBPVP"*/
|
||||
char contents[lengthOfLongestSignature];
|
||||
ImageDecoder*decoder = nullptr;
|
||||
auto stream = ctx?ctx->getInputStream(resourceId):std::make_unique<std::ifstream>(resourceId,std::ios::in);
|
||||
stream->read(contents,lengthOfLongestSignature);
|
||||
unsigned length = stream->gcount();
|
||||
std::unique_ptr<std::istream>istm = ctx->getInputStream(resourceId);
|
||||
istm->read(contents,lengthOfLongestSignature);
|
||||
unsigned length = istm->gcount();
|
||||
if (length < lengthOfLongestSignature)
|
||||
return nullptr;
|
||||
stream->seekg(0,std::ios::beg);
|
||||
istm->seekg(0,std::ios::beg);
|
||||
#if ENABLE(GIF)
|
||||
if (matchesGIFSignature(contents))
|
||||
decoder = new GIFDecoder();//::create(alphaOption, gammaAndColorProfileOption);
|
||||
decoder = new GIFDecoder(std::move(istm));
|
||||
#endif
|
||||
if (matchesPNGSignature(contents))
|
||||
decoder = new APNGDecoder();//::create(alphaOption, gammaAndColorProfileOption);
|
||||
decoder = new APNGDecoder(std::move(istm));
|
||||
#if USE(ICO)
|
||||
if (matchesICOSignature(contents) || matchesCURSignature(contents))
|
||||
return ICOImageDecoder::create(alphaOption, gammaAndColorProfileOption);
|
||||
#endif
|
||||
#if ENABLE(JPEG)
|
||||
if (matchesJPEGSignature(contents))
|
||||
decoder = new JPEGDecoder();//::create(alphaOption, gammaAndColorProfileOption);
|
||||
decoder = new JPEGDecoder(std::move(istm));
|
||||
#endif
|
||||
#if USE(OPENJPEG)
|
||||
if (matchesJP2Signature(contents))
|
||||
@ -127,13 +127,12 @@ ImageDecoder*ImageDecoder::create(Context*ctx,const std::string&resourceId){
|
||||
|
||||
#if ENABLE(WEBP)
|
||||
if (matchesWebPSignature(contents))
|
||||
return new WebpDecoder();//WEBPImageDecoder::create(alphaOption, gammaAndColorProfileOption);
|
||||
return new WebpDecoder(std::move(istm));
|
||||
#endif
|
||||
#if USE(BITMAP)
|
||||
if (matchesBMPSignature(contents))
|
||||
return BMPImageDecoder::create(alphaOption, gammaAndColorProfileOption);
|
||||
#endif
|
||||
if(decoder)decoder->load(*stream);
|
||||
return decoder;
|
||||
}
|
||||
|
||||
|
@ -10,15 +10,16 @@ namespace cdroid{
|
||||
|
||||
class ImageDecoder{
|
||||
protected:
|
||||
void*mPrivate;
|
||||
struct PRIVATE*mPrivate;
|
||||
int mFrameCount;
|
||||
int mImageWidth;
|
||||
int mImageHeight;
|
||||
float mScale;
|
||||
std::unique_ptr<std::istream>istream;
|
||||
public:
|
||||
ImageDecoder();
|
||||
ImageDecoder(std::unique_ptr<std::istream>);
|
||||
virtual ~ImageDecoder();
|
||||
virtual int load(std::istream&)=0;
|
||||
virtual int load()=0;
|
||||
int getWidth()const;
|
||||
int getHeight()const;
|
||||
float getScale()const;
|
||||
@ -32,33 +33,33 @@ public:
|
||||
|
||||
class GIFDecoder:public ImageDecoder{
|
||||
public:
|
||||
GIFDecoder();
|
||||
GIFDecoder(std::unique_ptr<std::istream>);
|
||||
~GIFDecoder()override;
|
||||
int load(std::istream&)override;
|
||||
int load()override;
|
||||
virtual int getFrameDuration(int)const;
|
||||
int readImage(Cairo::RefPtr<Cairo::ImageSurface>image,int frameIndex)override;
|
||||
};
|
||||
|
||||
class JPEGDecoder:public ImageDecoder{
|
||||
public:
|
||||
JPEGDecoder();
|
||||
int load(std::istream&)override;
|
||||
JPEGDecoder(std::unique_ptr<std::istream>);
|
||||
int load()override;
|
||||
int readImage(Cairo::RefPtr<Cairo::ImageSurface>image,int frameIndex)override;
|
||||
};
|
||||
|
||||
class APNGDecoder:public ImageDecoder{
|
||||
public:
|
||||
APNGDecoder();
|
||||
APNGDecoder(std::unique_ptr<std::istream>);
|
||||
~APNGDecoder()override;
|
||||
int load(std::istream&)override;
|
||||
int load()override;
|
||||
int readImage(Cairo::RefPtr<Cairo::ImageSurface>image,int frameIndex)override;
|
||||
};
|
||||
|
||||
class WebpDecoder:public ImageDecoder{
|
||||
public:
|
||||
WebpDecoder();
|
||||
WebpDecoder(std::unique_ptr<std::istream>);
|
||||
~WebpDecoder();
|
||||
int load(std::istream&)override;
|
||||
int load()override;
|
||||
int readImage(Cairo::RefPtr<Cairo::ImageSurface>image,int frameIndex)override;
|
||||
};
|
||||
}/*endof namespace*/
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
namespace cdroid{
|
||||
|
||||
JPEGDecoder::JPEGDecoder(){
|
||||
JPEGDecoder::JPEGDecoder(std::unique_ptr<std::istream>stm):ImageDecoder(std::move(stm)){
|
||||
}
|
||||
|
||||
struct decoder_error_mgr {
|
||||
@ -156,7 +156,7 @@ int JPEGDecoder::readImage(Cairo::RefPtr<Cairo::ImageSurface>image,int frameInde
|
||||
return 0;//sfc;
|
||||
}
|
||||
|
||||
int JPEGDecoder::load(std::istream&){
|
||||
int JPEGDecoder::load(){
|
||||
return 0;
|
||||
}
|
||||
}/*endof namespacee*/
|
||||
|
@ -416,15 +416,15 @@ INT GFXBlit(HANDLE dstsurface,int dx,int dy,HANDLE srcsurface,const GFXRect*srcr
|
||||
opt.stClipRect.u32Width= rs.w;
|
||||
opt.stClipRect.u32Height=rs.h;
|
||||
if(nsrc->alpha!=255){
|
||||
opt.u32GlobalSrcConstColor = 0x00FFFFFF|(0xa0<<24);//(nsrc->alpha<<24);
|
||||
opt.u32GlobalSrcConstColor = 0x00FFFFFF|(0xa0<<24);//(nsrc->alpha<<24);
|
||||
|
||||
opt.u32GlobalDstConstColor = 0xFFFFFFFF;
|
||||
|
||||
opt.eSrcDfbBldOp = E_MI_GFX_DFB_BLD_ONE;// 透叠
|
||||
opt.eDstDfbBldOp = E_MI_GFX_DFB_BLD_INVSRCALPHA;
|
||||
|
||||
opt.eDFBBlendFlag = E_MI_GFX_DFB_BLEND_COLORALPHA
|
||||
| E_MI_GFX_DFB_BLEND_ALPHACHANNEL
|
||||
opt.eDFBBlendFlag = E_MI_GFX_DFB_BLEND_COLORALPHA
|
||||
| E_MI_GFX_DFB_BLEND_ALPHACHANNEL
|
||||
| E_MI_GFX_DFB_BLEND_SRC_PREMULTIPLY;
|
||||
}else{
|
||||
opt.u32GlobalSrcConstColor = 0xFFFFFFFF;
|
||||
|
Loading…
Reference in New Issue
Block a user