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

📄 image.cpp

📁 俄罗斯人开发的大名鼎鼎的Pocket Pc 阅读器haaliread的源代码,visual c
💻 CPP
📖 第 1 页 / 共 2 页
字号:
      rs->accum[i+0] += rs->lb[i+0]*rs->outh;
      rs->accum[i+1] += rs->lb[i+1]*rs->outh;
      rs->accum[i+2] += rs->lb[i+2]*rs->outh;
    }
  }
  rs->inptr+=rs->outh;
}

struct my_src_mgr {
  struct jpeg_source_mgr  pub;
  ImageLoader::BinReader  *rdr;
  JOCTET		  *buffer;
};

METHODDEF(void) jsrc_init_source (j_decompress_ptr cinfo) {
  // do nothing
}

METHODDEF(boolean) jsrc_fill_input_buffer (j_decompress_ptr cinfo) {
  my_src_mgr	*mgr=(my_src_mgr*)cinfo->src;

  int	  nr=mgr->rdr->Read(mgr->buffer,INBUF_SIZE);
  if (nr<=0) { // eof
    // fake EOI marker
    mgr->buffer[0]=(JOCTET)0xff;
    mgr->buffer[1]=(JOCTET)JPEG_EOI;
    nr=2;
  }
  mgr->pub.bytes_in_buffer=nr;
  mgr->pub.next_input_byte=mgr->buffer;
  return TRUE;
}

METHODDEF(void) jsrc_skip_input_data (j_decompress_ptr cinfo, long bytes) {
  my_src_mgr	*mgr=(my_src_mgr*)cinfo->src;

  if (bytes > 0) {
    while (bytes > (long) mgr->pub.bytes_in_buffer) {
      bytes -= (long) mgr->pub.bytes_in_buffer;
      jsrc_fill_input_buffer(cinfo);
      /* note we assume that fill_input_buffer will never return FALSE,
       * so suspension need not be handled.
       */
    }
    mgr->pub.next_input_byte += (size_t) bytes;
    mgr->pub.bytes_in_buffer -= (size_t) bytes;
  }
}

METHODDEF(void) jsrc_term_source(j_decompress_ptr cinfo) {
  // do nothing
}

static void prepare_buffer(j_decompress_ptr cinfo,ImageLoader::BinReader *rdr) {
  my_src_mgr  *mgr;

  if (cinfo->src==NULL) {
    cinfo->src=(struct jpeg_source_mgr *)
      (cinfo->mem->alloc_small((j_common_ptr)cinfo,JPOOL_PERMANENT,
	sizeof(my_src_mgr)));
    mgr=(my_src_mgr*)cinfo->src;
    mgr->buffer=(JOCTET*)
      (cinfo->mem->alloc_small((j_common_ptr)cinfo,JPOOL_PERMANENT,
	INBUF_SIZE*sizeof(JOCTET)));
  }
  mgr=(my_src_mgr*)cinfo->src;
  mgr->rdr=rdr;
  mgr->pub.init_source=jsrc_init_source;
  mgr->pub.fill_input_buffer=jsrc_fill_input_buffer;
  mgr->pub.skip_input_data=jsrc_skip_input_data;
  mgr->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */
  mgr->pub.term_source=jsrc_term_source;
  mgr->pub.bytes_in_buffer=0;
  mgr->pub.next_input_byte=NULL;
}

struct my_error_mgr {
  struct jpeg_error_mgr	  pub;
  jmp_buf		  jb;
};

METHODDEF(void) je_error_exit(j_common_ptr cinfo) {
  my_error_mgr	  *mgr=(my_error_mgr*)cinfo->err;
  /* Always display the message */
  (*cinfo->err->output_message) (cinfo);
  jpeg_destroy(cinfo);
  longjmp(mgr->jb,1);
}

METHODDEF(void) je_output_message(j_common_ptr cinfo) {
  char buffer[JMSG_LENGTH_MAX];
  /* Create the message */
  (*cinfo->err->format_message) (cinfo, buffer);
  // do nothing at this time
#if 0
  MessageBoxA(GetActiveWindow(),buffer,"JPEG Decompressor",MB_OK);
#endif
}

static void PNGAPI pngr_read_data(png_structp png_ptr,png_bytep data,png_size_t length) {
  ImageLoader::BinReader  *rdr=(ImageLoader::BinReader*)png_get_io_ptr(png_ptr);
  if (!rdr || rdr->Read(data,length)!=(int)length)
    png_error(png_ptr,"Read Error");
}

static int  get_bitmap_format() {
  static int	    format=BF_UNKNOWN;

#ifdef _WIN32_WCE
  if (format!=BF_UNKNOWN)
    return format;

  HINSTANCE hLib;

  if ((hLib=LoadLibrary(_T("gx.dll")))!=NULL) {
    GXDisplayProperties (*gp)();
    gp=(GXDisplayProperties (*)())GetProcAddress(hLib,
      _T("?GXGetDisplayProperties@@YA?AUGXDisplayProperties@@XZ"));
    if (gp) {
      GXDisplayProperties props=gp();
      if (props.ffFormat&kfDirect555)
	format=BF_555;
      else if (props.ffFormat&kfDirect565)
	format=BF_565;
      else
	format=BF_888;
    }
    FreeLibrary(hLib);
  }
#endif
  if (format!=BF_UNKNOWN)
    return format;
  HDC	hDC=GetDC(NULL);
  if (GetDeviceCaps(hDC,BITSPIXEL)==16)
    format=BF_565;
  else
    format=BF_888;
  ReleaseDC(NULL,hDC);
  return format;
}

static imagestore *bminit(HDC hDC,int w,int h,int maxw,int maxh,int rotate)
{
  struct {
    BITMAPINFOHEADER  h;
    DWORD	      masks[3];
  } bi;
  imagestore	*im=(imagestore*)malloc(sizeof(imagestore));
  if (!im)
    return NULL;
  void		*data;
  int		bpp;
  s32		rowstep;

  im->bmformat=get_bitmap_format();
  memset(&bi,0,sizeof(bi));
  switch (im->bmformat) {
  case BF_555:
    bpp=2;
    bi.masks[0]=0x7C00;
    bi.masks[1]=0x03E0;
    bi.masks[2]=0x001F;
    bi.h.biCompression=BI_BITFIELDS;
    im->packbits=packbits_24_to_15;
    break;
  case BF_565:
    bpp=2;
    bi.masks[0]=0xF800;
    bi.masks[1]=0x07E0;
    bi.masks[2]=0x001F;
    bi.h.biCompression=BI_BITFIELDS;
    im->packbits=packbits_24_to_16;
    break;
  case BF_888:
    bpp=3;
#ifdef _WIN32_WCE
    bi.masks[0]=0xFF0000;
    bi.masks[1]=0x00FF00;
    bi.masks[2]=0x0000FF;
    bi.h.biCompression=BI_BITFIELDS;
#else
    bi.h.biCompression=BI_RGB;
#endif
    im->packbits=packbits_24_to_24;
    break;
#ifndef STANDALONE
  default:
    ASSERT(0);
#endif
  }
  if (w<=maxw && h<=maxh) {
    im->width=w;
    im->height=h;
  } else {
    if (maxw*h<maxh*w) {
      im->width=maxw;
      im->height=(h*maxw)/w;
    } else {
      im->width=(w*maxh)/h;
      im->height=maxh;
    }
  }
  if (rotate==0 || rotate==1800) {
    im->realheight=im->height;
    im->realwidth=im->width;
  } else {
    im->realheight=im->width;
    im->realwidth=im->height;
  }
  if (!hDC)
    return im;
  rowstep=(im->realwidth*bpp+3)&~3;
  bi.h.biSize=sizeof(bi.h);
  bi.h.biWidth=im->realwidth;
  bi.h.biHeight=im->realheight;
  bi.h.biPlanes=1;
  bi.h.biBitCount=bpp==2 ? 16 : 24;
  if (!(im->bmp=CreateDIBSection(hDC,(BITMAPINFO*)&bi,DIB_RGB_COLORS,&data,NULL,0))) {
    DWORD err=GetLastError();
    free(im);
    return NULL;
  }
  switch (rotate) {
  case 2700:
    im->hstep=-rowstep;
    im->vstep=-bpp;
    im->bits=(u8*)data+bpp*(im->realwidth-1)+rowstep*(im->realheight-1);
    break;
  case 1800:
    im->hstep=-bpp;
    im->vstep=rowstep;
    im->bits=(u8*)data+bpp*(im->realwidth-1);
    break;
  case 900:
    im->hstep=rowstep;
    im->vstep=bpp;
    im->bits=(u8*)data;
    break;
  case 0:
    im->hstep=bpp;
    im->vstep=-rowstep;
    im->bits=(u8*)data+rowstep*(im->realheight-1);
    break;
#ifndef STANDALONE
  default:
    ASSERT(0);
#endif
  }
  return im;
}

bool	ImageLoader::Load(HDC hDC,const wchar_t *type,ImageLoader::BinReader *rdr,
			  int maxwidth,int maxheight,int rotation,HBITMAP& bmp,
			  int& width,int& height)
{
  imagestore		    *is=NULL;
  resize_state		    *rs=NULL;

  set_gamma(0.45455);
  if (!wcscmp(type,L"image/jpeg")) { // only jpeg images are supported at the time
    struct jpeg_decompress_struct   cinfo;
    struct my_error_mgr		    jerr;

    cinfo.err=jpeg_std_error(&jerr.pub);
    jerr.pub.error_exit=je_error_exit;
    jerr.pub.output_message=je_output_message;
    if (setjmp(jerr.jb))
      goto common_exit;
    jpeg_create_decompress(&cinfo);
    prepare_buffer(&cinfo,rdr);
    jpeg_read_header(&cinfo,TRUE);
    // do some scaling
    int scale,iw;
    for (scale=1,iw=cinfo.image_width;scale<8;scale<<=1,iw>>=1)
      if ((iw>>1)<maxwidth)
	break;
    cinfo.scale_denom=scale;
    cinfo.out_color_space=JCS_RGB;
    jpeg_calc_output_dimensions(&cinfo);
    is=bminit(hDC,cinfo.output_width,cinfo.output_height,maxwidth,maxheight,rotation);
    if (is && hDC) {
      if (is->width!=cinfo.output_width || is->height!=cinfo.output_height) {
	rs=resize_state_create(cinfo.output_width,cinfo.output_height,is);
	if (!rs)
	  goto outjpg;
      }
      jpeg_start_decompress(&cinfo);
      JSAMPARRAY  line=cinfo.mem->alloc_sarray((j_common_ptr)&cinfo,
			JPOOL_IMAGE,cinfo.output_width*cinfo.output_components,
			1);
      if (rs) {
	while (cinfo.output_scanline<cinfo.output_height) {
	  jpeg_read_scanlines(&cinfo,line,1);
	  resize_add_line(rs,line[0]);
	}
      } else {
	while (cinfo.output_scanline<cinfo.output_height) {
	  jpeg_read_scanlines(&cinfo,line,1);
	  is->packbits(is,line[0]);
	}
      }
      jpeg_finish_decompress(&cinfo);
    }
outjpg:
    jpeg_destroy_decompress(&cinfo);
  } else if (!wcscmp(type,L"image/png")) {
    // create png read structures
    png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL);
    if (!png_ptr) // out of memory?
      return false;
    png_infop	info_ptr = png_create_info_struct(png_ptr);
    if (!info_ptr) { // out of memory?
      png_destroy_read_struct(&png_ptr,NULL,NULL);
      return false;
    }
    // setup i/o routine
    png_set_read_fn(png_ptr,rdr,pngr_read_data);

    // init jmpbuf
    if (setjmp(png_jmpbuf(png_ptr))) { // error occurred
      png_destroy_read_struct(&png_ptr,&info_ptr,NULL);
      goto common_exit;
    }
    png_read_info(png_ptr,info_ptr);
    png_uint_32	width,height;
    int		bit_depth,color_type,interlace_type;
    png_get_IHDR(png_ptr,info_ptr,&width,&height,&bit_depth,&color_type,
		 &interlace_type,NULL,NULL);
    if (interlace_type!=PNG_INTERLACE_NONE) {
      png_destroy_read_struct(&png_ptr,&info_ptr,NULL);
      return false;
    }
    // configure transformations, we always want RGB data in the end
    if (color_type == PNG_COLOR_TYPE_PALETTE)
      png_set_palette_to_rgb(png_ptr);
    if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
      png_set_gray_1_2_4_to_8(png_ptr);
    if (png_get_valid(png_ptr, info_ptr,PNG_INFO_tRNS))
      png_set_tRNS_to_alpha(png_ptr);
    if (bit_depth == 16)
      png_set_strip_16(png_ptr);
    if (bit_depth < 8)
      png_set_packing(png_ptr);
    if (color_type == PNG_COLOR_TYPE_GRAY ||
        color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
      png_set_gray_to_rgb(png_ptr);

    // update info after applying transformations
    png_read_update_info(png_ptr,info_ptr);

    // reload info
    png_get_IHDR(png_ptr,info_ptr,&width,&height,&bit_depth,&color_type,
		 &interlace_type,NULL,NULL);

    // ok, now configure storer and resizer
    is=bminit(hDC,width,height,maxwidth,maxheight,rotation);
    if (is && hDC) {
      if (is->width!=width || is->height!=height) {
	rs=resize_state_create(width,height,is);
	if (!rs)
	  goto outpng;
      }

      // handle transparency
      if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
	// create a resizer, because we use it to apply
	// transparency
	if (!rs) {
	  rs=resize_state_create(width,height,is);
	  if (!rs)
	    goto outpng;
	}

	png_color_16p image_background;
	if (png_get_bKGD(png_ptr, info_ptr, &image_background))
	  resize_set_alpha(rs,RGB(image_background->red>>8,
				  image_background->green>>8,
				  image_background->blue>>8));
	else
	  resize_set_alpha(rs,::GetBkColor(hDC));
      }

      // now read the image line by line
      int		rowbytes=png_get_rowbytes(png_ptr,info_ptr);
      unsigned char	*row=(unsigned char *)malloc(rowbytes);
      if (!row)
	goto outpng;
      if (rs) {
	for (int i=0;i<(int)height;++i) {
	  png_read_row(png_ptr,row,NULL);
	  resize_add_line(rs,row);
	}
      } else {
	for (int i=0;i<(int)height;++i) {
	  png_read_row(png_ptr,row,NULL);
	  is->packbits(is,row);
	}
      }
      // destroy read struct
      free(row);
      png_read_end(png_ptr,NULL);
    }
outpng:
    png_destroy_read_struct(&png_ptr,&info_ptr,NULL);
  } else
    return false;
common_exit:
  if (is) {
    bmp=is->bmp;
    width=is->width;
    height=is->height;
  }
  resize_state_destroy(rs);
  free(is);
  return is!=NULL;
}

⌨️ 快捷键说明

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