btparser/cparser/tests/exp_lex/JPGTemplate.bt

1605 lines
41 KiB
Plaintext

1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45: LittleEndian ( ) ; BitfieldLeftToRight ( ) ;
46: BigEndian ( ) ; BitfieldLeftToRight ( ) ;
47:
48: local quad JpegFileEnd = 0 ;
49: local int colorId = 0 ;
50: local int colorSelect = 0 ;
51: local DWORD clr = 0 ;
52: local DWORD jetMap [ 6 * 3 ] = {
53: 0xCC , 0xFF , 0x33FF , 0x66FF , 0x99FF , 0xCCFF ,
54: 0xFFFF , 0x33FFCC , 0x66FF99 , 0x99FF66 , 0xCCFF33 , 0xFFFF00 ,
55: 0xFFCC00 , 0xFF9900 , 0xFF6600 , 0xFF3300 , 0xFF0000 , 0xCC0000
56: } ;
57: local char CameraMake [ 32 ] ;
58: local char CameraModel [ 40 ] ;
59:
60: local string stack_IFD_dirtype = "" ;
61:
62: enum IFD_dirtype {
63: IFD_TYPE_EXIF = 1 ,
64: IFD_TYPE_GEOTAG ,
65: IFD_TYPE_CASIO_QV_R62 ,
66: } ;
67:
68:
69:
70: void Stack_push ( string & s , int x )
71: {
72: s += ( char ) x ;
73: }
74:
75: void Stack_pop ( string & s )
76: {
77: s = SubStr ( s , 0 , Strlen ( s ) - 1 ) ;
78: }
79:
80: int Stack_top ( string & s )
81: {
82: return s [ Strlen ( s ) - 1 ] ;
83: }
84:
85: string ReadStringN ( int64 pos , int n )
86: {
87: local uchar s [ n ] ;
88: ReadBytes ( s , pos , n ) ;
89: return s ;
90: }
91:
92:
93:
94: void ChangeColor ( byte bChangeColor ) {
95: if ( bChangeColor == 1 ) { colorSelect ++ ; colorId = 0 ; }
96: clr = jetMap [ ( colorSelect % 3 ) * 6 + ( colorId % 6 ) ] ;
97: SetBackColor ( clr ) ;
98:
99: colorId ++ ;
100: }
101:
102:
103:
104: typedef enum < WORD > tagID
105: {
106: M_SOF0 = 0xFFC0 ,
107: M_SOF1 ,
108: M_SOF2 ,
109: M_SOF3 ,
110: M_DHT ,
111: M_SOF5 ,
112: M_SOF6 ,
113: M_SOF7 ,
114: M_JPG ,
115: M_SOF9 ,
116: M_SOF10 ,
117: M_SOF11 ,
118: M_DAC = 0xFFCC ,
119: M_SOF13 ,
120: M_SOF14 ,
121: M_SOF15 ,
122: M_RST0 = 0xFFD0 ,
123: M_RST1 , M_RST2 , M_RST3 , M_RST4 , M_RST5 , M_RST6 , M_RST7 ,
124: M_SOI = 0xFFD8 ,
125: M_EOI ,
126: M_SOS ,
127: M_DQT ,
128: M_DNL ,
129: M_DRI ,
130: M_DHP ,
131: M_EXP ,
132: M_APP0 = 0xFFE0 ,
133: M_APP1 ,
134: M_APP2 ,
135: M_APP3 ,
136: M_APP4 ,
137: M_APP5 ,
138: M_APP6 ,
139: M_APP7 ,
140: M_APP8 ,
141: M_APP9 ,
142: M_APP10 ,
143: M_APP11 ,
144: M_APP12 ,
145: M_APP13 ,
146: M_APP14 ,
147: M_APP15 ,
148: M_JPG0 = 0xFFF0 ,
149: M_JPG1 , M_JPG2 , M_JPG3 , M_JPG4 , M_JPG5 , M_JPG6 , M_JPGLS ,
150: M_JPG8 , M_JPG9 , M_JPG10 , M_JPG11 , M_JPG12 , M_JPG13 , M_JPG14 , M_JPG15 ,
151: M_COMM = 0xFFFE
152: } M_ID < format = hex > ;
153:
154:
155:
156:
157:
158: typedef enum < WORD > tagExifTag {
159:
160: InteropIndex = 0x1 ,
161: InteropVersion = 0x2 ,
162: SubfileType = 0xFE ,
163: OldSubfileType = 0xFF ,
164: ImageWidth = 0x100 ,
165: ImageHeight = 0x101 ,
166: BitsPerSample = 0x102 ,
167: Compression = 0x103 ,
168: PhotometricInterpretation = 0x106 ,
169: Thresholding = 0x107 ,
170: CellWidth = 0x108 ,
171: CellLength = 0x109 ,
172: FillOrder = 0x10A ,
173: DocumentName = 0x10D ,
174: ImageDescription = 0x10E ,
175: Make = 0x10F ,
176: Model = 0x110 ,
177: StripOffsets = 0x111 ,
178: Orientation = 0x112 ,
179: SamplesPerPixel = 0x115 ,
180: RowsPerStrip = 0x116 ,
181: StripByteCounts = 0x117 ,
182: MinSampleValue = 0x118 ,
183: MaxSampleValue = 0x119 ,
184: XResolution = 0x11A ,
185: YResolution = 0x11B ,
186: PlanarConfiguration = 0x11C ,
187: PageName = 0x11D ,
188: XPosition = 0x11E ,
189: YPosition = 0x11F ,
190: FreeOffsets = 0x120 ,
191: FreeByteCounts = 0x121 ,
192: GrayResponseUnit = 0x122 ,
193: GrayResponseCurve = 0x123 ,
194: T4Options = 0x124 ,
195: T6Options = 0x125 ,
196: ResolutionUnit = 0x128 ,
197: PageNumber = 0x129 ,
198: ColorResponseUnit = 0x12C ,
199: TransferFunction = 0x12D ,
200: Software = 0x131 ,
201: ModifyDate = 0x132 ,
202: Artist = 0x13B ,
203: HostComputer = 0x13C ,
204: Predictor = 0x13D ,
205: WhitePoint = 0x13E ,
206: PrimaryChromaticities = 0x13F ,
207: ColorMap = 0x140 ,
208: HalftoneHints = 0x141 ,
209: TileWidth = 0x142 ,
210: TileLength = 0x143 ,
211: TileOffsets = 0x144 ,
212: TileByteCounts = 0x145 ,
213: BadFaxLines = 0x146 ,
214: CleanFaxData = 0x147 ,
215: ConsecutiveBadFaxLines = 0x148 ,
216: SubIFD = 0x14A ,
217: InkSet = 0x14C ,
218: InkNames = 0x14D ,
219: NumberofInks = 0x14E ,
220: DotRange = 0x150 ,
221: TargetPrinter = 0x151 ,
222: ExtraSamples = 0x152 ,
223: SampleFormat = 0x153 ,
224: SMinSampleValue = 0x154 ,
225: SMaxSampleValue = 0x155 ,
226: TransferRange = 0x156 ,
227: ClipPath = 0x157 ,
228: XClipPathUnits = 0x158 ,
229: YClipPathUnits = 0x159 ,
230: Indexed = 0x15A ,
231: JPEGTables = 0x15B ,
232: OPIProxy = 0x15F ,
233: GlobalParametersIFD = 0x190 ,
234: ProfileType = 0x191 ,
235: FaxProfile = 0x192 ,
236: CodingMethods = 0x193 ,
237: VersionYear = 0x194 ,
238: ModeNumber = 0x195 ,
239: Decode = 0x1B1 ,
240: DefaultImageColor = 0x1B2 ,
241: JPEGProc = 0x200 ,
242: ThumbnailOffset = 0x201 ,
243: ThumbnailLength = 0x202 ,
244: JPEGRestartInterval = 0x203 ,
245: JPEGLosslessPredictors = 0x205 ,
246: JPEGPointTransforms = 0x206 ,
247: JPEGQTables = 0x207 ,
248: JPEGDCTables = 0x208 ,
249: JPEGACTables = 0x209 ,
250: YCbCrCoefficients = 0x211 ,
251: YCbCrSubSampling = 0x212 ,
252: YCbCrPositioning = 0x213 ,
253: ReferenceBlackWhite = 0x214 ,
254: StripRowCounts = 0x22F ,
255: ApplicationNotes = 0x2BC ,
256: RelatedImageFileFormat = 0x1000 ,
257: RelatedImageWidth = 0x1001 ,
258: RelatedImageLength = 0x1002 ,
259: ImageID = 0x800D ,
260: WangAnnotation = 0x80A4 ,
261: Matteing = 0x80E3 ,
262: DataType = 0x80E4 ,
263: ImageDepth = 0x80E5 ,
264: TileDepth = 0x80E6 ,
265: Model2 = 0x827D ,
266: CFARepeatPatternDim = 0x828D ,
267: CFAPattern2 = 0x828E ,
268: BatteryLevel = 0x828F ,
269: Copyright = 0x8298 ,
270: ExposureTime = 0x829A ,
271: FNumber = 0x829D ,
272: PixelScale = 0x830E ,
273: IPTC_NAA = 0x83BB ,
274: IntergraphPacketData = 0x8474 ,
275: IntergraphFlagRegisters = 0x847F ,
276: IntergraphMatrix = 0x8480 ,
277: ModelTiePoint = 0x8482 ,
278: Site = 0x84E0 ,
279: ColorSequence = 0x84E1 ,
280: IT8Header = 0x84E2 ,
281: RasterPadding = 0x84E3 ,
282: BitsPerRunLength = 0x84E4 ,
283: BitsPerExtendedRunLength = 0x84E5 ,
284: ColorTable = 0x84E6 ,
285: ImageColorIndicator = 0x84E7 ,
286: BackgroundColorIndicator = 0x84E8 ,
287: ImageColorValue = 0x84E9 ,
288: BackgroundColorValue = 0x84EA ,
289: PixelIntensityRange = 0x84EB ,
290: TransparencyIndicator = 0x84EC ,
291: ColorCharacterization = 0x84ED ,
292: HCUsage = 0x84EE ,
293: IPTC_NAA2 = 0x8568 ,
294: ModelTransform = 0x85D8 ,
295: PhotoshopSettings = 0x8649 ,
296: ExifOffset = 0x8769 ,
297: ICC_Profile = 0x8773 ,
298: ImageLayer = 0x87AC ,
299: GeoTiffDirectory = 0x87AF ,
300: GeoTiffDoubleParams = 0x87B0 ,
301: GeoTiffAsciiParams = 0x87B1 ,
302: ExposureProgram = 0x8822 ,
303: SpectralSensitivity = 0x8824 ,
304: GPSInfo = 0x8825 ,
305: ISO = 0x8827 ,
306: OptoElectricConvFactor = 0x8828 ,
307: Interlace = 0x8829 ,
308: TimeZoneOffset = 0x882A ,
309: SelfTimerMode = 0x882B ,
310: FaxRecvParams = 0x885C ,
311: FaxSubAddress = 0x885D ,
312: FaxRecvTime = 0x885E ,
313: ExifVersion = 0x9000 ,
314: DateTimeOriginal = 0x9003 ,
315: CreateDate = 0x9004 ,
316: ComponentsConfiguration = 0x9101 ,
317: CompressedBitsPerPixel = 0x9102 ,
318: ShutterSpeedValue = 0x9201 ,
319: ApertureValue = 0x9202 ,
320: BrightnessValue = 0x9203 ,
321: ExposureCompensation = 0x9204 ,
322: MaxApertureValue = 0x9205 ,
323: SubjectDistance = 0x9206 ,
324: MeteringMode = 0x9207 ,
325: LightSource = 0x9208 ,
326: Flash = 0x9209 ,
327: FocalLength = 0x920A ,
328: FlashEnergy = 0x920B ,
329: SpatialFrequencyResponse = 0x920C ,
330: Noise = 0x920D ,
331: FocalPlaneXResolution = 0x920E ,
332: FocalPlaneYResolution = 0x920F ,
333: FocalPlaneResolutionUnit = 0x9210 ,
334: ImageNumber = 0x9211 ,
335: SecurityClassification = 0x9212 ,
336: ImageHistory = 0x9213 ,
337: SubjectLocation = 0x9214 ,
338: ExposureIndex = 0x9215 ,
339: TIFF_EPStandardID = 0x9216 ,
340: SensingMethod = 0x9217 ,
341: StoNits = 0x923F ,
342: MakerNote = 0x927C ,
343: UserComment = 0x9286 ,
344: SubSecTime = 0x9290 ,
345: SubSecTimeOriginal = 0x9291 ,
346: SubSecTimeDigitized = 0x9292 ,
347: ImageSourceData = 0x935C ,
348: XPTitle = 0x9C9B ,
349: XPComment = 0x9C9C ,
350: XPAuthor = 0x9C9D ,
351: XPKeywords = 0x9C9E ,
352: XPSubject = 0x9C9F ,
353: FlashpixVersion = 0xA000 ,
354: ColorSpace = 0xA001 ,
355: ExifImageWidth = 0xA002 ,
356: ExifImageLength = 0xA003 ,
357: RelatedSoundFile = 0xA004 ,
358: InteropOffset = 0xA005 ,
359: FlashEnergy2 = 0xA20B ,
360: SpatialFrequencyResponse2 = 0xA20C ,
361: Noise2 = 0xA20D ,
362: FocalPlaneXResolution2 = 0xA20E ,
363: FocalPlaneYResolution2 = 0xA20F ,
364: FocalPlaneResolutionUnit2 = 0xA210 ,
365: ImageNumber2 = 0xA211 ,
366: SecurityClassification2 = 0xA212 ,
367: ImageHistory2 = 0xA213 ,
368: SubjectLocation2 = 0xA214 ,
369: ExposureIndex2 = 0xA215 ,
370: TIFF_EPStandardID2 = 0xA216 ,
371: SensingMethod2 = 0xA217 ,
372: FileSource = 0xA300 ,
373: SceneType = 0xA301 ,
374: CFAPattern = 0xA302 ,
375: CustomRendered = 0xA401 ,
376: ExposureMode = 0xA402 ,
377: WhiteBalance = 0xA403 ,
378: DigitalZoomRatio = 0xA404 ,
379: FocalLengthIn35mmFormat = 0xA405 ,
380: SceneCaptureType = 0xA406 ,
381: GainControl = 0xA407 ,
382: Contrast = 0xA408 ,
383: Saturation = 0xA409 ,
384: Sharpness = 0xA40A ,
385: DeviceSettingDescription = 0xA40B ,
386: SubjectDistanceRange = 0xA40C ,
387: ImageUniqueID = 0xA420 ,
388: GDALMetadata = 0xA480 ,
389: GDALNoData = 0xA481 ,
390: Gamma = 0xA500 ,
391: FilmProductCode = 0xC350 ,
392: ImageSourceEK = 0xC351 ,
393: CaptureConditionsPAR = 0xC352 ,
394: CameraOwner = 0xC353 ,
395: SerialNumber = 0xC354 ,
396: UserSelectGroupTitle = 0xC355 ,
397: DealerIDNumber = 0xC356 ,
398: CaptureDeviceFID = 0xC357 ,
399: EnvelopeNumber = 0xC358 ,
400: FrameNumber = 0xC359 ,
401: FilmCategory = 0xC35A ,
402: FilmGencode = 0xC35B ,
403: ModelAndVersion = 0xC35C ,
404: FilmSize = 0xC35D ,
405: SBA_RGBShifts = 0xC35E ,
406: SBAInputImageColorspace = 0xC35F ,
407: SBAInputImageBitDepth = 0xC360 ,
408: SBAExposureRecord = 0xC361 ,
409: UserAdjSBA_RGBShifts = 0xC362 ,
410: ImageRotationStatus = 0xC363 ,
411: RollGuidElements = 0xC364 ,
412: MetadataNumber = 0xC365 ,
413: EditTagArray = 0xC366 ,
414: Magnification = 0xC367 ,
415: NativeXResolution = 0xC36C ,
416: NativeYResolution = 0xC36D ,
417: KodakEffectsIFD = 0xC36E ,
418: KodakBordersIFD = 0xC36F ,
419: NativeResolutionUnit = 0xC37A ,
420: SourceImageDirectory = 0xC418 ,
421: SourceImageFileName = 0xC419 ,
422: SourceImageVolumeName = 0xC41A ,
423: OceScanjobDesc = 0xC427 ,
424: OceApplicationSelector = 0xC428 ,
425: OceIDNumber = 0xC429 ,
426: OceImageLogic = 0xC42A ,
427: Annotations = 0xC44F ,
428: PrintQuality = 0xC46C ,
429: ImagePrintStatus = 0xC46E ,
430: PrintIM = 0xC4A5 ,
431: DNGVersion = 0xC612 ,
432: DNGBackwardVersion = 0xC613 ,
433: UniqueCameraModel = 0xC614 ,
434: LocalizedCameraModel = 0xC615 ,
435: CFAPlaneColor = 0xC616 ,
436: CFALayout = 0xC617 ,
437: LinearizationTable = 0xC618 ,
438: BlackLevelRepeatDim = 0xC619 ,
439: BlackLevel = 0xC61A ,
440: BlackLevelDeltaH = 0xC61B ,
441: BlackLevelDeltaV = 0xC61C ,
442: WhiteLevel = 0xC61D ,
443: DefaultScale = 0xC61E ,
444: DefaultCropOrigin = 0xC61F ,
445: DefaultCropSize = 0xC620 ,
446: ColorMatrix1 = 0xC621 ,
447: ColorMatrix2 = 0xC622 ,
448: CameraCalibration1 = 0xC623 ,
449: CameraCalibration2 = 0xC624 ,
450: ReductionMatrix1 = 0xC625 ,
451: ReductionMatrix2 = 0xC626 ,
452: AnalogBalance = 0xC627 ,
453: AsShotNeutral = 0xC628 ,
454: AsShotWhiteXY = 0xC629 ,
455: BaselineExposure = 0xC62A ,
456: BaselineNoise = 0xC62B ,
457: BaselineSharpness = 0xC62C ,
458: BayerGreenSplit = 0xC62D ,
459: LinearResponseLimit = 0xC62E ,
460: DNGCameraSerialNumber = 0xC62F ,
461: DNGLensInfo = 0xC630 ,
462: ChromaBlurRadius = 0xC631 ,
463: AntiAliasStrength = 0xC632 ,
464: ShadowScale = 0xC633 ,
465: DNGPrivateData = 0xC634 ,
466: MakerNoteSafety = 0xC635 ,
467: CalibrationIlluminant1 = 0xC65A ,
468: CalibrationIlluminant2 = 0xC65B ,
469: BestQualityScale = 0xC65C ,
470: AliasLayerMetadata = 0xC660 ,
471: OwnerName = 0xFDE8 ,
472: SerialNumber2 = 0xFDE9 ,
473: Lens = 0xFDEA ,
474: RawFile = 0xFE4C ,
475: Converter = 0xFE4D ,
476: WhiteBalance2 = 0xFE4E ,
477: Exposure = 0xFE51 ,
478: Shadows = 0xFE52 ,
479: Brightness = 0xFE53 ,
480: Contrast2 = 0xFE54 ,
481: Saturation2 = 0xFE55 ,
482: Sharpness2 = 0xFE56 ,
483: Smoothness = 0xFE57 ,
484: MoireFilter = 0xFE58 ,
485: } ExifTag ;
486:
487: enum < WORD > GeoTag {
488: GPSVersionID ,
489: GPSLatitudeRef ,
490: GPSLatitude ,
491: GPSLongitudeRef ,
492: GPSLongitude ,
493: GPSAltitudeRef ,
494: GPSAltitude ,
495: GPSTimeStamp ,
496: GPSSatellites ,
497: GPSStatus ,
498: GPSMeasureMode ,
499: GPSDOP ,
500: GPSSpeedRef ,
501: GPSSpeed ,
502: GPSTrackRef ,
503: GPSTrack ,
504: GPSImgDirectionRef ,
505: GPSImgDirection ,
506: GPSMapDatum ,
507: GPSDestLatitudeRef ,
508: GPSDestLatitude ,
509: GPSDestLongitudeRef ,
510: GPSDestLongitude ,
511: GPSDestBearingRef ,
512: GPSDestBearing ,
513: GPSDestDistanceRef ,
514: GPSDestDistance ,
515: GPSProcessingMehotd ,
516: GPSAreaInformation ,
517: GPSDateStamp ,
518: GPSDifferential ,
519: } ;
520:
521:
522:
523: typedef enum < WORD > tagCasioTag2 {
524: PreviewThumbnailDimensions = 0x2 ,
525: PreviewThumbnailSize = 0x3 ,
526: PreviewThumbnailOffset = 0x4 ,
527: CSQualityMode = 0x8 ,
528: CsImageSize = 0x9 ,
529: CSFocusMode = 0xD ,
530: CsIsoSensitivity = 0x14 ,
531: CsWhiteBalance = 0x19 ,
532: CsFocalLength = 0x1D ,
533: CsSaturation = 0x1F ,
534: CsContrast = 0x20 ,
535: CsSharpness = 0x21 ,
536: CsPrintImageMatchingInfo = 0xE00 ,
537: CasioPreviewThumbnail = 0x2000 ,
538: CsWhiteBalanceBias = 0x2011 ,
539: CsFlashMode = 0x2012 ,
540: CsObjectDistance = 0x2022 ,
541: CsFlashDistance = 0x2034 ,
542: CsRecordMode = 0x3000 ,
543: CsSelfTimer = 0x3001 ,
544: CsQuality = 0x3002 ,
545: CsMeteringMode2 = 0x3003 ,
546: CsTimeZone = 0x3006 ,
547: CsBestshotMode = 0x3007 ,
548: CsCCDISOSensitivity = 0x3014 ,
549: CsColourMode = 0x3015 ,
550: CsEnhancement = 0x3016 ,
551: CsFilter = 0x3017 ,
552: } CasioTag2 ;
553:
554:
555:
556:
557: typedef uint32 DC_UINT32 ;
558: typedef int32 DC_SINT32 ;
559: typedef float DC_FLOAT32 ;
560:
561: typedef struct tgCifDirEntry {
562: uint16 storage_method : 2 ;
563: uint16 data_type : 3 ;
564: uint16 id_code : 11 < format = hex > ;
565: if ( storage_method == kStg_InHeapSpace ) {
566: DWORD sData ;
567: DWORD oData ;
568: } else {
569: switch ( data_type << 11 | id_code ) {
570: case kTC_ImageFormat :
571: DC_UINT32 fileFormat ;
572: DC_FLOAT32 targetCompressionRatio ;
573: break ;
574: default :
575: byte data [ 8 ] ;
576: break ;
577: }
578: }
579: } CifDirEntry < read = ReadCifDirEntry > ;
580:
581: enum CIFFTagStg {
582: kStg_InHeapSpace ,
583: kStg_InRecordEntry ,
584: kStg_reversed2 ,
585: kStg_reversed3 ,
586: } ;
587:
588: enum CIFFTagDataType {
589: kDT_BYTE = 0x0 ,
590: kDT_ASCII = 0x800 ,
591: kDT_WORD = 0x1000 ,
592: kDT_DWORD = 0x1800 ,
593: kDT_BYTE2 = 0x2000 ,
594: kDT_HeapTypeProperty1 = 0x2800 ,
595: kDT_HeapTypeProperty2 = 0x3000 ,
596: } ;
597:
598: enum < uint16 > CIFFTagType {
599: kTC_Null = 0 ,
600: kTC_Free ,
601: kTC_ExFree ,
602:
603: kTC_Description = 0x805 ,
604: kTC_ModelName = 0x80A ,
605: kTC_FirmwareVersion = 0x80B ,
606: kTC_ComponentVersion = 0x80C ,
607: kTC_ROMOperationMode = 0x80D ,
608: kTC_OwnerName = 0x810 ,
609: kTC_ImageFileName = 0x816 ,
610: kTC_ThumbnailFileName = 0x817 ,
611:
612: kTC_TargetImageType = 0x100A ,
613: kTC_SR_ReleaseMethod = 0x1010 ,
614: kTC_SR_ReleaseTiming = 0x1011 ,
615: kTC_ReleaseSetting = 0x1016 ,
616: kTC_BodySensitivity = 0x101C ,
617:
618: kTC_ImageFormat = 0x1803 ,
619: kTC_RecordID = 0x1804 ,
620: kTC_SelfTimerTime = 0x1806 ,
621: kTC_SR_TargetDistanceSetting = 0x1807 ,
622: kTC_BodyID = 0x180B ,
623: kTC_CapturedTime = 0x180E ,
624: kTC_ImageSpec = 0x1810 ,
625: kTC_SR_EF = 0x1813 ,
626: kTC_MI_EV = 0x1814 ,
627: kTC_SerialNumber = 0x1817 ,
628:
629: kTC_CameraObject = 0x2807 ,
630: kTC_ShootingRecord = 0x3002 ,
631: kTC_MeasuredInfo = 0x3003 ,
632: kTC_CameraSpecification = 0x3004 ,
633: } ;
634:
635: string ReadCifDirEntry ( CifDirEntry & e )
636: {
637: local string s ;
638: local uint16 tc = e . data_type << 11 | e . id_code ;
639: local CIFFTagType x = ( CIFFTagType ) tc ;
640: local CIFFTagStg stg = ( CIFFTagStg ) e . storage_method ;
641: local CIFFTagDataType dt = ( CIFFTagDataType ) ( e . data_type << 11 ) ;
642: if ( EnumToString ( x ) != "" ) {
643: SPrintf ( s , "%s, %s" ,
644: EnumToString ( stg ) ,
645: EnumToString ( x ) ) ;
646: } else {
647: SPrintf ( s , "%s, %s, 0x%x" ,
648: EnumToString ( stg ) ,
649: EnumToString ( dt ) ,
650: e . id_code ) ;
651: }
652:
653: return s ;
654: }
655:
656: typedef struct tgCDir {
657: ChangeColor ( 0 ) ;
658:
659: local quad myOffset = cDirOffset ;
660: local DWORD S = ReadInt ( myOffset + cDirSize - 4 ) ;
661: FSeek ( cDirOffset + S ) ;
662:
663: WORD nDirEntry ;
664:
665: ChangeColor ( 0 ) ;
666: CifDirEntry dirEntries [ nDirEntry ] < optimize = false > ;
667: DWORD szValues ;
668: local int i ;
669: for ( i = 0 ; i < nDirEntry ; i ++ ) {
670:
671: if ( dirEntries [ i ] . storage_method == kStg_InHeapSpace ) {
672:
673: FSeek ( myOffset + dirEntries [ i ] . oData ) ;
674: ChangeColor ( 0 ) ;
675:
676: switch ( dirEntries [ i ] . data_type << 11 | dirEntries [ i ] . id_code ) {
677: case kTC_ImageSpec :
678: struct {
679: DC_UINT32 imageWidth ;
680: DC_UINT32 imageHeight ;
681: DC_FLOAT32 pixelAspectRatio ;
682: DC_SINT32 rotationAngle ;
683: DC_UINT32 componentBitDepth ;
684: DC_UINT32 colorBitDepth ;
685: DC_UINT32 colorBW ;
686: } DC_IMAGESPEC ;
687: break ;
688: default :
689: switch ( dirEntries [ i ] . data_type << 11 ) {
690: case kDT_BYTE :
691: struct {
692: byte bData [ dirEntries [ i ] . sData ] ;
693: } strBytes ;
694: break ;
695: case kDT_ASCII :
696: struct {
697: char sData [ dirEntries [ i ] . sData ] ;
698: } strStrings ;
699: break ;
700: case kDT_WORD :
701: struct {
702: WORD wData [ dirEntries [ i ] . sData >> 1 ] ;
703: } str2Bytes ;
704: break ;
705: case kDT_DWORD :
706: union {
707: DWORD dwData [ dirEntries [ i ] . sData >> 2 ] ;
708: DWORD flData [ dirEntries [ i ] . sData >> 2 ] ;
709: } str4Bytes ;
710: break ;
711: case kDT_HeapTypeProperty1 :
712: case kDT_HeapTypeProperty2 :
713: cDirOffset = dirEntries [ i ] . oData + myOffset ;
714: cDirSize = dirEntries [ i ] . sData ;
715: struct CDIR subDir ;
716: break ;
717: default :
718: struct {
719: char uData [ dirEntries [ i ] . sData ] ;
720: } strUnknown ;
721: break ;
722: }
723: break ;
724: }
725: }
726:
727: }
728:
729: } CDIR ;
730:
731:
732:
733: const local int dataFormatLength [ 13 ] = { 0 , 1 , 1 , 2 , 4 , 8 , 1 , 1 , 2 , 4 , 8 , 4 , 8 } ;
734:
735: typedef enum < WORD > tagDataFormat {
736: uByte = 1 ,
737: ascString ,
738: uShort ,
739: uLong ,
740: uRatio ,
741: sByte ,
742: undefined = 7 ,
743: sShort ,
744: sLong = 9 ,
745: sRatio ,
746: sFloat ,
747: dFloat ,
748: } DataFormat ;
749:
750:
751: typedef struct tgDIRENTRY {
752: ChangeColor ( 0 ) ;
753: switch ( Stack_top ( stack_IFD_dirtype ) ) {
754: case IFD_TYPE_EXIF :
755: ExifTag tagNumber ;
756: break ;
757: case IFD_TYPE_GEOTAG :
758: GeoTag tagNumber ;
759: break ;
760: case IFD_TYPE_CASIO_QV_R62 :
761: CasioTag2 tagNumber ;
762: break ;
763: }
764: DataFormat dataFormat ;
765: DWORD nComponent ;
766: local int j = 0 ;
767: local int length = - 1 ;
768:
769: if ( 1 <= dataFormat && dataFormat < 13 )
770: length = dataFormatLength [ dataFormat ] * nComponent ;
771: else {
772:
773: }
774:
775: if ( 1 <= dataFormat && dataFormat < 13 && 0 <= length && length <= 4 ) {
776: switch ( tagNumber ) {
777: case ExposureProgram :
778: enum < short > {
779: EP_Not_defined ,
780: EP_Manual ,
781: EP_Normal_program ,
782: EP_Aperture_priority ,
783: EP_Shutter_priority ,
784: EP_Creative_program ,
785: EP_Action_program ,
786: EP_Portrait_mode ,
787: EP_Landscape_mode ,
788: } ExposureProgram ;
789: break ;
790: case MeteringMode :
791: enum < short > {
792: MM_unknown ,
793: MM_Average ,
794: MM_CenterWeightedAverage ,
795: MM_Spot ,
796: MM_MultiSpot ,
797: MM_Pattern ,
798: MM_Partial ,
799: MM_other = 255 ,
800: } MeteringMode ;
801: break ;
802: case LightSource :
803: enum < short > {
804: LS_unknown ,
805: LS_Daylight ,
806: LS_Fluorescent ,
807: LS_Tungsten ,
808: LS_Flash ,
809: LS_Fine_weather = 9 ,
810: LS_Cloudy_weather ,
811: LS_Shade ,
812: LS_Daylight_fluorescent ,
813: LS_Day_white_fluorescent ,
814: LS_Cool_white_fluorescent ,
815: LS_White_fluorescent ,
816: LS_Standard_light_A ,
817: LS_Standard_light_B ,
818: LS_Standard_light_C ,
819: LS_D55 ,
820: LS_D65 ,
821: LS_D75 ,
822: LS_D50 ,
823: LS_ISO_studio_tungsten ,
824: LS_other_light_scoure = 255 ,
825: } LightSource ;
826: break ;
827: case Flash :
828: short unused : 9 ;
829: short red_eye_mode : 1 ;
830: short flash_function : 1 ;
831: short flash_mode : 2 ;
832: short flash_return : 2 ;
833: short flash_fired : 1 ;
834: break ;
835: case ExposureMode :
836: enum < short > {
837: EM_Auto_exposure ,
838: EM_Manual_exposure ,
839: EM_Auto_bracket ,
840: } ExposureMode ;
841: break ;
842: case WhiteBalance :
843: enum < short > {
844: WB_Auto_white_balance ,
845: WB_Manual_white_balance ,
846: } WhiteBalance ;
847: break ;
848: case SceneCaptureType :
849: enum < short > {
850: SCT_Standard ,
851: SCT_Landscape ,
852: SCT_Portrait ,
853: SCT_Night_scene ,
854: } SceneCaptureType ;
855: break ;
856: case SubjectDistanceRange :
857: enum < short > {
858: SDR_unknown ,
859: SDR_Macro ,
860: SDR_Close_view ,
861: SDR_Distant_view ,
862: } SubjectDistanceRange ;
863: break ;
864: default :
865: switch ( dataFormat ) {
866: case uByte :
867: struct {
868: uchar oneByteData [ nComponent ] ;
869: } strAscii ;
870: break ;
871: case ascString :
872: struct StrAscii1 {
873: char oneByteData [ nComponent ] ;
874: } strAscii < read = ReadAscString1 > ;
875: break ;
876: case undefined :
877: struct {
878: uchar oneByteData [ nComponent ] ;
879: } strAscii ;
880: break ;
881: case uShort :
882: for ( j = 0 ; j < nComponent ; j ++ )
883: ushort usValue ;
884: break ;
885: case uLong :
886: if ( nComponent == 1 )
887: ulong ulValue ;
888: break ;
889: case sByte :
890: struct {
891: char sBValue [ nComponent ] ;
892: } strSByte ;
893: break ;
894: case sShort :
895: struct {
896: short sisValue [ nComponent ] ;
897: } strSShort ;
898: break ;
899: case sLong :
900: if ( nComponent == 1 )
901: ulong siLValue ;
902: break ;
903: case sFloat :
904: if ( nComponent == 1 )
905: float flValue ;
906: break ;
907: }
908: break ;
909: }
910: if ( length != 4 )
911: uchar padding [ 4 - length ] ;
912: } else {
913: DWORD offsetData ;
914: }
915: } DIRENTRY < read = ReadDirEntry > ;
916:
917: string ReadDirEntry ( DIRENTRY & entry ) {
918: local char no [ 50 ] ;
919: SPrintf ( no , "Tag# = 0x%x (%s)" , entry . tagNumber , EnumToString ( entry . tagNumber ) ) ;
920: return no ;
921: }
922:
923:
924: typedef struct tgIFD {
925: WORD nDirEntry ;
926: DIRENTRY dirEntry [ nDirEntry ] < optimize = false > ;
927: DWORD nextIFDoffset ;
928: local int i = 0 ;
929: for ( i = 0 ; i < nDirEntry ; i ++ ) {
930: ChangeColor ( 0 ) ;
931: switch ( dirEntry [ i ] . tagNumber ) {
932: case Make :
933: ReadBytes ( CameraMake , offset + dirEntry [ i ] . offsetData , dirEntry [ i ] . nComponent ) ;
934: Printf ( "Maker: %s\n" , CameraMake ) ;
935: break ;
936: case Model :
937: ReadBytes ( CameraModel , offset + dirEntry [ i ] . offsetData , dirEntry [ i ] . nComponent ) ;
938: Printf ( "Model: %s\n" , CameraModel ) ;
939: break ;
940: }
941:
942:
943: if ( ! ( 1 <= dirEntry [ i ] . dataFormat && dirEntry [ i ] . dataFormat < 13 ) )
944: continue ;
945: if ( dataFormatLength [ dirEntry [ i ] . dataFormat ] * dirEntry [ i ] . nComponent <= 4 ) {
946: continue ;
947: }
948:
949: FSeek ( offset + dirEntry [ i ] . offsetData ) ;
950: switch ( dirEntry [ i ] . tagNumber ) {
951: default :
952: switch ( dirEntry [ i ] . dataFormat ) {
953: case ascString :
954: struct StrAscii {
955: char oneByteData [ dirEntry [ i ] . nComponent ] ;
956: } strAscii < read = ReadAscString > ;
957: break ;
958: case undefined :
959: struct {
960: uchar oneByteData [ dirEntry [ i ] . nComponent ] ;
961: } strAscii ;
962: break ;
963: case uShort :
964: struct {
965: ushort usValue [ dirEntry [ i ] . nComponent ] ;
966: } strUShort ;
967: break ;
968: case uLong :
969: struct {
970: ulong ulValue [ dirEntry [ i ] . nComponent ] ;
971: } strULong ;
972: break ;
973: case uRatio :
974: struct URatio {
975: struct {
976: DWORD num ;
977: DWORD den ;
978: } uRValue [ dirEntry [ i ] . nComponent ] ;
979: } strURatio < read = ReadURatio > ;
980: break ;
981: case sByte :
982: struct {
983: char sBValue [ dirEntry [ i ] . nComponent ] ;
984: } strSByte ;
985: break ;
986: case sShort :
987: struct {
988: short sisValue [ dirEntry [ i ] . nComponent ] ;
989: } strSShort ;
990: break ;
991: case sLong :
992: struct {
993: ulong siLValue [ dirEntry [ i ] . nComponent ] ;
994: } strSLong ;
995: break ;
996: case sRatio :
997: struct {
998: struct {
999: int num ;
1000: int den ;
1001: } siRValue [ dirEntry [ i ] . nComponent ] ;
1002: } strSRatio ;
1003: break ;
1004: case sFloat :
1005: struct {
1006: float flValue [ dirEntry [ i ] . nComponent ] ;
1007: } strsFloat ;
1008: break ;
1009: case dFloat :
1010: struct {
1011: double dFValue [ dirEntry [ i ] . nComponent ] ;
1012: } strdFloat ;
1013: break ;
1014: }
1015: }
1016: }
1017:
1018: for ( i = 0 ; i < nDirEntry ; i ++ ) {
1019: ChangeColor ( 0 ) ;
1020: switch ( dirEntry [ i ] . tagNumber ) {
1021: case ExifOffset :
1022: FSeek ( offset + dirEntry [ i ] . ulValue ) ;
1023: Stack_push ( stack_IFD_dirtype , IFD_TYPE_EXIF ) ;
1024: struct IFD subDir ;
1025: Stack_pop ( stack_IFD_dirtype ) ;
1026: break ;
1027: case GPSInfo :
1028: FSeek ( offset + dirEntry [ i ] . ulValue ) ;
1029: Stack_push ( stack_IFD_dirtype , IFD_TYPE_GEOTAG ) ;
1030: struct IFD subDir ;
1031: Stack_pop ( stack_IFD_dirtype ) ;
1032: break ;
1033: case InteropOffset :
1034: FSeek ( offset + dirEntry [ i ] . ulValue ) ;
1035: Stack_push ( stack_IFD_dirtype , IFD_TYPE_EXIF ) ;
1036: struct IFD subDir ;
1037: Stack_pop ( stack_IFD_dirtype ) ;
1038: break ;
1039: case MakerNote :
1040: if ( ! Strncmp ( "CASIO COMPUTER CO.,LTD" , CameraMake , 22 ) &&
1041: ! Strncmp ( "QV-R62" , CameraModel , 6 ) ) {
1042: FSeek ( offset + dirEntry [ i ] . ulValue ) ;
1043: struct {
1044: char Header [ 6 ] ;
1045: Stack_push ( stack_IFD_dirtype , IFD_TYPE_CASIO_QV_R62 ) ;
1046: struct IFD CasioIFD ;
1047: Stack_pop ( stack_IFD_dirtype ) ;
1048: } CasioMake ;
1049: }
1050: break ;
1051: case CasioPreviewThumbnail :
1052: FSeek ( offset + dirEntry [ i ] . ulValue ) ;
1053: Printf ( "Casio Thumbnail Offset = %#Lx\n" , offset + dirEntry [ i ] . ulValue ) ;
1054: local quad JpegFileEnd2 = JpegFileEnd ;
1055: JpegFileEnd = FTell ( ) + dirEntry [ i ] . nComponent ;
1056: struct JPGFILE CasioMakerThumbnail ;
1057: JpegFileEnd = JpegFileEnd2 ;
1058: break ;
1059: }
1060: }
1061: } IFD ;
1062:
1063: string ReadAscString1 ( StrAscii1 & s )
1064: {
1065: return s . oneByteData ;
1066: }
1067: string ReadAscString ( StrAscii & s )
1068: {
1069: return s . oneByteData ;
1070: }
1071:
1072: string ReadURatio ( URatio & ur )
1073: {
1074: local int i ;
1075: local string s ;
1076: local string result = "" ;
1077: for ( i = 0 ; exists ( ur . uRValue [ i ] ) ; i ++ ) {
1078: SPrintf ( s , "%d/%d" , ur . uRValue [ i ] . num , ur . uRValue [ i ] . den ) ;
1079: result += s + " " ;
1080: }
1081: return result ;
1082: }
1083:
1084:
1085: typedef struct tagApp0 {
1086: M_ID marker ;
1087: WORD szSection ;
1088:
1089: if ( ReadStringN ( FTell ( ) , 5 ) == "JFIF" ) {
1090:
1091: char App0Type [ 5 ] ;
1092: short versionHigh : 8 ;
1093: short versionLow : 8 ;
1094: ubyte units ;
1095: WORD Xdensity ;
1096: WORD Ydensity ;
1097: ubyte xThumbnail ;
1098: ubyte yThumbnail ;
1099: if ( xThumbnail != 0 && yThumbnail != 0 ) {
1100: struct {
1101: uchar r , g , b ;
1102: } rgb [ ( ushort ) xThumbnail * yThumbnail ] ;
1103: }
1104: } else if ( ReadStringN ( FTell ( ) , 5 ) == "JFXX" ) {
1105:
1106: char App0Type [ 5 ] ;
1107: byte extension_code < format = hex > ;
1108: switch ( extension_code ) {
1109: case 0x10 :
1110: local quad JpegFileEnd2 = JpegFileEnd ;
1111: JpegFileEnd = FTell ( ) + szSection - 8 ;
1112: struct JPGFILE thumbnail ;
1113: JpegFileEnd = JpegFileEnd2 ;
1114: break ;
1115: case 0x11 :
1116: ubyte xThumbnail ;
1117: ubyte yThumbnail ;
1118: struct {
1119: uchar r , g , b ;
1120: } palette [ 256 ] ;
1121: uchar pixel [ szSection - 8 ] ;
1122: break ;
1123: case 0x13 :
1124: ubyte xThumbnail ;
1125: ubyte yThumbnail ;
1126: struct {
1127: uchar r , g , b ;
1128: } pixel [ ( ushort ) xThumbnail * yThumbnail ] ;
1129: break ;
1130: default :
1131:
1132: char unknown [ szSection - 8 ] ;
1133: }
1134: } else if ( ( ReadStringN ( FTell ( ) , 2 ) == "II" || ReadStringN ( FTell ( ) , 2 ) == "MM" )
1135: && ReadStringN ( FTell ( ) + 6 , 8 ) == "HEAPJPGM" ) {
1136:
1137: local quad cDirSize = 0 ;
1138: local quad cDirOffset = 0 ;
1139: local quad cifOffset = FTell ( ) ;
1140:
1141: char ByteOrder [ 2 ] ;
1142: if ( ! Strncmp ( ByteOrder , "II" , 2 ) ) LittleEndian ( ) ;
1143: DWORD HeaderLength ;
1144: char type [ 4 ] ;
1145: char subtype [ 4 ] ;
1146:
1147:
1148: cDirOffset = HeaderLength + cifOffset ;
1149: cDirSize = szSection - 2 - HeaderLength ;
1150: CDIR APP0_Ciff ;
1151: BigEndian ( ) ;
1152: FSeek ( cifOffset + szSection - 2 ) ;
1153: }
1154: else {
1155:
1156: char unknown [ szSection - 2 ] ;
1157: }
1158: } APP0 ;
1159:
1160: typedef struct tgAPP1 {
1161: M_ID marker ;
1162: WORD szSection ;
1163:
1164: if ( ReadStringN ( FTell ( ) , 5 ) == "Exif" ) {
1165: char EXIF [ 6 ] ;
1166: local quad offset = FTell ( ) ;
1167: byte align [ 2 ] ;
1168: if ( align [ 0 ] == 'I' ) { LittleEndian ( ) ; }
1169: WORD tagMark ;
1170: DWORD offsetFirstIFD ;
1171: if ( offsetFirstIFD != 8 )
1172: FSeek ( offset + offsetFirstIFD ) ;
1173: ChangeColor ( 0 ) ;
1174: Stack_push ( stack_IFD_dirtype , IFD_TYPE_EXIF ) ;
1175: IFD ifdMainImage ;
1176: Stack_pop ( stack_IFD_dirtype ) ;
1177: if ( ifdMainImage . nextIFDoffset ) {
1178: FSeek ( offset + ifdMainImage . nextIFDoffset ) ;
1179: ChangeColor ( 0 ) ;
1180: Stack_push ( stack_IFD_dirtype , IFD_TYPE_EXIF ) ;
1181: IFD ifdThumbnailImage ;
1182: Stack_pop ( stack_IFD_dirtype ) ;
1183: local int i = 0 ;
1184: local int thumbOffset = 0 ;
1185: local int thumbLength = 0 ;
1186: local int compression = 10 ;
1187: for ( i ; i < ifdThumbnailImage . nDirEntry ; i ++ ) {
1188: switch ( ifdThumbnailImage . dirEntry [ i ] . tagNumber ) {
1189: case Compression :
1190: compression = ifdThumbnailImage . dirEntry [ i ] . usValue ;
1191: break ;
1192: case ThumbnailOffset :
1193: case StripOffsets :
1194: thumbOffset = ifdThumbnailImage . dirEntry [ i ] . ulValue ;
1195: break ;
1196: case ThumbnailLength :
1197: case StripByteCounts :
1198: thumbLength = ifdThumbnailImage . dirEntry [ i ] . ulValue ;
1199: break ;
1200: }
1201: }
1202: if ( thumbLength && thumbOffset ) {
1203: FSeek ( offset + thumbOffset ) ;
1204: Printf ( "Thumbnail Offset = %#Lx\n" , offset + thumbOffset ) ;
1205: if ( compression == 6 ) {
1206: local quad JpegFileEnd2 = JpegFileEnd ;
1207: JpegFileEnd = FTell ( ) + thumbLength ;
1208: struct JPGFILE thumbnail ;
1209: JpegFileEnd = JpegFileEnd2 ;
1210: }
1211: else
1212: char imageData [ thumbLength ] ;
1213: }
1214: }
1215: FSeek ( offset + szSection - 8 ) ;
1216: if ( align [ 0 ] == 'I' ) { BigEndian ( ) ; }
1217: } else if ( ReadStringN ( FTell ( ) , 29 ) == "http://ns.adobe.com/xap/1.0/" ) {
1218:
1219: char XAP [ 29 ] ;
1220: char remain [ szSection - 31 ] ;
1221: } else {
1222:
1223: char unknown [ szSection - 2 ] ;
1224: }
1225: } APP1 ;
1226:
1227: typedef struct tgAPP2 {
1228: M_ID marker ;
1229: WORD szSection ;
1230:
1231: if ( ReadStringN ( FTell ( ) , 5 ) == "FPXR" ) {
1232: char FPXR [ 5 ] ;
1233: uchar version ;
1234: char remain [ szSection - 8 ] ;
1235:
1236: } else if ( ReadStringN ( FTell ( ) , 12 ) == "ICC_PROFILE" ) {
1237: char ICC_PROFILE [ 12 ] ;
1238: uchar block_num ;
1239: uchar block_total ;
1240: char data [ szSection - 16 ] ;
1241: } else {
1242:
1243: char unknown [ szSection - 2 ] ;
1244: }
1245: } APP2 ;
1246:
1247: typedef struct tagAPP12 {
1248: M_ID marker ;
1249: WORD szSection ;
1250:
1251: if ( ReadStringN ( FTell ( ) , 5 ) == "Ducky" ) {
1252:
1253: char Ducky [ 5 ] ;
1254: local WORD s = szSection ;
1255: while ( s > 0 ) {
1256: struct {
1257: enum < uint16 > {
1258: DK_End ,
1259: DK_Quality ,
1260: DK_Comment ,
1261: DK_Copyright ,
1262: } tag ;
1263: if ( tag == DK_End )
1264: break ;
1265:
1266: uint16 len ;
1267:
1268: switch ( tag ) {
1269: case DK_End :
1270: break ;
1271: case DK_Quality :
1272: uint32 value ;
1273: break ;
1274: case DK_Comment :
1275: uint32 count ;
1276: char comment [ len - 4 ] ;
1277: break ;
1278: case DK_Copyright :
1279: uint32 count ;
1280: char comment [ len - 4 ] ;
1281: break ;
1282: default :
1283: char unknown [ len ] ;
1284: break ;
1285: }
1286: } entry ;
1287: if ( entry . tag == DK_End )
1288: break ;
1289: s -= sizeof ( entry ) ;
1290: }
1291: } else {
1292:
1293: char unknown [ szSection - 2 ] ;
1294: }
1295: } APP12 ;
1296:
1297: typedef struct tagAPP13 {
1298: M_ID marker ;
1299: WORD szSection ;
1300:
1301: if ( ReadStringN ( FTell ( ) , 14 ) == "Photoshop 3.0" ) {
1302:
1303: char photoshop30 [ 14 ] ;
1304: local int remainsize = szSection - 16 ;
1305: while ( remainsize > 0 ) {
1306: struct {
1307: char type [ 4 ] ;
1308: if ( type == "8BIM" ) {
1309: } else if ( type == "PHUT" || type == "DCSR" || type == "AgHg" ) {
1310: } else {
1311: char unknown [ remainsize - 4 ] ;
1312: break ;
1313: }
1314: enum < uint16 > {
1315: PS_IPTCData = 0x404 ,
1316: PS_JPEG_Quality = 0x406 ,
1317: PS_PhotoshopBGRThumbnail = 0x409 ,
1318: PS_CopyrightFlag = 0x40A ,
1319: PS_URL = 0x40B ,
1320: PS_PhotoshopThumbnail = 0x40C ,
1321: PS_ICC_Profile = 0x40F ,
1322: PS_GlobalAltitude = 0x419 ,
1323: PS_EXIFInfo = 0x422 ,
1324: PS_XMP = 0x424 ,
1325: PS_IPTCDigest = 0x425 ,
1326: PS_ClippingPathName = 0xBB7 ,
1327: } tag ;
1328: uchar namelen ;
1329: if ( namelen )
1330: char name [ namelen ] ;
1331: if ( namelen % 2 != 1 )
1332: char padding ;
1333: uint32 size ;
1334: if ( size )
1335: char data [ size ] ;
1336: if ( size % 2 != 0 )
1337: char padding ;
1338: } block ;
1339: remainsize -= sizeof ( block ) ;
1340: }
1341: } else if ( ReadStringN ( FTell ( ) , 9 ) == "Adobe_CM" ) {
1342: char adobe_cm [ 9 ] ;
1343: uchar AdobeCMType ;
1344: if ( szSection != 12 )
1345: char unknown [ szSection - 12 ] ;
1346: } else {
1347:
1348: char unknown [ szSection - 2 ] ;
1349: }
1350: } APP13 ;
1351:
1352: typedef struct tagAPP14 {
1353: M_ID marker ;
1354: WORD szSection ;
1355:
1356: if ( ReadStringN ( FTell ( ) , 5 ) == "Adobe" ) {
1357:
1358: char adobe [ 5 ] ;
1359: uint16 version ;
1360: uint16 flag0 ;
1361: uint16 flag1 ;
1362: uchar color_transform_code ;
1363: if ( FTell ( ) < szSection + startof ( szSection ) ) char unknown [ szSection + startof ( szSection ) - FTell ( ) ] ;
1364: } else {
1365:
1366: char unknown [ szSection - 2 ] ;
1367: }
1368: } APP14 ;
1369:
1370:
1371:
1372: typedef struct tagSOS {
1373: M_ID marker ;
1374: WORD szSection ;
1375: ubyte nr_comp ;
1376: ChangeColor ( 0 ) ;
1377: struct COMPSOS {
1378: ubyte AC : 4 ;
1379: ubyte DC : 4 ;
1380: } comp [ nr_comp ] ;
1381: uchar Ss ;
1382: uchar Se ;
1383: uchar Ah : 4 ;
1384: uchar Al : 4 ;
1385: } SOS ;
1386:
1387: typedef struct tagUNK {
1388: M_ID UnknownMarker ;
1389:
1390: WORD szSection ;
1391: if ( FTell ( ) + szSection - 2 >= JpegFileEnd ) {
1392: Warning ( "unknown section length pass the end of jpeg file" ) ;
1393: ubyte unknown [ JpegFileEnd - FTell ( ) ] ;
1394: } else {
1395: ubyte unknown [ szSection - 2 ] ;
1396: }
1397: } UNKNOWN ;
1398:
1399: typedef struct tagDHT {
1400: M_ID marker ;
1401: WORD szSection ;
1402: local WORD huffsz = szSection - 2 ;
1403: while ( huffsz > 0 ) {
1404: ChangeColor ( 0 ) ;
1405: struct Huffmann_Table {
1406: ubyte htInfo ;
1407: ubyte length [ 16 ] ;
1408: local int sumLen = 0 ;
1409: local int i = 0 ;
1410: for ( i ; i < 16 ; i ++ ) {
1411: sumLen += length [ i ] ;
1412: }
1413: ubyte HTV [ sumLen ] ;
1414: } huff_table ;
1415: huffsz -= sizeof ( huff_table ) ;
1416: }
1417: } DHT ;
1418:
1419: typedef struct tagDQT {
1420: M_ID marker ;
1421: WORD szSection ;
1422: local WORD qtsz = szSection - 2 ;
1423: while ( qtsz > 0 ) {
1424: ChangeColor ( 0 ) ;
1425: struct QuanTable {
1426: uchar Pq : 4 ;
1427: uchar Tq : 4 ;
1428: if ( Pq == 0 )
1429: byte qTable [ 64 ] ;
1430: else
1431: uint16 qTable [ 64 ] ;
1432: } qtable ;
1433: qtsz -= sizeof ( qtable ) ;
1434: }
1435: } DQT ;
1436:
1437: typedef struct tagDRI {
1438: M_ID marker ;
1439: WORD szSection ;
1440: WORD Ri ;
1441: } DRI ;
1442:
1443: typedef struct tagDHP {
1444: M_ID marker ;
1445: WORD szSection ;
1446: uchar P ;
1447: uint16 Y ;
1448: uint16 X ;
1449: uchar Nf ;
1450: struct {
1451: uchar id ;
1452: uchar h_factor : 4 ;
1453: uchar v_factor : 4 ;
1454: uchar Tq ;
1455: } component_param [ Nf ] ;
1456: } DHP ;
1457:
1458: typedef struct tgSOFx {
1459: M_ID marker ;
1460: WORD szSection ;
1461: ubyte precision ;
1462: WORD Y_image ;
1463: WORD X_image ;
1464: ubyte nr_comp ;
1465: ChangeColor ( 0 ) ;
1466: struct COMPS {
1467: ubyte compId ;
1468: ubyte Horz : 4 ;
1469: ubyte Vert : 4 ;
1470: ubyte compNr ;
1471: } comp [ nr_comp ] ;
1472: } SOFx ;
1473:
1474: typedef struct tagCOMMENT {
1475: M_ID CommentMarker ;
1476: WORD szSection ;
1477: char comment [ szSection - 2 ] ;
1478:
1479:
1480: local char comments [ szSection - 1 ] = { 0 } ;
1481: local int i = 0 ;
1482: Memcpy ( comments , comment , szSection - 2 ) ;
1483: for ( i = 0 ; i < szSection - 1 ; i ++ ) {
1484: if ( comments [ i ] == 0 ) comments [ i ] = 'x' ;
1485: }
1486: comments [ szSection - 2 ] = 0 ;
1487: Printf ( "\nCOMMENT :\n%s\n\n" , comments ) ;
1488:
1489: } COMMENT < read = ReadComment > ;
1490:
1491: typedef struct tagJPGLS {
1492: M_ID marker ;
1493: WORD szSection ;
1494:
1495: uchar precision < comment = "bits per sample" > ;
1496: WORD Y_numlines ;
1497: WORD X_numcols ;
1498: uchar Nf < comment = "number of components in frame" > ;
1499: uchar C_compID ;
1500: uchar sub_sampling ;
1501: uchar Tq < comment = "always 0" > ;
1502:
1503: if ( 11 < szSection )
1504: uchar uknown [ szSection - 11 ] ;
1505: } JPGLS ;
1506:
1507: string ReadComment ( COMMENT & com )
1508: {
1509: return com . comment ;
1510: }
1511:
1512: JpegFileEnd = FileSize ( ) ;
1513:
1514:
1515:
1516:
1517: SetBackColor ( jetMap [ 0 ] ) ;
1518: typedef struct tgJPGFile {
1519: local int was_bigendian = IsBigEndian ( ) ;
1520: BigEndian ( ) ;
1521: local WORD NextMarker ;
1522: local quad fpos2 ;
1523: local byte bEOI = 0 ;
1524: while ( FTell ( ) < JpegFileEnd && ! bEOI ) {
1525:
1526: while ( ReadUShort ( FTell ( ) ) == 0xFFFF ) FSkip ( 1 ) ;
1527:
1528: NextMarker = ReadUShort ( FTell ( ) ) ;
1529: switch ( NextMarker ) {
1530: case M_SOI :
1531: M_ID SOIMarker ;
1532: Printf ( "Start of Image Marker\n" ) ;
1533: break ;
1534: case M_SOS :
1535: SOS scanStart ;
1536: Printf ( "Start of Scan Marker\n" ) ;
1537: NextMarker = ReadUShort ( JpegFileEnd - 2 ) ;
1538: fpos2 = 0 ;
1539: while ( NextMarker != M_EOI ) {
1540: NextMarker = ReadUShort ( JpegFileEnd - 2 - ( ++ fpos2 ) ) ;
1541: }
1542: char scanData [ JpegFileEnd - FTell ( ) - 2 - fpos2 ] ;
1543: ChangeColor ( 1 ) ;
1544: M_ID EOIMarker ;
1545: Printf ( "End of File Image\n" ) ;
1546: if ( fpos2 ) char unknownPadding [ fpos2 ] ;
1547: bEOI = 1 ;
1548: break ;
1549: case M_APP0 :
1550: APP0 app0 ;
1551: break ;
1552: case M_DHT :
1553: DHT dht ;
1554: break ;
1555: case M_DQT :
1556: DQT dqt ;
1557: break ;
1558: case M_DRI :
1559: DRI dri ;
1560: break ;
1561: case M_DHP :
1562: DHP dhp ;
1563: break ;
1564: case M_SOF0 :
1565: SOFx sof0 ;
1566: break ;
1567: case M_SOF1 :
1568: SOFx sof1 ;
1569: break ;
1570: case M_SOF2 :
1571: SOFx sof2 ;
1572: break ;
1573: case M_APP1 :
1574: APP1 app1 ;
1575: break ;
1576: case M_APP2 :
1577: APP2 app2 ;
1578: break ;
1579: case M_APP12 :
1580: APP12 app12 ;
1581: break ;
1582: case M_APP13 :
1583: APP13 app13 ;
1584: break ;
1585: case M_APP14 :
1586: APP14 app14 ;
1587: break ;
1588: case M_COMM :
1589: COMMENT comment ;
1590: break ;
1591: case M_JPGLS :
1592: JPGLS jpgls ;
1593: break ;
1594: default :
1595: UNKNOWN unknownSection ;
1596: break ;
1597: }
1598: ChangeColor ( ! bEOI ) ;
1599: }
1600: if ( ! was_bigendian )
1601: LittleEndian ( ) ;
1602: } JPGFILE ;
1603:
1604: JPGFILE jpgfile ;
1605: tok_eof