159 {
160 FILE* fp = fopen(jpegPath, "rb");
161 if (!fp)
safe_exit(
"Cannot open input JPEG file.");
162
163 std::vector<unsigned char> iccData;
164 unsigned char marker[2];
165 bool found = false;
166
167
168
169
170 while (fread(marker, 1, 2, fp) == 2) {
171 if (marker[0] != 0xFF) break;
172 if (marker[1] == 0xD9) break;
173
174 unsigned short len = 0;
175 if (fread(&len, 2, 1, fp) != 1) break;
176 len = ntohs(len);
177
178 if (len < 2) break;
179 std::vector<unsigned char> segment(len - 2);
180 if (fread(segment.data(), 1, segment.size(), fp) != segment.size())
181 break;
182
183 printf("[INFO] Scanning segment 0x%02X, length: %u bytes\n", marker[1], len);
184
185
186
187
188 if (marker[1] == 0xE2 && len > 16) {
189 if (memcmp(segment.data(), "ICC_PROFILE\0", 12) == 0) {
190 unsigned char* dataStart = segment.data() + 14;
191 size_t dataLen = segment.size() - 14;
192 iccData.insert(iccData.end(), dataStart, dataStart + dataLen);
193 printf("[INFO] Found ICC_PROFILE in APP2 segment.\n");
194 found = true;
195 break;
196 }
197 }
198
199
200
201
202 if (marker[1] >= 0xE0 && marker[1] <= 0xEF) {
203 for (size_t i = 0; i + 4 < segment.size(); ++i) {
204 if (memcmp(&segment[i], "acsp", 4) == 0) {
205 iccData.insert(iccData.end(), segment.begin() + i, segment.end());
206 printf("[INFO] Found 'acsp' ICC magic in APP segment 0x%02X at offset %zu.\n", marker[1], i);
207 found = true;
208 goto done;
209 }
210 }
211 }
212 }
213
214
215
216
217 if (!found) {
218 std::ifstream file(jpegPath, std::ios::binary);
219 if (!file) {
221 return false;
222 }
223
224 std::vector<unsigned char> raw((std::istreambuf_iterator<char>(file)),
225 std::istreambuf_iterator<char>());
226
227 for (size_t i = 0; i + 4 < raw.size(); ++i) {
228 if (memcmp(&raw[i], "acsp", 4) == 0) {
229 iccData.insert(iccData.end(), raw.begin() + i, raw.end());
230 printf("[INFO] Fallback: Found 'acsp' in raw file at offset %zu.\n", i);
231 found = true;
232 break;
233 }
234 }
235 }
236
237done:
238 fclose(fp);
239
240 if (iccData.empty()) {
242 return false;
243 }
244
245 FILE* out = fopen(iccOutPath, "wb");
246 if (!out)
safe_exit(
"Failed to open output ICC file.");
247 fwrite(iccData.data(), 1, iccData.size(), out);
248 fclose(out);
249
250 printf("[INFO] ICC profile extracted to: %s\n", iccOutPath);
251 return true;
252}
#define LOG_ERROR(msg)
Definition iccJpegDump.cpp:125
#define safe_exit(reason)
Definition iccJpegDump.cpp:126