⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mpng.c

📁 multi-tabed terminal based on rxvt
💻 C
📖 第 1 页 / 共 2 页
字号:
/*--------------------------------*-C-*---------------------------------* * File:    mpng.c *----------------------------------------------------------------------* * * All portions of code are copyright by their respective author/s. * Copyright (c) 1999-2002   Toshikaz Hirabayashi * Copyright (c) 2004        Jingmin Zhou <jimmyzhou@users.sourceforge.net> * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. *----------------------------------------------------------------------*/#include "../config.h"#include "rxvt.h"#ifdef USE_PNGstatic voidpng_cexcept_error (png_structp png_ptr, png_const_charp msg){    if(png_ptr){	rxvt_msg (DBG_ERROR, DBG_IMAGES, "png file read error: %s\n", msg);    }}longPngReadFileToPixmap (Display* display, Window window, GC gc, char* filename, Pixmap* pixmap, long* w, long* h){    int red_mask, green_mask, blue_mask;    int red_shift, green_shift, blue_shift;    int start_shift, msb_flag;    unsigned int start_mask, udat;    XWindowAttributes win_attr;    FILE* ifile;  long display_depth;      png_byte            sig[8];  png_infop info_ptr;  png_structp png_ptr;      png_uint_32 png_width;    png_uint_32 png_height;    int png_depth;    int png_color_type;png_uint_32 png_row_bytes;  png_uint_32 png_channels;    long rwidth;    long rheight;    long components;    unsigned char* buf;    png_byte** png_row_ptrs;    long vwidth;    long vheight;    long stretched;    XImage* image;    Visual* visual;    Pixmap pix;    int i;    char* data1;    unsigned char r,g,b;    long ptr = 0;    long ptr2 = 0;    long j;    red_mask = green_mask = blue_mask = 0;    red_shift = green_shift = blue_shift = 0;    ifile = fopen(filename,"r");    if (ifile == NULL){      return -1;    }    display_depth = XDefaultDepth(display,XDefaultScreen(display));    fread(sig, 1, 8, ifile);    if (!png_check_sig(sig, 8)){      fclose(ifile);      return -1;    }    png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL,      (png_error_ptr)png_cexcept_error, (png_error_ptr)NULL);    if (png_ptr == NULL){      fclose(ifile);      return -1;    }     info_ptr = png_create_info_struct(png_ptr);    if (info_ptr == NULL){      png_destroy_read_struct(&png_ptr, NULL, NULL);      fclose(ifile);      return -1;    }    png_init_io(png_ptr, ifile);    png_set_sig_bytes(png_ptr, 8);    png_read_info(png_ptr, info_ptr);    png_get_IHDR(png_ptr, info_ptr, &png_width, &png_height, &png_depth,            &png_color_type, NULL, NULL, NULL);    if (png_depth == 16){      png_set_strip_16(png_ptr);    }    png_row_bytes = png_get_rowbytes(png_ptr, info_ptr);    png_channels = png_get_channels(png_ptr, info_ptr);    if (png_depth < 8){      if (png_color_type == PNG_COLOR_TYPE_GRAY ){        png_set_gray_1_2_4_to_8(png_ptr);        png_row_bytes = png_width;      }else{        png_set_expand(png_ptr);        png_row_bytes = png_width;        png_row_bytes = png_width * 3;        png_channels = 3;      }    }    if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)){      png_set_expand(png_ptr);      png_row_bytes = png_width;    }    if (png_color_type == PNG_COLOR_TYPE_GRAY ||        png_color_type == PNG_COLOR_TYPE_GRAY_ALPHA){      png_set_gray_to_rgb(png_ptr);      png_row_bytes = png_width;    }    if (png_color_type == PNG_COLOR_TYPE_PALETTE){      png_set_palette_to_rgb(png_ptr);      png_row_bytes = png_width * 3;      png_channels = 3;    }    rwidth = png_width;    rheight = png_height;    components = png_channels;    /* possible integer overflow? */    assert ((int) png_row_bytes > 0);    assert ((int) png_height > 0);    assert (((int)png_row_bytes) * ((int)png_height) * sizeof(png_byte) > 0);    buf = rxvt_malloc(png_row_bytes * png_height * sizeof(png_byte));    if (buf == NULL){      rxvt_msg (DBG_ERROR, DBG_IMAGES, "png read error: out of memory..\n");      png_destroy_read_struct(&png_ptr, &info_ptr, NULL);      fclose(ifile);      return -1;    }    /* possible integer overflow? */    assert ((int) png_height > 0);    assert (sizeof(png_bytep) * ((int)png_height) > 0);    png_row_ptrs = rxvt_malloc (sizeof(png_bytep)*png_height);    if (png_row_ptrs == NULL){      rxvt_msg (DBG_ERROR, DBG_IMAGES, "png read error: out of memory..\n");      png_destroy_read_struct(&png_ptr, &info_ptr, NULL);      fclose(ifile);      return -1;    }    for(i = 0; i < (int)png_height; i++){      png_row_ptrs[i] = (png_byte*)(buf + i * png_row_bytes);    }    png_read_image(png_ptr, png_row_ptrs);    png_read_end(png_ptr,NULL);    rxvt_free(png_row_ptrs);    vwidth = *w;    vheight = *h;    stretched =0;    if (*w == 0 || *h == 0){      *w = rwidth;      *h = rheight;    }else{      if ((long)((double)rwidth * vheight/vwidth) < rheight){        *w = (long)((double)vheight * rwidth/rheight);      }else{        *h = (long)((double)vwidth * rheight/rwidth);      }      stretched = 1;    }    vwidth = *w;    vheight = *h;    image = 0;    visual = XDefaultVisual(display,XDefaultScreen(display));    if (display_depth >16){      image = XCreateImage(display,visual, display_depth,                           ZPixmap,0,0,vwidth,vheight,32,0);    }else    if (display_depth >8){      image = XCreateImage(display,visual, display_depth,                           ZPixmap,0,0,vwidth,vheight,16,0);    }else{      image = XCreateImage(display,visual, display_depth,                           ZPixmap,0,0,vwidth,vheight,8,0);    }    msb_flag = (ImageByteOrder(display) == MSBFirst)?1:0;    if (XGetWindowAttributes(display,                     RootWindow(display, DefaultScreen(display)),                     &win_attr) == 0) {        fclose(ifile);                 return -1;    }    if ((win_attr.depth == 24) || (win_attr.depth == 16)) {      unsigned int n;      if (win_attr.depth == 24) {        start_shift = 24;        start_mask = 0x80000000;      }else{        start_shift = 8;        start_mask = 0x8000;      }      red_mask = win_attr.visual->red_mask;      red_shift = start_shift;      n = start_mask;      while (!(n & red_mask)) {        n >>= 1;        red_shift--;      }      green_mask = win_attr.visual->green_mask;      green_shift = start_shift;      n = start_mask;      while (!(n & green_mask)) {        n >>= 1;        green_shift--;      }      blue_mask = win_attr.visual->blue_mask;      blue_shift = start_shift;      n = start_mask;      while (!(n & blue_mask)) {        n >>= 1;        blue_shift--;      }    }    /* possible integer overflow? */    assert ((int) image->bytes_per_line > 0);    assert ((int) vheight > 0);    assert (((int)image->bytes_per_line) * ((int)vheight) > 0);    data1 = rxvt_malloc(image->bytes_per_line * vheight);    if (image->bits_per_pixel ==32){      if (components == 3 || components == 4){        for(i=0; i<vheight; i++){          for(j=0; j<vwidth; j++){            if (stretched != 0){              ptr = (long)((double)i*rheight/vheight)*rwidth                   + (long)((double)j*rwidth/vwidth);              ptr *= 3;            }            r = buf[ptr++];            g = buf[ptr++];            b = buf[ptr++];            if (components == 4){              ptr++;            }            udat = 0;            if (red_shift >= 0){              udat |= (((int)r << red_shift) & red_mask);            }else{              udat |= (((int)r >> (-red_shift)) & red_mask);            }            if (green_shift >= 0){              udat |= (((int)g << green_shift) & green_mask);            }else{              udat |= (((int)g >> (-green_shift)) & green_mask);            }            if (blue_shift >= 0){              udat |= (((int)b << blue_shift) & blue_mask);            }else{              udat |= (((int)b >> (-blue_shift)) & blue_mask);            }            if (msb_flag){              ((unsigned char*)data1)[ptr2++] = (udat & 0xff000000)>>24;              ((unsigned char*)data1)[ptr2++] = (udat & 0xff0000)>>16;              ((unsigned char*)data1)[ptr2++] = (udat & 0xff00)>>8;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -