1 Star 3 Fork 2

只要998/Onscripter-Official

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
resize_image.cpp 8.06 KB
一键复制 编辑 原始数据 按行查看 历史
只要998 提交于 2020-04-20 20:31 . no commit message
/* -*- C++ -*-
*
* resize_image.cpp - resize image using smoothing and resampling
*
* Copyright (c) 2001-2012 Ogapee. All rights reserved.
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <stdio.h>
#include <string.h>
static unsigned long *pixel_accum=NULL;
static unsigned long *pixel_accum_num=NULL;
static int pixel_accum_size=0;
static unsigned long tmp_acc[4];
static unsigned long tmp_acc_num[4];
static void calcWeightedSumColumnInit(unsigned char **src,
int interpolation_height,
int image_width, int image_height, int image_pixel_width, int byte_per_pixel)
{
int y_end = -interpolation_height/2+interpolation_height;
memset(pixel_accum, 0, image_width*byte_per_pixel*sizeof(unsigned long));
memset(pixel_accum_num, 0, image_width*byte_per_pixel*sizeof(unsigned long));
for (int s=0 ; s<byte_per_pixel ; s++){
for (int i=0 ; i<y_end-1 ; i++){
if (i >= image_height) break;
unsigned long *pa = pixel_accum + image_width*s;
unsigned long *pan = pixel_accum_num + image_width*s;
unsigned char *p = *src+image_pixel_width*i+s;
for (int j=image_width ; j!=0 ; j--, p+=byte_per_pixel){
*pa++ += *p;
(*pan++)++;
}
}
}
}
static void calcWeightedSumColumn(unsigned char **src, int y,
int interpolation_height,
int image_width, int image_height, int image_pixel_width, int byte_per_pixel)
{
int y_start = y-interpolation_height/2;
int y_end = y-interpolation_height/2+interpolation_height;
for (int s=0 ; s<byte_per_pixel ; s++){
if ((y_start-1)>=0 && (y_start-1)<image_height){
unsigned long *pa = pixel_accum + image_width*s;
unsigned long *pan = pixel_accum_num + image_width*s;
unsigned char *p = *src+image_pixel_width*(y_start-1)+s;
for (int j=image_width ; j!=0 ; j--, p+=byte_per_pixel){
*pa++ -= *p;
(*pan++)--;
}
}
if ((y_end-1)>=0 && (y_end-1)<image_height){
unsigned long *pa = pixel_accum + image_width*s;
unsigned long *pan = pixel_accum_num + image_width*s;
unsigned char *p = *src+image_pixel_width*(y_end-1)+s;
for (int j=image_width ; j!=0 ; j--, p+=byte_per_pixel){
*pa++ += *p;
(*pan++)++;
}
}
}
}
static void calcWeightedSum(unsigned char **dst, unsigned char **src, int x,
int interpolation_width,
int image_width, int byte_per_pixel)
{
int x_start = x-interpolation_width/2;
int x_end = x-interpolation_width/2+interpolation_width;
for (int s=0 ; s<byte_per_pixel ; s++){
if ((x_start-1)>=0 && (x_start-1)<image_width){
tmp_acc[s] -= pixel_accum[image_width*s+x_start-1];
tmp_acc_num[s] -= pixel_accum_num[image_width*s+x_start-1];
}
if ((x_end-1)>=0 && (x_end-1)<image_width){
tmp_acc[s] += pixel_accum[image_width*s+x_end-1];
tmp_acc_num[s] += pixel_accum_num[image_width*s+x_end-1];
}
*(*dst)++ = (unsigned char)(tmp_acc[s]/tmp_acc_num[s]);
}
}
void resizeImage( unsigned char *dst_buffer, int dst_width, int dst_height, int dst_total_width,
unsigned char *src_buffer, int src_width, int src_height, int src_total_width,
int byte_per_pixel, unsigned char *tmp_buffer, int tmp_total_width, bool palette_flag )
{
if (dst_width == 0 || dst_height == 0) return;
unsigned char *tmp_buf = tmp_buffer;
unsigned char *src_buf = src_buffer;
int i, j, s;
int tmp_offset = tmp_total_width - src_width * byte_per_pixel;
unsigned int mx, my;
if ( src_width > 1 ) mx = 1;
else mx = 0;
if ( src_height > 1 ) my = 1;
else my = 0;
int interpolation_width = src_width / dst_width;
if ( interpolation_width == 0 ) interpolation_width = 1;
int interpolation_height = src_height / dst_height;
if ( interpolation_height == 0 ) interpolation_height = 1;
if (pixel_accum_size < src_width*byte_per_pixel){
pixel_accum_size = src_width*byte_per_pixel;
if (pixel_accum) delete[] pixel_accum;
pixel_accum = new unsigned long[pixel_accum_size];
if (pixel_accum_num) delete[] pixel_accum_num;
pixel_accum_num = new unsigned long[pixel_accum_size];
}
/* smoothing */
if ( byte_per_pixel >= 3 ){
calcWeightedSumColumnInit(&src_buf, interpolation_height,
src_width, src_height, src_total_width, byte_per_pixel );
for ( i=0 ; i<src_height ; i++ ){
calcWeightedSumColumn(&src_buf, i, interpolation_height,
src_width, src_height, src_total_width, byte_per_pixel );
for (s=0 ; s<byte_per_pixel ; s++){
tmp_acc[s]=0;
tmp_acc_num[s]=0;
for (j=0 ; j<-interpolation_width/2+interpolation_width-1 ; j++){
if (j >= src_width) break;
tmp_acc[s] += pixel_accum[src_width*s+j];
tmp_acc_num[s] += pixel_accum_num[src_width*s+j];
}
}
for ( j=0 ; j<src_width ; j++ )
calcWeightedSum(&tmp_buf, &src_buf, j,
interpolation_width,
src_width, byte_per_pixel );
tmp_buf += tmp_offset;
}
}
else{
tmp_buffer = src_buffer;
}
/* resampling */
unsigned char *dst_buf = dst_buffer;
int dh1 = dst_height-1; if (dh1==0) dh1 = 1;
int dw1 = dst_width-1; if (dw1==0) dw1 = 1;
for ( i=0 ; i<dst_height ; i++ ){
int y = (i<<3) * (src_height-1) / dh1;
int dy = y & 0x7;
y >>= 3;
for ( j=0 ; j<dst_width ; j++ ){
int x = (j<<3) * (src_width-1) / dw1;
int dx = x & 0x7;
x >>= 3;
int k = tmp_total_width * y + x * byte_per_pixel;
if (palette_flag){ //assuming byte_per_pixel=1
*dst_buf++ = tmp_buffer[k];
}
else{
for ( s=0 ; s<byte_per_pixel ; s++, k++ ){
unsigned int p;
p = (8-dx)*(8-dy)*tmp_buffer[ k ];
p += dx *(8-dy)*tmp_buffer[ k+mx*byte_per_pixel ];
p += (8-dx)* dy *tmp_buffer[ k+my*tmp_total_width ];
p += dx * dy *tmp_buffer[ k+mx*byte_per_pixel+my*tmp_total_width ];
*dst_buf++ = (unsigned char)(p>>6);
}
}
}
for ( j=0 ; j<dst_total_width - dst_width*byte_per_pixel ; j++ )
*dst_buf++ = 0;
}
/* pixels at the corners are preserved */
for ( i=0 ; i<byte_per_pixel ; i++ ){
dst_buffer[i] = src_buffer[i];
dst_buffer[(dst_width-1)*byte_per_pixel+i] = src_buffer[(src_width-1)*byte_per_pixel+i];
dst_buffer[(dst_height-1)*dst_total_width+i] = src_buffer[(src_height-1)*src_total_width+i];
dst_buffer[(dst_height-1)*dst_total_width+(dst_width-1)*byte_per_pixel+i] =
src_buffer[(src_height-1)*src_total_width+(src_width-1)*byte_per_pixel+i];
}
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C++
1
https://gitee.com/only998/Onscripter-Official.git
[email protected]:only998/Onscripter-Official.git
only998
Onscripter-Official
Onscripter-Official
master

搜索帮助