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 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM