libjpeg(2)

来源:互联网 发布:远程网络教育考试 编辑:程序博客网 时间:2024/05/18 06:28
/* JPEG解压缩的示例程序。我们假定源文件名被传入。我们想要成功返回1,错误为0。*/struct my_error_mgr{  struct jpeg_error_mgr pub;    /* "public" fields */  jmp_buf setjmp_buffer;        /* for return to caller */};typedef struct my_error_mgr *my_error_ptr;void my_error_exit (j_common_ptr cinfo){  /* cinfo-> err真的指向一个my_error_mgr结构,所以强制指针*/  my_error_ptr myerr = (my_error_ptr) cinfo->err;  /*始终显示消息。*/  /*如果我们选择,我们可以推迟这个,直到返回。*/  (*cinfo->err->output_message) (cinfo);  /*将控制返回到setjmp点*/  longjmp(myerr->setjmp_buffer, 1);}int read_JPEG_file (char *filename){  /*此结构体包含JPEG解压缩参数和指针工作空间(由JPEG库根据需要分配)*/  struct jpeg_decompress_struct cinfo;  /*我们使用我们的专用扩展JPEG错误处理程序。   *请注意,此结构体必须与主要的JPEG参数一样的生存周期,以避免指针问题。   */  struct my_error_mgr jerr;  FILE *infile;                 /* 源文件 */  JSAMPARRAY buffer;            /* 输出行缓冲区*/  int row_stride;               /* 输出缓冲区中的物理行宽 */  /*在这个例子中,我们要做任何事情之前打开输入文件,   *所以下面的setjmp()错误恢复可以假定文件是打开的。   *使用“b”选项来fopen()要求它读取二进制文件。   */  if ((infile = fopen(filename, "rb")) == NULL) {    fprintf(stderr, "can't open %s\n", filename);    return 0;  }   /*步骤1:分配和初始化JPEG解压缩对象*/  /*我们设置正常的JPEG错误例程,然后覆盖error_exit。*/  cinfo.err = jpeg_std_error(&jerr.pub);  jerr.pub.error_exit = my_error_exit;     /*建立my_error_exit使用的setjmp返回上下文。*/  if (setjmp(jerr.setjmp_buffer))  {    /*如果我们到达这里,JPEG代码发出了一个错误信号。     *我们需要清理JPEG对象,关闭输入文件并返回。     */    jpeg_destroy_decompress(&cinfo);    fclose(infile);    return 0;  }   /*现在我们可以初始化JPEG解压缩对象。*/  jpeg_create_decompress(&cinfo);  /*步骤2:指定数据源(例如,文件)*/  jpeg_stdio_src(&cinfo, infile);  /*步骤3:使用jpeg_read_header()*/  (void) jpeg_read_header(&cinfo, TRUE);  /*我们可以忽略来自jpeg_read_header的返回值   *(a)stdio数据源不可能暂停,   *(b)我们通过TRUE来拒绝仅表格的JPEG文件作为错误。   */   /*步骤4:设置解压缩参数*/   /*在本示例中,我们不需要更改任何设置的默认值    * jpeg_read_header(),所以我们什么也不做。    */  /*步骤5:启动解压缩器*/  (void) jpeg_start_decompress(&cinfo);   /*我们可以忽略返回值,因为暂停是不可能的与stdio数据源。*/  /*在阅读之前,我们可能需要做一些我们自己的设置数据。   *在jpeg_start_decompress()之后,我们有正确的缩放   *输出图像尺寸可用,以及输出颜色图   *如果我们要求颜色量化。   *在这个例子中,我们需要制作一个正确大小的输出工作缓冲区。   */     /*输出缓冲区中每行的JSAMPLE */  row_stride = cinfo.output_width * cinfo.output_components;  /*制作一行高的样本数组,当完成图像*/  buffer = (*cinfo.mem->alloc_sarray)                ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);  /*步骤6:while(扫描线仍然被读取)*/  /* jpeg_read_scanlines(...); */  /*这里我们使用库的状态变量cinfo.output_scanline作为循环计数器*/  while (cinfo.output_scanline < cinfo.output_height)  {    /* jpeg_read_scanlines需要一组指向扫描线的指针。     *这里的数组只有一个元素长,但你可以要求一次扫描线一次,如果这样更方便。     */    (void) jpeg_read_scanlines(&cinfo, buffer, 1);    /*假设put_scanline_someplace需要一个指针和样本计数。*/    put_scanline_someplace(buffer[0], row_stride);  }  /*步骤7:完成减压*/  (void) jpeg_finish_decompress(&cinfo);     /*我们可以忽略返回值,因为暂停是不可能的与stdio数据源。*/      /*第8步:释放JPEG解压缩对象*/   /*这是一个重要的步骤,因为它会释放大量的内存。*/  jpeg_destroy_decompress(&cinfo);  /*在finish_decompress之后,我们可以关闭输入文件。   *这里我们推迟它,直到没有更多的JPEG错误是可能的,以便简化上面的setjmp错误逻辑。   */  fclose(infile); /*此时,您可能需要检查是否有损坏的数据发生警告(测试jerr.pub.num_warnings是否为零)*/  return 1;}

原创粉丝点击