djiparsetxt
parseRecord_JPEG.cpp
Go to the documentation of this file.
1 /**********
2 This program is free software: you can redistribute it and/or modify
3 it under the terms of the GNU General Public License as published by
4 the Free Software Foundation, either version 3 of the License, or
5 (at your option) any later version.
6 
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
11 
12 You should have received a copy of the GNU General Public License
13 along with this program. If not, see <http://www.gnu.org/licenses/>.
14 **********/
15 /*
16  A C++ program to parse DJI's ".txt" log files (recorded by the "DJI Go 4" app).
17  Version 2021-05-20
18 
19  Copyright (c) 2021 Live Networks, Inc. All rights reserved.
20  For the latest version of this program (and more information), visit http://djilogs.live555.com
21 
22  Parsing JPEG records within DJI ".txt" files.
23  Implementation.
24 */
25 
27 
28 #include <stdio.h>
29 #include <string.h>
30 
31 #define JPEG_SOI_BYTE 0xD8
32 #define JPEG_SOI ((0xFF<<8)|JPEG_SOI_BYTE)
33 #define JPEG_EOI 0xFFD9
34 
36 
37 static char outputJPGFilenamePrefix[] = "embeddedImage";
38 
39 static FILE* openOutputJPGFile() {
40  static unsigned jpgFileNumber = 0;
41  char outputFileName[strlen(outputJPGFilenamePrefix) + 100];
42  sprintf(outputFileName, "embedded%d.jpg", ++jpgFileNumber);
43  FILE* outputFid = fopen(outputFileName, "wb");
44  if (outputFid == NULL) {
45  fprintf(stderr, "Failed to open output JPG file \"%s\"\n", outputFileName);
46  } else {
47  fprintf(stderr, "\tOutputting embedded JPEG image to the file \"%s\"\n", outputFileName);
48 
49  // Begin by writing the initial JPEG SOI code:
50  fputc(JPEG_SOI>>8, outputFid); fputc(JPEG_SOI, outputFid);
51  }
52 
53  return outputFid;
54 }
55 
56 int RecordAndDetailsParser::parseRecord_JPEG(u_int8_t const*& ptr, u_int8_t const* limit) {
57  // Skip the first two bytes (both zero) in the record:
58  (void)get2BytesBE(ptr, limit);
59 
60  if (ptr == limit) return 1; // We're done; there are no JPEG images in the record
61 
62  // The next two bytes should be the JPEG 'start of image' code:
63  if (get2BytesBE(ptr, limit) != JPEG_SOI) {
64  // Unknown contents. Skip all bytes up to and including the next 0xFF (or until "limit"):
65  while (ptr < limit && *ptr++ != 0xFF) {}
66  return 1;
67  }
68 
69  // The JPEG data is all following data, up to (and including) the next JPEG 'end of image' code,
70  // that's not then immediately followed by a JPEG 'start of image' code:
71  FILE* outputFid = NULL;
72  if (outputJPGFiles) {
73  outputFid = openOutputJPGFile();
74  if (outputFid == NULL) return 0;
75  }
76 
77  while (1) {
78  u_int16_t next2Bytes = get2BytesBE(ptr, limit);
79  if (next2Bytes == JPEG_EOI) {
80  if (outputJPGFiles) {
81  // We've finished writing the JPG file:
82  fputc(JPEG_EOI>>8, outputFid); fputc(JPEG_EOI, outputFid);
83  fclose(outputFid);
84  }
85 
86  // Look for an immediately following JPEG 'start of image' code (if there's more data left):
87  if (ptr == limit) return 1; // we're done
88  next2Bytes = get2BytesBE(ptr, limit);
89  if (next2Bytes == JPEG_SOI) {
90  if (outputJPGFiles) {
91  outputFid = openOutputJPGFile();
92  if (outputFid == NULL) return 0;
93  }
94  } else {
95  ptr -= 2;
96  return 1;
97  }
98  } else {
99  // Output the first byte, then continue:
100  if (outputJPGFiles) {
101  u_int8_t firstByte = next2Bytes >> 8;
102  fputc(firstByte, outputFid);
103  }
104  --ptr;
105  }
106  }
107 
108  return 0; // never reached
109 }
static char outputJPGFilenamePrefix[]
static FILE * openOutputJPGFile()
int outputJPGFiles
int parseRecord_JPEG(u_int8_t const *&ptr, u_int8_t const *limit)
#define JPEG_EOI
#define JPEG_SOI
u_int16_t get2BytesBE(u_int8_t const *&ptr, u_int8_t const *limit)