source: psi/trunk/libpsi/psipng/psipng.cpp@ 189

Last change on this file since 189 was 2, checked in by dmik, 19 years ago

Imported original Psi 0.10 sources from Affinix

File size: 3.2 KB
Line 
1/*
2 * psipng.cpp - QImageFormat for loading Psi PNG animations
3 * Copyright (C) 2003 Michail Pishchagin
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 */
20
21#include "psipng.h"
22
23#include <qasyncimageio.h>
24
25//! if _hide_doc_
26class PsiPNGFormat : public QImageFormat {
27private:
28 int w, h;
29 QImage image;
30 int numFrames;
31 int frame, frameW;
32 int frameBytes;
33
34 int maxLen, curLen;
35
36 static const int framePeriod;
37
38public:
39 PsiPNGFormat()
40 {
41 }
42
43 ~PsiPNGFormat()
44 {
45 }
46
47 int decode(QImage &img, QImageConsumer *consumer, const uchar *buffer, int length)
48 {
49 if ( !length )
50 return 0;
51
52 if ( image.isNull() ) { // cache our image for speedup
53 if ( image.loadFromData( buffer, length ) ) {
54 w = image.width();
55 h = image.height();
56
57 numFrames = w / h;
58 frameBytes = length / numFrames;
59 frameW = w / numFrames;
60 frame = 0;
61
62 consumer->setLooping( numFrames > 1 ? 0 : 1 );
63 consumer->setFramePeriod(framePeriod);
64 consumer->setSize(frameW, h);
65
66 maxLen = length;
67 curLen = 0;
68 }
69 else {
70 if ( !image.isNull() )
71 qWarning("PsiPNGFormat::decode: WARNING: QImage is not loaded and is NOT null!!!");
72 return 0;
73 }
74 }
75
76 if ( frame < numFrames ) {
77 img = image.copy(frame++ * frameW, 0, frameW, h);
78 consumer->frameDone(QPoint(0, 0), QRect(0, 0, frameW, h));
79
80 if ( frame >= numFrames ) {
81 consumer->end();
82 frameBytes = maxLen - curLen;
83 }
84 else
85 consumer->setFramePeriod(framePeriod);
86 }
87
88 curLen += frameBytes;
89 return frameBytes;
90 }
91};
92//! \endif
93const int PsiPNGFormat::framePeriod = 120;
94
95class PsiPNGFormatType : public QImageFormatType
96{
97 QImageFormat *decoderFor(const uchar *buffer, int length)
98 {
99 if (length < 8)
100 return 0;
101
102 if (buffer[0]==137
103 && buffer[1]=='P'
104 && buffer[2]=='N'
105 && buffer[3]=='G'
106 && buffer[4]==13
107 && buffer[5]==10
108 && buffer[6]==26
109 && buffer[7]==10)
110 return new PsiPNGFormat;
111
112 return 0;
113 }
114
115 const char *formatName() const
116 {
117 return "PsiPNG";
118 }
119};
120
121PsiPNGFormatType *globalPsiPngFormatTypeObject = 0;
122
123void cleanupPsiPngIO()
124{
125 if ( globalPsiPngFormatTypeObject ) {
126 delete globalPsiPngFormatTypeObject;
127 globalPsiPngFormatTypeObject = 0;
128 }
129}
130
131/*!
132 Call this function to register PsiPNG animation format.
133
134 In this format, all animation frames are stored in one .png file.
135 <tt>Frame width = Frame height</tt>, and
136 <tt>total .png width = tatal .png height * numFrames</tt>.
137*/
138void initPsiPngIO()
139{
140 static bool done = FALSE;
141 if ( !done ) {
142 done = TRUE;
143 globalPsiPngFormatTypeObject = new PsiPNGFormatType;
144 qAddPostRoutine( cleanupPsiPngIO );
145 }
146}
Note: See TracBrowser for help on using the repository browser.