Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
itdan3344
stb
提交
529d8163
S
stb
项目概览
itdan3344
/
stb
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
S
stb
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
529d8163
编写于
1月 13, 2015
作者:
E
Emmanuel Julien
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Add support for writing through callback functions in stb_image_write.h.
上级
a7c8694d
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
166 addition
and
45 deletion
+166
-45
stb_image_write.h
stb_image_write.h
+166
-45
未找到文件。
stb_image_write.h
浏览文件 @
529d8163
...
@@ -19,16 +19,23 @@ ABOUT:
...
@@ -19,16 +19,23 @@ ABOUT:
The PNG output is not optimal; it is 20-50% larger than the file
The PNG output is not optimal; it is 20-50% larger than the file
written by a decent optimizing implementation. This library is designed
written by a decent optimizing implementation. This library is designed
for source code compactness and simplicit
l
y, not optimal image file size
for source code compactness and simplicity, not optimal image file size
or run-time performance.
or run-time performance.
USAGE:
USAGE:
There are
three functions, one for each image file format
:
There are
functions for each image file format and output method
:
int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes);
int stbi_write_png_to_file(char const *filename, int x, int y, int comp, const void *data, int stride_bytes);
int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data);
int stbi_write_bmp_to_file(char const *filename, int x, int y, int comp, const void *data);
int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data);
int stbi_write_tga_to_file(char const *filename, int x, int y, int comp, const void *data);
int stbi_write_png_to_callbacks(stbi_io_write_callbacks const *clbk, void *user, int x, int y, int comp, const void *data, int stride_bytes);
int stbi_write_bmp_to_callbacks(stbi_io_write_callbacks const *clbk, void *user, int x, int y, int comp, const void *data);
int stbi_write_tga_to_callbacks(stbi_io_write_callbacks const *clbk, void *user, int x, int y, int comp, const void *data);
You can define STBI_WRITE_NO_STDIO to disable the file variant of these
functions.
Each function returns 0 on failure and non-0 on success.
Each function returns 0 on failure and non-0 on success.
...
@@ -51,6 +58,16 @@ USAGE:
...
@@ -51,6 +58,16 @@ USAGE:
formats do not. (Thus you cannot write a native-format BMP through the BMP
formats do not. (Thus you cannot write a native-format BMP through the BMP
writer, both because it is in BGR order and because it may have padding
writer, both because it is in BGR order and because it may have padding
at the end of the line.)
at the end of the line.)
===========================================================================
I/O callbacks
I/O callbacks allow you to write to arbitrary sources, like packaged
files or some other source.
The function you must define is "write" (writes some bytes of data).
*/
*/
#ifndef INCLUDE_STB_IMAGE_WRITE_H
#ifndef INCLUDE_STB_IMAGE_WRITE_H
...
@@ -60,9 +77,22 @@ USAGE:
...
@@ -60,9 +77,22 @@ USAGE:
extern
"C"
{
extern
"C"
{
#endif
#endif
extern
int
stbi_write_png
(
char
const
*
filename
,
int
w
,
int
h
,
int
comp
,
const
void
*
data
,
int
stride_in_bytes
);
typedef
struct
extern
int
stbi_write_bmp
(
char
const
*
filename
,
int
w
,
int
h
,
int
comp
,
const
void
*
data
);
{
extern
int
stbi_write_tga
(
char
const
*
filename
,
int
w
,
int
h
,
int
comp
,
const
void
*
data
);
int
(
*
write
)
(
void
*
user
,
void
*
data
,
int
size
);
// write 'size' bytes from 'data'. return number of bytes actually written
}
stbi_io_write_callbacks
;
extern
int
stbi_write_png_to_callbacks
(
stbi_io_write_callbacks
const
*
clbk
,
void
*
user
,
int
x
,
int
y
,
int
comp
,
const
void
*
data
,
int
stride_bytes
);
extern
int
stbi_write_bmp_to_callbacks
(
stbi_io_write_callbacks
const
*
clbk
,
void
*
user
,
int
x
,
int
y
,
int
comp
,
const
void
*
data
);
extern
int
stbi_write_tga_to_callbacks
(
stbi_io_write_callbacks
const
*
clbk
,
void
*
user
,
int
x
,
int
y
,
int
comp
,
const
void
*
data
);
#ifndef STBI_WRITE_NO_STDIO
extern
int
stbi_write_png_to_file
(
char
const
*
filename
,
int
x
,
int
y
,
int
comp
,
const
void
*
data
,
int
stride_bytes
);
extern
int
stbi_write_bmp_to_file
(
char
const
*
filename
,
int
x
,
int
y
,
int
comp
,
const
void
*
data
);
extern
int
stbi_write_tga_to_file
(
char
const
*
filename
,
int
x
,
int
y
,
int
comp
,
const
void
*
data
);
#endif // !STBI_WRITE_NO_STDIO
#ifdef __cplusplus
#ifdef __cplusplus
}
}
...
@@ -72,28 +102,68 @@ extern int stbi_write_tga(char const *filename, int w, int h, int comp, const vo
...
@@ -72,28 +102,68 @@ extern int stbi_write_tga(char const *filename, int w, int h, int comp, const vo
#ifdef STB_IMAGE_WRITE_IMPLEMENTATION
#ifdef STB_IMAGE_WRITE_IMPLEMENTATION
#ifndef STBI_WRITE_NO_STDIO
#include <stdio.h>
#endif // STBI_WRITE_NO_STDIO
#include <stdarg.h>
#include <stdarg.h>
#include <stdlib.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <string.h>
#include <assert.h>
#include <assert.h>
typedef
struct
{
stbi_io_write_callbacks
io
;
void
*
io_user_data
;
}
stbi__write_context
;
// initialize a callback-based context
static
void
stbi__start_write_callbacks
(
stbi__write_context
*
s
,
stbi_io_write_callbacks
const
*
c
,
void
*
user
)
{
s
->
io
=
*
c
;
s
->
io_user_data
=
user
;
}
#ifndef STBI_WRITE_NO_STDIO
static
int
stbi__stdio_write
(
void
*
user
,
void
*
data
,
int
size
)
{
return
(
int
)
fwrite
(
data
,
1
,
size
,(
FILE
*
)
user
);
}
static
stbi_io_write_callbacks
stbi__stdio_write_callbacks
=
{
stbi__stdio_write
};
static
void
stbi__start_write_file
(
stbi__write_context
*
s
,
const
char
*
filename
)
{
FILE
*
f
=
fopen
(
filename
,
"wb"
);
stbi__start_write_callbacks
(
s
,
&
stbi__stdio_write_callbacks
,
(
void
*
)
f
);
}
static
void
stbi__end_write_file
(
stbi__write_context
*
s
)
{
fclose
((
FILE
*
)
s
->
io_user_data
);
}
#endif // !STBI_WRITE_NO_STDIO
typedef
unsigned
int
stbiw_uint32
;
typedef
unsigned
int
stbiw_uint32
;
typedef
int
stb_image_write_test
[
sizeof
(
stbiw_uint32
)
==
4
?
1
:
-
1
];
typedef
int
stb_image_write_test
[
sizeof
(
stbiw_uint32
)
==
4
?
1
:
-
1
];
static
void
writefv
(
FILE
*
f
,
const
char
*
fmt
,
va_list
v
)
static
void
writefv
(
stbi__write_context
const
*
s
,
const
char
*
fmt
,
va_list
v
)
{
{
while
(
*
fmt
)
{
while
(
*
fmt
)
{
switch
(
*
fmt
++
)
{
switch
(
*
fmt
++
)
{
case
' '
:
break
;
case
' '
:
break
;
case
'1'
:
{
unsigned
char
x
=
(
unsigned
char
)
va_arg
(
v
,
int
);
fputc
(
x
,
f
);
break
;
}
case
'1'
:
{
unsigned
char
x
=
(
unsigned
char
)
va_arg
(
v
,
int
);
s
->
io
.
write
(
s
->
io_user_data
,
&
x
,
1
);
break
;
}
case
'2'
:
{
int
x
=
va_arg
(
v
,
int
);
unsigned
char
b
[
2
];
case
'2'
:
{
int
x
=
va_arg
(
v
,
int
);
unsigned
char
b
[
2
];
b
[
0
]
=
(
unsigned
char
)
x
;
b
[
1
]
=
(
unsigned
char
)
(
x
>>
8
);
b
[
0
]
=
(
unsigned
char
)
x
;
b
[
1
]
=
(
unsigned
char
)
(
x
>>
8
);
fwrite
(
b
,
2
,
1
,
f
);
break
;
}
s
->
io
.
write
(
s
->
io_user_data
,
b
,
2
);
break
;
}
case
'4'
:
{
stbiw_uint32
x
=
va_arg
(
v
,
int
);
unsigned
char
b
[
4
];
case
'4'
:
{
stbiw_uint32
x
=
va_arg
(
v
,
int
);
unsigned
char
b
[
4
];
b
[
0
]
=
(
unsigned
char
)
x
;
b
[
1
]
=
(
unsigned
char
)(
x
>>
8
);
b
[
0
]
=
(
unsigned
char
)
x
;
b
[
1
]
=
(
unsigned
char
)(
x
>>
8
);
b
[
2
]
=
(
unsigned
char
)(
x
>>
16
);
b
[
3
]
=
(
unsigned
char
)(
x
>>
24
);
b
[
2
]
=
(
unsigned
char
)(
x
>>
16
);
b
[
3
]
=
(
unsigned
char
)(
x
>>
24
);
fwrite
(
b
,
4
,
1
,
f
);
break
;
}
s
->
io
.
write
(
s
->
io_user_data
,
b
,
4
);
break
;
}
default:
default:
assert
(
0
);
assert
(
0
);
return
;
return
;
...
@@ -101,14 +171,14 @@ static void writefv(FILE *f, const char *fmt, va_list v)
...
@@ -101,14 +171,14 @@ static void writefv(FILE *f, const char *fmt, va_list v)
}
}
}
}
static
void
write3
(
FILE
*
f
,
unsigned
char
a
,
unsigned
char
b
,
unsigned
char
c
)
static
void
write3
(
stbi__write_context
const
*
s
,
unsigned
char
a
,
unsigned
char
b
,
unsigned
char
c
)
{
{
unsigned
char
arr
[
3
];
unsigned
char
arr
[
3
];
arr
[
0
]
=
a
,
arr
[
1
]
=
b
,
arr
[
2
]
=
c
;
arr
[
0
]
=
a
,
arr
[
1
]
=
b
,
arr
[
2
]
=
c
;
fwrite
(
arr
,
3
,
1
,
f
);
s
->
io
.
write
(
s
->
io_user_data
,
arr
,
3
);
}
}
static
void
write_pixels
(
FILE
*
f
,
int
rgb_dir
,
int
vdir
,
int
x
,
int
y
,
int
comp
,
void
*
data
,
int
write_alpha
,
int
scanline_pad
)
static
void
write_pixels
(
stbi__write_context
const
*
s
,
int
rgb_dir
,
int
vdir
,
int
x
,
int
y
,
int
comp
,
void
*
data
,
int
write_alpha
,
int
scanline_pad
)
{
{
unsigned
char
bg
[
3
]
=
{
255
,
0
,
255
},
px
[
3
];
unsigned
char
bg
[
3
]
=
{
255
,
0
,
255
},
px
[
3
];
stbiw_uint32
zero
=
0
;
stbiw_uint32
zero
=
0
;
...
@@ -126,65 +196,100 @@ static void write_pixels(FILE *f, int rgb_dir, int vdir, int x, int y, int comp,
...
@@ -126,65 +196,100 @@ static void write_pixels(FILE *f, int rgb_dir, int vdir, int x, int y, int comp,
for
(
i
=
0
;
i
<
x
;
++
i
)
{
for
(
i
=
0
;
i
<
x
;
++
i
)
{
unsigned
char
*
d
=
(
unsigned
char
*
)
data
+
(
j
*
x
+
i
)
*
comp
;
unsigned
char
*
d
=
(
unsigned
char
*
)
data
+
(
j
*
x
+
i
)
*
comp
;
if
(
write_alpha
<
0
)
if
(
write_alpha
<
0
)
fwrite
(
&
d
[
comp
-
1
],
1
,
1
,
f
);
s
->
io
.
write
(
s
->
io_user_data
,
&
d
[
comp
-
1
],
1
);
switch
(
comp
)
{
switch
(
comp
)
{
case
1
:
case
1
:
case
2
:
fwrite
(
d
,
1
,
1
,
f
);
case
2
:
s
->
io
.
write
(
s
->
io_user_data
,
d
,
1
);
break
;
break
;
case
4
:
case
4
:
if
(
!
write_alpha
)
{
if
(
!
write_alpha
)
{
// composite against pink background
// composite against pink background
for
(
k
=
0
;
k
<
3
;
++
k
)
for
(
k
=
0
;
k
<
3
;
++
k
)
px
[
k
]
=
bg
[
k
]
+
((
d
[
k
]
-
bg
[
k
])
*
d
[
3
])
/
255
;
px
[
k
]
=
bg
[
k
]
+
((
d
[
k
]
-
bg
[
k
])
*
d
[
3
])
/
255
;
write3
(
f
,
px
[
1
-
rgb_dir
],
px
[
1
],
px
[
1
+
rgb_dir
]);
write3
(
s
,
px
[
1
-
rgb_dir
],
px
[
1
],
px
[
1
+
rgb_dir
]);
break
;
break
;
}
}
/* FALLTHROUGH */
/* FALLTHROUGH */
case
3
:
case
3
:
write3
(
f
,
d
[
1
-
rgb_dir
],
d
[
1
],
d
[
1
+
rgb_dir
]);
write3
(
s
,
d
[
1
-
rgb_dir
],
d
[
1
],
d
[
1
+
rgb_dir
]);
break
;
break
;
}
}
if
(
write_alpha
>
0
)
if
(
write_alpha
>
0
)
fwrite
(
&
d
[
comp
-
1
],
1
,
1
,
f
);
s
->
io
.
write
(
s
->
io_user_data
,
&
d
[
comp
-
1
],
1
);
}
}
fwrite
(
&
zero
,
scanline_pad
,
1
,
f
);
s
->
io
.
write
(
s
->
io_user_data
,
&
zero
,
scanline_pad
);
}
}
}
}
static
int
outfile
(
char
const
*
filename
,
int
rgb_dir
,
int
vdir
,
int
x
,
int
y
,
int
comp
,
void
*
data
,
int
alpha
,
int
pad
,
const
char
*
fmt
,
...)
static
int
outfile
(
stbi__write_context
const
*
s
,
int
rgb_dir
,
int
vdir
,
int
x
,
int
y
,
int
comp
,
void
*
data
,
int
alpha
,
int
pad
,
const
char
*
fmt
,
...)
{
{
FILE
*
f
;
if
(
y
<
0
||
x
<
0
)
return
0
;
if
(
y
<
0
||
x
<
0
)
return
0
;
f
=
fopen
(
filename
,
"wb"
);
va_list
v
;
if
(
f
)
{
va_start
(
v
,
fmt
);
va_list
v
;
writefv
(
s
,
fmt
,
v
);
va_start
(
v
,
fmt
);
va_end
(
v
);
writefv
(
f
,
fmt
,
v
);
write_pixels
(
s
,
rgb_dir
,
vdir
,
x
,
y
,
comp
,
data
,
alpha
,
pad
);
va_end
(
v
);
return
1
;
write_pixels
(
f
,
rgb_dir
,
vdir
,
x
,
y
,
comp
,
data
,
alpha
,
pad
);
fclose
(
f
);
}
return
f
!=
NULL
;
}
}
int
stbi_write_bmp
(
char
const
*
filename
,
int
x
,
int
y
,
int
comp
,
const
void
*
data
)
int
stbi_write_bmp
(
stbi__write_context
const
*
s
,
int
x
,
int
y
,
int
comp
,
const
void
*
data
)
{
{
int
pad
=
(
-
x
*
3
)
&
3
;
int
pad
=
(
-
x
*
3
)
&
3
;
return
outfile
(
filename
,
-
1
,
-
1
,
x
,
y
,
comp
,(
void
*
)
data
,
0
,
pad
,
return
outfile
(
s
,
-
1
,
-
1
,
x
,
y
,
comp
,(
void
*
)
data
,
0
,
pad
,
"11 4 22 4"
"4 44 22 444444"
,
"11 4 22 4"
"4 44 22 444444"
,
'B'
,
'M'
,
14
+
40
+
(
x
*
3
+
pad
)
*
y
,
0
,
0
,
14
+
40
,
// file header
'B'
,
'M'
,
14
+
40
+
(
x
*
3
+
pad
)
*
y
,
0
,
0
,
14
+
40
,
// file header
40
,
x
,
y
,
1
,
24
,
0
,
0
,
0
,
0
,
0
,
0
);
// bitmap header
40
,
x
,
y
,
1
,
24
,
0
,
0
,
0
,
0
,
0
,
0
);
// bitmap header
}
}
int
stbi_write_tga
(
char
const
*
filename
,
int
x
,
int
y
,
int
comp
,
const
void
*
data
)
int
stbi_write_bmp_to_callbacks
(
stbi_io_write_callbacks
const
*
clbk
,
void
*
user
,
int
x
,
int
y
,
int
comp
,
const
void
*
data
)
{
stbi__write_context
s
;
stbi__start_write_callbacks
(
&
s
,
clbk
,
user
);
return
stbi_write_bmp
(
&
s
,
x
,
y
,
comp
,
data
);
}
#ifndef STBI_WRITE_NO_STDIO
int
stbi_write_bmp_to_file
(
char
const
*
filename
,
int
x
,
int
y
,
int
comp
,
const
void
*
data
)
{
stbi__write_context
s
;
stbi__start_write_file
(
&
s
,
filename
);
int
r
=
stbi_write_bmp
(
&
s
,
x
,
y
,
comp
,
data
);
stbi__end_write_file
(
&
s
);
return
r
;
}
#endif //!STBI_WRITE_NO_STDIO
int
stbi_write_tga
(
stbi__write_context
const
*
s
,
int
x
,
int
y
,
int
comp
,
const
void
*
data
)
{
{
int
has_alpha
=
(
comp
==
2
||
comp
==
4
);
int
has_alpha
=
(
comp
==
2
||
comp
==
4
);
int
colorbytes
=
has_alpha
?
comp
-
1
:
comp
;
int
colorbytes
=
has_alpha
?
comp
-
1
:
comp
;
int
format
=
colorbytes
<
2
?
3
:
2
;
// 3 color channels (RGB/RGBA) = 2, 1 color channel (Y/YA) = 3
int
format
=
colorbytes
<
2
?
3
:
2
;
// 3 color channels (RGB/RGBA) = 2, 1 color channel (Y/YA) = 3
return
outfile
(
filename
,
-
1
,
-
1
,
x
,
y
,
comp
,
(
void
*
)
data
,
has_alpha
,
0
,
return
outfile
(
s
,
-
1
,
-
1
,
x
,
y
,
comp
,
(
void
*
)
data
,
has_alpha
,
0
,
"111 221 2222 11"
,
0
,
0
,
format
,
0
,
0
,
0
,
0
,
0
,
x
,
y
,
(
colorbytes
+
has_alpha
)
*
8
,
has_alpha
*
8
);
"111 221 2222 11"
,
0
,
0
,
format
,
0
,
0
,
0
,
0
,
0
,
x
,
y
,
(
colorbytes
+
has_alpha
)
*
8
,
has_alpha
*
8
);
}
}
int
stbi_write_tga_to_callbacks
(
stbi_io_write_callbacks
const
*
clbk
,
void
*
user
,
int
x
,
int
y
,
int
comp
,
const
void
*
data
)
{
stbi__write_context
s
;
stbi__start_write_callbacks
(
&
s
,
clbk
,
user
);
return
stbi_write_tga
(
&
s
,
x
,
y
,
comp
,
data
);
}
#ifndef STBI_WRITE_NO_STDIO
int
stbi_write_tga_to_file
(
char
const
*
filename
,
int
x
,
int
y
,
int
comp
,
const
void
*
data
)
{
stbi__write_context
s
;
stbi__start_write_file
(
&
s
,
filename
);
int
r
=
stbi_write_tga
(
&
s
,
x
,
y
,
comp
,
data
);
stbi__end_write_file
(
&
s
);
return
r
;
}
#endif //!STBI_WRITE_NO_STDIO
// stretchy buffer; stbiw__sbpush() == vector<>::push_back() -- stbiw__sbcount() == vector<>::size()
// stretchy buffer; stbiw__sbpush() == vector<>::push_back() -- stbiw__sbcount() == vector<>::size()
#define stbiw__sbraw(a) ((int *) (a) - 2)
#define stbiw__sbraw(a) ((int *) (a) - 2)
#define stbiw__sbm(a) stbiw__sbraw(a)[0]
#define stbiw__sbm(a) stbiw__sbraw(a)[0]
...
@@ -490,19 +595,35 @@ unsigned char *stbi_write_png_to_mem(unsigned char *pixels, int stride_bytes, in
...
@@ -490,19 +595,35 @@ unsigned char *stbi_write_png_to_mem(unsigned char *pixels, int stride_bytes, in
return
out
;
return
out
;
}
}
int
stbi_write_png
(
char
const
*
filename
,
int
x
,
int
y
,
int
comp
,
const
void
*
data
,
int
stride_bytes
)
int
stbi_write_png
(
stbi__write_context
const
*
s
,
int
x
,
int
y
,
int
comp
,
const
void
*
data
,
int
stride_bytes
)
{
{
FILE
*
f
;
int
len
;
int
len
;
unsigned
char
*
png
=
stbi_write_png_to_mem
((
unsigned
char
*
)
data
,
stride_bytes
,
x
,
y
,
comp
,
&
len
);
unsigned
char
*
png
=
stbi_write_png_to_mem
((
unsigned
char
*
)
data
,
stride_bytes
,
x
,
y
,
comp
,
&
len
);
if
(
!
png
)
return
0
;
if
(
!
png
)
return
0
;
f
=
fopen
(
filename
,
"wb"
);
int
r
=
s
->
io
.
write
(
s
->
io_user_data
,
png
,
len
);
if
(
!
f
)
{
free
(
png
);
return
0
;
}
fwrite
(
png
,
1
,
len
,
f
);
fclose
(
f
);
free
(
png
);
free
(
png
);
return
1
;
return
r
;
}
int
stbi_write_png_to_callbacks
(
stbi_io_write_callbacks
const
*
clbk
,
void
*
user
,
int
x
,
int
y
,
int
comp
,
const
void
*
data
,
int
stride_bytes
)
{
stbi__write_context
s
;
stbi__start_write_callbacks
(
&
s
,
clbk
,
user
);
return
stbi_write_png
(
&
s
,
x
,
y
,
comp
,
data
,
stride_bytes
);
}
}
#ifndef STBI_WRITE_NO_STDIO
int
stbi_write_png_to_file
(
char
const
*
filename
,
int
x
,
int
y
,
int
comp
,
const
void
*
data
,
int
stride_bytes
)
{
stbi__write_context
s
;
stbi__start_write_file
(
&
s
,
filename
);
int
r
=
stbi_write_png
(
&
s
,
x
,
y
,
comp
,
data
,
stride_bytes
);
stbi__end_write_file
(
&
s
);
return
r
;
}
#endif //!STBI_WRITE_NO_STDIO
#endif // STB_IMAGE_WRITE_IMPLEMENTATION
#endif // STB_IMAGE_WRITE_IMPLEMENTATION
/* Revision history
/* Revision history
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录