1 /*$
2 Copyright (C) 2013-2020 Azel.
3
4 This file is part of AzPainter.
5
6 AzPainter is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 AzPainter is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18 $*/
19
20 /*****************************************
21 * GIF 保存
22 *****************************************/
23
24 #include <stdio.h>
25
26 #include "mDef.h"
27 #include "mSaveImage.h"
28 #include "mGIFEncode.h"
29
30
31 //--------------------
32
33 typedef struct
34 {
35 mSaveImage *param;
36
37 mGIFEncode *gifenc;
38 uint8_t *rowbuf,
39 *palbuf;
40
41 int transparent;
42 }SAVEGIF;
43
44 //--------------------
45
46
47 /** 初期化 */
48
_init(SAVEGIF * p,mSaveImage * param)49 static int _init(SAVEGIF *p,mSaveImage *param)
50 {
51 mGIFEncodeGlobalInfo global;
52 mGIFEncodeImage img;
53 int ret;
54
55 //パレット
56
57 p->palbuf = mSaveImage_convertPalette_RGB(param);
58 if(!p->palbuf) return MSAVEIMAGE_ERR_ALLOC;
59
60 //GIF エンコーダ作成
61
62 global.width = param->width;
63 global.height = param->height;
64 global.bkgnd_index = 0;
65 global.bits = mGIFEncode_colnumToBits(param->palette_num);
66 global.palette_buf = p->palbuf;
67 global.palette_num = param->palette_num;
68
69 p->gifenc = mGIFEncode_create(&global);
70 if(!p->gifenc) return MSAVEIMAGE_ERR_ALLOC;
71
72 //開く
73
74 switch(param->output.type)
75 {
76 case MSAVEIMAGE_OUTPUT_TYPE_PATH:
77 if(!mGIFEncode_open_filename(p->gifenc, param->output.filename))
78 return MSAVEIMAGE_ERR_OPENFILE;
79 break;
80 case MSAVEIMAGE_OUTPUT_TYPE_STDIO:
81 mGIFEncode_open_stdio(p->gifenc, param->output.fp);
82 break;
83 }
84
85 //ヘッダ
86
87 mGIFEncode_writeHeader(p->gifenc);
88
89 //設定
90
91 p->transparent = -1;
92
93 if((ret = (param->set_option)(param)))
94 return ret;
95
96 //画像制御ブロック (透過色)
97
98 if(p->transparent >= 0)
99 mGIFEncode_writeGrpCtrl(p->gifenc, p->transparent, 0, 0, FALSE);
100
101 //画像開始
102
103 img.offsetx = img.offsety = 0;
104 img.width = param->width;
105 img.height = param->height;
106 img.palette_buf = NULL;
107 img.palette_num = 0;
108
109 mGIFEncode_startImage(p->gifenc, &img);
110
111 //Y1行バッファ確保
112
113 p->rowbuf = (uint8_t *)mMalloc(param->width, FALSE);
114 if(!p->rowbuf) return MSAVEIMAGE_ERR_ALLOC;
115
116 return 0;
117 }
118
119 /** メイン処理 */
120
_main_proc(SAVEGIF * p)121 static int _main_proc(SAVEGIF *p)
122 {
123 mSaveImage *param = p->param;
124 int ret,i;
125
126 //初期化
127
128 if((ret = _init(p, param)))
129 return ret;
130
131 //画像
132
133 for(i = param->height; i > 0; i--)
134 {
135 //取得
136
137 ret = (param->send_row)(param, p->rowbuf, param->width);
138 if(ret) return ret;
139
140 //書き込み
141
142 mGIFEncode_writeImage(p->gifenc, p->rowbuf, param->width);
143 }
144
145 mGIFEncode_endImage(p->gifenc);
146 mGIFEncode_writeEnd(p->gifenc);
147
148 return 0;
149 }
150
151
152 /**
153
154 @ingroup saveimage
155 @{
156
157 */
158
159
160 /** GIF ファイルに保存
161 *
162 * 入力データは 8bit パレットのみ。 */
163
mSaveImageGIF(mSaveImage * param)164 mBool mSaveImageGIF(mSaveImage *param)
165 {
166 SAVEGIF *p;
167 int ret;
168
169 //確保
170
171 p = (SAVEGIF *)mMalloc(sizeof(SAVEGIF), TRUE);
172 if(!p) return FALSE;
173
174 p->param = param;
175 param->internal = p;
176
177 //処理
178
179 ret = _main_proc(p);
180
181 if(ret)
182 {
183 if(ret > 0)
184 mSaveImage_setMessage_errno(param, ret);
185 }
186
187 //解放
188
189 mGIFEncode_close(p->gifenc);
190
191 mFree(p->rowbuf);
192 mFree(p->palbuf);
193 mFree(p);
194
195 return (ret == 0);
196 }
197
198 /** 透過色のインデックスをセット */
199
mSaveImageGIF_setTransparent(mSaveImage * p,int index)200 void mSaveImageGIF_setTransparent(mSaveImage *p,int index)
201 {
202 ((SAVEGIF *)p->internal)->transparent = index;
203 }
204
205 /* @} */
206