• C/C++判断某张jpg图片是否完整


    本文转自:https://blog.csdn.net/10km/article/details/82263274

    关于jpg图片的编码格式可以在网上找资料,本文主要用一段程序实现如何识别一张jpg图片是否完整。

      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <stdint.h>
      4 #include <stdbool.h>
      5 #include <iostream>
      6 
      7 using namespace std;
      8 
      9 
     10 static inline uint16_t archswap16(uint16_t D) {
     11     return((D << 8) | (D >> 8));
     12 }
     13 // gcc 预定义宏判断大小端
     14 #if __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__
     15 #define arch_swap_be16(X)        archswap16(X)
     16 #else
     17 #define arch_swap_be16(X)        (X)
     18 #endif
     19 
     20 /**
     21 * 从文件流中读取一个大端的16位整数,
     22 * 读取成功返回true,否则返回false
     23 */
     24 static bool read_be16(FILE *stream, /*uint16_t *value*/uint8_t *value)
     25 {
     26     if (sizeof(*value) != fread(value, sizeof(*value), 1, stream))
     27         return false;
     28     *value = (arch_swap_be16(*value));
     29     return true;
     30 }
     31 
     32 /*
     33 * Common JPEG markers(JPEG标记定义)
     34 * 参见 https://en.wikipedia.org/wiki/JPEG
     35 * */
     36 #define JMK_SOI         0xFFD8     /* Start Of Image */
     37 #define JMK_SOF0        0xFFC0     /* Start Of Frame (baseline DCT) */
     38 #define JMK_SOF2        0xFFC2     /* Start Of Frame (progressive DCT) */
     39 #define JMK_DHT         0xFFC4     /* Define Huffman Table(s) */
     40 #define JMK_DQT         0xFFDB     /* Define Quantization Table(s) */
     41 #define JMK_DRI         0xFFDD     /* Define Restart Interval */
     42 #define JMK_SOS         0xFFDA     /* Start Of Scan */
     43 #define JMK_RST_mask    0xFFD0     /* mask of Restart */
     44 #define JMK_APP_mask    0xFFE0     /* mask of Application-specific */
     45 #define JMK_COM         0xFFFE     /* Comment */
     46 #define JMK_EOI         0xFFD9     /* End Of Image */
     47 
     48 /**
     49 * 判断文件流是否为JPEG格式图像.
     50 * 逻辑说明:循环从文件流中读取 JPEG 标记,直到遇到SOF0,SOF2标记,就返回true,否则返回false.
     51 */
     52 bool check_jpg(FILE* stream)
     53 {
     54     //uint16_t jpeg_marker;
     55     uint8_t jpeg_marker;
     56     if (!stream)
     57         return false;
     58     for (; read_be16(stream, &jpeg_marker) /* 读取一个JPEG标记 */;)
     59     {
     60         /* 当前标记的数据长度(不含标记本身) */
     61         //uint16_t payload = 1; /* 设置为0或1用于指定当前JPEG 标记是否有附加数据*/
     62         uint8_t payload = 1; /* 设置为0或1用于指定当前JPEG 标记是否有附加数据*/
     63         switch (jpeg_marker)
     64         {
     65         case JMK_SOI:
     66             payload = 0; /* no payload,没有附加数据 */
     67             break;
     68         case JMK_SOF0:
     69         case JMK_SOF2:
     70             return true; /* 找到SOF0,SOF2 marker,确认为JPEG 格式*/
     71         case JMK_DHT:
     72         case JMK_DQT:
     73         case JMK_DRI:
     74         case JMK_SOS:
     75         case JMK_COM:
     76             break;
     77         case JMK_EOI:
     78             return false; /* not JPEG image*/
     79         default:
     80             if ((0XFFF8 & jpeg_marker) == JMK_RST_mask) {
     81                 payload = 0; /* RST0~7(FFD0~FFD7),no payload */
     82             }
     83             else if ((0XFFF0 & jpeg_marker) == JMK_APP_mask) {
     84                 /* APP0~APP15,do nothing */
     85             }
     86             else
     87                 return false; /* not JPEG image*/
     88         }
     89         if (payload) {
     90             /*读取 JPEG 标记之后的附加数据长度字段,根据这个字段的值移动文件游标位置跳到下一个 JPEG 标记 */
     91             if (!read_be16(stream, &payload))
     92                 return false; /* not JPEG image*/
     93             fseek(stream, payload - sizeof(payload), SEEK_CUR);
     94         }
     95     }
     96     return false; /* not JPEG image*/
     97 }
     98 
     99 int main(void)
    100 {
    101     //保存输入图像文件名和输出图像文件名
    102     char InImgName[10];
    103     //图像数据长度
    104     int length;
    105     //文件指针
    106     FILE* fp;
    107     //输入要读取的图像名
    108     cout << "Enter Image name:";
    109     cin >> InImgName;
    110     //以二进制方式打开图像
    111     if ((fp = fopen(InImgName, "rb")) == NULL)
    112     {
    113         cout << "Open image failed!" << endl;
    114         exit(0);
    115     }
    116     rewind(fp);
    117     if (check_jpg(fp)) {
    118         cout << "jpg file" << endl;
    119     }
    120     else {
    121         cout << "no jpg file" << endl;
    122     }
    123 
    124     fclose(fp);
    125 
    126     system("pause");
    127 
    128     return 0;
    129 }
  • 相关阅读:
    【原创】go语言学习(十六)接口
    【原创】go语言学习(十五)IO操作2
    【原创】go语言学习(十四)IO操作1
    【原创】go语言学习(十三)struct介绍2
    【原创】go语言学习(十二)struct介绍1
    【原创】go语言学习(十一)package简介
    【原创】sed正则表达式替换
    【原创】go语言学习(十)Map类型
    【原创】go语言学习(九)指针类型
    【原创】go语言学习(八)切片
  • 原文地址:https://www.cnblogs.com/liangzige/p/15172324.html
Copyright © 2020-2023  润新知