commit 5cd871ac23e18ac767e747106ebab7479b8dcd5cd0e88d38c3919578c29e0dcf Author: Adrian Schröter Date: Fri May 3 12:00:36 2024 +0200 Sync from SUSE:SLFO:Main dcraw revision 8997fb911317f27102cbd1d4cd1a5b1e diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..9b03811 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,23 @@ +## Default LFS +*.7z filter=lfs diff=lfs merge=lfs -text +*.bsp filter=lfs diff=lfs merge=lfs -text +*.bz2 filter=lfs diff=lfs merge=lfs -text +*.gem filter=lfs diff=lfs merge=lfs -text +*.gz filter=lfs diff=lfs merge=lfs -text +*.jar filter=lfs diff=lfs merge=lfs -text +*.lz filter=lfs diff=lfs merge=lfs -text +*.lzma filter=lfs diff=lfs merge=lfs -text +*.obscpio filter=lfs diff=lfs merge=lfs -text +*.oxt filter=lfs diff=lfs merge=lfs -text +*.pdf filter=lfs diff=lfs merge=lfs -text +*.png filter=lfs diff=lfs merge=lfs -text +*.rpm filter=lfs diff=lfs merge=lfs -text +*.tbz filter=lfs diff=lfs merge=lfs -text +*.tbz2 filter=lfs diff=lfs merge=lfs -text +*.tgz filter=lfs diff=lfs merge=lfs -text +*.ttf filter=lfs diff=lfs merge=lfs -text +*.txz filter=lfs diff=lfs merge=lfs -text +*.whl filter=lfs diff=lfs merge=lfs -text +*.xz filter=lfs diff=lfs merge=lfs -text +*.zip filter=lfs diff=lfs merge=lfs -text +*.zst filter=lfs diff=lfs merge=lfs -text diff --git a/README b/README new file mode 100644 index 0000000..a50b707 --- /dev/null +++ b/README @@ -0,0 +1,1267 @@ +https://www.dechifro.org/dcraw/: + + [1]Back to Dave Coffin's Home Page + + [2]Live free or die / DCRAW / New Hampshire + + [3]en Esperanto + [4]em Português + [5]auf Deutsch + [6]на русском + [7]па-беларуску + + Welcome! If you are wondering how to connect your digital camera and + download images to a Linux PC, go to the [8]gPhoto homepage. My + software is for processing those images after downloading them. + + If you're downloading JPEG files, you don't need my software at all. + The image has already been processed inside the camera. Almost all + digital cameras made since 1997 produce JPEG images, so why would you + want to do it any other way? + + Well, despite the convenience and ubiquity of JPEG, there are some + disadvantages. JPEG is a lossy format -- to fit a big image into a + small file, a lot of information is thrown away. That's why midrange + and high-end digital cameras offer an alternative: Raw, unprocessed CCD + data files, for which the camera manufacturer provides special decoding + software. + + Of course this software is for Windows and Macintosh only, with no + source code. So it's useless to users of other operating systems, + programmers hoping to design a better interpolation algorithm, and + historians not yet born in an era when the only Windows machines will + be in museums. + + So here is my mission: Write and maintain an ANSI C program that + decodes any raw image from any digital camera on any computer running + any operating system. + + That program is called [9]dcraw (pronounced "dee-see-raw"), and it's + become a standard tool within and without the Open Source world. It's + small (about 9000 lines), portable (standard C libraries only), free + (both "gratis" and "libre"), and when used skillfully, produces better + quality output than the tools provided by the camera vendor. + + [10]Here's my resume. I do freelance consulting related to dcraw, and + I'm also available for full-time software work in the Northeast USA. + + I can be reached by sending e-mail to cybercom dot net with the + username "dcoffin". + + News and Interviews + + [11]Essay for Digital Outback Photo, 25 April 2003 + [12]Article in News.com, 21 April 2005 + [13]Interview with Digital Photography Review, 27 April 2005 + [14]Dcraw mentioned in Editors Guild magazine, July/August 2005 + [15]Interview with Thorsten Schnebeck, 10 June 2006 + [16]Interview with Ladinamo, 16 June 2006 + + My Code + + Unless otherwise noted in the source code, these programs are free for + all uses, although I would like to receive credit for them. Donations + are welcome too, if you're making money from my code. + Make payments with PayPal - it's fast, free and secure! + + Note to Linux distributors: The only executable files that should be + installed by a dcraw package are "dcraw", "clean_crw", and maybe + "fuji_green", "fujiturn", and "fujiturn16". My shell scripts are + dangerous and should only be installed in a "doc" directory without + execute permission. + * [17]dcraw.c -- decodes raw photos, extracts thumbnails, and + displays metadata + Supports 731 cameras at last count. Compile with "gcc -o dcraw -O4 + dcraw.c -lm -ljasper -ljpeg -llcms2" or "gcc -o dcraw -O4 dcraw.c + -lm -DNODEPS". Run with no arguments to see a usage message. Don't + complain that 16-bit output is too dark -- read the [18]FAQ! + * [19]UNIX manpage for dcraw + This is dcraw's official user documentation, updated in lockstep + with the source code. + * [20]rawphoto.c -- basic plugin for GIMP 1.2 & 2.0 + After installing "dcraw", do "gimptool --install rawphoto.c". My + plugin provides a simple dialog box for loading raw files into the + Gimp. [21]Udi Fuchs and [22]Joseph Heled have written much nicer + plugins, with live preview, histograms, and color curves. + * [23].badpixels -- my camera's "hot pixels" + This file tells dcraw which pixels have died and when, so that it + can interpolate around them. + * [24]dcraw.c,v -- complete unabridged RCS file + This file contains the entire history of dcraw.c since its + conception on February 23, 1997. If you don't have the RCS toolkit, + [25]download it here. + * [26]parse.c -- read image data structures + This program displays CIFF and TIFF data structures in a very + cryptic format. + * [27]clean_crw.c -- clean Canon CRW files + Recovered or undeleted CRW files often have junk appended to them + that makes them unreadable. This program safely cleans CRW files. + * [28]fujiturn.c -- rotate Fuji Super CCD images + An alternative to dcraw's built-in Fuji rotation. + * [29]fuji_green.c -- convert Fuji green pixels to PGM + A side benefit of the Fuji Super CCD design is that its green + pixels make nice greyscale images. + + For hackers only: + * [30]decompress.c is a simple reference decompressor for CRW files. + * [31]sony_clear.c decrypts SRF files from the Sony DSC-F828. + + Internationalization + + To build and install multilingual dcraw in Linux, download the latest + tarball [32]from this directory and run the "install" script. The + currently supported languages are [33]Esperanto, [34]Russian, + [35]French, [36]Italian, [37]German, [38]Portuguese, [39]Spanish, + [40]Dutch, [41]Polish, [42]Hungarian, [43]Czech, [44]Swedish, + [45]Catalan, [46]Danish, [47]Romanian, [48]Japanese, and Chinese (both + [49]Traditional and [50]Simplified). + + To build a unilingual, self-contained DCRAW.EXE for DOS/Windows, use a + source file [51]from this directory instead. + + To add another language, send me translations of [52]this manpage and + [53]this message table in UTF-8 encoding. Translate only from my + original English and Esperanto texts -- other languages may contain + factual errors invisible to me. + + Do not translate "Cannot do X" as "It is impossible to do X". Dcraw is + not perfect, so if it cannot do something, that does not mean that the + task is impossible. Computers must never use the pronoun "I", so write + "dcraw cannot do X". + + When in doubt, translate everything. I proofread these texts before + releasing them, and it's much easier for me to correct over-translation + than under-translation. + + Dcraw decodes raw photos, not raw files. No digital camera generates + raw files in normal usage, there's always a header with useful + metadata. (For abnormal usage, see CHDK and DIAG RAW below) + + "raw" is an English word, not an acronym or file format. "raw photo" + should be translated with the same adjective that you would use for + "crude oil" or "raw materials". + + There are dozens of raw photo formats: CRW, CR2, MRW, NEF, RAF, etc. + "RAW Format" does not exist; it is an illusion created by dcraw's + ability to read all raw formats. + + Other Raw Photo Decoders + + Dcraw has made it far easier for developers to support a wide range of + digital cameras in their applications. They can call dcraw from a + graphical interface, paste pieces of dcraw.c into their code, or just + use dcraw.c as the documentation that camera makers refuse to provide: + * [54]ACDSee + * [55]Adobe Photoshop + * [56]BR's PhotoArchiver by Baard Riiber + * [57]BreezeBrowser by Chris Breeze + * [58]Conceiva Lightbox + * [59]cPicture by Jürgen Eidt + * [60]Cumulus by Canto + * [61]dcRAW-X by Bryan Chang + * [62]DCRawUI by Sune Trudslev + * [63]DDRoom by Mykhailo Malyshko + * [64]Directory Opus Plugin by Leo Davidson(with C++ source code) + * [65]DeepSkyStacker by Luc Coiffier + * [66]DF Studio by DigitalFusion + * [67]dpMagic by Mikhail Stolpner + * [68]GraphicConverter by Thorsten Lemke + * [69]GTKRawGallery by Daniele Isca + * [70]GVBox from JCO Consulting + * [71]HDR Shop + * [72]ImageLab from Aragon System + * [73]Imagina by Rob Baker + * [74]IrfanView by Irfan Skiljan + * [75]IRIS image processor for astronomers + * [76]Lightbox by Josh Anon + * [77]LightZone by LightZone project + * [78]LRViewer by Marc Rochkind + * [79]MediaRECOVER File Recovery Software + * [80]Mixpo by Mixpo Portfolio Broadcasting Inc. + * [81]Photo Acute by Almalence + * [82]Photo Companion by Jeff Moore + * [83]Photo Jockey by Davie Lee Reed who also wrote a [84]dcraw + interface for Delphi programmers. + * [85]Photo Organizer by Balint Kis + * [86]PhotoRescue from DataRescue + * [87]PhotoReviewer by Ben Haller + * [88]Photovault by Harri Kaimio + * [89]Picasa from Google + * [90]Picture Arena by Felix Schwarz + * [91]PixInsight by Pleiades Software + * [92]PolyView by Polybytes + * [93]PRISM by Alcor System + * [94]RAW Developer by Iridient Digital + * [95]Raw Magick + * [96]RawDrop by Frank Siegert + * [97]RawTherapee by RT Team + * [98]Serif PhotoPlus, PanoramaPlus, and AlbumPlus + * [99]SharpRaw by Duane DeSieno + * [100]SilverFast DCPro by LaserSoft Imaging + * [101]StudioLine Photo by H&M Software + * [102]ViewIt by Zdzislaw Losvik + * [103]Viewer n5 by Dmitry Fedorov + * [104]VueScan by Ed Hamrick + * [105]Xara Xtreme Pro + + Frequently Asked Questions + + I don't have a C compiler. Could you send me an executable? + Sergio Namias has built [106]some current Windows EXE files + here. Dcraw has also been ported to [107]Amiga, [108]MorphOS, + [109]BeOS, [110]OS/2, and [111]RISC OS. + + Why does dcraw say "Out of memory" in Windows Vista? + Ostensibly to stop memory leaks, Microsoft decided that programs + using the old MS-DOS API, including anything compiled with + [112]DJGPP, shall be confined to 32MB of memory. This limitation + can be removed by some combination of service packs and registry + hacks, or you can compile dcraw to use the newer Win32 API. + Thomas Nicely (of Pentium FDIV fame) has a [113]page describing + the problem and various workarounds. + + How can I read the EXIF data (shutter speed, aperture, etc.)? + [114]Phil Harvey's ExifTool provides a unified Perl-based EXIF + reader (and editor!) for all cameras and file formats. "dcraw -i + -v" is much faster, but provides less information. + + How can I read NEF files from Nikon scanners? + Dcraw only supports cameras. Try [115]this simple program for + scanners. + + How can I read Nikon Dust Off images (NDF files)? + [116]Use this program. + + Do you have any specifications describing raw photo formats? + Yes, but they tend to omit important details, like how to + decompress the raw image or decrypt private metadata. See the + [117]TIFF spec, the [118]TIFF/EP spec, the [119]Adobe DNG spec, + the [120]CIFF (CRW) spec, and the [121]X3F spec. + + Where can I get an assortment of raw photos to test my software? + For the latest cameras, I get samples from [122]Photography + Blog. A "Full Review" at [123]Imaging Resource usually includes + a few raw shots. [124]www.rawsamples.ch is no longer updated, + but it has samples from older cameras. For $800, I sell a + complete test suite on six DVDs containing every camera + supported by dcraw, and provide web-based updates for $300/year. + + I'm designing a digital camera. How do I convert its raw photos into + something that dcraw and Adobe Photoshop can open? + Download [125]LibTIFF v3.8.2 and apply [126]this patch. Then use + [127]this C program as a template for converting your photos to + valid [128]Adobe DNG files. + + Why are dcraw output images larger than camera JPEGs? + Any algorithm that combines each pixel with its neighbors is + going to have problems near the edges. C code is cheap, so dcraw + applies a different algorithm to edge pixels. Hardware logic is + expensive, so cameras crop off the edge pixels after processing. + + I shot a raw photo with no light. Why does it appear all noisy, when it + should be solid black? + No matter how dark an image is, dcraw's auto-exposure stretches + it so that one percent of its pixels appear white. The "-W" + option avoids this behavior. + + I bracket plus/minus two stops, but all five shots look almost the same + in dcraw. Why? + See the previous question. + + Why is 16-bit output dark / unreadable? + If you want pretty pictures straight out of dcraw, stay with + 8-bit output. 16-bit linear output is the best raw material for + professional image editors such as [129]Photoshop and + [130]CinePaint, but it's no good for most image viewers. + + What does the "-f" (four color RGB) option do? + If you see patterns like [131]this or [132]this in your output + images, first try "dcraw -a". If these patterns persist, use + "dcraw -f" to get rid of them. + + Could you please add an option for TIFF / FITS / PNG / BMP / JPEG + output? + In versions 8.25 and later, "dcraw -T" writes TIFF output with + metadata. To write other formats: + +dcraw -c crw_0001.crw | pnmtofits > crw_0001.fits +dcraw -c crw_0001.crw | pnmtopng > crw_0001.png +dcraw -c crw_0001.crw | ppmtobmp > crw_0001.bmp +dcraw -c crw_0001.crw | cjpeg > crw_0001.jpeg + + I used the [133]Netpbm toolkit in these examples. + [134]ImageMagick also does command-line format conversions. Both + are free. + + Why don't you implement dcraw as a library? + I have decided that dcraw shall be a command-line program + written in C, and that any further abstraction layers must be + added around this core, not inside it. + + Library code is ugly because it cannot use global variables. + Libraries are more difficult to modify, build, install, and test + than standalone programs, and so are inappropriate for file + formats that change every day. + + There's a simpler way to make dcraw modular and thread-safe: Run + it as a separate process. Eric Raymond [135]explains this + technique here. + + Why are there false colors along edges within the image? + Because of interpolation. This is a hard problem, easily + defined: + + 1. Take a three-color RGB image. At each pixel, set two color + values to zero. + 2. Reconstruct the original three-color image as best you can + from the remaining one color per pixel. + + Dcraw currently gives a choice of four methods: Bilinear, + Variable Number of Gradients (VNG), Patterned Pixel Grouping + (PPG), and Adaptive Homogeneity-Directed (AHD). + + [136]The Foveon X3 Capture chip requires a different kind of + interpolation. Unlike CCD arrays, it captures three colors at + every pixel location. But the colors are not well separated, so + the raw data looks very gray. Much processing is needed to + enhance color while suppressing noise. + + How do I get my camera to take raw photos? + For Canon PowerShots that don't output CRW or CR2, you need the + [137]CHDK hack. + For some Nikon Coolpix cameras, you need to enable a + [138]special "DIAG RAW" mode. + For Casio cameras, see [139]Maurice Delaney's website or read + [140]this discussion on dpreview. + For the Minolta DiMAGE G400, G500, G530, or G600, go [141]here + (in Russian) or [142]here (in English). + For the Minolta DiMAGE Z2 and Nikon Coolpix 2100/3100/3700, + [143]go here. + For SMaL cameras, see the [144]camerahacking Forum. + For Agfa and Samsung cameras, [145]go here. + + For other cameras, refer to the User's Manual. + + Does dcraw work with my camera? + + Most likely, yes. If your camera is not on the Supported list, + try dcraw anyway. If it doesn't work perfectly, don't just sit + quietly waiting for my next version. Ask me if I need any raw + photos, or go ahead and post a photo to your website and e-mail + me the URL. If you don't have a website, use [146]YouSendIt, + [147]RapidShare, [148]Sendshack, [149]ShareFile, [150]sendspace, + or [151]Megaupload. + + Before choosing a photo to send, read the next question: + + Why does dcraw output have a green tint and weak color? + + Because dcraw doesn't have a color matrix for your camera model, + it outputs raw color instead of sRGB. To fix this, I need a + photo of a [152]Wolf Faust, [153]ColorChecker, [154]CMP, or + other calibrated color chart. Follow this checklist: + + + Use a real chart, not a printout or screen image. + + Wait for sunny weather, local noon ± two hours. + + Carefully brush any dust off the chart. + + Tilt the chart 90° to the camera and 45° to the sun to avoid + specular reflections. + + Set the camera two meters away and use telephoto zoom. + + Use the lowest ISO setting. + + Supported Cameras + + * [155]Adobe Digital Negative (DNG) + * AgfaPhoto DC-833m + * Alcatel 5035D + * Apple QuickTake 100 + * Apple QuickTake 150 + * Apple QuickTake 200 + * [156]ARRIRAW format + * AVT F-080C + * AVT F-145C + * AVT F-201C + * AVT F-510C + * AVT F-810C + * Baumer TXG14 + * Blackmagic URSA + * Canon PowerShot 600 + * Canon PowerShot A5 + * Canon PowerShot A5 Zoom + * Canon PowerShot A50 + * Canon PowerShot A460 (CHDK hack) + * Canon PowerShot A470 (CHDK hack) + * Canon PowerShot A530 (CHDK hack) + * Canon PowerShot A570 (CHDK hack) + * Canon PowerShot A590 (CHDK hack) + * Canon PowerShot A610 (CHDK hack) + * Canon PowerShot A620 (CHDK hack) + * Canon PowerShot A630 (CHDK hack) + * Canon PowerShot A640 (CHDK hack) + * Canon PowerShot A650 (CHDK hack) + * Canon PowerShot A710 IS (CHDK hack) + * Canon PowerShot A720 IS (CHDK hack) + * Canon PowerShot A3300 IS (CHDK hack) + * Canon PowerShot Pro70 + * Canon PowerShot Pro90 IS + * Canon PowerShot Pro1 + * Canon PowerShot G1 + * Canon PowerShot G1 X + * Canon PowerShot G1 X Mark II + * Canon PowerShot G2 + * Canon PowerShot G3 + * Canon PowerShot G3 X + * Canon PowerShot G5 + * Canon PowerShot G5 X + * Canon PowerShot G6 + * Canon PowerShot G7 (CHDK hack) + * Canon PowerShot G7 X + * Canon PowerShot G7 X Mark II + * Canon PowerShot G9 + * Canon PowerShot G9 X + * Canon PowerShot G10 + * Canon PowerShot G11 + * Canon PowerShot G12 + * Canon PowerShot G15 + * Canon PowerShot G16 + * Canon PowerShot S2 IS (CHDK hack) + * Canon PowerShot S3 IS (CHDK hack) + * Canon PowerShot S5 IS (CHDK hack) + * Canon PowerShot SD300 (CHDK hack) + * Canon PowerShot S30 + * Canon PowerShot S40 + * Canon PowerShot S45 + * Canon PowerShot S50 + * Canon PowerShot S60 + * Canon PowerShot S70 + * Canon PowerShot S90 + * Canon PowerShot S95 + * Canon PowerShot S100 + * Canon PowerShot S110 + * Canon PowerShot S120 + * Canon PowerShot SX1 IS + * Canon PowerShot SX110 IS (CHDK hack) + * Canon PowerShot SX120 IS (CHDK hack) + * Canon PowerShot SX220 HS (CHDK hack) + * Canon PowerShot SX20 IS (CHDK hack) + * Canon PowerShot SX30 IS (CHDK hack) + * Canon PowerShot SX50 HS + * Canon PowerShot SX60 HS + * Canon IXUS 160 (CHDK hack) + * Canon EOS D30 + * Canon EOS D60 + * Canon EOS 5D + * Canon EOS 5D Mark II + * Canon EOS 5D Mark III + * Canon EOS 5DS + * Canon EOS 5DS R + * Canon EOS 6D + * Canon EOS 7D + * Canon EOS 7D Mark II + * Canon EOS 10D + * Canon EOS 20D + * Canon EOS 30D + * Canon EOS 40D + * Canon EOS 50D + * Canon EOS 60D + * Canon EOS 70D + * Canon EOS 77D / 9000D + * Canon EOS 80D + * Canon EOS 300D / Digital Rebel / Kiss Digital + * Canon EOS 350D / Digital Rebel XT / Kiss Digital N + * Canon EOS 400D / Digital Rebel XTi / Kiss Digital X + * Canon EOS 450D / Digital Rebel XSi / Kiss Digital X2 + * Canon EOS 500D / Digital Rebel T1i / Kiss Digital X3 + * Canon EOS 550D / Digital Rebel T2i / Kiss Digital X4 + * Canon EOS 600D / Digital Rebel T3i / Kiss Digital X5 + * Canon EOS 650D / Digital Rebel T4i / Kiss Digital X6i + * Canon EOS 700D / Digital Rebel T5i / Kiss Digital X7i + * Canon EOS 750D / Digital Rebel T6i / Kiss Digital X8i + * Canon EOS 760D / Digital Rebel T6s / Kiss Digital X9 + * Canon EOS 800D / Digital Rebel T7i / Kiss Digital X9i + * Canon EOS 100D / Digital Rebel SL1 / Kiss Digital X7 + * Canon EOS 1000D / Digital Rebel XS / Kiss Digital F + * Canon EOS 1100D / Digital Rebel T3 / Kiss Digital X50 + * Canon EOS 1200D / Digital Rebel T5 / Kiss Digital X70 + * Canon EOS 1300D / Digital Rebel T6 / Kiss Digital X80 + * Canon EOS 1500D / Digital Rebel T7 / Kiss Digital X90 / EOS 2000D + * Canon EOS 3000D / Digital Rebel T100 / EOS 4000D + * Canon EOS C500 + * Canon EOS D2000C + * Canon EOS M + * Canon EOS M3 + * Canon EOS M10 + * Canon EOS-1D + * Canon EOS-1DS + * Canon EOS-1D X + * Canon EOS-1D X Mark II + * Canon EOS-1D Mark II + * Canon EOS-1D Mark II N + * Canon EOS-1D Mark III + * Canon EOS-1D Mark IV + * Canon EOS-1Ds Mark II + * Canon EOS-1Ds Mark III + * Casio QV-2000UX + * Casio QV-3000EX + * Casio QV-3500EX + * Casio QV-4000 + * Casio QV-5700 + * Casio QV-R41 + * Casio QV-R51 + * Casio QV-R61 + * Casio EX-FH100 + * Casio EX-S20 + * Casio EX-S100 + * Casio EX-Z4 + * Casio EX-Z50 + * Casio EX-Z500 + * Casio EX-Z55 + * Casio EX-Z60 + * Casio EX-Z75 + * Casio EX-Z750 + * Casio EX-Z8 + * Casio EX-Z850 + * Casio EX-Z1050 + * Casio EX-Z1080 + * Casio EX-ZR100 + * Casio Exlim Pro 505 + * Casio Exlim Pro 600 + * Casio Exlim Pro 700 + * Contax N Digital + * Creative PC-CAM 600 + * DJI 4384x3288 + * DxO ONE + * Epson R-D1 + * Foculus 531C + * Fuji E550 + * Fuji E900 + * Fuji F700 + * Fuji F710 + * Fuji S1 + * Fuji S2Pro + * Fuji S3Pro + * Fuji S5Pro + * Fuji S20Pro + * Fuji S100FS + * Fuji S5000 + * Fuji S5100/S5500 + * Fuji S5200/S5600 + * Fuji S6000fd + * Fuji S7000 + * Fuji S9000/S9500 + * Fuji S9100/S9600 + * Fuji S200EXR + * Fuji SL1000 + * Fuji HS10/HS11 + * Fuji HS20EXR + * Fuji HS30EXR + * Fuji HS50EXR + * Fuji F550EXR + * Fuji F600EXR + * Fuji F770EXR + * Fuji F800EXR + * Fuji F900EXR + * Fuji X-Pro1 + * Fuji X-Pro2 + * Fuji X-A1 + * Fuji X-A2 + * Fuji X-E1 + * Fuji X-E2 + * Fuji X-E2S + * Fuji X-H1 + * Fuji X-M1 + * Fuji X-S1 + * Fuji X-T1 + * Fuji X-T2 + * Fuji X-T10 + * Fuji X-T20 + * Fuji XF1 + * Fuji XQ1 + * Fuji XQ2 + * Fuji X100 + * Fuji X100F + * Fuji X100S + * Fuji X100T + * Fuji X10 + * Fuji X20 + * Fuji X30 + * Fuji X70 + * Fuji IS-1 + * Hasselblad CFV + * Hasselblad CFV-2 + * Hasselblad H3D + * Hasselblad H4D + * Hasselblad V96C + * Hasselblad X1D + * Imacon Ixpress 16-megapixel + * Imacon Ixpress 22-megapixel + * Imacon Ixpress 39-megapixel + * ISG 2020x1520 + * Kodak DC20 + * Kodak DC25 + * Kodak DC40 + * Kodak DC50 + * Kodak DC120 (also try [157]kdc2tiff) + * Kodak DCS200 + * Kodak DCS315C + * Kodak DCS330C + * Kodak DCS420 + * Kodak DCS460 + * Kodak DCS460A + * Kodak DCS460D + * Kodak DCS520C + * Kodak DCS560C + * Kodak DCS620C + * Kodak DCS620X + * Kodak DCS660C + * Kodak DCS660M + * Kodak DCS720X + * Kodak DCS760C + * Kodak DCS760M + * Kodak EOSDCS1 + * Kodak EOSDCS3B + * Kodak NC2000F + * Kodak ProBack + * Kodak PB645C + * Kodak PB645H + * Kodak PB645M + * Kodak DCS Pro 14n + * Kodak DCS Pro 14nx + * Kodak DCS Pro SLR/c + * Kodak DCS Pro SLR/n + * Kodak C330 + * Kodak C603 + * Kodak P850 + * Kodak P880 + * Kodak Z980 + * Kodak Z981 + * Kodak Z990 + * Kodak Z1015 + * Kodak KAI-0340 + * Konica KD-400Z + * Konica KD-510Z + * Leaf AFi 7 + * Leaf AFi-II 12 + * Leaf Aptus 17 + * Leaf Aptus 22 + * Leaf Aptus 54S + * Leaf Aptus 65 + * Leaf Aptus 75 + * Leaf Aptus 75S + * Leaf Cantare + * Leaf CatchLight + * Leaf CMost + * Leaf DCB2 + * Leaf Valeo 6 + * Leaf Valeo 11 + * Leaf Valeo 17 + * Leaf Valeo 22 + * Leaf Volare + * Leica C (Typ 112) + * Leica CL + * Leica Digilux 2 + * Leica Digilux 3 + * Leica D-LUX2 + * Leica D-LUX3 + * Leica D-LUX4 + * Leica D-LUX5 + * Leica D-LUX6 + * Leica D-LUX (Typ 109) + * Leica M (Typ 240) + * Leica M (Typ 262) + * Leica M Monochrom (Typ 246) + * Leica M8 + * Leica M9 + * Leica M10 + * Leica Q (Typ 116) + * Leica R8 + * Leica S (Typ 007) + * Leica SL (Typ 601) + * Leica T (Typ 701) + * Leica TL + * Leica TL2 + * Leica V-LUX1 + * Leica V-LUX2 + * Leica V-LUX3 + * Leica V-LUX4 + * Leica V-LUX (Typ 114) + * Leica X VARIO (Typ 107) + * Leica X1 + * Leica X2 + * Leica X (Typ 113) + * Leica X-E (Typ 102) + * Leica X-U (Typ 113) + * Lenovo A820 + * Logitech Fotoman Pixtura + * Mamiya ZD + * Matrix 4608x3288 + * Micron 2010 + * Minolta RD175 + * Minolta DiMAGE 5 + * Minolta DiMAGE 7 + * Minolta DiMAGE 7i + * Minolta DiMAGE 7Hi + * Minolta DiMAGE A1 + * Minolta DiMAGE A2 + * Minolta DiMAGE A200 + * Minolta DiMAGE G400 + * Minolta DiMAGE G500 + * Minolta DiMAGE G530 + * Minolta DiMAGE G600 + * Minolta DiMAGE Z2 + * Minolta Alpha/Dynax/Maxxum 5D + * Minolta Alpha/Dynax/Maxxum 7D + * Motorola PIXL + * Nikon D1 + * Nikon D1H + * Nikon D1X + * Nikon D2H + * Nikon D2Hs + * Nikon D2X + * Nikon D2Xs + * Nikon D3 + * Nikon D3s + * Nikon D3X + * Nikon D4 + * Nikon D4s + * Nikon Df + * Nikon D40 + * Nikon D40X + * Nikon D5 + * Nikon D50 + * Nikon D60 + * Nikon D70 + * Nikon D70s + * Nikon D80 + * Nikon D90 + * Nikon D100 + * Nikon D200 + * Nikon D300 + * Nikon D300s + * Nikon D500 + * Nikon D600 + * Nikon D610 + * Nikon D700 + * Nikon D750 + * Nikon D800 + * Nikon D800E + * Nikon D810 + * Nikon D850 + * Nikon D3000 + * Nikon D3100 + * Nikon D3200 + * Nikon D3300 + * Nikon D3400 + * Nikon D5000 + * Nikon D5100 + * Nikon D5200 + * Nikon D5300 + * Nikon D5500 + * Nikon D7000 + * Nikon D7100 + * Nikon D7200 + * Nikon D7500 + * Nikon 1 AW1 + * Nikon 1 J1 + * Nikon 1 J2 + * Nikon 1 J3 + * Nikon 1 J4 + * Nikon 1 J5 + * Nikon 1 S1 + * Nikon 1 V1 + * Nikon 1 V2 + * Nikon 1 V3 + * Nikon E700 ("DIAG RAW" hack) + * Nikon E800 ("DIAG RAW" hack) + * Nikon E880 ("DIAG RAW" hack) + * Nikon E900 ("DIAG RAW" hack) + * Nikon E950 ("DIAG RAW" hack) + * Nikon E990 ("DIAG RAW" hack) + * Nikon E995 ("DIAG RAW" hack) + * Nikon E2100 ("DIAG RAW" hack) + * Nikon E2500 ("DIAG RAW" hack) + * Nikon E3200 ("DIAG RAW" hack) + * Nikon E3700 ("DIAG RAW" hack) + * Nikon E4300 ("DIAG RAW" hack) + * Nikon E4500 ("DIAG RAW" hack) + * Nikon E5000 + * Nikon E5400 + * Nikon E5700 + * Nikon E8400 + * Nikon E8700 + * Nikon E8800 + * Nikon Coolpix A + * Nikon Coolpix P330 + * Nikon Coolpix P340 + * Nikon Coolpix P6000 + * Nikon Coolpix P7000 + * Nikon Coolpix P7100 + * Nikon Coolpix P7700 + * Nikon Coolpix P7800 + * Nikon Coolpix S6 ("DIAG RAW" hack) + * Nokia N9 + * Nokia N95 + * Nokia X2 + * Nokia 1200x1600 + * Nokia Lumia 1020 + * Olympus AIR-A01 + * Olympus C3030Z + * Olympus C5050Z + * Olympus C5060WZ + * Olympus C7070WZ + * Olympus C70Z,C7000Z + * Olympus C740UZ + * Olympus C770UZ + * Olympus C8080WZ + * Olympus X200,D560Z,C350Z + * Olympus E-1 + * Olympus E-3 + * Olympus E-5 + * Olympus E-10 + * Olympus E-20 + * Olympus E-30 + * Olympus E-300 + * Olympus E-330 + * Olympus E-400 + * Olympus E-410 + * Olympus E-420 + * Olympus E-500 + * Olympus E-510 + * Olympus E-520 + * Olympus E-620 + * Olympus E-M1 + * Olympus E-M1 Mark II + * Olympus E-M5 + * Olympus E-M5 Mark II + * Olympus E-M10 + * Olympus E-M10 Mark II + * Olympus E-M10 Mark III + * Olympus E-P1 + * Olympus E-P2 + * Olympus E-P3 + * Olympus E-P5 + * Olympus E-PL1 + * Olympus E-PL1s + * Olympus E-PL2 + * Olympus E-PL3 + * Olympus E-PL5 + * Olympus E-PL7 + * Olympus E-PL8 + * Olympus E-PL9 + * Olympus E-PM1 + * Olympus E-PM2 + * Olympus PEN-F + * Olympus SH-2 + * Olympus SP310 + * Olympus SP320 + * Olympus SP350 + * Olympus SP500UZ + * Olympus SP510UZ + * Olympus SP550UZ + * Olympus SP560UZ + * Olympus SP570UZ + * Olympus STYLUS1 + * Olympus TG-4 + * Olympus TG-5 + * Olympus XZ-1 + * Olympus XZ-2 + * Olympus XZ-10 + * OmniVision OV5647 (Raspberry Pi) + * Panasonic DMC-CM1 + * Panasonic DMC-FZ8 + * Panasonic DMC-FZ18 + * Panasonic DMC-FZ28 + * Panasonic DMC-FZ30 + * Panasonic DMC-FZ35/FZ38 + * Panasonic DMC-FZ40 + * Panasonic DMC-FZ50 + * Panasonic DMC-FZ70 + * Panasonic DC-FZ80 + * Panasonic DMC-FZ100 + * Panasonic DMC-FZ150 + * Panasonic DMC-FZ200 + * Panasonic DMC-FZ300 + * Panasonic DMC-FZ330 + * Panasonic DMC-FZ1000 + * Panasonic DMC-FZ2000 + * Panasonic DMC-FX150 + * Panasonic DMC-G1 + * Panasonic DMC-G2 + * Panasonic DMC-G3 + * Panasonic DMC-G5 + * Panasonic DMC-G6 + * Panasonic DMC-G7 + * Panasonic DC-G9 + * Panasonic DMC-G80 + * Panasonic DMC-GF1 + * Panasonic DMC-GF2 + * Panasonic DMC-GF3 + * Panasonic DMC-GF5 + * Panasonic DMC-GF6 + * Panasonic DMC-GF7 + * Panasonic DMC-GH1 + * Panasonic DMC-GH2 + * Panasonic DMC-GH3 + * Panasonic DMC-GH4 + * Panasonic DC-GH5 + * Panasonic DMC-GM1 + * Panasonic DMC-GM5 + * Panasonic DMC-GX1 + * Panasonic DMC-GX7 + * Panasonic DMC-GX8 + * Panasonic DC-GX9 + * Panasonic DMC-GX80 + * Panasonic DC-GX800 + * Panasonic DMC-L1 + * Panasonic DMC-L10 + * Panasonic DMC-LC1 + * Panasonic DMC-LF1 + * Panasonic DMC-LX1 + * Panasonic DMC-LX2 + * Panasonic DMC-LX3 + * Panasonic DMC-LX5 + * Panasonic DMC-LX7 + * Panasonic DMC-LX15 + * Panasonic DMC-LX100 + * Panasonic DMC-TZ61 + * Panasonic DMC-TZ80 + * Panasonic DC-TZ90 + * Panasonic DMC-TZ100 + * Panasonic DC-TZ200 + * Panasonic DMC-ZS40 + * Pentax *ist D + * Pentax *ist DL + * Pentax *ist DL2 + * Pentax *ist DS + * Pentax *ist DS2 + * Pentax K10D + * Pentax K20D + * Pentax K100D + * Pentax K100D Super + * Pentax K200D + * Pentax K2000/K-m + * Pentax K-x + * Pentax K-r + * Pentax K-1 + * Pentax K-3 + * Pentax K-3 II + * Pentax K-5 + * Pentax K-5 II + * Pentax K-5 II s + * Pentax K-50 + * Pentax K-70 + * Pentax K-500 + * Pentax K-7 + * Pentax K-S1 + * Pentax K-S2 + * Pentax KP + * Pentax Optio S + * Pentax Optio S4 + * Pentax Optio 33WR + * Pentax Optio 750Z + * Pentax Q-S1 + * Pentax Q7 + * Pentax 645D + * Pentax 645Z + * Phase One LightPhase + * Phase One H 10 + * Phase One H 20 + * Phase One H 25 + * Phase One P 20 + * Phase One P 25 + * Phase One P 30 + * Phase One P 45 + * Phase One P 45+ + * Photron BC2-HD + * Pixelink A782 + * Polaroid x530 + * Redcode R3D format + * Ricoh GR + * Ricoh GR II + * Ricoh GX200 + * Ricoh GXR MOUNT A12 + * Ricoh GXR A16 + * Rollei d530flex + * RoverShot 3320af + * Samsung EK-GN120 + * Samsung EX1 + * Samsung EX2F + * Samsung GX-1S + * Samsung GX10 + * Samsung GX20 + * Samsung NX1 + * Samsung NX10 + * Samsung NX11 + * Samsung NX100 + * Samsung NX20 + * Samsung NX200 + * Samsung NX210 + * Samsung NX30 + * Samsung NX300 + * Samsung NX300M + * Samsung NX500 + * Samsung NX1000 + * Samsung NX1100 + * Samsung NX2000 + * Samsung NX3000 + * Samsung NX mini + * Samsung WB550 + * Samsung WB2000 + * Samsung S85 (hacked) + * Samsung S850 (hacked) + * Sarnoff 4096x5440 + * Sigma SD9 + * Sigma SD10 + * Sigma SD14 + * Sigma SD15 + * Sigma SD1 + * Sigma SD1 Merill + * Sigma DP1 + * Sigma DP1 Merill + * Sigma DP1S + * Sigma DP1X + * Sigma DP2 + * Sigma DP2 Merill + * Sigma DP2S + * Sigma DP2X + * Sinar 3072x2048 + * Sinar 4080x4080 + * Sinar 4080x5440 + * Sinar STI format + * SMaL Ultra-Pocket 3 + * SMaL Ultra-Pocket 4 + * SMaL Ultra-Pocket 5 + * Sony DSC-F828 + * Sony DSC-R1 + * Sony DSC-RX0 + * Sony DSC-RX1 + * Sony DSC-RX1R + * Sony DSC-RX1RM2 + * Sony DSC-RX10 + * Sony DSC-RX10M2 + * Sony DSC-RX10M3 + * Sony DSC-RX10M4 + * Sony DSC-RX100 + * Sony DSC-RX100M2 + * Sony DSC-RX100M3 + * Sony DSC-RX100M4 + * Sony DSC-RX100M5 + * Sony DSC-V3 + * Sony DSLR-A100 + * Sony DSLR-A200 + * Sony DSLR-A230 + * Sony DSLR-A290 + * Sony DSLR-A300 + * Sony DSLR-A330 + * Sony DSLR-A350 + * Sony DSLR-A380 + * Sony DSLR-A450 + * Sony DSLR-A500 + * Sony DSLR-A550 + * Sony DSLR-A580 + * Sony DSLR-A700 + * Sony DSLR-A850 + * Sony DSLR-A900 + * Sony ILCA-68 + * Sony ILCA-77M2 + * Sony ILCA-99M2 + * Sony ILCE-7 + * Sony ILCE-7M2 + * Sony ILCE-7M3 + * Sony ILCE-7R + * Sony ILCE-7RM2 + * Sony ILCE-7RM3 + * Sony ILCE-7S + * Sony ILCE-7SM2 + * Sony ILCE-9 + * Sony ILCE-3000 + * Sony ILCE-5000 + * Sony ILCE-5100 + * Sony ILCE-6000 + * Sony ILCE-6300 + * Sony ILCE-6500 + * Sony ILCE-QX1 + * Sony NEX-3 + * Sony NEX-3N + * Sony NEX-5 + * Sony NEX-5N + * Sony NEX-5R + * Sony NEX-5T + * Sony NEX-6 + * Sony NEX-7 + * Sony NEX-C3 + * Sony NEX-F3 + * Sony SLT-A33 + * Sony SLT-A35 + * Sony SLT-A37 + * Sony SLT-A55V + * Sony SLT-A57 + * Sony SLT-A58 + * Sony SLT-A65V + * Sony SLT-A77V + * Sony SLT-A99V + * Sony XCD-SX910CR + * STV680 VGA + * Xiro Xplorer V + * YI M1 + __________________________________________________________________ + +References + + 1. https://www.dechifro.org/ + 2. https://www.dechifro.org/dcraw/plate_large.jpg + 3. https://www.dechifro.org/dcraw/index_eo.html + 4. https://www.dechifro.org/dcraw/index_pt.html + 5. https://www.dechifro.org/dcraw/index_de.html + 6. https://www.dechifro.org/dcraw/index_ru.html + 7. http://science-all.com/dcraw.html + 8. http://gphoto.sourceforge.net/ + 9. https://www.dechifro.org/dcraw/dcraw.c + 10. https://www.dechifro.org/resume.html + 11. http://www.outbackphoto.com/artofraw/raw_07/essay.html + 12. http://news.cnet.com/Nikons-photo-encryption-reported-broken/2100-1030_3-5679848.html + 13. http://www.dpreview.com/news/0504/05042701davecoffininterview.asp + 14. http://www.editorsguild.com/v2/magazine/archives/0705/cover_story.htm + 15. http://archive.is/0FyJw + 16. https://web.archive.org/web/20121015035554/http://www.ladinamo.org/english/raw-format-the-captive-photo.php + 17. https://www.dechifro.org/dcraw/dcraw.c + 18. https://www.dechifro.org/dcraw/#faq + 19. https://www.dechifro.org/dcraw/dcraw.1.html + 20. https://www.dechifro.org/dcraw/rawphoto.c + 21. http://ufraw.sourceforge.net/ + 22. http://homepages.ihug.co.nz/~peps/ + 23. https://www.dechifro.org/dcraw/.badpixels + 24. https://www.dechifro.org/dcraw/RCS/dcraw.c,v + 25. http://www.cs.purdue.edu/homes/trinkle/RCS/ + 26. https://www.dechifro.org/dcraw/parse.c + 27. https://www.dechifro.org/dcraw/clean_crw.c + 28. https://www.dechifro.org/dcraw/fujiturn.c + 29. https://www.dechifro.org/dcraw/fuji_green.c + 30. https://www.dechifro.org/dcraw/decompress.c + 31. https://www.dechifro.org/dcraw/sony_clear.c + 32. https://www.dechifro.org/dcraw/archive/ + 33. https://www.dechifro.org/dcraw/dcraw_eo.1.html + 34. https://www.dechifro.org/dcraw/dcraw_ru.1.html + 35. https://www.dechifro.org/dcraw/dcraw_fr.1.html + 36. https://www.dechifro.org/dcraw/dcraw_it.1.html + 37. https://www.dechifro.org/dcraw/dcraw_de.1.html + 38. https://www.dechifro.org/dcraw/dcraw_pt.1.html + 39. https://www.dechifro.org/dcraw/dcraw_es.1.html + 40. https://www.dechifro.org/dcraw/dcraw_nl.1.html + 41. https://www.dechifro.org/dcraw/dcraw_pl.1.html + 42. https://www.dechifro.org/dcraw/dcraw_hu.1.html + 43. https://www.dechifro.org/dcraw/dcraw_cs.1.html + 44. https://www.dechifro.org/dcraw/dcraw_sv.1.html + 45. https://www.dechifro.org/dcraw/dcraw_ca.1.html + 46. https://www.dechifro.org/dcraw/dcraw_da.1.html + 47. https://www.dechifro.org/dcraw/dcraw_ro.1.html + 48. https://www.dechifro.org/dcraw/dcraw_ja.1.html + 49. https://www.dechifro.org/dcraw/dcraw_zh_TW.1.html + 50. https://www.dechifro.org/dcraw/dcraw_zh_CN.1.html + 51. https://www.dechifro.org/dcraw/msdos/ + 52. https://www.dechifro.org/dcraw/dcraw.1 + 53. https://www.dechifro.org/dcraw/dcraw_eo.po + 54. http://www.acdsystems.com/ + 55. http://www.adobe.com/products/photoshop/cameraraw.html + 56. http://www.br-software.com/ + 57. http://www.breezesys.com/ + 58. http://www.conceiva.com/ + 59. http://cpicture.net/en/t_raw.html + 60. http://www.canto.com/ + 61. http://frostyplace.com/dcraw/ + 62. http://www.tanis.dk/wiki/index.php/DCRawUI + 63. https://github.com/ddroom/DDRoom/releases + 64. http://www.pretentiousname.com/jp2raw/ + 65. http://deepskystacker.free.fr/ + 66. http://www.dfstudio.com/ + 67. http://www.dpmagic.com/ + 68. http://www.lemkesoft.com/ + 69. http://sourceforge.net/projects/gtkrawgallery/ + 70. http://jcoconsulting.com/index.asp?Section=GVOCX + 71. http://www.hdrshop.com/ + 72. http://www.aragonsystem.com/ + 73. http://www.planetimagina.com/ + 74. http://www.irfanview.com/ + 75. http://www.astrosurf.com/buil/us/iris/iris.htm + 76. http://www.lightboxsoftware.com/ + 77. http://lightzoneproject.org/ + 78. http://imageingester.com/ + 79. http://www.mediarecover.com/ + 80. http://www.mixpo.com/ + 81. http://www.photoacute.com/ + 82. http://www.wildcape.com/ + 83. http://photojockey.com/ + 84. http://smatters.com/dcraw/ + 85. http://www.k-i-s.net/ + 86. http://www.datarescue.com/photorescue/ + 87. http://www.sticksoftware.com/software/PhotoReviewer.html + 88. http://www.photovault.org/ + 89. http://www.picasa.com/ + 90. http://www.picturearena.com/ + 91. http://pleiades-astrophoto.com/ + 92. http://www.polybytes.com/ + 93. http://www.prism-america.com/ + 94. http://www.iridientdigital.com/ + 95. http://www.rawmagick.com/ + 96. http://www.wizards.de/rawdrop + 97. http://www.rawtherapee.com/ + 98. http://www.serif.com/ + 99. http://www.logicaldesigns.com/ + 100. http://www.silverfast.com/ + 101. http://www.studioline.net/ + 102. http://www.hexcat.com/viewit/ + 103. http://www.dimin.net/software/viewer/ + 104. http://www.hamrick.com/ + 105. http://www.xara.com/products/xtreme/ + 106. http://www.centrostudiprogressofotografico.it/en/dcraw/ + 107. http://os4depot.net/index.php?function=showfile&file=graphics/convert/dcraw.lha + 108. http://morphos-files.ppa.pl/find.php?find=dcraw + 109. http://www.pidcock.co.uk/beos/index.html + 110. http://hobbes.nmsu.edu/h-search.php?key=dcraw + 111. http://www.riscos.info/packages/GraphicsDetails.html + 112. http://www.delorie.com/djgpp/ + 113. http://www.trnicely.net/misc/vista.html + 114. http://www.sno.phy.queensu.ca/~phil/exiftool/ + 115. https://www.dechifro.org/dcraw/scan.c + 116. https://www.dechifro.org/dcraw/read_ndf.c + 117. http://partners.adobe.com/asn/developer/PDFS/TN/TIFF6.pdf + 118. https://www.dechifro.org/N4378.pdf + 119. http://www.adobe.com/products/dng/pdfs/dng_spec.pdf + 120. http://xyrion.org/ciff/ + 121. http://web.archive.org/web/20070317042320/http://www.x3f.info/technotes/FileDocs/X3F_Format.pdf + 122. http://www.photographyblog.com/ + 123. http://www.imaging-resource.com/MFR1.HTM + 124. http://www.rawsamples.ch/ + 125. http://dl.maptools.org/dl/libtiff/tiff-3.8.2.tar.gz + 126. https://www.dechifro.org/dcraw/libtiff.patch + 127. https://www.dechifro.org/dcraw/elphel_dng.c + 128. http://www.adobe.com/products/dng/main.html + 129. http://www.adobe.com/products/photoshop/main.html + 130. http://cinepaint.sourceforge.net/ + 131. https://www.dechifro.org/dcraw/ahd_maze.png + 132. https://www.dechifro.org/dcraw/vng_grid.png + 133. http://netpbm.sourceforge.net/ + 134. http://www.imagemagick.org/ + 135. http://www.faqs.org/docs/artu/multiprogramchapter.html + 136. http://www.dpreview.com/news/0202/02021101foveonx3.asp + 137. http://digicanon.narod.ru/ + 138. http://e2500.narod.ru/raw_format_e.htm + 139. http://www.inweb.ch/foto/rawformat.html + 140. http://forums.dpreview.com/forums/read.asp?forum=1015&message=4961779 + 141. http://myfototest.narod.ru/ + 142. http://forums.dpreview.com/forums/read.asp?forum=1024&message=11773287 + 143. http://tester13.nm.ru/nikon/ + 144. http://camerahacks.10.forumer.com/ + 145. http://forums.dpreview.com/forums/read.asp?forum=1001&message=28484239 + 146. http://yousendit.com/ + 147. http://rapidshare.com/ + 148. http://sendshack.com/ + 149. http://www.sharefile.com/ + 150. http://www.sendspace.com/ + 151. http://www.megaupload.com/ + 152. http://www.targets.coloraid.de/ + 153. http://xritephoto.com/ph_product_overview.aspx?ID=1192 + 154. http://www.cmp-color.fr/eng digital target.html + 155. http://www.adobe.com/products/dng/ + 156. http://www.arri.com/DE/camera/alexa/learn/arriraw_faq/ + 157. http://kdc2tiff.sourceforge.net/ diff --git a/README.openSUSE b/README.openSUSE new file mode 100644 index 0000000..1eb9f6a --- /dev/null +++ b/README.openSUSE @@ -0,0 +1,3 @@ +To prevent name clashes, following tools from dcraw were renamed: + +parse -> dcparse diff --git a/badpixels b/badpixels new file mode 100644 index 0000000..8391f49 --- /dev/null +++ b/badpixels @@ -0,0 +1,37 @@ +# .badpixels file for my Canon PowerShot G2, serial no. 4624504380 +# dcraw will use this file if run in the same directory, or in any +# subdirectory. + +# Always use "dcraw -d -j -t 0" when locating bad pixels!! + +# Format is: pixel column, pixel row, UNIX time of death + +# This pixel went bad between August 1 and 4, 2002 + 962 91 1028350000 +# This pixel went bad between January 9 and 30, 2003 + 902 877 1043000000 + +# These are only visible in low light, so I haven't dated them: + 621 943 0 +1285 1067 0 +1286 1067 0 +2181 1532 0 + +# I swept these up 4/19/2005 + 763 36 1110000000 +1827 466 1110000000 + +# low light + 198 1288 1110000000 + 346 328 1110000000 + 429 273 1110000000 + 621 943 1110000000 + 624 874 1110000000 + 848 400 1110000000 +1682 1686 1110000000 +1892 1250 1110000000 +2234 484 1110000000 +2242 618 1110000000 + + 555 698 1135100000 # December 20-21, 2005 + 640 157 1139000000 # February 2-5, 2006 diff --git a/clean_crw.c b/clean_crw.c new file mode 100644 index 0000000..c4f6b53 --- /dev/null +++ b/clean_crw.c @@ -0,0 +1,80 @@ +/* + Because they are parsed from the end, Canon CRW files + become unreadable if garbage data is appended to them, as + often happens when files are recovered from damaged media. + This program truncates CRW files to the correct size. + + Copyright 2005 by Dave Coffin, dcoffin a cybercom o net + Free for all uses. + + $Revision$ + $Date$ + */ + +#include +#include +#include + +unsigned char *buffer; + +int get4 (int i) +{ + if (buffer[0] == 'I') + return buffer[i+3] << 24 | buffer[i+2] << 16 | buffer[i+1] << 8 | buffer[i]; + else + return buffer[i] << 24 | buffer[i+1] << 16 | buffer[i+2] << 8 | buffer[i+3]; +} + +int main (int argc, char **argv) +{ + int arg, size, end, diff, status=1; + unsigned char *fname; + FILE *fp; + + if (argc == 1) + fprintf (stderr, "Usage: %s crw_0001.crw crw_0002.crw ...\n", argv[0]); + + for (arg=1; arg < argc; arg++) { + status = 1; + fp = fopen (argv[arg], "rb"); + fseek (fp, 0, SEEK_END); + size = ftell(fp); + buffer = malloc (size + strlen(argv[arg]) + 10); + if (!buffer) { + fprintf (stderr, "Cannot allocate memory!\n"); + return 2; + } + fname = buffer + size; + sprintf (fname, "%s.clean", argv[arg]); + fseek (fp, 0, SEEK_SET); + fread (buffer, 1, size, fp); + fclose (fp); + if (strncmp (buffer, "II\x1a\0\0\0HEAPCCDR", 14) && + strncmp (buffer, "MM\0\0\0\x1aHEAPCCDR", 14)) { + fprintf (stderr, "%s is not a CRW file!\n", argv[arg]); + free (buffer); + continue; + } + for (end=size; end > 0xa0000; end--) { + diff = end - get4(end-4); + if (diff > 50 && diff < 120 && diff % 10 == 2) { + status = 0; + break; + } + } + if (status) + fprintf (stderr, "Failed to clean %s\n", argv[arg]); + else { + if ((fp = fopen (fname, "wb"))) { + fprintf (stderr, "Writing %s\n", fname); + fwrite (buffer, 1, end, fp); + fclose (fp); + } else { + perror (fname); + status = 1; + } + } + free (buffer); + } + return status; +} diff --git a/dcraw-9.28.0.tar.gz b/dcraw-9.28.0.tar.gz new file mode 100644 index 0000000..c37a94f --- /dev/null +++ b/dcraw-9.28.0.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2890c3da2642cd44c5f3bfed2c9b2c1db83da5cec09cc17e0fa72e17541fb4b9 +size 194193 diff --git a/dcraw-CVE-2017-13735.patch b/dcraw-CVE-2017-13735.patch new file mode 100644 index 0000000..94a4a92 --- /dev/null +++ b/dcraw-CVE-2017-13735.patch @@ -0,0 +1,14 @@ +diff -urNp old/dcraw.c new/dcraw.c +--- old/dcraw.c 2018-07-11 10:33:06.280425391 +0200 ++++ new/dcraw.c 2018-07-11 10:45:52.722922118 +0200 +@@ -2250,6 +2250,10 @@ void CLASS kodak_radc_load_raw() + ((short *)buf)[i] = 2048; + for (row=0; row < height; row+=4) { + FORC3 mul[c] = getbits(6); ++#ifdef LIBRAW_LIBRARY_BUILD ++ if(!mul[0] || !mul[1] || !mul[2]) ++ throw LIBRAW_EXCEPTION_IO_CORRUPT; ++#endif + FORC3 { + val = ((0x1000000/last[c] + 0x7ff) >> 12) * mul[c]; + s = val > 65564 ? 10:12; diff --git a/dcraw-CVE-2017-14608.patch b/dcraw-CVE-2017-14608.patch new file mode 100644 index 0000000..efebd30 --- /dev/null +++ b/dcraw-CVE-2017-14608.patch @@ -0,0 +1,21 @@ +diff -urNp old/dcraw.c new/dcraw.c +--- old/dcraw.c 2018-07-11 10:53:51.141803505 +0200 ++++ new/dcraw.c 2018-07-11 11:30:08.850528389 +0200 +@@ -2627,8 +2627,15 @@ void CLASS kodak_65000_load_raw() + len = MIN (256, width-col); + ret = kodak_65000_decode (buf, len); + for (i=0; i < len; i++) +- if ((RAW(row,col+i) = curve[ret ? buf[i] : +- (pred[i & 1] += buf[i])]) >> 12) derror(); ++ { ++ int idx = ret ? buf[i] : (pred[i & 1] += buf[i]); ++ if(idx >=0 && idx <= 0xffff) ++ { ++ if ((RAW(row,col+i) = curve[idx]) >> 12) derror(); ++ } ++ else ++ derror(); ++ } + } + } + diff --git a/dcraw-CVE-2018-19655.patch b/dcraw-CVE-2018-19655.patch new file mode 100644 index 0000000..4f0a8b4 --- /dev/null +++ b/dcraw-CVE-2018-19655.patch @@ -0,0 +1,39 @@ +Author: Filip Hroch +Description: stack-based buffer overflow bug +--- a/dcraw.c ++++ b/dcraw.c +@@ -8345,9 +8345,15 @@ + { + UINT64 bitbuf=0; + int vbits, col, i, c; +- ushort img[2][2064]; ++ ushort *img; + double sum[]={0,0}; + ++#define IMG2D(row,col) \ ++ img[(row)*width+(col)] ++ ++ img = (ushort *) malloc(2*width*sizeof(ushort)); ++ merror (img, "find_green()"); ++ + FORC(2) { + fseek (ifp, c ? off1:off0, SEEK_SET); + for (vbits=col=0; col < width; col++) { +@@ -8356,13 +8362,14 @@ + for (i=0; i < bite; i+=8) + bitbuf |= (unsigned) (fgetc(ifp) << i); + } +- img[c][col] = bitbuf << (64-bps-vbits) >> (64-bps); ++ IMG2D(c,col) = bitbuf << (64-bps-vbits) >> (64-bps); + } + } + FORC(width-1) { +- sum[ c & 1] += ABS(img[0][c]-img[1][c+1]); +- sum[~c & 1] += ABS(img[1][c]-img[0][c+1]); ++ sum[ c & 1] += ABS(IMG2D(0,c)-IMG2D(1,c+1)); ++ sum[~c & 1] += ABS(IMG2D(1,c)-IMG2D(0,c+1)); + } ++ free(img); + return 100 * log(sum[0]/sum[1]); + } + diff --git a/dcraw-CVE-2018-5801.patch b/dcraw-CVE-2018-5801.patch new file mode 100644 index 0000000..72a92fd --- /dev/null +++ b/dcraw-CVE-2018-5801.patch @@ -0,0 +1,125 @@ +diff -urNp old/dcraw.c new/dcraw.c +--- old/dcraw.c 2018-06-14 12:38:10.519964843 +0200 ++++ new/dcraw.c 2018-06-14 13:31:46.304679761 +0200 +@@ -1248,6 +1248,10 @@ void CLASS nikon_load_raw() + + void CLASS nikon_yuv_load_raw() + { ++#ifdef LIBRAW_LIBRARY_BUILD ++ if(!image) ++ throw LIBRAW_EXCEPTION_IO_CORRUPT; ++#endif + int row, col, yuv[4], rgb[3], b, c; + UINT64 bitbuf=0; + +@@ -1889,6 +1893,10 @@ void CLASS sinar_4shot_load_raw() + unpacked_load_raw(); + return; + } ++#ifdef LIBRAW_LIBRARY_BUILD ++ else if(!image) ++ throw LIBRAW_EXCEPTION_IO_CORRUPT; ++#endif + pixel = (ushort *) calloc (raw_width, sizeof *pixel); + merror (pixel, "sinar_4shot_load_raw()"); + for (shot=0; shot < 4; shot++) { +@@ -2188,6 +2196,11 @@ void CLASS quicktake_100_load_raw() + + void CLASS kodak_radc_load_raw() + { ++#ifdef LIBRAW_LIBRARY_BUILD ++ // All kodak radc images are 768x512 ++ if(width>768 || raw_width>768 || height > 512 || raw_height>512 ) ++ throw LIBRAW_EXCEPTION_IO_CORRUPT; ++#endif + static const char src[] = { + 1,1, 2,3, 3,4, 4,2, 5,7, 6,5, 7,6, 7,8, + 1,0, 2,1, 3,3, 4,4, 5,2, 6,7, 7,6, 8,5, 8,8, +@@ -2348,6 +2361,10 @@ void CLASS gamma_curve (double pwr, doub + + void CLASS lossy_dng_load_raw() + { ++#ifdef LIBRAW_LIBRARY_BUILD ++ if(!image) ++ throw LIBRAW_EXCEPTION_IO_CORRUPT; ++#endif + struct jpeg_decompress_struct cinfo; + struct jpeg_error_mgr jerr; + JSAMPARRAY buf; +@@ -2444,6 +2461,10 @@ void CLASS eight_bit_load_raw() + + void CLASS kodak_c330_load_raw() + { ++#ifdef LIBRAW_LIBRARY_BUILD ++ if(!image) ++ throw LIBRAW_EXCEPTION_IO_CORRUPT; ++#endif + uchar *pixel; + int row, col, y, cb, cr, rgb[3], c; + +@@ -2469,6 +2490,10 @@ void CLASS kodak_c330_load_raw() + + void CLASS kodak_c603_load_raw() + { ++#ifdef LIBRAW_LIBRARY_BUILD ++ if(!image) ++ throw LIBRAW_EXCEPTION_IO_CORRUPT; ++#endif + uchar *pixel; + int row, col, y, cb, cr, rgb[3], c; + +@@ -2596,6 +2621,10 @@ void CLASS kodak_65000_load_raw() + + void CLASS kodak_ycbcr_load_raw() + { ++#ifdef LIBRAW_LIBRARY_BUILD ++ if(!image) ++ throw LIBRAW_EXCEPTION_IO_CORRUPT; ++#endif + short buf[384], *bp; + int row, col, len, c, i, j, k, y[2][2], cb, cr, rgb[3]; + ushort *ip; +@@ -2624,6 +2653,10 @@ void CLASS kodak_ycbcr_load_raw() + + void CLASS kodak_rgb_load_raw() + { ++#ifdef LIBRAW_LIBRARY_BUILD ++ if(!image) ++ throw LIBRAW_EXCEPTION_IO_CORRUPT; ++#endif + short buf[768], *bp; + int row, col, len, c, i, rgb[3]; + ushort *ip=image[0]; +@@ -2640,6 +2673,10 @@ void CLASS kodak_rgb_load_raw() + + void CLASS kodak_thumb_load_raw() + { ++#ifdef LIBRAW_LIBRARY_BUILD ++ if(!image) ++ throw LIBRAW_EXCEPTION_IO_CORRUPT; ++#endif + int row, col; + colors = thumb_misc >> 5; + for (row=0; row < height; row++) +@@ -3109,6 +3146,10 @@ void CLASS foveon_thumb() + + void CLASS foveon_sd_load_raw() + { ++#ifdef LIBRAW_LIBRARY_BUILD ++ if(!image) ++ throw LIBRAW_EXCEPTION_IO_CORRUPT; ++#endif + struct decode *dindex; + short diff[1024]; + unsigned bitbuf=0; +@@ -3156,6 +3197,10 @@ void CLASS foveon_huff (ushort *huff) + + void CLASS foveon_dp_load_raw() + { ++#ifdef LIBRAW_LIBRARY_BUILD ++ if(!image) ++ throw LIBRAW_EXCEPTION_IO_CORRUPT; ++#endif + unsigned c, roff[4], row, col, diff; + ushort huff[512], vpred[2][2], hpred[2]; + diff --git a/dcraw-CVE-2021-3624.patch b/dcraw-CVE-2021-3624.patch new file mode 100644 index 0000000..67f9e7f --- /dev/null +++ b/dcraw-CVE-2021-3624.patch @@ -0,0 +1,17 @@ +--- dcraw/dcraw.c 2022-04-12 14:29:23.791896447 +0200 ++++ dcraw/dcraw.c 2022-04-12 14:59:50.767180929 +0200 +@@ -3289,7 +3289,13 @@ + } + } else if (type == 4) { + free (meta_data); +- meta_data = (char *) malloc (meta_length = wide*high*3/2); ++ meta_data = NULL; ++ meta_length = wide*high*3/2; ++ if (meta_length/wide != high*3/2) { ++ fprintf(stderr, "Potential buffer overflow (meta_length %u, wide %u, high %u). Bailing out...\n", meta_length, wide, high); ++ longjmp(failure, 2); ++ } ++ meta_data = (char *) malloc (meta_length); + merror (meta_data, "foveon_load_camf()"); + foveon_huff (huff); + get4(); diff --git a/dcraw-glibc-2.38.patch b/dcraw-glibc-2.38.patch new file mode 100644 index 0000000..7ff0c48 --- /dev/null +++ b/dcraw-glibc-2.38.patch @@ -0,0 +1,24 @@ +Index: dcraw/parse.c +=================================================================== +--- dcraw.orig/parse.c ++++ dcraw/parse.c +@@ -1213,7 +1213,7 @@ void parse_qt (int level, int end) + } + } + +-char *memmem (char *haystack, size_t haystacklen, ++static char *my_memmem (char *haystack, size_t haystacklen, + char *needle, size_t needlelen) + { + char *c; +@@ -1239,8 +1239,8 @@ void identify() + tread (head, 1, 32, ifp); + tseek (ifp, 0, SEEK_END); + fsize = ftell(ifp); +- if ((cp = memmem (head, 32, "MMMM", 4)) || +- (cp = memmem (head, 32, "IIII", 4))) { ++ if ((cp = my_memmem (head, 32, "MMMM", 4)) || ++ (cp = my_memmem (head, 32, "IIII", 4))) { + parse_phase_one (cp-head); + if (cp-head) parse_tiff (0,0); + } else if (order == 0x4949 || order == 0x4d4d) { diff --git a/dcraw.changes b/dcraw.changes new file mode 100644 index 0000000..b8786b3 --- /dev/null +++ b/dcraw.changes @@ -0,0 +1,532 @@ +------------------------------------------------------------------- +Mon Aug 7 09:53:25 UTC 2023 - Dirk Müller + +- add dcraw-glibc-2.38.patch to fix prototype clash on memmem with glibc 2.38+ + +------------------------------------------------------------------- +Tue Apr 12 11:30:56 UTC 2022 - Fridrich Strba + +- Added patches: + * iowrappers.patch + + Written wrappers of fread(),fwrite(),fseek() library functions + which check their return values. If an input/output failure is + detected, dcraw immediately exits with non-zero status and + prints a descriptive message (bsc#1097973, CVE-2018-5805; + bsc#1097974, CVE-2018-5806; bsc#1117622, CVE-2018-19565; + bsc#1117517, CVE-2018-19566; bsc#1117512, CVE-2018-19567; + bsc#1117436, CVE-2018-19568) + * dcraw-CVE-2021-3624.patch + + Bail out if integer overflow happened and the allocated buffer + would be too small (bsc#1189642, CVE-2021-3624) + +------------------------------------------------------------------- +Sun Aug 16 22:39:47 UTC 2020 - Matthias Eliasson + +- Update to version 9.28.0: + dcraw - revision 1.478 + * Caught up on two years' worth of new cameras. +- Update upstream URL to new address +- Add patches for CVEs: + * dcraw-CVE-2017-13735.patch (CVE-2017-13735, bsc#1056170) + * dcraw-CVE-2017-14608.patch (CVE-2017-14608, bsc#1063798) + * dcraw-CVE-2018-19655.patch (CVE-2018-19655, bsc#1117896) + * dcraw-CVE-2018-5801.patch (CVE-2018-5801, bsc#1084690) +- Run spec-cleaner + * Remove package groups + +------------------------------------------------------------------- +Fri Aug 5 22:12:55 UTC 2016 - asterios.dramis@gmail.com + +- Update to version 9.27.0: + dcraw - revision 1.477 + * Added "-o 6" for ACES colorspace. + * Copied color matrices from DNG Converter 9.5.1. + * Support the Canon EOS 80D & IXUS 160, Fuji X-E2 & X-E2S & + X-Pro2. + +------------------------------------------------------------------- +Mon Jul 20 07:34:22 UTC 2015 - fstrba@suse.com + +- Update to version 9.26.0: + * fixes: + dcraw revision 1.476 + * Support the Blackmagic URSA, Nokia N9, and Photron BC2-HD. + * Support the Canon EOS 750D, 760D, EOS M, and sRAW/mRAW for EOS 5DS R. + * When there's a tie for largest raw image, "-s" says which to decode. + * Fixed null-byte warnings in TIFF output. + dcraw revision 1.475 + * Use typecasts instead of [0] to flatten multi-dimensional arrays. + dcraw revision 1.474 + * Updated color matrices, support the Canon EOS 5DS. + +------------------------------------------------------------------- +Fri Feb 27 22:05:35 UTC 2015 - asterios.dramis@gmail.com + +- Update to version 9.24.2: + dcraw - revision 1.473 + * Canon multi-exposure files are already white-balanced. + * Moved border_interpolate() to the end of xtrans_interpolate(). + From version 9.24.1: + * No visible changes. + From version 9.24.0: + dcraw - revision 1.471 + * Support all format options of the Nikon D4S and D810. + * Guess which filter pattern OmniVision cameras use. + dcparse - revision 1.77 + * Display OmniVision's MakerNote. + From version 9.23.0: + dcraw - revision 1.470 + * Fixed data errors with Olympus E-M5MarkII HR images. + * Support the Lenovo A820. + * Copied color matrices from DNG Converter 8.7.1. + * Support pre-release Sonys and Canons that lack a proper model + name. + * Support the Samsung NX1 (yet another compression algorithm). + * Read camera white balance in all professional Kodak cameras. + * Reduced zippering in Fuji X-Trans interpolation. + * Support YCbCr files from the Kodak C330. + * Support Hasselblad multi-shot files. + dcparse - revision 1.76 + * Parse Redcine and Canon EOS QuickTime movies. + +------------------------------------------------------------------- +Tue Jul 15 17:59:16 UTC 2014 - asterios.dramis@gmail.com + +- Update to version 9.22: + dcraw - revision 1.467 + * Correctly handle Fuji X-Trans images in DNG format. + * Copied color matrices from DNG Converter 8.5. + From version 9.21: + dcraw - revision 1.465 + * In colorcheck(), darken sample squares and do a second pass for exact white + balance. + * Removed C99 dependency in Phase One code. + * Correctly dereference TIFF type 13 (SubIFD) tags. + * Removed redundant strings. + * Support Lossy DNG files that lack an OpcodeList2 tag. + * Decode DNG files made from Fuji X-Trans photos. + * Support the Canon G1 X Mark II, Nikon P340, Samsing NX mini. + * Patched in Anders Torger's code for Phase One correction. + * Correctly crop all Sony cameras, read Panasonic blacklevels. + +------------------------------------------------------------------- +Mon Feb 17 21:56:48 UTC 2014 - asterios.dramis@gmail.com + +- Update to version 9.20: + dcraw - revision 1.461 + * Fixed Sony A700 black level. + * Added three temporary color matrices. + * Use Little CMS version 2. + * Support the Kodak 12-megapixel camera(s). + * Can now use "-M" with a DNG file that embeds a bad color matrix. + * Improved support for Nokia cameraphones. + * Support the Alcatel 5235D, Powershot G16 and S120, Pentax K-3, etc. + * Added tone curve for Canon RMF files. + * Copied color matrices from DNG Converter 8.3. + * Support blacklevel patterns up to 64x64. + dcparse - revision 1.75 + * Read the Pentax K-3 MakerNote. +- Renamed README.SuSE to README.openSUSE. +- Added new build requirement liblcms2-devel (removed liblcms-devel). + +------------------------------------------------------------------- +Sun Jun 16 20:54:03 UTC 2013 - asterios.dramis@gmail.com + +- Update to version 9.19: + dcraw - revision 1.456 + * Fix green spots when half-sizing Fuji X-Trans images. + * Support the Baumer TXG14, OmniVision OV5647 (Raspberry Pi), and Samsung + NX2000. + From version 9.18: + dcraw - revision 1.455 + * Support the Fuji HS50, X20, X100S, SL1000, Samsung NX300, Canon A3300 and + EOS C500, and Olympus XZ-10. + * Added Frank Markesteijn's X-Trans demosaic algorithm. + * Lowercased the names of all camera makers. + * Hardened dcraw against corrupt input files. + * Tableized away large chunks of code in identify(). +- Removed dcraw.1.patch (not needed anymore). + +------------------------------------------------------------------- +Fri Jan 18 12:52:55 UTC 2013 - postadal@suse.cz + +- Update to version 9.17: + dcraw - revision 1.454 + * Copied color matrices from DNG Converter 7.3. + * Support the Canon EOS 6D, 1DX, SX50, Casio EX-ZR100, Fuji X-E1 & XF1, + Pentax K-5 II (s), and Samsung EX2F +- updated update_dcraw script to be able to work with dcraw tarball + +------------------------------------------------------------------- +Mon Jul 30 20:44:51 UTC 2012 - asterios.dramis@gmail.com + +- Update to version 9.16: + dcraw - revision 1.452 + * Measured saturation level on the Canon EOS-1D X. + * Support the Samsung NX1000 and Sony RX100. + * Support the Canon EOS 650D, Samsung NX20, and Sigma SD1. + +------------------------------------------------------------------- +Tue Jun 26 17:57:13 UTC 2012 - asterios.dramis@gmail.com + +- Update to version 9.15: + dcraw - revision 1.449 + * Fixed gravity sensor for Canon 5D Mark III with Firmware Version 1.1.x. + * Decode CAMF and IMAG blocks from Sigma SD15 and DP cameras. Added "-E" and + "-I" options to support raw pixel substitution. Support Adobe Lossy DNG and + the Imacon Flexframe 3f format. Support the Canon G1-X, 1D-X, 5D Mark III, + the Fuji X-Pro1, X-S1, and many others. + * Support the Casio EX-Z500. + dcparse - revision 1.74 + * Decode CAMF blocks from Sigma SD15 and DP cameras. +- Dropped dcraw-omp.patch (wasn't used anyway). + +------------------------------------------------------------------- +Tue Mar 27 08:41:25 UTC 2012 - cfarrell@suse.com + +- license update: GPL-2.0+ + Use option (b) from dcraw.c + +------------------------------------------------------------------- +Fri Dec 23 18:52:51 UTC 2011 - asterios.dramis@gmail.com + +- Update to version 9.12: + dcraw - revision 1.446 + * Support the Canon S100, Nikon 1 J1 and V1, Panasonic GX1, Fuji X10, and + Samsung NX200 with color matrices from DNG Converter 6.6. + +------------------------------------------------------------------- +Fri Oct 7 19:34:48 UTC 2011 - asterios.dramis@gmail.com + +- Update to version 9.11: + dcraw - revision 1.445 + * Copied new color matrices from DNG Converter 6.5. +- Spec file updates: + * Changes based on spec-cleaner run. + * Removed support for openSUSE < 11.3. + +------------------------------------------------------------------- +Sun Sep 18 17:17:12 UTC 2011 - jengelh@medozas.de + +- Remove redundant tags/sections from specfile + (cf. packaging guidelines) + +------------------------------------------------------------------- +Wed Aug 3 21:04:01 UTC 2011 - asterios.dramis@gmail.com + +- updated to version 9.10 + dcraw - revision 1.444 + * Support ARRIRAW and Redcode R3D raw formats (video only). + * Support the Leica D-LUX 5 and V-LUX 2, Panasonic G3 and GF3, Olympus E-P3, + Sony NEX-C3 and SLT-A35, and Canon SX30. + * Updated support for Nikon encrypted WB and Canon sRAW/mRAW. +- Spec file updates: + * Added libjasper-devel in BuildRequires:. + +------------------------------------------------------------------- +Sat May 14 12:05:25 UTC 2011 - asterios.dramis@gmail.com + +- updated to version 9.08 + dcraw - revision 1.443 + * Support the Fuji HS20EXR/F550EXR, Kodak Z990, Leaf AFi-II 12, Nikon D5100 + and Samsung NX11 and NX100. + dcparse - revision 1.73 + * Improved parsing of Fuji images. +- Spec file updates: + * Small fix if suse_version is not set. + +------------------------------------------------------------------- +Mon Apr 4 20:18:58 UTC 2011 - asterios.dramis@gmail.com + +- updated to version 9.07 (dcraw revision 1.442) + * Support the Hasselblad 9044x6732 back, Leaf 1068x1464 back, Fuji X100 and + Canon 600D and 1100D. + +------------------------------------------------------------------- +Wed Mar 23 19:09:55 UTC 2011 - asterios.dramis@gmail.com + +- updated to version 9.06 + * Support the Nikon D3100 & D7000 & P7000, Panasonic FZ40 & FZ100 & LX5, + Samsung WB2000, Nokia X2, Canon SX120 & PowerShot G12, Hasselblad H4D, + Pentax 645D & K-5 & K-r, Sony SLT-A33 & SLT-A55V, Canon SX20 IS, Samsung + EX1, Sony A450, Kodak Z981, Olympus E-P2, Panasonic G2 & GF1, Samsung WB550 + and NX10, Casio EX-Z1050, Fuji HS10, Canon EOS 550D / Digital Rebel T2i / + Kiss Digital X4. + * Support high-ISO images from the Samsung WB2000. + * Read correct camera WB from Nikon NRW and Samsung SRW files. + * Copied color matrices from Adobe DNG Converter 6.3. + * Fixed rotation for Kodak EasyShare and some Canon EOS photos. + * Get Fuji HS10 black level from the metadata. + * Built color matrices for the Sony NEX-3 and NEX-5. + * Support A100 images modified by Sony software. + * Split the darkness level into four separate color channels. +- Replaced dcraw.c and dcraw.1 with the package tarball provided from the official + site. +- Added clean_crw and fuji_green programs. +- Added rawphoto.c file in the documentation (gimp-plugin). +- Removed dcwrap program (no longer provided from the official site). +- Spec file updates: + * Changed version numbering scheme (used the one from the tarball provided). + * Changes based on rpmdevtools templates and spec-cleaner run. + * Added description for dcraw-omp.patch based on openSUSE Patches Guidelines. + * Added gettext-runtime in BuildRequires:. + * Added dcraw-lang package. + * Compile also fujiturn16 program (to rotate 48-bit PPM images). + * Updates in %prep, %build, %install and %files sections based also on Fedora + and Debian packages. +- Rebased dcraw-omp.patch to apply cleanly. +- Added a patch for dcraw.1 to fix "macro `LO' not defined" rpm post build + check warning. +- Added a patch for fuji_green.c to fix gcc implicit declaration warning. + +------------------------------------------------------------------- +Sun May 2 00:56:47 CEST 2010 - postadal@suse.cz + +- updated to RCS 1.432 + * Support the Canon EOS-1D Mark IV and PowerShots G11 and S90, + Casio EX-Z750, Pentax K-x, Fuji SX200EXR, Sony A550, Sony DSLR-A850, + Canon EOS 7D, Casio EX-Z850, Canon A470, G11, Nikon D3000, + Panasonic FZ35/FZ38, Casio Z60, Casio Z75, Kodak Z980, Pentax K-7, + Olympus X200,D560Z,C350Z + * Correctly crop Nikon D300S photos + * Support camera WB for the Kodak EasyShare Z980 and Z1015 + * Decode all packed 10-bit and 12-bit formats in one function + * Copied color matrices from Adobe DNG Converter 5.4 + +------------------------------------------------------------------- +Sun Nov 15 16:39:58 CET 2009 - meissner@suse.de + +- rediffed OMP patch to get fuzz-0 + +------------------------------------------------------------------- +Thu Aug 6 16:11:05 CEST 2009 - postadal@suse.cz + +- updated to RCS 1.425 + * Support the Phase One P45+, Casio EX-S20, Samsung S850, Agfa DC-833m, + Panasonic DMC-GH1, Canon SX1, SX110,, EOS 500D/Rebel T1i/Kiss X3, + Motorola PIXL, Kodak Z1015, Olympus E-30, Pentax K2000/K-m, Hasselblad V96C, + Samsung S85, Leaf AFi 7, Panasonic FX150 and G1, Canon PowerShot G10, + Panasonics LX3 and FZ28, Nikons D90 and P6000, Canon EOS 50D, Sony A900, + * When sampling dark pixels, don't get too close to the light pixels + * Linearize the Apple Quicktake, Kodak DC40/DC50, and Logitech Fotoman Pixtura + * Added "-g" option for custom gamma curves + * Support 3672 x 2486 images from the Panasonic DMC-FZ50 + * Correctly handle negative pixels in split NEF files + * Support GPS-tagged ORFs and anonymous DNGs + * Support the sRAW1 and sRAW2 modes of the Canon EOS 50D and 5D Mark II +- updated omp.patch + +------------------------------------------------------------------- +Sun Sep 7 22:40:44 CEST 2008 - postadal@suse.cz + +- updated to RCS 1.404 + * Support the Kodak C603, Nikon D700, Canon EOS 1000D, + Canon PowerShot SD300, and Olympus E-520, SONY A300 + * Removed useless code from ppg_interpolate() + * Don't crash on corrupt CR2 files + * Extract the largest JPEG from any X3F file + * Fixed camera WB on the A200 + * Set model-specific saturation levels in adobe_coeff() + +------------------------------------------------------------------- +Sun Apr 13 22:57:10 CEST 2008 - postadal@suse.cz + +- updated to RCS 1.401 + * Copy GPS data into thumbnails and TIFF output + * Support the Apple QuickTake 200, Fuji IS-1, Sony DSLR-A350, + Pentax K20D, Nokia N95, and Canon PowerShots A460, A530, and A650 + Canon EOS 450D, Nikon D60, and Fuji S100FS, Olympus E-420 + * Copied new matrices from Adobe DNG Converter 4.4 + * fixed sRAW support (broke Fuji DNG files) +- added omp.patch to speed up decoding (-fomp disabled by default) + +------------------------------------------------------------------- +Tue Feb 12 10:54:10 CET 2008 - postadal@suse.cz + +- updated to RCS 1.398 + * Added the "-P" and "-S" options + * Support the Sony DSLR-A200 and the PowerShots A720 and S5 IS + * Support the Panasonic DMC-L10, added the "-W" option + * Cropped four columns from the Nikon D3 + * Abolished the getrat() macro, support the Hasselblad H3D + * Added the Olympus E-3 and adjusted a few maximums + * Support the AVT F-080C, Canon EOS 40D, Canon EOS-1Ds Mark III, + Canon PowerShot G9, Nikon Coolpix S6, Nikon D3, Nikon D300, + Panasonic DMC-FZ18, and Sony DSLR-A700 + * Support the new Canon sRAW CR2 format + * Added median filtering after interpolation + * Use fseeko() and ftello() only when needed + * Reject TIFF files with unsupported Compression tags + +------------------------------------------------------------------- +Fri Aug 3 17:16:18 CEST 2007 - postadal@suse.cz + +- updated to RCS 1.390 + * Added Patterned Pixel Grouping interpolation + * Support 3096x2103 mode for the Panasonic DMC-FZ8. + * Added "-C" option to correct chromatic aberration. + * Support the Hasselblad CFV, Kodak EasyShare C330, and Nikon D40X. + * Use a switch statement for Leica and Panasonic models. + * Output seven new TIFF tags, including ImageDescription and Artist. + * Generated color matrices for the Apple QuickTake and Phase One H 20. + * Copied new matrices from Adobe DNG Converter 4.1. + * Added "-M" option and improved PPG interpolation. + * Reports of corruption in 16-bit linear DNGs were false. + * Support all Lossless JPEG predictors. + * Reject 8-bit grayscale TIFFs. + * Decode raw CINE files, which may exceed 2GB. + * Error-check the "-s" option, and enable "-s all". + * Support camera WB for the Canon EOS-1D and EOS-1DS. + * Use full output range for "-H 2". + * Added color matrix for the Canon PowerShot A640. + * When they differ, use DateTimeOriginal instead of DateTime. + +------------------------------------------------------------------- +Thu May 3 14:31:24 CEST 2007 - postadal@suse.cz + +- updated to RCS 1.379 + * Offer blended highlights with the "-H 2" option + * Set "shot_order" for ORF and CR2 files + * Added "-A" option to select a rectangle for white balance + * Protect against overflow attacks on malloc() or calloc() + * Nucore raw formats are not used outside Nucore, so drop them + * Support the Canon PowerShots A630 and A640, Panasonic DMC-FZ8, + * Sigma SD14, Apple QuickTake 100 & 150, Mamiya ZD, Casio QV-R41, + Olympus E-410 and Pentax Optio 750Z +- fixed doc permissions + +------------------------------------------------------------------- +Wed Apr 25 02:12:58 CEST 2007 - postadal@suse.cz + +- updated to RCS 1.377 + * Added a color matrix for the Fuji S6000fd + * Set aspect ratio for the Kodak DC20 and DC25 + * Replaced bilateral filter with wavelet denoising + * Fixed incompatibility between "-f" and "-p" + * Fixed strange color casts with the Polaroid x530 + * Added Adobe matrices for the Nikon D40 and Pentax K10D + * Found larger JPEG thumbs for Nikon D100,D1H,D1X,D2H,D2X,E5000,E5700 + * Support the Canon EOS-1D Mark III, Olympus SP550UZ, Fuji FinePix S5Pro + * Use the "a trous" wavelet transform instead of the JPEG2000 method + * Apply sqrt() to denoise highlights and shadows evenly + * Optimized AHD interpolation to take 22% less time + * Better detect and reject non-raw TIFFs +- fixed dcraw permission + +------------------------------------------------------------------- +Thu Feb 8 12:29:52 CET 2007 - postadal@suse.cz + +- updated to RCS 1.364 + * Built a color matrix for Canon PowerShot S3 IS, Canon PowerShot A610 + * Added Olympus SP510UZ, Panasonic DMC-L1, Leica Digilux 3, + Casio EX-Z4, Kodak DCS200, Canon PowerShots A620, S3 IS, Pentax K10D, + Canon PowerShot A610 + * Suport Olympus E-400, Sinar 4-shot and Sinar IA file format + * Added "-K" option for dark-frame subtraction + * Get the Olympus black level from the ORF metadata. + * Found a more reliable way to identify 4775936-byte images + +------------------------------------------------------------------- +Mon Oct 16 22:47:15 CEST 2006 - postadal@suse.cz + +- updated to RCS 1.353 + * added support for Pentax K100D, Nikon D200, D80, E3200, + Canon EOS 400D, Panasonic DMC-LX2, DMC-FZ50 + * correctly display long exposure times for CRW files + * added color matrices from Adobe DNG Converter 3.5 + * display the focal length of Canon CRW images + +------------------------------------------------------------------- +Thu Aug 17 17:35:46 CEST 2006 - postadal@suse.cz + +- updated to RCS 1.340 + * improved support for the Olympus E-330 + +------------------------------------------------------------------- +Wed Aug 2 12:35:19 CEST 2006 - postadal@suse.cz + +- updated to RCS 1.338 + * added "-H 2" option for rudimentary highlight recovery + * new "-T" option provides TIFF output with metadata and ICC profile + * replaced "-r" and "-l" options with raw white balance + * added support for Imacon Ixpress 22-Mp, Leaf Aptus 75, Leica D-Lux 2, + Sony DSLR-A100, Minolta DiMAGE G530, Sinar 4080x4080, Samsung GX-1S + * fixed camera WB for Canon EOS 10D, 300D, and clones + * added camera WB for the Kodak DCS Pro SLR models, Imacon Ixpress, + Kodak P850/P880 + +------------------------------------------------------------------- +Sun Mar 26 15:56:10 CEST 2006 - postadal@suse.cz + +- updated to RCS 1.319 + * new color matrix for the Nikon E700, E800, and E950 + * new "-D" option to output unscaled raw pixels (totally raw) + * fixed defective pixels and columns in Phase One images + +------------------------------------------------------------------- +Thu Feb 9 22:12:25 CET 2006 - dmueller@suse.de + +- update to RCS 1.315 (#112733) + +------------------------------------------------------------------- +Wed Feb 8 02:36:13 CET 2006 - dmueller@suse.de + +- update to RCS 1.314: + Updated color matrices based on Adobe DNG Converter 3.3. + Added Kodak ProPhoto D65 as an output option. + +------------------------------------------------------------------- +Thu Jan 26 12:29:16 CET 2006 - sbrabec@suse.cz + +- Updated to dcraw v8, RCS 1.313. +- Added simple update_dcraw script. + +------------------------------------------------------------------- +Wed Jan 25 21:35:24 CET 2006 - mls@suse.de + +- converted neededforbuild to BuildRequires + +------------------------------------------------------------------- +Wed Jan 11 15:56:34 CET 2006 - adrian@suse.de + +- add stack protector compiler flag + +------------------------------------------------------------------- +Thu Oct 13 13:48:05 CEST 2005 - postadal@suse.cz + +- update to RCS 1.290 + * added as default new interpolation algorithm AHD + (Adaptive homogeneity-directed demosaicing algorithm) + * new Bilateral filtering to remove color noises in CIELAB space +- update dcraw.1, fujiturn, dcparse (parse.c) +- removed crwfixdates (fixdates.c) superseded by "dcraw -z" + +------------------------------------------------------------------- +Tue Jun 7 12:00:09 CEST 2005 - adrian@suse.de + +- update to RCS 1.263 +- compile with -fno-strict-aliasing to avoid compiler errors + +------------------------------------------------------------------- +Fri Jun 3 12:46:05 CEST 2005 - postadal@suse.cz + +- Updated to current version on maintainers website. + RCS version 1.262. + +------------------------------------------------------------------- +Fri Feb 4 15:43:01 CET 2005 - meissner@suse.de + +- Updated to current version on maintainers website. + RCS version 1.234. + +------------------------------------------------------------------- +Thu Aug 26 14:05:18 CEST 2004 - sbrabec@suse.cz + +- Updated to dcraw RCS version 1.200. +- Added more tools and documentation. + +------------------------------------------------------------------- +Wed Jun 16 10:48:17 CEST 2004 - adrian@suse.de + +- initial package of version 1.194 + diff --git a/dcraw.spec b/dcraw.spec new file mode 100644 index 0000000..a327fa1 --- /dev/null +++ b/dcraw.spec @@ -0,0 +1,167 @@ +# +# spec file for package dcraw +# +# Copyright (c) 2023 SUSE LLC +# +# All modifications and additions to the file contributed by third parties +# remain the property of their copyright owners, unless otherwise agreed +# upon. The license for this file, and modifications and additions to the +# file, is the same license as for the pristine package itself (unless the +# license for the pristine package is not an Open Source License, in which +# case the license is the MIT License). An "Open Source License" is a +# license that conforms to the Open Source Definition (Version 1.9) +# published by the Open Source Initiative. + +# Please submit bugfixes or comments via https://bugs.opensuse.org/ +# + + +Name: dcraw +Version: 9.28.0 +Release: 0 +Summary: Raw Digital Photo Decoding +License: GPL-2.0-or-later +URL: https://www.dechifro.org/dcraw/ +#*** NOTE: run "sh update_dcraw" to update to latest version of the following sources ("wget", "rcs" and "lynx" packages are required for the update). +Source0: https://www.dechifro.org/dcraw/archive/dcraw-%{version}.tar.gz +Source1: README +# http://www.cybercom.net/~dcoffin/dcraw/.badpixels +Source2: badpixels +Source3: https://www.dechifro.org/dcraw/clean_crw.c +Source4: https://www.dechifro.org/dcraw/fuji_green.c +Source5: https://www.dechifro.org/dcraw/fujiturn.c +Source6: https://www.dechifro.org/dcraw/parse.c +Source7: https://www.dechifro.org/dcraw/rawphoto.c +#*** +Source100: README.openSUSE +Source101: update_dcraw +# PATCH-FIX-OPENSUSE fuji_green.c_fix_gcc_warnings.patch asterios.dramis@gmail.com -- Fix gcc implicit declaration warning +Patch0: fuji_green.c_fix_gcc_warnings.patch +# PATCH-FIX-UPSTREAM dcraw-CVE-2017-13735.patch +Patch1: dcraw-CVE-2017-13735.patch +# PATCH-FIX-UPSTREAM dcraw-CVE-2017-14608.patch +Patch2: dcraw-CVE-2017-14608.patch +# PATCH-FIX-UPSTREAM dcraw-CVE-2018-19655.patch +Patch3: dcraw-CVE-2018-19655.patch +# PATCH-FIX-UPSTREAM dcraw-CVE-2018-5801.patch +Patch4: dcraw-CVE-2018-5801.patch +Patch5: iowrappers.patch +Patch6: dcraw-CVE-2021-3624.patch +Patch7: dcraw-glibc-2.38.patch +BuildRequires: gettext-runtime +BuildRequires: libjasper-devel +BuildRequires: libjpeg-devel +BuildRequires: liblcms2-devel +Recommends: %{name}-lang = %{version} + +%description +Command line tools for raw digital photo decoding and processing. + +%lang_package + +%prep +%setup -q -n %{name} +cp -a %{SOURCE3} %{SOURCE4} %{SOURCE5} %{SOURCE6} . +%patch0 +%patch1 -p1 +%patch2 -p1 +%patch3 -p1 +%patch4 -p1 +%patch5 -p1 +%patch6 -p1 +%patch7 -p1 + +%build +export CFLAGS="%{optflags} -fno-strict-aliasing -fstack-protector-all" + +for file in *.c ; do + LDFLAGS= + OTHERFLAGS= + if test $file = dcraw.c ; then + LDFLAGS="-lm -ljasper -ljpeg -llcms2 -DLOCALEDIR=\""%{_datadir}/locale"\"" + fi + if test $file = fuji_green.c ; then + LDFLAGS="-lm" + fi + gcc $CFLAGS $OTHERFLAGS -o ${file%.c} $file $LDFLAGS +done +# Compile with -D_16BIT to rotate 48-bit PPM images +gcc $CFLAGS -D_16BIT -o fujiturn16 fujiturn.c + +# Build language catalogs +for catsrc in dcraw_*.po ; do + lang="${catsrc%.po}" + lang="${lang#dcraw_}" + msgfmt -o "dcraw_${lang}.mo" "$catsrc" +done + +%install +install -d -m 0755 %{buildroot}%{_bindir} +install -d -m 0755 %{buildroot}%{_mandir}/man1 + +install -pm 0755 dcraw %{buildroot}%{_bindir}/ +install -pm 0644 dcraw.1 %{buildroot}%{_mandir}/man1/ + +install -pm 0755 clean_crw %{buildroot}%{_bindir}/ +install -pm 0755 fuji_green %{buildroot}%{_bindir}/ +install -pm 0755 fujiturn %{buildroot}%{_bindir}/ +install -pm 0755 fujiturn16 %{buildroot}%{_bindir}/ +install -pm 0755 parse %{buildroot}%{_bindir}/dcparse + +# Install language catalogs +for catalog in dcraw_*.mo ; do + lang="${catalog%.mo}" + lang="${lang#dcraw_}" + install -d -m 0755 "%{buildroot}%{_datadir}/locale/${lang}/LC_MESSAGES" + install -pm 0644 "$catalog" "%{buildroot}%{_datadir}/locale/${lang}/LC_MESSAGES/dcraw.mo" +done + +# Install localized manpages +for manpage in dcraw_*.1 ; do + lang="${manpage%.1}" + lang="${lang#dcraw_}" + install -d -m 0755 "%{buildroot}%{_mandir}/${lang}/man1" + install -pm 0644 "${manpage}" "%{buildroot}%{_mandir}/${lang}/man1/dcraw.1" +done + +# Documentation +cp -a %{SOURCE1} %{SOURCE2} %{SOURCE7} %{SOURCE100} . +mv badpixels .badpixels + +%find_lang %{name} --with-man + +%files +%doc .badpixels README README.openSUSE rawphoto.c +%{_bindir}/clean_crw +%{_bindir}/dcparse +%{_bindir}/dcraw +%{_bindir}/fuji_green +%{_bindir}/fujiturn +%{_bindir}/fujiturn16 +%{_mandir}/man1/dcraw.1%{?ext_man} + +%files lang -f %{name}.lang +%dir %{_mandir}/ca +%dir %{_mandir}/ca/man1 +%dir %{_mandir}/cs +%dir %{_mandir}/cs/man1 +%dir %{_mandir}/da +%dir %{_mandir}/da/man1 +%dir %{_mandir}/eo +%dir %{_mandir}/eo/man1 +%dir %{_mandir}/hu +%dir %{_mandir}/hu/man1 +%dir %{_mandir}/pl +%dir %{_mandir}/pl/man1 +%dir %{_mandir}/pt +%dir %{_mandir}/pt/man1 +%dir %{_mandir}/ro +%dir %{_mandir}/ro/man1 +%dir %{_mandir}/sv +%dir %{_mandir}/sv/man1 +%dir %{_mandir}/zh_CN +%dir %{_mandir}/zh_CN/man1 +%dir %{_mandir}/zh_TW +%dir %{_mandir}/zh_TW/man1 + +%changelog diff --git a/fuji_green.c b/fuji_green.c new file mode 100644 index 0000000..67a4750 --- /dev/null +++ b/fuji_green.c @@ -0,0 +1,375 @@ +/* + fuji_green -- read Fuji green pixels + + $Revision: 1.2 $ + $Date: 2006/03/01 01:46:47 $ + */ + +#include +#include +#include +#include +#include +#include + +#define ushort UshORt +typedef unsigned char uchar; +typedef unsigned short ushort; + +FILE *ifp; +short order; +char *ifname, make[64], model[64]; +int data_offset, raw_height, raw_width, height, width; +int fuji_layout, fuji_secondary, use_secondary=0, verbose=0; +ushort *image; +void (*load_raw)(); +float bright=1.0; +void write_ppm(FILE *); +void (*write_fun)(FILE *) = write_ppm; +jmp_buf failure; + +#define CLASS + +void CLASS merror (void *ptr, char *where) +{ + if (ptr) return; + fprintf (stderr, "%s: Out of memory in %s\n", ifname, where); + longjmp (failure, 1); +} + +ushort CLASS get2() +{ + uchar a, b; + + a = fgetc(ifp); + b = fgetc(ifp); + if (order == 0x4949) /* "II" means little-endian */ + return a + (b << 8); + else /* "MM" means big-endian */ + return (a << 8) + b; +} + +int CLASS get4() +{ + uchar a, b, c, d; + + a = fgetc(ifp); + b = fgetc(ifp); + c = fgetc(ifp); + d = fgetc(ifp); + if (order == 0x4949) + return a + (b << 8) + (c << 16) + (d << 24); + else + return (a << 24) + (b << 16) + (c << 8) + d; +} + +/* + Faster than calling get2() multiple times. + */ +void CLASS read_shorts (ushort *pixel, int count) +{ + fread (pixel, 2, count, ifp); + if ((order == 0x4949) == (ntohs(0x1234) == 0x1234)) + swab (pixel, pixel, count*2); +} + +void CLASS fuji_load_raw() +{ + ushort *pixel, *img; + int row, col; + + pixel = calloc (raw_width, 2); + merror (pixel, "fuji_load_raw()"); + for (row=0; row < height; row++) + if (fuji_layout) { + read_shorts (image+row*width, width); + fseek (ifp, (raw_width*2 - width)*2, SEEK_CUR); + } else { + read_shorts (pixel, raw_width); + for (img=image+row*width, col=0; col < width; col++) + img[col] = pixel[col*2+1]; + } + free (pixel); +} + +void CLASS parse_fuji (int offset) +{ + unsigned entries, tag, len, save; + + fseek (ifp, offset, SEEK_SET); + entries = get4(); + if (entries > 255) return; + while (entries--) { + tag = get2(); + len = get2(); + save = ftell(ifp); + if (tag == 0x100) { + raw_height = get2(); + raw_width = get2(); + } else if (tag == 0x121) { + height = get2(); + width = get2(); + } else if (tag == 0x130) + fuji_layout = fgetc(ifp) >> 7; + fseek (ifp, save+len, SEEK_SET); + } + if (fuji_layout) { + height *= 2; + width /= 2; + } +} + +void CLASS parse_tiff (int base) +{ + int doff, entries, tag, type, len, save; + + fseek (ifp, base, SEEK_SET); + order = get2(); + get2(); /* Should be 42 for standard TIFF */ + while ((doff = get4())) { + fseek (ifp, doff+base, SEEK_SET); + entries = get2(); + while (entries--) { + tag = get2(); + type = get2(); + len = get4(); + save = ftell(ifp)+4; + fseek (ifp, base+get4(), SEEK_SET); + switch (tag) { + case 0x10f: /* Make tag */ + fgets (make, 64, ifp); + break; + case 0x110: /* Model tag */ + fgets (model, 64, ifp); + } + fseek (ifp, save, SEEK_SET); + } + } +} + +int CLASS identify() +{ + char head[32], *c; + int thumb_offset; + + make[0] = model[0] = 0; + data_offset = raw_height = raw_width = height = width = 0; + fuji_secondary = 0; + + order = 0x4d4d; + fread (head, 1, 32, ifp); + if (memcmp (head, "FUJIFILM", 8)) return 1; + fseek (ifp, 84, SEEK_SET); + thumb_offset = get4(); + fseek (ifp, 92, SEEK_SET); + parse_fuji (get4()); + if (thumb_offset > 120) { + fseek (ifp, 120, SEEK_SET); + fuji_secondary = get4() && 1; + } + fseek (ifp, 100, SEEK_SET); + data_offset = get4(); + parse_tiff (thumb_offset+12); + c = model + strlen(model); /* Remove trailing spaces */ + while (*--c == ' ') *c = 0; + if (!strcmp(model,"FinePix S5100") || + !strcmp(model,"FinePix S5500")) return 1; + load_raw = fuji_load_raw; + if (!strcmp(model+7,"S2Pro")) { + strcpy (model+7," S2Pro"); + height = 2144; + width = 2880; + } + data_offset += (raw_height - height + 1)*raw_width - width; + if (fuji_secondary) + data_offset += use_secondary * ( strcmp(model+7," S3Pro") + ? (raw_width *= 2) : raw_height*raw_width*2 ); + data_offset += fuji_layout*raw_width*2; + width >>= !fuji_layout; + height >>= fuji_layout; + fseek (ifp, data_offset, SEEK_SET); + return 0; +} + +void CLASS write_ppm (FILE *ofp) +{ + int i, size, val, total, histogram[0x2000]; + float white, r; + uchar lut[0x10000]; + + memset (histogram, 0, sizeof histogram); + size = width * height; + for (i = 0; i < size; i++) + histogram[image[i] >> 4]++; + i = size * 0.01; /* 99th percentile white point */ + for (val=0x2000, total=0; --val; ) + if ((total += histogram[val]) > i) break; + white = (val << 4) / bright; + + for (i=0; i < 0x10000; i++) { + r = i / white; + val = (r <= 0.018 ? r*4.5 : pow(r,0.45)*1.099-0.099) * 256; + if (val > 255) val = 255; + lut[i] = val; + } + fprintf (ofp, "P5\n%d %d\n255\n", width, height); + for (i=0; i < size; i++) + fputc (lut[image[i]], ofp); +} + +void CLASS write_raw16 (FILE *ofp) +{ + if (ntohs(0x1234) != 0x1234) + swab (image, image, width*height*2); + fwrite (image, width*height, 2, ofp); +} + +void CLASS write_ppm16 (FILE *ofp) +{ + fprintf (ofp, "P5\n%d %d\n%d\n", width, height, 65535); + write_raw16 (ofp); +} + +void CLASS write_psd (FILE *ofp) +{ + char head[] = { + '8','B','P','S', /* signature */ + 0,1,0,0,0,0,0,0, /* version and reserved */ + 0,1, /* number of channels */ + 0,0,0,0, /* height, big-endian */ + 0,0,0,0, /* width, big-endian */ + 0,16, /* 16-bit color */ + 0,1, /* mode (1=grey, 3=rgb) */ + 0,0,0,0, /* color mode data */ + 0,0,0,0, /* image resources */ + 0,0,0,0, /* layer/mask info */ + 0,0 }; /* no compression */ + int hw[2]; + + hw[0] = htonl(height*2); /* write the header */ + hw[1] = htonl(width*2); + memcpy (head+14, hw, sizeof hw); + fwrite (head, 40, 1, ofp); + write_raw16 (ofp); +} + +int CLASS main (int argc, char **argv) +{ + int arg, status=0; + int identify_only=0, write_to_stdout=0; + char opt, *ofname, *cp; + const char *write_ext = ".pgm"; + FILE *ofp = stdout; + + if (argc == 1) { + fprintf (stderr, + "\nFuji Green channel output" + "\nby Dave Coffin, dcoffin a cybercom o net" + "\n\nUsage: %s [options] file1 file2 ...\n" + "\nValid options:" + "\n-v Print verbose messages" + "\n-c Write image data to standard output" + "\n-i Identify files without decoding them" + "\n-s Use secondary pixels if available" + "\n-b Set brightness (default = 1.0)" + "\n-2 Write 8-bit non-linear PGM (default)" + "\n-4 Write 16-bit linear PGM" + "\n-3 Write 16-bit linear PSD (Adobe Photoshop)" + "\n\n", argv[0]); + return 1; + } + argv[argc] = ""; + for (arg=1; argv[arg][0] == '-'; ) { + opt = argv[arg++][1]; + if (strchr ("b", opt) && !isdigit(argv[arg][0])) { + fprintf (stderr, "\"-%c\" requires a numeric argument.\n", opt); + return 1; + } + switch (opt) { + case 'v': verbose = 1; break; + case 'i': identify_only = 1; break; + case 'c': write_to_stdout = 1; break; + case 's': use_secondary = 1; break; + case 'b': bright = atof(argv[arg++]); break; + case '2': write_fun = write_ppm; break; + case '4': write_fun = write_ppm16; break; + case '3': write_fun = write_psd; write_ext = ".psd"; break; + default: + fprintf (stderr, "Unknown option \"-%c\".\n", opt); + return 1; + } + } + if (arg == argc) { + fprintf (stderr, "No files to process.\n"); + return 1; + } + if (write_to_stdout) { + if (isatty(1)) { + fprintf (stderr, "Will not write an image to the terminal!\n"); + return 1; + } +#if defined(WIN32) || defined(DJGPP) + if (setmode(1,O_BINARY) < 0) { + perror("setmode()"); + return 1; + } +#endif + } + for ( ; arg < argc; arg++) { + status = 1; + image = NULL; + if (setjmp (failure)) { + if (fileno(ifp) > 2) fclose (ifp); + if (fileno(ofp) > 2) fclose (ofp); + if (image) free (image); + status = 1; + continue; + } + ifname = argv[arg]; + if (!(ifp = fopen (ifname, "rb"))) { + perror (ifname); + continue; + } + if ((status = identify())) { + fprintf (stderr, "%s: unsupported file format.\n", ifname); + fclose (ifp); + continue; + } + if (identify_only) { + fprintf (stderr, "%s is a %s %s image.\n", ifname, make, model); + fclose (ifp); + continue; + } + image = calloc (height * width, sizeof *image); + merror (image, "main()"); + if (verbose) + fprintf (stderr, + "Loading %s %s image from %s...\n", make, model, ifname); + (*load_raw)(); + fclose (ifp); + ofname = malloc (strlen(ifname) + 16); + merror (ofname, "main()"); + if (write_to_stdout) + strcpy (ofname, "standard output"); + else { + strcpy (ofname, ifname); + if ((cp = strrchr (ofname, '.'))) *cp = 0; + strcat (ofname, write_ext); + ofp = fopen (ofname, "wb"); + if (!ofp) { + status = 1; + perror (ofname); + goto cleanup; + } + } + if (verbose) + fprintf (stderr, "Writing data to %s...\n", ofname); + (*write_fun)(ofp); + if (ofp != stdout) + fclose (ofp); +cleanup: + free (ofname); + free (image); + } + return status; +} diff --git a/fuji_green.c_fix_gcc_warnings.patch b/fuji_green.c_fix_gcc_warnings.patch new file mode 100644 index 0000000..d0a41be --- /dev/null +++ b/fuji_green.c_fix_gcc_warnings.patch @@ -0,0 +1,11 @@ +--- fuji_green.c.orig 2006-03-01 03:46:47.000000000 +0200 ++++ fuji_green.c 2011-03-22 21:26:43.871000023 +0200 +@@ -11,6 +11,8 @@ + #include + #include + #include ++#include ++#include + + #define ushort UshORt + typedef unsigned char uchar; diff --git a/fujiturn.c b/fujiturn.c new file mode 100644 index 0000000..abad34a --- /dev/null +++ b/fujiturn.c @@ -0,0 +1,102 @@ +/* + fujiturn.c by Dave Coffin + + UNIX filter to correct the 45-degree rotation in images from + Fuji digital cameras. Compile with -D_16BIT to rotate 48-bit + PPM images. Sample usage: + + dcraw -c -j dscf0000.raf | fujiturn | pnmscale 0.70710678 > dscf0000.ppm + + $Revision: 1.6 $ + $Date: 2005/04/29 16:35:42 $ + + */ + +#include +#include +#include + +#ifdef _16BIT +typedef unsigned short value; +#else +typedef unsigned char value; +#define ntohs(x) (x) +#define htons(x) (x) +#endif + +void merror (void *ptr, char *what) +{ + if (ptr) return; + fprintf (stderr, "Not enough memory for %s\n", what); + exit(1); +} + +int main() +{ + FILE *ifp, *ofp; + value (*in)[3], (*mid)[3], (*pix)[3], (*out)[3]; + char nl; + int maxval, i, j, iwide, ihigh, owide, ohigh; + unsigned irow, icol, orow, ocol; + +#if defined(WIN32) || defined(DJGPP) + if (setmode(0,O_BINARY) < 0) perror("setmode(0)"); + if (setmode(1,O_BINARY) < 0) perror("setmode(1)"); +#endif + ifp = stdin; + ofp = stdout; + if (fscanf (ifp, "P6 %d %d %d%c", &iwide, &ihigh, &maxval, &nl) != 4 + || abs(iwide - ihigh) > 1) { + fprintf (stderr, "Input is not a Fuji image processed by dcraw.\n"); + exit(1); + } + i = (maxval > 255) ? 16 : 8; + j = 8 * sizeof (value); + if (i != j) { + fprintf (stderr, "Input is %d-bit, fujiturn is %d-bit\n", i, j); + exit(1); + } + in = calloc (iwide, sizeof *in); + merror (in, "input array"); + fread (in, iwide, sizeof *in, ifp); + for (i = 0; i < iwide; i++) + if (in[i][0] || in[i][1] || in[i][2]) break; + ohigh = (iwide - i) * 2 - 4; + for (i = iwide; --i;) + if (in[i][0] || in[i][1] || in[i][2]) break; + owide = i; + mid = calloc (ohigh * owide, sizeof *mid); + merror (mid, "middle array"); + for (irow = 0; irow < ihigh; irow++) { + for (icol = 0; icol < iwide; icol++) { + orow = irow + icol - owide + 5; + ocol = (icol - irow + owide - 1)/2; + if (orow < ohigh && ocol < owide) + for (i = 0; i < 3; i++) + mid[orow*owide+ocol][i] = ntohs(in[icol][i]); + } + fread (in, iwide, sizeof *in, ifp); + } + free(in); + out = calloc (2*owide, sizeof *out); + merror (out, "output array"); + fprintf (ofp, "P6\n%d %d\n%d\n", owide*2, ohigh, maxval); + for (orow = 0; orow < ohigh; orow++) { + for (ocol = 0; ocol < owide*2; ocol++) { + pix = mid + orow*owide + ocol/2; + if ((orow+ocol) & 1) { + if (orow-1 < ohigh-2 && ocol-1 < owide*2-2) + for (i = 0; i < 3; i++) + out[ocol][i] = htons ( + ( pix[-owide][i] + pix[0-(orow&1)][i] + + pix[ owide][i] + pix[1-(orow&1)][i] ) >> 2); + } else + for (i = 0; i < 3; i++) + out[ocol][i] = htons(pix[0][i]); + } + fwrite (out, 2*owide, 3*sizeof (value), ofp); + } + free(mid); + free(out); + return 0; +} diff --git a/iowrappers.patch b/iowrappers.patch new file mode 100644 index 0000000..e3d4120 --- /dev/null +++ b/iowrappers.patch @@ -0,0 +1,2636 @@ +--- dcraw/dcraw.c 2022-04-12 13:09:25.758417413 +0200 ++++ dcraw/dcraw.c 2022-04-12 13:11:37.499225280 +0200 +@@ -292,6 +292,34 @@ + data_error++; + } + ++void CLASS tseek(FILE *stream, long offset, int whence) ++{ ++ char line[81]; ++ if( fseek(stream,offset,whence) != 0 ) { ++ snprintf(line,80,"fseek(%p,%ld,%d)",stream,offset,whence); ++ perror(line); ++ exit(1); ++ } ++} ++ ++void CLASS tread(void *ptr, size_t size, size_t nmemb, FILE *stream) ++{ ++ if( fread (ptr, size, nmemb, stream) != nmemb ) { ++ derror(); ++ exit(1); ++ } ++} ++ ++void CLASS twrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) ++{ ++ char line[81]; ++ if( fwrite (ptr, size, nmemb, stream) != nmemb ) { ++ snprintf(line,80,"fwrite(%p,%ld,%ld,%p)",ptr,(long)size,(long)nmemb,stream); ++ perror(line); ++ exit(1); ++ } ++} ++ + ushort CLASS sget2 (uchar *s) + { + if (order == 0x4949) /* "II" means little-endian */ +@@ -303,7 +331,7 @@ + ushort CLASS get2() + { + uchar str[2] = { 0xff,0xff }; +- fread (str, 1, 2, ifp); ++ tread (str, 1, 2, ifp); + return sget2(str); + } + +@@ -319,7 +347,7 @@ + unsigned CLASS get4() + { + uchar str[4] = { 0xff,0xff,0xff,0xff }; +- fread (str, 1, 4, ifp); ++ tread (str, 1, 4, ifp); + return sget4(str); + } + +@@ -584,7 +612,7 @@ + unsigned row; + + for (row=0; row < 100; row++) { +- fseek (ifp, row*3340 + 3284, SEEK_SET); ++ tseek (ifp, row*3340 + 3284, SEEK_SET); + if (getc(ifp) > 15) return 1; + } + return 0; +@@ -741,8 +769,8 @@ + uchar test[0x4000]; + int ret=1, i; + +- fseek (ifp, 0, SEEK_SET); +- fread (test, 1, sizeof test, ifp); ++ tseek (ifp, 0, SEEK_SET); ++ tread (test, 1, sizeof test, ifp); + for (i=540; i < sizeof test - 1; i++) + if (test[i] == 0xff) { + if (test[i+1]) return 1; +@@ -760,7 +788,7 @@ + crw_init_tables (tiff_compress, huff); + lowbits = canon_has_lowbits(); + if (!lowbits) maximum = 0x3ff; +- fseek (ifp, 540 + lowbits*raw_height*raw_width/4, SEEK_SET); ++ tseek (ifp, 540 + lowbits*raw_height*raw_width/4, SEEK_SET); + zero_after_ff = 1; + getbits(-1); + for (row=0; row < raw_height; row+=8) { +@@ -791,7 +819,7 @@ + } + if (lowbits) { + save = ftell(ifp); +- fseek (ifp, 26 + row*raw_width/4, SEEK_SET); ++ tseek (ifp, 26 + row*raw_width/4, SEEK_SET); + for (prow=pixel, i=0; i < raw_width*2; i++) { + c = fgetc(ifp); + for (r=0; r < 8; r+=2, prow++) { +@@ -800,7 +828,7 @@ + *prow = val; + } + } +- fseek (ifp, save, SEEK_SET); ++ tseek (ifp, save, SEEK_SET); + } + } + FORC(2) free (huff[c]); +@@ -825,7 +853,7 @@ + tag = data[0] << 8 | data[1]; + len = (data[2] << 8 | data[3]) - 2; + if (tag <= 0xff00) return 0; +- fread (data, 1, len, ifp); ++ tread (data, 1, len, ifp); + switch (tag) { + case 0xffc3: + jh->sraw = ((data[7] >> 4) * (data[7] & 15) - 1) & 3; +@@ -896,7 +924,7 @@ + if (jrow * jh->wide % jh->restart == 0) { + FORC(6) jh->vpred[c] = 1 << (jh->bits-1); + if (jrow) { +- fseek (ifp, -2, SEEK_CUR); ++ tseek (ifp, -2, SEEK_CUR); + do mark = (mark << 8) + (c = fgetc(ifp)); + while (c != EOF && mark >> 4 != 0xffd); + } +@@ -1096,7 +1124,7 @@ + while (trow < raw_height) { + save = ftell(ifp); + if (tile_length < INT_MAX) +- fseek (ifp, get4(), SEEK_SET); ++ tseek (ifp, get4(), SEEK_SET); + if (!ljpeg_start (&jh, 0)) break; + jwide = jh.wide; + if (filters) jwide *= jh.clrs; +@@ -1127,7 +1155,7 @@ + } + } + } +- fseek (ifp, save+4, SEEK_SET); ++ tseek (ifp, save+4, SEEK_SET); + if ((tcol += tile_width) >= raw_width) + trow += tile_length + (tcol = 0); + ljpeg_end (&jh); +@@ -1161,16 +1189,16 @@ + int dep, row, col, diff, c, i; + ushort vpred[2][2] = {{0,0},{0,0}}, hpred[2]; + +- fseek (ifp, meta_offset, SEEK_SET); ++ tseek (ifp, meta_offset, SEEK_SET); + dep = (get2() + 12) & 15; +- fseek (ifp, 12, SEEK_CUR); ++ tseek (ifp, 12, SEEK_CUR); + FORC(dep) bit[0][c] = get2(); + FORC(dep) bit[1][c] = fgetc(ifp); + FORC(dep) + for (i=bit[0][c]; i <= ((bit[0][c]+(4096 >> bit[1][c])-1) & 4095); ) + huff[++i] = bit[1][c] << 8 | c; + huff[0] = 12; +- fseek (ifp, data_offset, SEEK_SET); ++ tseek (ifp, data_offset, SEEK_SET); + getbits(-1); + for (row=0; row < raw_height; row++) + for (col=0; col < raw_width; col++) { +@@ -1200,11 +1228,11 @@ + ushort *huff, ver0, ver1, vpred[2][2], hpred[2], csize; + int i, min, max, step=0, tree=0, split=0, row, col, len, shl, diff; + +- fseek (ifp, meta_offset, SEEK_SET); ++ tseek (ifp, meta_offset, SEEK_SET); + ver0 = fgetc(ifp); + ver1 = fgetc(ifp); + if (ver0 == 0x49 || ver1 == 0x58) +- fseek (ifp, 2110, SEEK_CUR); ++ tseek (ifp, 2110, SEEK_CUR); + if (ver0 == 0x46) tree = 2; + if (tiff_bps == 14) tree += 3; + read_shorts (vpred[0], 4); +@@ -1217,13 +1245,13 @@ + for (i=0; i < max; i++) + curve[i] = ( curve[i-i%step]*(step-i%step) + + curve[i-i%step+step]*(i%step) ) / step; +- fseek (ifp, meta_offset+562, SEEK_SET); ++ tseek (ifp, meta_offset+562, SEEK_SET); + split = get2(); + } else if (ver0 != 0x46 && csize <= 0x4001) + read_shorts (curve, max=csize); + while (curve[max-2] == curve[max-1]) max--; + huff = make_decoder (nikon_tree[tree]); +- fseek (ifp, data_offset, SEEK_SET); ++ tseek (ifp, data_offset, SEEK_SET); + getbits(-1); + for (min=row=0; row < height; row++) { + if (split && row == split) { +@@ -1279,7 +1307,7 @@ + const uchar often[] = { 0x00, 0x55, 0xaa, 0xff }; + + memset (histo, 0, sizeof histo); +- fseek (ifp, -2000, SEEK_END); ++ tseek (ifp, -2000, SEEK_END); + for (i=0; i < 2000; i++) + histo[fgetc(ifp)]++; + for (i=0; i < 4; i++) +@@ -1296,9 +1324,9 @@ + uchar t[12]; + int i; + +- fseek (ifp, 0, SEEK_SET); ++ tseek (ifp, 0, SEEK_SET); + for (i=0; i < 1024; i++) { +- fread (t, 1, 12, ifp); ++ tread (t, 1, 12, ifp); + if (((t[2] & t[4] & t[7] & t[9]) >> 4 + & t[1] & t[6] & t[8] & t[11] & 3) != 3) + return 0; +@@ -1319,8 +1347,8 @@ + { 0x32, "Nikon", "E3700" }, + { 0x33, "Olympus", "C740UZ" } }; + +- fseek (ifp, 3072, SEEK_SET); +- fread (dp, 1, 24, ifp); ++ tseek (ifp, 3072, SEEK_SET); ++ tread (dp, 1, 24, ifp); + bits = (dp[8] & 3) << 4 | (dp[20] & 3); + for (i=0; i < sizeof table / sizeof *table; i++) + if (bits == table[i].bits) { +@@ -1337,8 +1365,8 @@ + int i, nz; + char tail[424]; + +- fseek (ifp, -sizeof tail, SEEK_END); +- fread (tail, 1, sizeof tail, ifp); ++ tseek (ifp, -sizeof tail, SEEK_END); ++ tread (tail, 1, sizeof tail, ifp); + for (nz=i=0; i < sizeof tail; i++) + if (tail[i]) nz++; + return nz > 20; +@@ -1353,8 +1381,8 @@ + thumb = (char *) malloc (thumb_length); + merror (thumb, "ppm_thumb()"); + fprintf (ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height); +- fread (thumb, 1, thumb_length, ifp); +- fwrite (thumb, 1, thumb_length, ofp); ++ tread (thumb, 1, thumb_length, ifp); ++ twrite (thumb, 1, thumb_length, ofp); + free (thumb); + } + +@@ -1369,7 +1397,7 @@ + for (i=0; i < thumb_length; i++) + thumb[i] = ((ushort *) thumb)[i] >> 8; + fprintf (ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height); +- fwrite (thumb, 1, thumb_length, ofp); ++ twrite (thumb, 1, thumb_length, ofp); + free (thumb); + } + +@@ -1384,7 +1412,7 @@ + merror (thumb, "layer_thumb()"); + fprintf (ofp, "P%d\n%d %d\n255\n", + 5 + (colors >> 1), thumb_width, thumb_height); +- fread (thumb, thumb_length, colors, ifp); ++ tread (thumb, thumb_length, colors, ifp); + for (i=0; i < thumb_length; i++) + FORCC putc (thumb[i+thumb_length*(map[thumb_misc >> 8][c]-'0')], ofp); + free (thumb); +@@ -1499,17 +1527,17 @@ + + if (half_size || !meta_length) return; + if (verbose) fprintf (stderr,_("Phase One correction...\n")); +- fseek (ifp, meta_offset, SEEK_SET); ++ tseek (ifp, meta_offset, SEEK_SET); + order = get2(); +- fseek (ifp, 6, SEEK_CUR); +- fseek (ifp, meta_offset+get4(), SEEK_SET); ++ tseek (ifp, 6, SEEK_CUR); ++ tseek (ifp, meta_offset+get4(), SEEK_SET); + entries = get4(); get4(); + while (entries--) { + tag = get4(); + len = get4(); + data = get4(); + save = ftell(ifp); +- fseek (ifp, meta_offset+data, SEEK_SET); ++ tseek (ifp, meta_offset+data, SEEK_SET); + if (tag == 0x419) { /* Polynomial curve */ + for (get4(), i=0; i < 8; i++) + poly[i] = getreal(11); +@@ -1566,7 +1594,7 @@ + } else if (tag == 0x40b) { /* Red+blue flat field */ + phase_one_flat_field (0, 4); + } else if (tag == 0x412) { +- fseek (ifp, 36, SEEK_CUR); ++ tseek (ifp, 36, SEEK_CUR); + diff = abs (get2() - ph1.tag_21a); + if (mindiff > diff) { + mindiff = diff; +@@ -1650,10 +1678,10 @@ + qmult_applied = 1; + qlin_applied = 1; + } +- fseek (ifp, save, SEEK_SET); ++ tseek (ifp, save, SEEK_SET); + } + if (off_412) { +- fseek (ifp, off_412, SEEK_SET); ++ tseek (ifp, off_412, SEEK_SET); + for (i=0; i < 9; i++) head[i] = get4() & 0x7fff; + yval[0] = (float *) calloc (head[1]*head[3] + head[2]*head[4], 6); + merror (yval[0], "phase_one_correct()"); +@@ -1691,11 +1719,11 @@ + int a, b, i; + ushort akey, bkey, mask; + +- fseek (ifp, ph1.key_off, SEEK_SET); ++ tseek (ifp, ph1.key_off, SEEK_SET); + akey = get2(); + bkey = get2(); + mask = ph1.format == 1 ? 0x5555:0x1354; +- fseek (ifp, data_offset, SEEK_SET); ++ tseek (ifp, data_offset, SEEK_SET); + read_shorts (raw_image, raw_width*raw_height); + if (ph1.format) + for (i=0; i < raw_width*raw_height; i+=2) { +@@ -1740,21 +1768,21 @@ + pixel = (ushort *) calloc (raw_width*3 + raw_height*4, 2); + merror (pixel, "phase_one_load_raw_c()"); + offset = (int *) (pixel + raw_width); +- fseek (ifp, strip_offset, SEEK_SET); ++ tseek (ifp, strip_offset, SEEK_SET); + for (row=0; row < raw_height; row++) + offset[row] = get4(); + cblack = (short (*)[2]) (offset + raw_height); +- fseek (ifp, ph1.black_col, SEEK_SET); ++ tseek (ifp, ph1.black_col, SEEK_SET); + if (ph1.black_col) + read_shorts ((ushort *) cblack[0], raw_height*2); + rblack = cblack + raw_height; +- fseek (ifp, ph1.black_row, SEEK_SET); ++ tseek (ifp, ph1.black_row, SEEK_SET); + if (ph1.black_row) + read_shorts ((ushort *) rblack[0], raw_width*2); + for (i=0; i < 256; i++) + curve[i] = i*i / 3.969 + 0.5; + for (row=0; row < raw_height; row++) { +- fseek (ifp, data_offset + offset[row], SEEK_SET); ++ tseek (ifp, data_offset + offset[row], SEEK_SET); + ph1_bits(-1); + pred[0] = pred[1] = 0; + for (col=0; col < raw_width; col++) { +@@ -1852,8 +1880,8 @@ + FORC(tiff_samples) + for (r=0; r < raw_height; r++) { + if (r % tile_length == 0) { +- fseek (ifp, data_offset + 4*tile++, SEEK_SET); +- fseek (ifp, get4(), SEEK_SET); ++ tseek (ifp, data_offset + 4*tile++, SEEK_SET); ++ tseek (ifp, get4(), SEEK_SET); + } + if (filters && c != shot_select) continue; + if (filters) pixel = raw_image + r*raw_width; +@@ -1889,8 +1917,8 @@ + + if (raw_image) { + shot = LIM (shot_select, 1, 4) - 1; +- fseek (ifp, data_offset + shot*4, SEEK_SET); +- fseek (ifp, get4(), SEEK_SET); ++ tseek (ifp, data_offset + shot*4, SEEK_SET); ++ tseek (ifp, get4(), SEEK_SET); + unpacked_load_raw(); + return; + } +@@ -1901,8 +1929,8 @@ + pixel = (ushort *) calloc (raw_width, sizeof *pixel); + merror (pixel, "sinar_4shot_load_raw()"); + for (shot=0; shot < 4; shot++) { +- fseek (ifp, data_offset + shot*4, SEEK_SET); +- fseek (ifp, get4(), SEEK_SET); ++ tseek (ifp, data_offset + shot*4, SEEK_SET); ++ tseek (ifp, get4(), SEEK_SET); + for (row=0; row < raw_height; row++) { + read_shorts (pixel, raw_width); + if ((r = row-top_margin - (shot >> 1 & 1)) >= height) continue; +@@ -1943,10 +1971,10 @@ + (row = irow % half * 2 + irow / half) == 1 && + load_flags & 4) { + if (vbits=0, tiff_compress) +- fseek (ifp, data_offset - (-half*bwide & -2048), SEEK_SET); ++ tseek (ifp, data_offset - (-half*bwide & -2048), SEEK_SET); + else { +- fseek (ifp, 0, SEEK_END); +- fseek (ifp, ftell(ifp) >> 3 << 2, SEEK_SET); ++ tseek (ifp, 0, SEEK_END); ++ tseek (ifp, ftell(ifp) >> 3 << 2, SEEK_SET); + } + } + for (col=0; col < raw_width; col++) { +@@ -2019,8 +2047,8 @@ + + if (!nbits) return vbits=0; + if (!vbits) { +- fread (buf+load_flags, 1, 0x4000-load_flags, ifp); +- fread (buf, 1, load_flags, ifp); ++ tread (buf+load_flags, 1, 0x4000-load_flags, ifp); ++ tread (buf, 1, load_flags, ifp); + } + vbits = (vbits - nbits) & 0x1ffff; + byte = vbits >> 3 ^ 0x3ff0; +@@ -2058,7 +2086,7 @@ + huff[n=0] = 0xc0c; + for (i=12; i--; ) + FORC(2048 >> i) huff[++n] = (i+1) << 8 | i; +- fseek (ifp, 7, SEEK_CUR); ++ tseek (ifp, 7, SEEK_CUR); + getbits(-1); + for (row=0; row < height; row++) { + memset (acarry, 0, sizeof acarry); +@@ -2388,16 +2416,16 @@ + double coeff[9], tot; + + if (meta_offset) { +- fseek (ifp, meta_offset, SEEK_SET); ++ tseek (ifp, meta_offset, SEEK_SET); + order = 0x4d4d; + ntags = get4(); + while (ntags--) { + opcode = get4(); get4(); get4(); + if (opcode != 8) +- { fseek (ifp, get4(), SEEK_CUR); continue; } +- fseek (ifp, 20, SEEK_CUR); ++ { tseek (ifp, get4(), SEEK_CUR); continue; } ++ tseek (ifp, 20, SEEK_CUR); + if ((c = get4()) > 2) break; +- fseek (ifp, 12, SEEK_CUR); ++ tseek (ifp, 12, SEEK_CUR); + if ((deg = get4()) > 8) break; + for (i=0; i <= deg && i < 9; i++) + coeff[i] = getreal(12); +@@ -2415,9 +2443,9 @@ + cinfo.err = jpeg_std_error (&jerr); + jpeg_create_decompress (&cinfo); + while (trow < raw_height) { +- fseek (ifp, save+=4, SEEK_SET); ++ tseek (ifp, save+=4, SEEK_SET); + if (tile_length < INT_MAX) +- fseek (ifp, get4(), SEEK_SET); ++ tseek (ifp, get4(), SEEK_SET); + jpeg_stdio_src (&cinfo, ifp); + jpeg_read_header (&cinfo, TRUE); + jpeg_start_decompress (&cinfo); +@@ -2486,7 +2514,7 @@ + for (row=0; row < height; row++) { + if (fread (pixel, raw_width, 2, ifp) < 2) derror(); + if (load_flags && (row & 31) == 31) +- fseek (ifp, raw_width*32, SEEK_CUR); ++ tseek (ifp, raw_width*32, SEEK_CUR); + for (col=0; col < width; col++) { + y = pixel[col*2]; + cb = pixel[(col*2 & -4) | 1] - 128; +@@ -2547,7 +2575,7 @@ + FORC(ns) strip[c] = get4(); + for (row=0; row < raw_height; row++) { + if ((row & 31) == 0) { +- fseek (ifp, strip[row >> 5], SEEK_SET); ++ tseek (ifp, strip[row >> 5], SEEK_SET); + getbits(-1); + pi = 0; + } +@@ -2583,7 +2611,7 @@ + c = fgetc(ifp); + if ((blen[i ] = c & 15) > 12 || + (blen[i+1] = c >> 4) > 12 ) { +- fseek (ifp, save, SEEK_SET); ++ tseek (ifp, save, SEEK_SET); + for (i=0; i < bsize; i+=8) { + read_shorts (raw, 6); + out[i ] = raw[0] >> 12 << 8 | raw[2] >> 12 << 4 | raw[4] >> 12; +@@ -2728,16 +2756,16 @@ + ushort *pixel; + unsigned i, key, row, col; + +- fseek (ifp, 200896, SEEK_SET); +- fseek (ifp, (unsigned) fgetc(ifp)*4 - 1, SEEK_CUR); ++ tseek (ifp, 200896, SEEK_SET); ++ tseek (ifp, (unsigned) fgetc(ifp)*4 - 1, SEEK_CUR); + order = 0x4d4d; + key = get4(); +- fseek (ifp, 164600, SEEK_SET); +- fread (head, 1, 40, ifp); ++ tseek (ifp, 164600, SEEK_SET); ++ tread (head, 1, 40, ifp); + sony_decrypt ((unsigned *) head, 10, 1, key); + for (i=26; i-- > 22; ) + key = key << 8 | head[i]; +- fseek (ifp, data_offset, SEEK_SET); ++ tseek (ifp, data_offset, SEEK_SET); + for (row=0; row < raw_height; row++) { + pixel = raw_image + row*raw_width; + if (fread (pixel, 2, raw_width, ifp) < raw_width) derror(); +@@ -2777,7 +2805,7 @@ + data = (uchar *) malloc (raw_width+1); + merror (data, "sony_arw2_load_raw()"); + for (row=0; row < height; row++) { +- fread (data, 1, raw_width, ifp); ++ tread (data, 1, raw_width, ifp); + for (dp=data, col=0; col < raw_width-30; dp+=16) { + max = 0x7ff & (val = sget4(dp)); + min = 0x7ff & val >> 11; +@@ -2806,8 +2834,8 @@ + + order = 0x4949; + for (row=0; row < raw_height; row++) { +- fseek (ifp, strip_offset+row*4, SEEK_SET); +- fseek (ifp, data_offset+get4(), SEEK_SET); ++ tseek (ifp, strip_offset+row*4, SEEK_SET); ++ tseek (ifp, data_offset+get4(), SEEK_SET); + ph1_bits(-1); + FORC4 len[c] = row < 2 ? 7:4; + for (col=0; col < raw_width; col+=16) { +@@ -2859,11 +2887,11 @@ + ushort lent[3][2], len[4], *prow[2]; + + order = 0x4949; +- fseek (ifp, 9, SEEK_CUR); ++ tseek (ifp, 9, SEEK_CUR); + opt = fgetc(ifp); + init = (get2(),get2()); + for (row=0; row < raw_height; row++) { +- fseek (ifp, (data_offset-ftell(ifp)) & 15, SEEK_CUR); ++ tseek (ifp, (data_offset-ftell(ifp)) & 15, SEEK_CUR); + ph1_bits(-1); + mag = 0; pmode = 7; + FORC(6) ((ushort *)lent)[c] = row < 2 ? 7:4; +@@ -2916,7 +2944,7 @@ + uchar diff, pred[]={0,0}; + ushort data=0, range=0; + +- fseek (ifp, seg[0][1]+1, SEEK_SET); ++ tseek (ifp, seg[0][1]+1, SEEK_SET); + getbits(-1); + if (seg[1][0] > raw_width*raw_height) + seg[1][0] = raw_width*raw_height; +@@ -2972,7 +3000,7 @@ + { + unsigned seg[2][2]; + +- fseek (ifp, 16, SEEK_SET); ++ tseek (ifp, 16, SEEK_SET); + seg[0][0] = 0; + seg[0][1] = get2(); + seg[1][0] = raw_width * raw_height; +@@ -3023,15 +3051,15 @@ + { + unsigned seg[256][2], offset, nseg, holes, i; + +- fseek (ifp, 67, SEEK_SET); ++ tseek (ifp, 67, SEEK_SET); + offset = get4(); + nseg = (uchar) fgetc(ifp); +- fseek (ifp, offset, SEEK_SET); ++ tseek (ifp, offset, SEEK_SET); + for (i=0; i < nseg*2; i++) + ((unsigned *)seg)[i] = get4() + data_offset*(i & 1); +- fseek (ifp, 78, SEEK_SET); ++ tseek (ifp, 78, SEEK_SET); + holes = fgetc(ifp); +- fseek (ifp, 88, SEEK_SET); ++ tseek (ifp, 88, SEEK_SET); + seg[nseg][0] = raw_height * raw_width; + seg[nseg][1] = get4() + data_offset; + for (i=0; i < nseg; i++) +@@ -3139,8 +3167,8 @@ + buf = (char *) malloc (bwide); + merror (buf, "foveon_thumb()"); + for (row=0; row < thumb_height; row++) { +- fread (buf, 1, bwide, ifp); +- fwrite (buf, 3, thumb_width, ofp); ++ tread (buf, 1, bwide, ifp); ++ twrite (buf, 3, thumb_width, ofp); + } + free (buf); + return; +@@ -3224,12 +3252,12 @@ + unsigned c, roff[4], row, col, diff; + ushort huff[512], vpred[2][2], hpred[2]; + +- fseek (ifp, 8, SEEK_CUR); ++ tseek (ifp, 8, SEEK_CUR); + foveon_huff (huff); + roff[0] = 48; + FORC3 roff[c+1] = -(-(roff[c] + get4()) & -16); + FORC3 { +- fseek (ifp, data_offset+roff[c], SEEK_SET); ++ tseek (ifp, data_offset+roff[c], SEEK_SET); + getbits(-1); + vpred[0][0] = vpred[0][1] = vpred[1][0] = vpred[1][1] = 512; + for (row=0; row < height; row++) { +@@ -3248,12 +3276,12 @@ + unsigned type, wide, high, i, j, row, col, diff; + ushort huff[258], vpred[2][2] = {{512,512},{512,512}}, hpred[2]; + +- fseek (ifp, meta_offset, SEEK_SET); ++ tseek (ifp, meta_offset, SEEK_SET); + type = get4(); get4(); get4(); + wide = get4(); + high = get4(); + if (type == 2) { +- fread (meta_data, 1, meta_length, ifp); ++ tread (meta_data, 1, meta_length, ifp); + for (i=0; i < meta_length; i++) { + high = (high * 1597 + 51749) % 244944; + wide = high * (INT64) 301593171 >> 24; +@@ -3985,7 +4013,7 @@ + pixel = (ushort *) calloc (width, sizeof *pixel); + merror (pixel, "subtract()"); + for (row=0; row < height; row++) { +- fread (pixel, 2, width, fp); ++ tread (pixel, 2, width, fp); + for (col=0; col < width; col++) + BAYER(row,col) = MAX (BAYER(row,col) - ntohs(pixel[col]), 0); + } +@@ -5188,7 +5216,7 @@ + *len = get4(); + *save = ftell(ifp) + 4; + if (*len * ("11124811248484"[*type < 14 ? *type:0]-'0') > 4) +- fseek (ifp, get4()+base, SEEK_SET); ++ tseek (ifp, get4()+base, SEEK_SET); + } + + void CLASS parse_thumb_note (int base, unsigned toff, unsigned tlen) +@@ -5200,7 +5228,7 @@ + tiff_get (base, &tag, &type, &len, &save); + if (tag == toff) thumb_offset = get4()+base; + if (tag == tlen) thumb_length = get4(); +- fseek (ifp, save, SEEK_SET); ++ tseek (ifp, save, SEEK_SET); + } + } + +@@ -5251,7 +5279,7 @@ + its own byte-order!), or it might just be a table. + */ + if (!strcmp(make,"Nokia")) return; +- fread (buf, 1, 10, ifp); ++ tread (buf, 1, 10, ifp); + if (!strncmp (buf,"KDK" ,3) || /* these aren't TIFF tables */ + !strncmp (buf,"VER" ,3) || + !strncmp (buf,"IIII",4) || +@@ -5273,11 +5301,11 @@ + order = get2(); + if (get2() != 42) goto quit; + offset = get4(); +- fseek (ifp, offset-8, SEEK_CUR); ++ tseek (ifp, offset-8, SEEK_CUR); + } else if (!strcmp (buf,"OLYMPUS") || + !strcmp (buf,"PENTAX ")) { + base = ftell(ifp)-10; +- fseek (ifp, -2, SEEK_CUR); ++ tseek (ifp, -2, SEEK_CUR); + order = get2(); + if (buf[0] == 'O') get2(); + } else if (!strncmp (buf,"SONY",4) || +@@ -5286,17 +5314,17 @@ + } else if (!strncmp (buf,"FUJIFILM",8)) { + base = ftell(ifp)-10; + nf: order = 0x4949; +- fseek (ifp, 2, SEEK_CUR); ++ tseek (ifp, 2, SEEK_CUR); + } else if (!strcmp (buf,"OLYMP") || + !strcmp (buf,"LEICA") || + !strcmp (buf,"Ricoh") || + !strcmp (buf,"EPSON")) +- fseek (ifp, -2, SEEK_CUR); ++ tseek (ifp, -2, SEEK_CUR); + else if (!strcmp (buf,"AOC") || + !strcmp (buf,"QVC")) +- fseek (ifp, -4, SEEK_CUR); ++ tseek (ifp, -4, SEEK_CUR); + else { +- fseek (ifp, -10, SEEK_CUR); ++ tseek (ifp, -10, SEEK_CUR); + if (!strncmp(make,"SAMSUNG",7)) + base = ftell(ifp); + } +@@ -5320,7 +5348,7 @@ + shot_order = (get2(),get2()); + } + if ((tag == 4 || tag == 0x114) && !strncmp(make,"KONICA",6)) { +- fseek (ifp, tag == 4 ? 140:160, SEEK_CUR); ++ tseek (ifp, tag == 4 ? 140:160, SEEK_CUR); + switch (get2()) { + case 72: flip = 0; break; + case 76: flip = 6; break; +@@ -5332,7 +5360,7 @@ + if (tag == 8 && type == 4) + shot_order = get4(); + if (tag == 9 && !strcmp(make,"Canon")) +- fread (artist, 64, 1, ifp); ++ tread (artist, 64, 1, ifp); + if (tag == 0xc && len == 4) + FORC3 cam_mul[(c << 1 | c >> 1) & 3] = getreal(type); + if (tag == 0xd && type == 7 && get2() == 0xaaaa) { +@@ -5345,24 +5373,24 @@ + if (tag == 0x10 && type == 4) + unique_id = get4(); + if (tag == 0x11 && is_raw && !strncmp(make,"NIKON",5)) { +- fseek (ifp, get4()+base, SEEK_SET); ++ tseek (ifp, get4()+base, SEEK_SET); + parse_tiff_ifd (base); + } + if (tag == 0x14 && type == 7) { + if (len == 2560) { +- fseek (ifp, 1248, SEEK_CUR); ++ tseek (ifp, 1248, SEEK_CUR); + goto get2_256; + } +- fread (buf, 1, 10, ifp); ++ tread (buf, 1, 10, ifp); + if (!strncmp(buf,"NRW ",4)) { +- fseek (ifp, strcmp(buf+4,"0100") ? 46:1546, SEEK_CUR); ++ tseek (ifp, strcmp(buf+4,"0100") ? 46:1546, SEEK_CUR); + cam_mul[0] = get4() << 2; + cam_mul[1] = get4() + get4(); + cam_mul[2] = get4() << 2; + } + } + if (tag == 0x15 && type == 2 && is_raw) +- fread (model, 64, 1, ifp); ++ tread (model, 64, 1, ifp); + if (strstr(make,"PENTAX")) { + if (tag == 0x1b) tag = 0x1018; + if (tag == 0x1c) tag = 0x1017; +@@ -5372,14 +5400,14 @@ + serial = serial*10 + (isdigit(c) ? c - '0' : c % 10); + if (tag == 0x29 && type == 1) { + c = wbi < 18 ? "012347800000005896"[wbi]-'0' : 0; +- fseek (ifp, 8 + c*32, SEEK_CUR); ++ tseek (ifp, 8 + c*32, SEEK_CUR); + FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get4(); + } + if (tag == 0x3d && type == 3 && len == 4) + FORC4 cblack[c ^ c >> 1] = get2() >> (14-tiff_bps); + if (tag == 0x81 && type == 4) { + data_offset = get4(); +- fseek (ifp, data_offset + 41, SEEK_SET); ++ tseek (ifp, data_offset + 41, SEEK_SET); + raw_height = get2() * 2; + raw_width = get2(); + filters = 0x61616161; +@@ -5401,29 +5429,29 @@ + ver97 = ver97 * 10 + fgetc(ifp)-'0'; + switch (ver97) { + case 100: +- fseek (ifp, 68, SEEK_CUR); ++ tseek (ifp, 68, SEEK_CUR); + FORC4 cam_mul[(c >> 1) | ((c & 1) << 1)] = get2(); + break; + case 102: +- fseek (ifp, 6, SEEK_CUR); ++ tseek (ifp, 6, SEEK_CUR); + FORC4 cam_mul[c ^ (c >> 1)] = get2(); + break; + case 103: +- fseek (ifp, 16, SEEK_CUR); ++ tseek (ifp, 16, SEEK_CUR); + FORC4 cam_mul[c] = get2(); + } + if (ver97 >= 200) { +- if (ver97 != 205) fseek (ifp, 280, SEEK_CUR); +- fread (buf97, 324, 1, ifp); ++ if (ver97 != 205) tseek (ifp, 280, SEEK_CUR); ++ tread (buf97, 324, 1, ifp); + } + } + if (tag == 0xa1 && type == 7) { + order = 0x4949; +- fseek (ifp, 140, SEEK_CUR); ++ tseek (ifp, 140, SEEK_CUR); + FORC3 cam_mul[c] = get4(); + } + if (tag == 0xa4 && type == 3) { +- fseek (ifp, wbi*48, SEEK_CUR); ++ tseek (ifp, wbi*48, SEEK_CUR); + FORC3 cam_mul[c] = get2(); + } + if (tag == 0xa7 && (unsigned) (ver97-200) < 17) { +@@ -5448,25 +5476,25 @@ + FORC4 cblack[c ^ c >> 1] = get4(); + if (tag == 0xe01) { /* Nikon Capture Note */ + order = 0x4949; +- fseek (ifp, 22, SEEK_CUR); ++ tseek (ifp, 22, SEEK_CUR); + for (offset=22; offset+22 < len; offset += 22+i) { + tag = get4(); +- fseek (ifp, 14, SEEK_CUR); ++ tseek (ifp, 14, SEEK_CUR); + i = get4()-4; + if (tag == 0x76a43207) flip = get2(); +- else fseek (ifp, i, SEEK_CUR); ++ else tseek (ifp, i, SEEK_CUR); + } + } + if (tag == 0xe80 && len == 256 && type == 7) { +- fseek (ifp, 48, SEEK_CUR); ++ tseek (ifp, 48, SEEK_CUR); + cam_mul[0] = get2() * 508 * 1.078 / 0x10000; + cam_mul[2] = get2() * 382 * 1.173 / 0x10000; + } + if (tag == 0xf00 && type == 7) { + if (len == 614) +- fseek (ifp, 176, SEEK_CUR); ++ tseek (ifp, 176, SEEK_CUR); + else if (len == 734 || len == 1502) +- fseek (ifp, 148, SEEK_CUR); ++ tseek (ifp, 148, SEEK_CUR); + else goto next; + goto get2_256; + } +@@ -5486,18 +5514,18 @@ + cam_mul[2] = get2() / 256.0; + } + if ((tag | 0x70) == 0x2070 && (type == 4 || type == 13)) +- fseek (ifp, get4()+base, SEEK_SET); ++ tseek (ifp, get4()+base, SEEK_SET); + if (tag == 0x2020 && !strncmp(buf,"OLYMP",5)) + parse_thumb_note (base, 257, 258); + if (tag == 0x2040) + parse_makernote (base, 0x2040); + if (tag == 0xb028) { +- fseek (ifp, get4()+base, SEEK_SET); ++ tseek (ifp, get4()+base, SEEK_SET); + parse_thumb_note (base, 136, 137); + } + if (tag == 0x4001 && len > 500) { + i = len == 582 ? 50 : len == 653 ? 68 : len == 5120 ? 142 : 126; +- fseek (ifp, i, SEEK_CUR); ++ tseek (ifp, i, SEEK_CUR); + FORC4 cam_mul[c ^ (c >> 1)] = get2(); + for (i+=18; i <= len; i+=10) { + get2(); +@@ -5514,7 +5542,7 @@ + if (tag == 0xb001) + unique_id = get2(); + next: +- fseek (ifp, save, SEEK_SET); ++ tseek (ifp, save, SEEK_SET); + } + quit: + order = sorder; +@@ -5534,7 +5562,7 @@ + if (reversed) + for (i=19; i--; ) str[i] = fgetc(ifp); + else +- fread (str, 19, 1, ifp); ++ tread (str, 19, 1, ifp); + memset (&t, 0, sizeof t); + if (sscanf (str, "%d:%d:%d %d:%d:%d", &t.tm_year, &t.tm_mon, + &t.tm_mday, &t.tm_hour, &t.tm_min, &t.tm_sec) != 6) +@@ -5575,7 +5603,7 @@ + for (exif_cfa=c=0; c < 8; c+=2) + exif_cfa |= fgetc(ifp) * 0x01010101 << c; + } +- fseek (ifp, save, SEEK_SET); ++ tseek (ifp, save, SEEK_SET); + } + } + +@@ -5596,7 +5624,7 @@ + case 18: case 29: + fgets ((char *) (gpsdata+14+tag/3), MIN(len,12), ifp); + } +- fseek (ifp, save, SEEK_SET); ++ tseek (ifp, save, SEEK_SET); + } + } + +@@ -5626,11 +5654,11 @@ + "","","","","Aptus-II 10R","Aptus-II 8","","Aptus-II 12","","AFi-II 12" }; + float romm_cam[3][3]; + +- fseek (ifp, offset, SEEK_SET); ++ tseek (ifp, offset, SEEK_SET); + while (1) { + if (get4() != 0x504b5453) break; + get4(); +- fread (data, 1, 40, ifp); ++ tread (data, 1, 40, ifp); + skip = get4(); + from = ftell(ifp); + if (!strcmp(data,"JPEG_preview_data")) { +@@ -5676,7 +5704,7 @@ + if (!strcmp(data,"Rows_data")) + load_flags = get4(); + parse_mos (from); +- fseek (ifp, skip+from, SEEK_SET); ++ tseek (ifp, skip+from, SEEK_SET); + } + if (planes) + filters = (planes == 1) * 0x01010101 * +@@ -5706,7 +5734,7 @@ + tiff_get (base, &tag, &type, &len, &save); + if (tag == 1020) wbi = getint(type); + if (tag == 1021 && len == 72) { /* WB set in software */ +- fseek (ifp, 40, SEEK_CUR); ++ tseek (ifp, 40, SEEK_CUR); + FORC3 cam_mul[c] = 2048.0 / get2(); + wbi = -2; + } +@@ -5728,7 +5756,7 @@ + FORC3 cam_mul[c] = get4(); + if (tag == 64019) width = getint(type); + if (tag == 64020) height = (getint(type)+1) & -2; +- fseek (ifp, save, SEEK_SET); ++ tseek (ifp, save, SEEK_SET); + } + } + +@@ -5779,7 +5807,7 @@ + break; + case 39: + if (len < 50 || cam_mul[0]) break; +- fseek (ifp, 12, SEEK_CUR); ++ tseek (ifp, 12, SEEK_CUR); + FORC3 cam_mul[c] = get2(); + break; + case 46: +@@ -5788,7 +5816,7 @@ + thumb_length = len; + break; + case 61440: /* Fuji HS10 table */ +- fseek (ifp, get4()+base, SEEK_SET); ++ tseek (ifp, get4()+base, SEEK_SET); + parse_tiff_ifd (base); + break; + case 2: case 256: case 61441: /* ImageWidth */ +@@ -5816,7 +5844,7 @@ + tiff_ifd[ifd].phint = get2(); + break; + case 270: /* ImageDescription */ +- fread (desc, 512, 1, ifp); ++ tread (desc, 512, 1, ifp); + break; + case 271: /* Make */ + fgets (make, 64, ifp); +@@ -5833,7 +5861,7 @@ + case 61447: + tiff_ifd[ifd].offset = get4()+base; + if (!tiff_ifd[ifd].bps && tiff_ifd[ifd].offset > 0) { +- fseek (ifp, tiff_ifd[ifd].offset, SEEK_SET); ++ tseek (ifp, tiff_ifd[ifd].offset, SEEK_SET); + if (ljpeg_start (&jh, 1)) { + tiff_ifd[ifd].comp = 6; + tiff_ifd[ifd].width = jh.wide; +@@ -5880,7 +5908,7 @@ + get_timestamp(0); + break; + case 315: /* Artist */ +- fread (artist, 64, 1, ifp); ++ tread (artist, 64, 1, ifp); + break; + case 322: /* TileWidth */ + tiff_ifd[ifd].tile_width = getint(type); +@@ -5905,9 +5933,9 @@ + } + while (len--) { + i = ftell(ifp); +- fseek (ifp, get4()+base, SEEK_SET); ++ tseek (ifp, get4()+base, SEEK_SET); + if (parse_tiff_ifd (base)) break; +- fseek (ifp, i+4, SEEK_SET); ++ tseek (ifp, i+4, SEEK_SET); + } + break; + case 400: +@@ -5949,7 +5977,7 @@ + } + case 64777: /* Kodak P-series */ + if ((plen=len) > 16) plen = 16; +- fread (cfa_pat, 1, plen, ifp); ++ tread (cfa_pat, 1, plen, ifp); + for (colors=cfa=i=0; i < plen && colors < 4; i++) { + colors += !(cfa & (1 << cfa_pat[i])); + cfa |= 1 << cfa_pat[i]; +@@ -5959,7 +5987,7 @@ + goto guess_cfa_pc; + case 33424: + case 65024: +- fseek (ifp, get4()+base, SEEK_SET); ++ tseek (ifp, get4()+base, SEEK_SET); + parse_kodak_ifd (base); + break; + case 33434: /* ExposureTime */ +@@ -5972,7 +6000,7 @@ + FORC4 cam_mul[c ^ 1] = 4096.0 / get2(); + break; + case 34307: /* Leaf CatchLight color matrix */ +- fread (software, 1, 7, ifp); ++ tread (software, 1, 7, ifp); + if (strncmp(software,"MATRIX",6)) break; + colors = 4; + for (raw_color = i=0; i < 3; i++) { +@@ -5989,11 +6017,11 @@ + strcpy (make, "Leaf"); + break; + case 34665: /* EXIF tag */ +- fseek (ifp, get4()+base, SEEK_SET); ++ tseek (ifp, get4()+base, SEEK_SET); + parse_exif (base); + break; + case 34853: /* GPSInfo tag */ +- fseek (ifp, get4()+base, SEEK_SET); ++ tseek (ifp, get4()+base, SEEK_SET); + parse_gps (base); + break; + case 34675: /* InterColorProfile */ +@@ -6031,9 +6059,9 @@ + break; + case 46279: + if (!ima_len) break; +- fseek (ifp, 38, SEEK_CUR); ++ tseek (ifp, 38, SEEK_CUR); + case 46274: +- fseek (ifp, 40, SEEK_CUR); ++ tseek (ifp, 40, SEEK_CUR); + raw_width = get4(); + raw_height = get4(); + left_margin = get4() & 7; +@@ -6045,9 +6073,9 @@ + width = 7244; + left_margin = 7; + } +- fseek (ifp, 52, SEEK_CUR); ++ tseek (ifp, 52, SEEK_CUR); + FORC3 cam_mul[c] = getreal(11); +- fseek (ifp, 114, SEEK_CUR); ++ tseek (ifp, 114, SEEK_CUR); + flip = (get2() >> 7) * 90; + if (width * height * 6 == ima_len) { + if (flip % 180 == 90) SWAP(width,height); +@@ -6066,7 +6094,7 @@ + case 50454: /* Sinar tag */ + case 50455: + if (!(cbuf = (char *) malloc(len))) break; +- fread (cbuf, 1, len, ifp); ++ tread (cbuf, 1, len, ifp); + for (cp = cbuf-1; cp && cp < cbuf+len; cp = strchr(cp,'\n')) + if (!strncmp (++cp,"Neutral ",8)) + sscanf (cp+8, "%f %f %f", cam_mul, cam_mul+1, cam_mul+2); +@@ -6080,7 +6108,7 @@ + j = ftell(ifp); + c = tiff_nifds; + order = get2(); +- fseek (ifp, j+(get2(),get4()), SEEK_SET); ++ tseek (ifp, j+(get2(),get4()), SEEK_SET); + parse_tiff_ifd (j); + maximum = 0xffff; + tiff_nifds = c; +@@ -6103,7 +6131,7 @@ + if (filters == 9) break; + if (len > 4) len = 4; + colors = len; +- fread (cfa_pc, 1, colors, ifp); ++ tread (cfa_pc, 1, colors, ifp); + guess_cfa_pc: + FORCC tab[cfa_pc[c]] = c; + cdesc[c] = 0; +@@ -6172,7 +6200,7 @@ + case 50740: /* DNGPrivateData */ + if (dng_version) break; + parse_minolta (j = get4()+base); +- fseek (ifp, j, SEEK_SET); ++ tseek (ifp, j, SEEK_SET); + parse_tiff_ifd (base); + break; + case 50752: +@@ -6194,25 +6222,25 @@ + break; + case 64772: /* Kodak P-series */ + if (len < 13) break; +- fseek (ifp, 16, SEEK_CUR); ++ tseek (ifp, 16, SEEK_CUR); + data_offset = get4(); +- fseek (ifp, 28, SEEK_CUR); ++ tseek (ifp, 28, SEEK_CUR); + data_offset += get4(); + load_raw = &CLASS packed_load_raw; + break; + case 65026: + if (type == 2) fgets (model2, 64, ifp); + } +- fseek (ifp, save, SEEK_SET); ++ tseek (ifp, save, SEEK_SET); + } + if (sony_length && (buf = (unsigned *) malloc(sony_length))) { +- fseek (ifp, sony_offset, SEEK_SET); +- fread (buf, sony_length, 1, ifp); ++ tseek (ifp, sony_offset, SEEK_SET); ++ tread (buf, sony_length, 1, ifp); + sony_decrypt (buf, sony_length/4, 1, sony_key); + sfp = ifp; + if ((ifp = tmpfile())) { +- fwrite (buf, sony_length, 1, ifp); +- fseek (ifp, 0, SEEK_SET); ++ twrite (buf, sony_length, 1, ifp); ++ tseek (ifp, 0, SEEK_SET); + parse_tiff_ifd (-sony_offset); + fclose (ifp); + } +@@ -6240,12 +6268,12 @@ + { + int doff; + +- fseek (ifp, base, SEEK_SET); ++ tseek (ifp, base, SEEK_SET); + order = get2(); + if (order != 0x4949 && order != 0x4d4d) return 0; + get2(); + while ((doff = get4())) { +- fseek (ifp, doff+base, SEEK_SET); ++ tseek (ifp, doff+base, SEEK_SET); + if (parse_tiff_ifd (base)) break; + } + return 1; +@@ -6258,7 +6286,7 @@ + + thumb_misc = 16; + if (thumb_offset) { +- fseek (ifp, thumb_offset, SEEK_SET); ++ tseek (ifp, thumb_offset, SEEK_SET); + if (ljpeg_start (&jh, 1)) { + thumb_misc = jh.bits; + thumb_width = jh.wide; +@@ -6423,7 +6451,7 @@ + int save, tag, len, offset, high=0, wide=0, i, c; + short sorder=order; + +- fseek (ifp, base, SEEK_SET); ++ tseek (ifp, base, SEEK_SET); + if (fgetc(ifp) || fgetc(ifp)-'M' || fgetc(ifp)-'R') return; + order = fgetc(ifp) * 0x101; + offset = base + get4() + 8; +@@ -6433,7 +6461,7 @@ + len = get4(); + switch (tag) { + case 0x505244: /* PRD */ +- fseek (ifp, 8, SEEK_CUR); ++ tseek (ifp, 8, SEEK_CUR); + high = get2(); + wide = get2(); + break; +@@ -6446,7 +6474,7 @@ + parse_tiff (ftell(ifp)); + data_offset = offset; + } +- fseek (ifp, save+len+8, SEEK_SET); ++ tseek (ifp, save+len+8, SEEK_SET); + } + raw_height = high; + raw_width = wide; +@@ -6536,24 +6564,24 @@ + int tboff, nrecs, c, type, len, save, wbi=-1; + ushort key[] = { 0x410, 0x45f3 }; + +- fseek (ifp, offset+length-4, SEEK_SET); ++ tseek (ifp, offset+length-4, SEEK_SET); + tboff = get4() + offset; +- fseek (ifp, tboff, SEEK_SET); ++ tseek (ifp, tboff, SEEK_SET); + nrecs = get2(); + if ((nrecs | depth) > 127) return; + while (nrecs--) { + type = get2(); + len = get4(); + save = ftell(ifp) + 4; +- fseek (ifp, offset+get4(), SEEK_SET); ++ tseek (ifp, offset+get4(), SEEK_SET); + if ((((type >> 8) + 8) | 8) == 0x38) + parse_ciff (ftell(ifp), len, depth+1); /* Parse a sub-table */ + if (type == 0x0810) +- fread (artist, 64, 1, ifp); ++ tread (artist, 64, 1, ifp); + if (type == 0x080a) { +- fread (make, 64, 1, ifp); +- fseek (ifp, strlen(make) - 63, SEEK_CUR); +- fread (model, 64, 1, ifp); ++ tread (make, 64, 1, ifp); ++ tseek (ifp, strlen(make) - 63, SEEK_CUR); ++ tread (model, 64, 1, ifp); + } + if (type == 0x1810) { + width = get4(); +@@ -6577,21 +6605,21 @@ + shutter = pow (2,-((short)get2())/32.0); + wbi = (get2(),get2()); + if (wbi > 17) wbi = 0; +- fseek (ifp, 32, SEEK_CUR); ++ tseek (ifp, 32, SEEK_CUR); + if (shutter > 1e6) shutter = get2()/10.0; + } + if (type == 0x102c) { + if (get2() > 512) { /* Pro90, G1 */ +- fseek (ifp, 118, SEEK_CUR); ++ tseek (ifp, 118, SEEK_CUR); + FORC4 cam_mul[c ^ 2] = get2(); + } else { /* G2, S30, S40 */ +- fseek (ifp, 98, SEEK_CUR); ++ tseek (ifp, 98, SEEK_CUR); + FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get2(); + } + } + if (type == 0x0032) { + if (len == 768) { /* EOS D30 */ +- fseek (ifp, 72, SEEK_CUR); ++ tseek (ifp, 72, SEEK_CUR); + FORC4 cam_mul[c ^ (c >> 1)] = 1024.0 / get2(); + if (!wbi) cam_mul[0] = -1; /* use my auto white balance */ + } else if (!cam_mul[0]) { +@@ -6602,14 +6630,14 @@ + c = "023457000000006000"[wbi]-'0'; + key[0] = key[1] = 0; + } +- fseek (ifp, 78 + c*8, SEEK_CUR); ++ tseek (ifp, 78 + c*8, SEEK_CUR); + FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get2() ^ key[c & 1]; + if (!wbi) cam_mul[0] = -1; + } + } + if (type == 0x10a9) { /* D60, 10D, 300D, and clones */ + if (len > 66) wbi = "0134567028"[wbi]-'0'; +- fseek (ifp, 2 + wbi*8, SEEK_CUR); ++ tseek (ifp, 2 + wbi*8, SEEK_CUR); + FORC4 cam_mul[c ^ (c >> 1)] = get2(); + } + if (type == 0x1030 && (0x18040 >> wbi & 1)) +@@ -6632,7 +6660,7 @@ + if ((type | 0x4000) == 0x580e) + timestamp = mktime (gmtime (×tamp)); + #endif +- fseek (ifp, save, SEEK_SET); ++ tseek (ifp, save, SEEK_SET); + } + } + +@@ -6641,7 +6669,7 @@ + char line[128], *val; + struct tm t; + +- fseek (ifp, 0, SEEK_SET); ++ tseek (ifp, 0, SEEK_SET); + memset (&t, 0, sizeof t); + do { + fgets (line, 128, ifp); +@@ -6680,18 +6708,18 @@ + char str[8], *cp; + + order = 0x4949; +- fseek (ifp, 4, SEEK_SET); ++ tseek (ifp, 4, SEEK_SET); + entries = get4(); +- fseek (ifp, get4(), SEEK_SET); ++ tseek (ifp, get4(), SEEK_SET); + while (entries--) { + off = get4(); get4(); +- fread (str, 8, 1, ifp); ++ tread (str, 8, 1, ifp); + if (!strcmp(str,"META")) meta_offset = off; + if (!strcmp(str,"THUMB")) thumb_offset = off; + if (!strcmp(str,"RAW0")) data_offset = off; + } +- fseek (ifp, meta_offset+20, SEEK_SET); +- fread (make, 64, 1, ifp); ++ tseek (ifp, meta_offset+20, SEEK_SET); ++ tread (make, 64, 1, ifp); + make[63] = 0; + if ((cp = strchr(make,' '))) { + strcpy (model, cp+1); +@@ -6713,10 +6741,10 @@ + char *cp; + + memset (&ph1, 0, sizeof ph1); +- fseek (ifp, base, SEEK_SET); ++ tseek (ifp, base, SEEK_SET); + order = get4() & 0xffff; + if (get4() >> 8 != 0x526177) return; /* "Raw" */ +- fseek (ifp, get4()+base, SEEK_SET); ++ tseek (ifp, get4()+base, SEEK_SET); + entries = get4(); + get4(); + while (entries--) { +@@ -6725,7 +6753,7 @@ + len = get4(); + data = get4(); + save = ftell(ifp); +- fseek (ifp, base+data, SEEK_SET); ++ tseek (ifp, base+data, SEEK_SET); + switch (tag) { + case 0x100: flip = "0653"[data & 3]-'0'; break; + case 0x106: +@@ -6757,10 +6785,10 @@ + case 0x225: ph1.black_row = data+base; break; + case 0x301: + model[63] = 0; +- fread (model, 1, 63, ifp); ++ tread (model, 1, 63, ifp); + if ((cp = strstr(model," camera"))) *cp = 0; + } +- fseek (ifp, save, SEEK_SET); ++ tseek (ifp, save, SEEK_SET); + } + load_raw = ph1.format < 3 ? + &CLASS phase_one_load_raw : &CLASS phase_one_load_raw_c; +@@ -6779,7 +6807,7 @@ + { + unsigned entries, tag, len, save, c; + +- fseek (ifp, offset, SEEK_SET); ++ tseek (ifp, offset, SEEK_SET); + entries = get4(); + if (entries > 255) return; + while (entries--) { +@@ -6808,7 +6836,7 @@ + height = get4(); + order = c; + } +- fseek (ifp, save+len, SEEK_SET); ++ tseek (ifp, save+len, SEEK_SET); + } + height <<= fuji_layout; + width >>= fuji_layout; +@@ -6818,7 +6846,7 @@ + { + int len, save, hlen, mark; + +- fseek (ifp, offset, SEEK_SET); ++ tseek (ifp, offset, SEEK_SET); + if (fgetc(ifp) != 0xff || fgetc(ifp) != 0xd8) return 0; + + while (fgetc(ifp) == 0xff && (mark = fgetc(ifp)) != 0xda) { +@@ -6835,7 +6863,7 @@ + if (get4() == 0x48454150) /* "HEAP" */ + parse_ciff (save+hlen, len-hlen, 0); + if (parse_tiff (save+6)) apply_tiff(); +- fseek (ifp, save+len, SEEK_SET); ++ tseek (ifp, save+len, SEEK_SET); + } + return 1; + } +@@ -6849,7 +6877,7 @@ + struct tm t; + + order = 0x4949; +- fread (tag, 4, 1, ifp); ++ tread (tag, 4, 1, ifp); + size = get4(); + end = ftell(ifp) + size; + if (!memcmp(tag,"RIFF",4) || !memcmp(tag,"LIST",4)) { +@@ -6862,10 +6890,10 @@ + size = get2(); + if ((i+1) >> 1 == 10 && size == 20) + get_timestamp(0); +- else fseek (ifp, size, SEEK_CUR); ++ else tseek (ifp, size, SEEK_CUR); + } + } else if (!memcmp(tag,"IDIT",4) && size < 64) { +- fread (date, 64, 1, ifp); ++ tread (date, 64, 1, ifp); + date[size] = 0; + memset (&t, 0, sizeof t); + if (sscanf (date, "%*s %s %d %d:%d:%d %d", month, &t.tm_mday, +@@ -6877,7 +6905,7 @@ + timestamp = mktime(&t); + } + } else +- fseek (ifp, size, SEEK_CUR); ++ tseek (ifp, size, SEEK_CUR); + } + + void CLASS parse_crx (int end) +@@ -6899,8 +6927,8 @@ + break; + case 0x75756964: /* uuid */ + switch (i=get4()) { +- case 0xeaf42b5e: fseek (ifp, 8, SEEK_CUR); +- case 0x85c0b687: fseek (ifp, 12, SEEK_CUR); ++ case 0xeaf42b5e: tseek (ifp, 8, SEEK_CUR); ++ case 0x85c0b687: tseek (ifp, 12, SEEK_CUR); + parse_crx (save+size); + } + break; +@@ -6908,14 +6936,14 @@ + case 0x434d5432: /* CMT2 */ + base = ftell(ifp); + order = get2(); +- fseek (ifp, 6, SEEK_CUR); ++ tseek (ifp, 6, SEEK_CUR); + tag & 1 ? parse_tiff_ifd (base) : parse_exif (base); + order = 0x4d4d; + break; + case 0x746b6864: /* tkhd */ +- fseek (ifp, 12, SEEK_CUR); ++ tseek (ifp, 12, SEEK_CUR); + index = get4(); +- fseek (ifp, 58, SEEK_CUR); ++ tseek (ifp, 58, SEEK_CUR); + wide = get4(); + high = get4(); + break; +@@ -6923,7 +6951,7 @@ + len = (get4(),get4()); + break; + case 0x636f3634: /* co64 */ +- fseek (ifp, 12, SEEK_CUR); ++ tseek (ifp, 12, SEEK_CUR); + off = get4(); + switch (index) { + case 1: /* 1 = full size, 2 = 27% size */ +@@ -6940,9 +6968,9 @@ + } + break; + case 0x50525657: /* PRVW */ +- fseek (ifp, 6, SEEK_CUR); ++ tseek (ifp, 6, SEEK_CUR); + } +- fseek (ifp, save+size, SEEK_SET); ++ tseek (ifp, save+size, SEEK_SET); + } + } + +@@ -6955,14 +6983,14 @@ + while (ftell(ifp)+7 < end) { + save = ftell(ifp); + if ((size = get4()) < 8) return; +- fread (tag, 4, 1, ifp); ++ tread (tag, 4, 1, ifp); + if (!memcmp(tag,"moov",4) || + !memcmp(tag,"udta",4) || + !memcmp(tag,"CNTH",4)) + parse_qt (save+size); + if (!memcmp(tag,"CNDA",4)) + parse_jpeg (ftell(ifp)); +- fseek (ifp, save+size, SEEK_SET); ++ tseek (ifp, save+size, SEEK_SET); + } + } + +@@ -6970,11 +6998,11 @@ + { + int ver; + +- fseek (ifp, offset+2, SEEK_SET); ++ tseek (ifp, offset+2, SEEK_SET); + order = 0x4949; + ver = fgetc(ifp); + if (ver == 6) +- fseek (ifp, 5, SEEK_CUR); ++ tseek (ifp, 5, SEEK_CUR); + if (get4() != fsize) return; + if (ver > 6) data_offset = get4(); + raw_height = height = get2(); +@@ -6990,32 +7018,32 @@ + unsigned off_head, off_setup, off_image, i; + + order = 0x4949; +- fseek (ifp, 4, SEEK_SET); ++ tseek (ifp, 4, SEEK_SET); + is_raw = get2() == 2; +- fseek (ifp, 14, SEEK_CUR); ++ tseek (ifp, 14, SEEK_CUR); + is_raw *= get4(); + off_head = get4(); + off_setup = get4(); + off_image = get4(); + timestamp = get4(); + if ((i = get4())) timestamp = i; +- fseek (ifp, off_head+4, SEEK_SET); ++ tseek (ifp, off_head+4, SEEK_SET); + raw_width = get4(); + raw_height = get4(); + switch (get2(),get2()) { + case 8: load_raw = &CLASS eight_bit_load_raw; break; + case 16: load_raw = &CLASS unpacked_load_raw; + } +- fseek (ifp, off_setup+792, SEEK_SET); ++ tseek (ifp, off_setup+792, SEEK_SET); + strcpy (make, "CINE"); + sprintf (model, "%d", get4()); +- fseek (ifp, 12, SEEK_CUR); ++ tseek (ifp, 12, SEEK_CUR); + switch ((i=get4()) & 0xffffff) { + case 3: filters = 0x94949494; break; + case 4: filters = 0x49494949; break; + default: is_raw = 0; + } +- fseek (ifp, 72, SEEK_CUR); ++ tseek (ifp, 72, SEEK_CUR); + switch ((get4()+3600) % 360) { + case 270: flip = 4; break; + case 180: flip = 1; break; +@@ -7025,11 +7053,11 @@ + cam_mul[0] = getreal(11); + cam_mul[2] = getreal(11); + maximum = ~(-1 << get4()); +- fseek (ifp, 668, SEEK_CUR); ++ tseek (ifp, 668, SEEK_CUR); + shutter = get4()/1000000000.0; +- fseek (ifp, off_image, SEEK_SET); ++ tseek (ifp, off_image, SEEK_SET); + if (shot_select < is_raw) +- fseek (ifp, shot_select*8, SEEK_CUR); ++ tseek (ifp, shot_select*8, SEEK_CUR); + data_offset = (INT64) get4() + 8; + data_offset += (INT64) get4() << 32; + } +@@ -7040,23 +7068,23 @@ + + order = 0x4d4d; + is_raw = 0; +- fseek (ifp, 52, SEEK_SET); ++ tseek (ifp, 52, SEEK_SET); + width = get4(); + height = get4(); +- fseek (ifp, 0, SEEK_END); +- fseek (ifp, -(i = ftello(ifp) & 511), SEEK_CUR); ++ tseek (ifp, 0, SEEK_END); ++ tseek (ifp, -(i = ftello(ifp) & 511), SEEK_CUR); + if (get4() != i || get4() != 0x52454f42) { + fprintf (stderr,_("%s: Tail is missing, parsing from head...\n"), ifname); +- fseek (ifp, 0, SEEK_SET); ++ tseek (ifp, 0, SEEK_SET); + while ((len = get4()) != EOF) { + if (get4() == 0x52454456) + if (is_raw++ == shot_select) + data_offset = ftello(ifp) - 8; +- fseek (ifp, len-8, SEEK_CUR); ++ tseek (ifp, len-8, SEEK_CUR); + } + } else { + rdvo = get4(); +- fseek (ifp, 12, SEEK_CUR); ++ tseek (ifp, 12, SEEK_CUR); + is_raw = get4(); + fseeko (ifp, rdvo+8 + shot_select*4, SEEK_SET); + data_offset = get4(); +@@ -7066,7 +7094,7 @@ + char * CLASS foveon_gets (int offset, char *str, int len) + { + int i; +- fseek (ifp, offset, SEEK_SET); ++ tseek (ifp, offset, SEEK_SET); + for (i=0; i < len-1; i++) + if ((str[i] = get2()) == 0) break; + str[i] = 0; +@@ -7079,10 +7107,10 @@ + char name[64], value[64]; + + order = 0x4949; /* Little-endian */ +- fseek (ifp, 36, SEEK_SET); ++ tseek (ifp, 36, SEEK_SET); + flip = get4(); +- fseek (ifp, -4, SEEK_END); +- fseek (ifp, get4(), SEEK_SET); ++ tseek (ifp, -4, SEEK_END); ++ tseek (ifp, get4(), SEEK_SET); + if (get4() != 0x64434553) return; /* SECd */ + entries = (get4(),get4()); + while (entries--) { +@@ -7090,12 +7118,12 @@ + len = get4(); + tag = get4(); + save = ftell(ifp); +- fseek (ifp, off, SEEK_SET); ++ tseek (ifp, off, SEEK_SET); + if (get4() != (0x20434553 | (tag << 24))) return; + switch (tag) { + case 0x47414d49: /* IMAG */ + case 0x32414d49: /* IMA2 */ +- fseek (ifp, 8, SEEK_CUR); ++ tseek (ifp, 8, SEEK_CUR); + pent = get4(); + wide = get4(); + high = get4(); +@@ -7111,7 +7139,7 @@ + data_offset = off+28; + is_foveon = 1; + } +- fseek (ifp, off+28, SEEK_SET); ++ tseek (ifp, off+28, SEEK_SET); + if (fgetc(ifp) == 0xff && fgetc(ifp) == 0xd8 + && thumb_length < len-28) { + thumb_offset = off+28; +@@ -7131,7 +7159,7 @@ + break; + case 0x504f5250: /* PROP */ + pent = (get4(),get4()); +- fseek (ifp, 12, SEEK_CUR); ++ tseek (ifp, 12, SEEK_CUR); + off += pent*8 + 24; + if ((unsigned) pent > 256) pent=256; + for (i=0; i < pent*2; i++) +@@ -7160,7 +7188,7 @@ + timestamp = mktime (gmtime (×tamp)); + #endif + } +- fseek (ifp, save, SEEK_SET); ++ tseek (ifp, save, SEEK_SET); + } + } + +@@ -8360,9 +8388,9 @@ + int t=2, msb; + double diff, sum[2] = {0,0}; + +- fread (test[0], 2, 2, ifp); ++ tread (test[0], 2, 2, ifp); + for (words-=2; words--; ) { +- fread (test[t], 2, 1, ifp); ++ tread (test[t], 2, 1, ifp); + for (msb=0; msb < 2; msb++) { + diff = (test[t^2][msb] << 8 | test[t^2][!msb]) + - (test[t ][msb] << 8 | test[t ][!msb]); +@@ -8387,7 +8415,7 @@ + merror (img, "find_green()"); + + FORC(2) { +- fseek (ifp, c ? off1:off0, SEEK_SET); ++ tseek (ifp, c ? off1:off0, SEEK_SET); + for (vbits=col=0; col < width; col++) { + for (vbits -= bps; vbits < 0; vbits += bite) { + bitbuf <<= bite; +@@ -8721,9 +8749,9 @@ + + order = get2(); + hlen = get4(); +- fseek (ifp, 0, SEEK_SET); +- fread (head, 1, 32, ifp); +- fseek (ifp, 0, SEEK_END); ++ tseek (ifp, 0, SEEK_SET); ++ tread (head, 1, 32, ifp); ++ tseek (ifp, 0, SEEK_END); + flen = fsize = ftell(ifp); + if ((cp = (char *) memmem (head, 32, "MMMM", 4)) || + (cp = (char *) memmem (head, 32, "IIII", 4))) { +@@ -8737,18 +8765,18 @@ + } else if (parse_tiff(0)) apply_tiff(); + } else if (!memcmp (head,"\xff\xd8\xff\xe1",4) && + !memcmp (head+6,"Exif",4)) { +- fseek (ifp, 4, SEEK_SET); ++ tseek (ifp, 4, SEEK_SET); + data_offset = 4 + get2(); +- fseek (ifp, data_offset, SEEK_SET); ++ tseek (ifp, data_offset, SEEK_SET); + if (fgetc(ifp) != 0xff) + parse_tiff(12); + thumb_offset = 0; + } else if (!memcmp (head+25,"ARECOYK",7)) { + strcpy (make, "Contax"); + strcpy (model,"N Digital"); +- fseek (ifp, 33, SEEK_SET); ++ tseek (ifp, 33, SEEK_SET); + get_timestamp(1); +- fseek (ifp, 60, SEEK_SET); ++ tseek (ifp, 60, SEEK_SET); + FORC4 cam_mul[c ^ (c >> 1)] = get4(); + } else if (!strcmp (head, "PXN")) { + strcpy (make, "Logitech"); +@@ -8762,18 +8790,18 @@ + strcpy (model,"QuickTake 150"); + load_raw = &CLASS kodak_radc_load_raw; + } else if (!memcmp (head,"FUJIFILM",8)) { +- fseek (ifp, 84, SEEK_SET); ++ tseek (ifp, 84, SEEK_SET); + thumb_offset = get4(); + thumb_length = get4(); +- fseek (ifp, 92, SEEK_SET); ++ tseek (ifp, 92, SEEK_SET); + parse_fuji (get4()); + if (thumb_offset > 120) { +- fseek (ifp, 120, SEEK_SET); ++ tseek (ifp, 120, SEEK_SET); + is_raw += (i = get4()) && 1; + if (is_raw == 2 && shot_select) + parse_fuji (i); + } +- fseek (ifp, 100+28*(shot_select > 0), SEEK_SET); ++ tseek (ifp, 100+28*(shot_select > 0), SEEK_SET); + parse_tiff (data_offset = get4()); + parse_tiff (thumb_offset+12); + apply_tiff(); +@@ -8782,20 +8810,20 @@ + tiff_bps = 14; + } + } else if (!memcmp (head,"RIFF",4)) { +- fseek (ifp, 0, SEEK_SET); ++ tseek (ifp, 0, SEEK_SET); + parse_riff(); + } else if (!memcmp (head+4,"ftypcrx ",8)) { +- fseek (ifp, 0, SEEK_SET); ++ tseek (ifp, 0, SEEK_SET); + parse_crx (fsize); + } else if (!memcmp (head+4,"ftypqt ",9)) { +- fseek (ifp, 0, SEEK_SET); ++ tseek (ifp, 0, SEEK_SET); + parse_qt (fsize); + is_raw = 0; + } else if (!memcmp (head,"\0\001\0\001\0@",6)) { +- fseek (ifp, 6, SEEK_SET); +- fread (make, 1, 8, ifp); +- fread (model, 1, 8, ifp); +- fread (model2, 1, 16, ifp); ++ tseek (ifp, 6, SEEK_SET); ++ tread (make, 1, 8, ifp); ++ tread (model, 1, 8, ifp); ++ tread (model2, 1, 16, ifp); + data_offset = get2(); + get2(); + raw_width = get2(); +@@ -8805,7 +8833,7 @@ + } else if (!memcmp (head,"NOKIARAW",8)) { + strcpy (make, "NOKIA"); + order = 0x4949; +- fseek (ifp, 300, SEEK_SET); ++ tseek (ifp, 300, SEEK_SET); + data_offset = get4(); + i = get4(); + width = get2(); +@@ -8819,24 +8847,24 @@ + filters = 0x61616161; + } else if (!memcmp (head,"ARRI",4)) { + order = 0x4949; +- fseek (ifp, 20, SEEK_SET); ++ tseek (ifp, 20, SEEK_SET); + width = get4(); + height = get4(); + strcpy (make, "ARRI"); +- fseek (ifp, 668, SEEK_SET); +- fread (model, 1, 64, ifp); ++ tseek (ifp, 668, SEEK_SET); ++ tread (model, 1, 64, ifp); + data_offset = 4096; + load_raw = &CLASS packed_load_raw; + load_flags = 88; + filters = 0x61616161; + } else if (!memcmp (head,"XPDS",4)) { + order = 0x4949; +- fseek (ifp, 0x800, SEEK_SET); +- fread (make, 1, 41, ifp); ++ tseek (ifp, 0x800, SEEK_SET); ++ tread (make, 1, 41, ifp); + raw_height = get2(); + raw_width = get2(); +- fseek (ifp, 56, SEEK_CUR); +- fread (model, 1, 30, ifp); ++ tseek (ifp, 56, SEEK_CUR); ++ tread (model, 1, 30, ifp); + data_offset = 0x10000; + load_raw = &CLASS canon_rmf_load_raw; + gamma_curve (0, 12.25, 1, 1023); +@@ -9201,7 +9229,7 @@ + } + load_flags = 6 + 24*(make[0] == 'M'); + } else if (fsize == 6291456) { +- fseek (ifp, 0x300000, SEEK_SET); ++ tseek (ifp, 0x300000, SEEK_SET); + if ((order = guess_byte_order(0x10000)) == 0x4d4d) { + height -= (top_margin = 16); + width -= (left_margin = 28); +@@ -9379,7 +9407,7 @@ + maximum = 0x3fff; + } else if (!strcmp(make,"Leaf")) { + maximum = 0x3fff; +- fseek (ifp, data_offset, SEEK_SET); ++ tseek (ifp, data_offset, SEEK_SET); + if (ljpeg_start (&jh, 1) && jh.bits == 15) + maximum = 0x1fff; + if (tiff_samples > 1) filters = 0; +@@ -9535,7 +9563,7 @@ + || !strcmp(model,"12MP")) { + order = 0x4949; + if (filters && data_offset) { +- fseek (ifp, data_offset < 4096 ? 168 : 5252, SEEK_SET); ++ tseek (ifp, data_offset < 4096 ? 168 : 5252, SEEK_SET); + read_shorts (curve, 256); + } else gamma_curve (0, 3.875, 1, 255); + load_raw = filters ? &CLASS eight_bit_load_raw : +@@ -9622,13 +9650,13 @@ + simple_coeff(2); + } else if (!strncmp(model,"QuickTake",9)) { + if (head[5]) strcpy (model+10, "200"); +- fseek (ifp, 544, SEEK_SET); ++ tseek (ifp, 544, SEEK_SET); + height = get2(); + width = get2(); + data_offset = (get4(),get2()) == 30 ? 738:736; + if (height > width) { + SWAP(height,width); +- fseek (ifp, data_offset-6, SEEK_SET); ++ tseek (ifp, data_offset-6, SEEK_SET); + flip = ~get2() & 3 ? 5:6; + } + filters = 0x61616161; +@@ -9653,7 +9681,7 @@ + sprintf (model, "%dx%d", width, height); + if (filters == UINT_MAX) filters = 0x94949494; + if (thumb_offset && !thumb_height) { +- fseek (ifp, thumb_offset, SEEK_SET); ++ tseek (ifp, thumb_offset, SEEK_SET); + if (ljpeg_start (&jh, 1)) { + thumb_width = jh.wide; + thumb_height = jh.high; +@@ -9724,8 +9752,8 @@ + else if (profile_length) { + prof = (char *) malloc (profile_length); + merror (prof, "apply_profile()"); +- fseek (ifp, profile_offset, SEEK_SET); +- fread (prof, 1, profile_length, ifp); ++ tseek (ifp, profile_offset, SEEK_SET); ++ tread (prof, 1, profile_length, ifp); + hInProfile = cmsOpenProfileFromMem (prof, profile_length); + free (prof); + } else +@@ -9734,11 +9762,11 @@ + if (!output) + hOutProfile = cmsCreate_sRGBProfile(); + else if ((fp = fopen (output, "rb"))) { +- fread (&size, 4, 1, fp); +- fseek (fp, 0, SEEK_SET); ++ tread (&size, 4, 1, fp); ++ tseek (fp, 0, SEEK_SET); + oprof = (unsigned *) malloc (size = ntohl(size)); + merror (oprof, "apply_profile()"); +- fread (oprof, 1, size, fp); ++ tread (oprof, 1, size, fp); + fclose (fp); + if (!(hOutProfile = cmsOpenProfileFromMem (oprof, size))) { + free (oprof); +@@ -10080,17 +10108,17 @@ + + thumb = (char *) malloc (thumb_length); + merror (thumb, "jpeg_thumb()"); +- fread (thumb, 1, thumb_length, ifp); ++ tread (thumb, 1, thumb_length, ifp); + fputc (0xff, ofp); + fputc (0xd8, ofp); + if (strcmp (thumb+6, "Exif")) { + memcpy (exif, "\xff\xe1 Exif\0\0", 10); + exif[1] = htons (8 + sizeof th); +- fwrite (exif, 1, sizeof exif, ofp); ++ twrite (exif, 1, sizeof exif, ofp); + tiff_head (&th, 0); +- fwrite (&th, 1, sizeof th, ofp); ++ twrite (&th, 1, sizeof th, ofp); + } +- fwrite (thumb+2, 1, thumb_length-2, ofp); ++ twrite (thumb+2, 1, thumb_length-2, ofp); + free (thumb); + } + +@@ -10119,9 +10147,9 @@ + merror (ppm, "write_ppm_tiff()"); + if (output_tiff) { + tiff_head (&th, 1); +- fwrite (&th, sizeof th, 1, ofp); ++ twrite (&th, sizeof th, 1, ofp); + if (oprof) +- fwrite (oprof, ntohl(oprof[0]), 1, ofp); ++ twrite (oprof, ntohl(oprof[0]), 1, ofp); + } else if (colors > 3) + fprintf (ofp, + "P7\nWIDTH %d\nHEIGHT %d\nDEPTH %d\nMAXVAL %d\nTUPLTYPE %s\nENDHDR\n", +@@ -10139,7 +10167,7 @@ + else FORCC ppm2[col*colors+c] = curve[image[soff][c]]; + if (output_bps == 16 && !output_tiff && htons(0x55aa) != 0x55aa) + swab (ppm2, ppm2, width*colors*2); +- fwrite (ppm, colors*output_bps/8, width, ofp); ++ twrite (ppm, colors*output_bps/8, width, ofp); + } + free (ppm); + } +@@ -10346,7 +10374,7 @@ + filters = 0; + colors = 3; + } else { +- fseek (ifp, thumb_offset, SEEK_SET); ++ tseek (ifp, thumb_offset, SEEK_SET); + write_fun = write_thumb; + goto thumbnail; + } +@@ -10454,7 +10482,7 @@ + ifname, shot_select); + fseeko (ifp, data_offset, SEEK_SET); + if (raw_image && read_from_stdin) +- fread (raw_image, 2, raw_height*raw_width, stdin); ++ tread (raw_image, 2, raw_height*raw_width, stdin); + else (*load_raw)(); + if (document_mode == 3) { + top_margin = left_margin = fuji_width = 0; +--- dcraw/parse.c 2022-04-12 13:09:25.758417413 +0200 ++++ dcraw/parse.c 2022-04-12 13:09:37.490489361 +0200 +@@ -39,6 +39,36 @@ + char *fname, make[128], model[128], model2[128]; + int is_dng; + ++void tseek(FILE *stream, long offset, int whence) ++{ ++ char line[81]; ++ if( fseek(stream,offset,whence) != 0 ) { ++ snprintf(line,80,"fseek(%p,%ld,%d)",stream,offset,whence); ++ perror(line); ++ exit(1); ++ } ++} ++ ++void tread(void *ptr, size_t size, size_t nmemb, FILE *stream) ++{ ++ char line[81]; ++ if( fread (ptr, size, nmemb, stream) != nmemb ) { ++ snprintf(line,80,"fread(%p,%ld,%ld,%p)",ptr,(long)size,(long)nmemb,stream); ++ perror(line); ++ exit(1); ++ } ++} ++ ++void twrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) ++{ ++ char line[81]; ++ if( fwrite (ptr, size, nmemb, stream) != nmemb ) { ++ snprintf(line,80,"fwrite(%p,%ld,%ld,%p)",ptr,(long)size,(long)nmemb,stream); ++ perror(line); ++ exit(1); ++ } ++} ++ + ushort sget2 (uchar *s) + { + if (order == 0x4949) /* "II" means little-endian */ +@@ -51,7 +81,7 @@ + ushort get2() + { + uchar str[2] = { 0xff,0xff }; +- fread (str, 1, 2, ifp); ++ tread (str, 1, 2, ifp); + return sget2(str); + } + +@@ -67,7 +97,7 @@ + int get4() + { + uchar str[4] = { 0xff,0xff,0xff,0xff }; +- fread (str, 1, 4, ifp); ++ tread (str, 1, 4, ifp); + return sget4(str); + } + +@@ -132,7 +162,7 @@ + int size[] = { 1,1,1,2,4,8,1,1,2,4,8,4,8 }; + + if (count * size[type < 13 ? type:0] > 4) +- fseek (ifp, get4()+base, SEEK_SET); ++ tseek (ifp, get4()+base, SEEK_SET); + save = ftell(ifp); + printf("%*stag=0x%x %d, type=%d, count=%d, offset=%06x, data=", + level*2, "", tag, tag, type, count, save); +@@ -163,7 +193,7 @@ + if (type==2) putchar('\"'); + quit: + putchar('\n'); +- fseek (ifp, save, SEEK_SET); ++ tseek (ifp, save, SEEK_SET); + } + + void parse_nikon_capture_note (int length) +@@ -173,10 +203,10 @@ + puts (" Nikon Capture Note:"); + sorder = order; + order = 0x4949; +- fseek (ifp, 22, SEEK_CUR); ++ tseek (ifp, 22, SEEK_CUR); + for (offset=22; offset+22 < length; offset += 22+size) { + tag = get4(); +- fseek (ifp, 14, SEEK_CUR); ++ tseek (ifp, 14, SEEK_CUR); + size = get4()-4; + printf(" tag=0x%08x, size=%d", tag, size); + for (j=0; j < size; j++) +@@ -247,17 +277,17 @@ + its own byte-order!), or it might just be a table. + */ + sorder = order; +- fread (buf, 1, 10, ifp); ++ tread (buf, 1, 10, ifp); + if (!strcmp (buf,"Nikon")) { /* starts with "Nikon\0\2\0\0\0" ? */ + base = ftell(ifp); + order = get2(); /* might differ from file-wide byteorder */ + val = get2(); /* should be 42 decimal */ + offset = get4(); +- fseek (ifp, offset-8, SEEK_CUR); ++ tseek (ifp, offset-8, SEEK_CUR); + } else if (!strcmp (buf,"OLYMPUS") || + !strcmp (buf,"PENTAX ")) { + base = ftell(ifp)-10; +- fseek (ifp, -2, SEEK_CUR); ++ tseek (ifp, -2, SEEK_CUR); + order = get2(); + if (buf[0] == 'O') get2(); + } else if (!strncmp (buf,"SONY",4) || +@@ -266,17 +296,17 @@ + } else if (!strncmp (buf,"FUJIFILM",8)) { + base = ftell(ifp)-10; + nf: order = 0x4949; +- fseek (ifp, 2, SEEK_CUR); ++ tseek (ifp, 2, SEEK_CUR); + } else if (!strcmp (buf,"OLYMP") || + !strcmp (buf,"LEICA") || + !strcmp (buf,"Ricoh") || + !strcmp (buf,"EPSON")) +- fseek (ifp, -2, SEEK_CUR); ++ tseek (ifp, -2, SEEK_CUR); + else if (!strcmp (buf,"AOC") || + !strcmp (buf,"QVC")) +- fseek (ifp, -4, SEEK_CUR); ++ tseek (ifp, -4, SEEK_CUR); + else { +- fseek (ifp, -10, SEEK_CUR); ++ tseek (ifp, -10, SEEK_CUR); + if (!strncmp(make,"SAMSUNG",7)) + base = ftell(ifp); + if (!strncmp (buf,"ev=",3)) { +@@ -297,27 +327,27 @@ + if ((tag == 0x11 && !strncmp(make,"NIKON",5)) || + (tag >> 8 == 0x20 && !strncmp(buf ,"OLYMP",5)) || type == 13) { + if (count == 1) +- fseek (ifp, get4()+base, SEEK_SET); ++ tseek (ifp, get4()+base, SEEK_SET); + parse_tiff_ifd (base, level+1); + } + if (tag == 0x1d) + while ((val = fgetc(ifp)) && val != EOF) + serial = serial*10 + (isdigit(val) ? val - '0' : val % 10); + if (tag == 0x91) +- fread (buf91, sizeof buf91, 1, ifp); ++ tread (buf91, sizeof buf91, 1, ifp); + if (tag == 0x97) +- fread (buf97, sizeof buf97, 1, ifp); ++ tread (buf97, sizeof buf97, 1, ifp); + if (tag == 0x98) +- fread (buf98, sizeof buf98, 1, ifp); ++ tread (buf98, sizeof buf98, 1, ifp); + if (tag == 0xa7) + key = fgetc(ifp)^fgetc(ifp)^fgetc(ifp)^fgetc(ifp); + if (tag == 0xe01) + parse_nikon_capture_note (count); + if (tag == 0xb028) { +- fseek (ifp, get4(), SEEK_SET); ++ tseek (ifp, get4(), SEEK_SET); + parse_tiff_ifd (base, level+1); + } +- fseek (ifp, save+12, SEEK_SET); ++ tseek (ifp, save+12, SEEK_SET); + } + nikon_decrypt (serial, key, 0x91, 4, sizeof buf91, buf91); + if (!strncmp ((char *)buf97, "0205", 4)) +@@ -342,7 +372,7 @@ + tiff_dump (base, tag, type, count, level); + if (tag == 0x927c) + parse_makernote (base, count, level+1); +- fseek (ifp, save+12, SEEK_SET); ++ tseek (ifp, save+12, SEEK_SET); + } + } + +@@ -354,7 +384,7 @@ + { + int i=order; + order = 0x4d4d; +- fseek (ifp, base, SEEK_SET); ++ tseek (ifp, base, SEEK_SET); + if (get4()==0xffd8ffe1 && get2() && get4()==0x45786966 && !get2()) { + printf ("%*sEmbedded JPEG:\n", level*2, ""); + parse_tiff (ftell(ifp), level+1); +@@ -410,15 +440,15 @@ + save2 = ftell(ifp); + for (i=0; i < count; i++) { + printf ("SubIFD #%d:\n", i+1); +- fseek (ifp, save2 + i*4, SEEK_SET); +- fseek (ifp, get4()+base, SEEK_SET); ++ tseek (ifp, save2 + i*4, SEEK_SET); ++ tseek (ifp, get4()+base, SEEK_SET); + parse_tiff_ifd (base, level+1); + } + break; + case 273: /* StripOffset */ + case 513: /* JpegIFOffset */ + case 61447: +- fseek (ifp, get4()+base, SEEK_SET); ++ tseek (ifp, get4()+base, SEEK_SET); + case 46: + parse_thumb (ftell(ifp), level); + break; +@@ -431,26 +461,26 @@ + case 33424: + case 65024: + puts("Kodak private data:"); +- fseek (ifp, get4()+base, SEEK_SET); ++ tseek (ifp, get4()+base, SEEK_SET); + parse_tiff_ifd (base, level+1); + break; + case 34310: + parse_mos(0); + break; + case 34665: +- fseek (ifp, get4()+base, SEEK_SET); ++ tseek (ifp, get4()+base, SEEK_SET); + parse_exif (base, level+1); + break; + case 34853: + puts("GPS data:"); +- fseek (ifp, get4()+base, SEEK_SET); ++ tseek (ifp, get4()+base, SEEK_SET); + parse_tiff_ifd (base, level+1); + break; + case 50459: + i = order; + save2 = ftell(ifp); + order = get2(); +- fseek (ifp, save2 + (get2(),get4()), SEEK_SET); ++ tseek (ifp, save2 + (get2(),get4()), SEEK_SET); + parse_tiff_ifd (save2, level+1); + order = i; + break; +@@ -460,19 +490,19 @@ + case 50740: + if (is_dng) break; + parse_minolta (i = get4()+base); +- fseek (ifp, i, SEEK_SET); ++ tseek (ifp, i, SEEK_SET); + parse_tiff_ifd (base, level+1); + } +- fseek (ifp, save+12, SEEK_SET); ++ tseek (ifp, save+12, SEEK_SET); + } + if (sony_length && (buf = malloc(sony_length))) { +- fseek (ifp, sony_offset, SEEK_SET); +- fread (buf, sony_length, 1, ifp); ++ tseek (ifp, sony_offset, SEEK_SET); ++ tread (buf, sony_length, 1, ifp); + sony_decrypt (buf, sony_length/4, 1, sony_key); + sfp = ifp; + if ((ifp = tmpfile())) { +- fwrite (buf, sony_length, 1, ifp); +- fseek (ifp, 0, SEEK_SET); ++ twrite (buf, sony_length, 1, ifp); ++ tseek (ifp, 0, SEEK_SET); + puts ("Sony SR2 encrypted IFD:"); + parse_tiff_ifd (-sony_offset, level); + fclose (ifp); +@@ -490,12 +520,12 @@ + { + int doff, ifd=0, sorder=order; + +- fseek (ifp, base, SEEK_SET); ++ tseek (ifp, base, SEEK_SET); + order = get2(); + if (order != 0x4949 && order != 0x4d4d) return; + get2(); + while ((doff = get4())) { +- fseek (ifp, doff+base, SEEK_SET); ++ tseek (ifp, doff+base, SEEK_SET); + printf ("%*sIFD #%d:\n", level*2, "", ifd++); + if (parse_tiff_ifd (base, level)) break; + } +@@ -507,12 +537,12 @@ + unsigned offset, save, len, j; + char tag[4]; + +- fseek (ifp, base, SEEK_SET); ++ tseek (ifp, base, SEEK_SET); + if (fgetc(ifp) || fgetc(ifp)-'M' || fgetc(ifp)-'R') return; + order = fgetc(ifp) * 0x101; + offset = base + get4() + 8; + while ((save=ftell(ifp)) < offset) { +- fread (tag, 1, 4, ifp); ++ tread (tag, 1, 4, ifp); + len = get4(); + printf ("Minolta tag %3.3s offset %06x length %06x", tag+1, save, len); + if (!strncmp (tag+1,"TTW",3)) { +@@ -523,7 +553,7 @@ + printf ("%c%04x",(j & 15) || len < 9 ? ' ':'\n', get2()); + putchar ('\n'); + } +- fseek (ifp, save+len+8, SEEK_SET); ++ tseek (ifp, save+len+8, SEEK_SET); + } + } + +@@ -536,9 +566,9 @@ + char c, name[256]; + ushort key[2]; + +- fseek (ifp, offset+length-4, SEEK_SET); ++ tseek (ifp, offset+length-4, SEEK_SET); + tboff = get4() + offset; +- fseek (ifp, tboff, SEEK_SET); ++ tseek (ifp, tboff, SEEK_SET); + nrecs = get2(); + if (nrecs > 100) return; + printf ("%*s%d records:\n", level*2, "", nrecs); +@@ -555,7 +585,7 @@ + aoff = offset + roff; + printf (", length=%d, reloff=%d, absoff=%d", + len, roff, aoff); +- fseek (ifp, aoff, SEEK_SET); ++ tseek (ifp, aoff, SEEK_SET); + } + if ((type & 0xe700) == 0) + printf (", data="); +@@ -567,7 +597,7 @@ + case 0x30: + putchar('\n'); + parse_ciff (aoff, len, level+1); +- fseek (ifp, save+10, SEEK_SET); ++ tseek (ifp, save+10, SEEK_SET); + continue; + case 0x00: /* byte values */ + for (j = 0; j < dlen; j++) +@@ -583,7 +613,7 @@ + break; + case 0x10: /* word values */ + key[0] = get2(); +- fseek (ifp, -2, SEEK_CUR); ++ tseek (ifp, -2, SEEK_CUR); + if (type == 0x1032 && key[0] == 1040) + key[1] = 17907; + else key[0] = key[1] = 0; +@@ -596,10 +626,10 @@ + printf ("%c%08x",(j & 31) || dlen < 16 ? ' ':'\n', get4()); + } + putchar('\n'); +- fseek (ifp, save+10, SEEK_SET); ++ tseek (ifp, save+10, SEEK_SET); + if (type == 0x080a) { /* Get the camera name */ +- fseek (ifp, aoff, SEEK_SET); +- fread (name, 256, 1, ifp); ++ tseek (ifp, aoff, SEEK_SET); ++ tread (name, 256, 1, ifp); + strcpy (make, name); + strcpy (model, name + strlen(make)+1); + } +@@ -610,7 +640,7 @@ + { + int len, save, hlen; + +- fseek (ifp, offset, SEEK_SET); ++ tseek (ifp, offset, SEEK_SET); + if (fgetc(ifp) != 0xff || fgetc(ifp) != 0xd8) return 0; + + while (fgetc(ifp) == 0xff && fgetc(ifp) >> 4 != 0xd) { +@@ -622,7 +652,7 @@ + if (get4() == 0x48454150) /* "HEAP" */ + parse_ciff (save+hlen, len-hlen, 0); + parse_tiff (save+6,0); +- fseek (ifp, save+len, SEEK_SET); ++ tseek (ifp, save+len, SEEK_SET); + } + return 1; + } +@@ -633,27 +663,27 @@ + char tag[4], type[4], buf[64]; + + order = 0x4949; +- fread (tag, 4, 1, ifp); ++ tread (tag, 4, 1, ifp); + size = get4(); + if (isdigit(tag[0])) { +- fseek (ifp, size, SEEK_CUR); ++ tseek (ifp, size, SEEK_CUR); + return; + } + printf ("%*.4s size %d", level*4+4, tag, size); + if (!memcmp(tag,"RIFF",4) || !memcmp(tag,"LIST",4)) { + end = ftell(ifp) + size; +- fread (type, 4, 1, ifp); ++ tread (type, 4, 1, ifp); + printf (" type %.4s:\n", type); + while (ftell(ifp)+7 < end) + parse_riff (level+1); + } else { + save = ftell(ifp); +- fread (buf, 1, 40, ifp); ++ tread (buf, 1, 40, ifp); + printf (": "); + for (i=0; i < 40 && isprint(buf[i]); i++) + putchar (buf[i]); + putchar ('\n'); +- fseek (ifp, save+size, SEEK_SET); ++ tseek (ifp, save+size, SEEK_SET); + } + } + +@@ -668,7 +698,7 @@ + if (get4() != 0x504b5453) break; + get4(); + printf ("%*sPKTS ", level, ""); +- fread (data, 1, 40, ifp); ++ tread (data, 1, 40, ifp); + skip = get4(); + printf ("%s %d bytes: ", data, skip); + if (!strcmp(data,"pattern_ratation_angle")) { +@@ -681,23 +711,23 @@ + putchar('\n'); + continue; + } +- fread (data, 1, sizeof data, ifp); +- fseek (ifp, -sizeof data, SEEK_CUR); ++ tread (data, 1, sizeof data, ifp); ++ tseek (ifp, -sizeof data, SEEK_CUR); + data[sizeof data - 1] = 0; + while ((cp=strchr(data,'\n'))) + *cp = ' '; + printf ("%s\n",data); + parse_mos(level+2); +- fseek (ifp, skip, SEEK_CUR); ++ tseek (ifp, skip, SEEK_CUR); + } +- fseek (ifp, save, SEEK_SET); ++ tseek (ifp, save, SEEK_SET); + } + + void parse_rollei() + { + char line[128], *val; + +- fseek (ifp, 0, SEEK_SET); ++ tseek (ifp, 0, SEEK_SET); + do { + fgets (line, 128, ifp); + fputs (line, stdout); +@@ -715,7 +745,7 @@ + ushort c; + char *cp; + +- fseek (ifp, offset, SEEK_SET); ++ tseek (ifp, offset, SEEK_SET); + for (cp=buf; (c = get2()) && cp+3 < buf+len; ) { + if (c < 0x80) + *cp++ = c; +@@ -739,8 +769,8 @@ + ushort huff[258], vpred[2][2], hpred[2]; + + order = 0x4949; /* Little-endian */ +- fseek (ifp, -4, SEEK_END); +- fseek (ifp, get4(), SEEK_SET); ++ tseek (ifp, -4, SEEK_END); ++ tseek (ifp, get4(), SEEK_SET); + if (get4() != 0x64434553) { /* SECd */ + printf ("Bad Section identifier at %6x\n", (int)ftell(ifp)-4); + return; +@@ -752,7 +782,7 @@ + len = get4(); + tag = get4(); + save = ftell(ifp); +- fseek (ifp, off, SEEK_SET); ++ tseek (ifp, off, SEEK_SET); + printf ("%c%c%c%c at offset %06x, length %06x, ", + tag, tag >> 8, tag >> 16, tag >> 24, off, len); + if (get4() != (0x20434553 | (tag << 24))) { +@@ -780,7 +810,7 @@ + high = get4(); + if (type == 2) { + camf = malloc (len -= 28); +- fread (camf, 1, len, ifp); ++ tread (camf, 1, len, ifp); + for (i=0; i < len; i++) { + high = (high * 1597 + 51749) % 244944; + val = high * (INT64) 301593171 >> 24; +@@ -796,7 +826,7 @@ + for (j=0; j < 256 >> tag; ) + huff[val+ ++j] = tag << 8 | i; + } +- fseek (ifp, 6, SEEK_CUR); ++ tseek (ifp, 6, SEEK_CUR); + getbits(-1); + vpred[0][0] = vpred[0][1] = + vpred[1][0] = vpred[1][1] = 512; +@@ -901,7 +931,7 @@ + strcpy (model, value); + } + } +- fseek (ifp, save, SEEK_SET); ++ tseek (ifp, save, SEEK_SET); + } + } + +@@ -909,10 +939,10 @@ + { + int entries, tag, len; + +- fseek (ifp, offset, SEEK_SET); ++ tseek (ifp, offset, SEEK_SET); + if (!(len = get4())) return; + printf ("Fuji Image %c:\n", offset < 100 ? 'S':'R'); +- fseek (ifp, len, SEEK_SET); ++ tseek (ifp, len, SEEK_SET); + entries = get4(); + if (entries > 255) return; + while (entries--) { +@@ -931,10 +961,10 @@ + unsigned meta=0, wide=0, high=0, i, j; + char str[256]; + +- fseek (ifp, base, SEEK_SET); ++ tseek (ifp, base, SEEK_SET); + order = get4() & 0xffff; + if (get4() >> 8 != 0x526177) return; +- fseek (ifp, base+get4(), SEEK_SET); ++ tseek (ifp, base+get4(), SEEK_SET); + entries = get4(); + get4(); + while (entries--) { +@@ -950,9 +980,9 @@ + putchar ('\n'); + if (tag == 0x110) meta = base+data; + if (len > 4) +- fseek (ifp, base+data, SEEK_SET); ++ tseek (ifp, base+data, SEEK_SET); + if (type == 1 && len < 256) { +- fread (str, 256, 1, ifp); ++ tread (str, 256, 1, ifp); + puts (str); + } + if (tag != 0x21c && type == 4 && len > 4) { +@@ -960,15 +990,15 @@ + printf ("%f ", int_to_float(get4())); + puts (""); + } +- fseek (ifp, save, SEEK_SET); ++ tseek (ifp, save, SEEK_SET); + } + strcpy (make, "Phase One"); + strcpy (model, "unknown"); + if (!meta) return; +- fseek (ifp, meta, SEEK_SET); ++ tseek (ifp, meta, SEEK_SET); + order = get2(); +- fseek (ifp, 6, SEEK_CUR); +- fseek (ifp, meta+get4(), SEEK_SET); ++ tseek (ifp, 6, SEEK_CUR); ++ tseek (ifp, meta+get4(), SEEK_SET); + entries = get4(); + get4(); + while (entries--) { +@@ -979,7 +1009,7 @@ + printf ("Phase One meta tag=0x%x, len=%2d, offset = 0x%x, data = ", + tag, len, data); + if (!((0x000801f4 >> (tag-0x400)) & 1)) putchar ('\n'); +- fseek (ifp, meta+data, SEEK_SET); ++ tseek (ifp, meta+data, SEEK_SET); + switch (tag) { + case 0x400: + for (i=0; i < len; i+=2) +@@ -996,7 +1026,7 @@ + printf ("%f\n", int_to_float (data)); + break; + case 0x404: case 0x405: case 0x406: case 0x407: +- fread (str, 256, 1, ifp); ++ tread (str, 256, 1, ifp); + puts (str); + break; + case 0x408: case 0x413: +@@ -1030,7 +1060,7 @@ + printf ("%02X%c", fgetc(ifp), + (i & 15) == 15 || i == len-1 ? '\n':' '); + } +- fseek (ifp, save, SEEK_SET); ++ tseek (ifp, save, SEEK_SET); + } + } + +@@ -1047,7 +1077,7 @@ + switch (tag >> 12) { + case 1: + if (len-4 < sizeof buf) { +- fread (buf, 1,len-4, ifp); ++ tread (buf, 1,len-4, ifp); + printf ("\"%.*s\"", len-4, buf); + } + break; +@@ -1081,21 +1111,21 @@ + level*2, "", (INT64) base, len, tag, ctag); + switch (tag) { + case 0x52454431: /* RED1 */ +- fseek (ifp, 59, SEEK_CUR); +- fread (buf, 1, 256, ifp); ++ tseek (ifp, 59, SEEK_CUR); ++ tread (buf, 1, 256, ifp); + printf (" Original name: %s\n", buf); + break; + case 0x52454432: /* RED2 */ +- fseek (ifp, 18, SEEK_CUR); ++ tseek (ifp, 18, SEEK_CUR); + case 0x52444901: /* RDI */ +- fseek (ifp, 88, SEEK_CUR); ++ tseek (ifp, 88, SEEK_CUR); + parse_uuid (level+1); + base = -(-(base+len) & -4096); + continue; + #if 0 + case 0x52454441: /* REDA */ +- fread (buf, 1, sizeof buf, ifp); +- fwrite (buf+24, 1, len-32, stdout); ++ tread (buf, 1, sizeof buf, ifp); ++ twrite (buf+24, 1, len-32, stdout); + break; + #endif + case 0x52454456: /* REDV */ +@@ -1103,7 +1133,7 @@ + parse_redcine (base+20, level+1); + break; + case 0x75756964: /* uuid */ +- fseek (ifp, 16, SEEK_CUR); ++ tseek (ifp, 16, SEEK_CUR); + parse_uuid (level+1); + } + base += len; +@@ -1119,31 +1149,31 @@ + order = 0x4d4d; + size = get4(); + if (size < 8 || save+size > end) { +- fseek (ifp, -4, SEEK_CUR); +- fread (buf, 1, 400, ifp); ++ tseek (ifp, -4, SEEK_CUR); ++ tread (buf, 1, 400, ifp); + printf (" ="); + for (i=0; i < 400 && i < end-save; i++) + printf ("%s%02x",i & 3 ? "":" ",buf[i] & 255); +- fseek (ifp, end, SEEK_SET); ++ tseek (ifp, end, SEEK_SET); + return; + } +- fread (tag, 4, 1, ifp); ++ tread (tag, 4, 1, ifp); + printf ("\n%*.4s size %d", level*2+4, tag, size); + memset (uuid, 0, 16); + if (!memcmp(tag,"uuid",4)) { + for (i=0; i < 4; i++) uuid[i] = get4(); +- fseek (ifp, -16, SEEK_CUR); ++ tseek (ifp, -16, SEEK_CUR); + printf(" = "); + for (i=0; i < 16; i++) + printf ("%s%02x",(0x550 >> i) & 1 ? "-":"", fgetc(ifp)); + } + if (!memcmp(tag,"stsd",4)) +- fseek (ifp, 8, SEEK_CUR); ++ tseek (ifp, 8, SEEK_CUR); + if (!memcmp(tag,"CMT",3)) { + putchar ('\n'); + parse_tiff (ftell(ifp),level+1); + } else parse_crx (level+1, save+size); +- fseek (ifp, save+size, SEEK_SET); ++ tseek (ifp, save+size, SEEK_SET); + } + if (!level) { + printf ("Finished parsing at offset 0x%lx, ",ftell(ifp)); +@@ -1160,7 +1190,7 @@ + while (ftell(ifp)+7 < end) { + save = ftell(ifp); + if ((size = get4()) < 8) return; +- fread (tag, 4, 1, ifp); ++ tread (tag, 4, 1, ifp); + printf ("%*.4s size %d", level*4+4, tag, size); + for (lcase=1, i=0; i < 4; i++) + if (!islower(tag[i])) lcase = 0; +@@ -1173,13 +1203,13 @@ + puts (" *** parsing JPEG thumbnail ..."); + parse_jpeg (ftell(ifp)); + } else { +- fread (buf, 1, 40, ifp); ++ tread (buf, 1, 40, ifp); + printf (" : "); + for (i=0; i < 40 && i < size-8; i++) + putchar (isprint(buf[i]) ? buf[i] : '.'); + putchar ('\n'); + } +- fseek (ifp, save+size, SEEK_SET); ++ tseek (ifp, save+size, SEEK_SET); + } + } + +@@ -1205,9 +1235,9 @@ + make[0] = model[0] = model2[0] = is_dng = 0; + order = get2(); + hlen = get4(); +- fseek (ifp, 0, SEEK_SET); +- fread (head, 1, 32, ifp); +- fseek (ifp, 0, SEEK_END); ++ tseek (ifp, 0, SEEK_SET); ++ tread (head, 1, 32, ifp); ++ tseek (ifp, 0, SEEK_END); + fsize = ftell(ifp); + if ((cp = memmem (head, 32, "MMMM", 4)) || + (cp = memmem (head, 32, "IIII", 4))) { +@@ -1216,7 +1246,7 @@ + } else if (order == 0x4949 || order == 0x4d4d) { + if (!memcmp(head+6,"HEAPCCDR",8)) { + parse_ciff (hlen, fsize - hlen, 0); +- fseek (ifp, hlen, SEEK_SET); ++ tseek (ifp, hlen, SEEK_SET); + } else + parse_tiff (0,0); + } else if (!memcmp (head,"NDF0",4)) { +@@ -1224,26 +1254,26 @@ + } else if (!memcmp (head,"\0MRM",4)) { + parse_minolta (0); + } else if (!memcmp (head,"FUJIFILM",8)) { +- fseek (ifp, 84, SEEK_SET); ++ tseek (ifp, 84, SEEK_SET); + toff = get4(); + tlen = get4(); + parse_fuji (92); +- fseek (ifp, 100, SEEK_SET); ++ tseek (ifp, 100, SEEK_SET); + parse_tiff (get4(),0); + if (toff > 120) { + parse_fuji (120); +- fseek (ifp, 128, SEEK_SET); ++ tseek (ifp, 128, SEEK_SET); + parse_tiff (get4(),0); + } + parse_thumb (toff,0); + } else if (!memcmp (head,"RIFF",4)) { +- fseek (ifp, 0, SEEK_SET); ++ tseek (ifp, 0, SEEK_SET); + parse_riff(0); + } else if (!memcmp (head+4,"ftypcrx ",8)) { +- fseek (ifp, 0, SEEK_SET); ++ tseek (ifp, 0, SEEK_SET); + parse_crx (0, fsize); + } else if (!memcmp (head+4,"ftypqt ",9)) { +- fseek (ifp, 0, SEEK_SET); ++ tseek (ifp, 0, SEEK_SET); + parse_qt (0, fsize); + } else if (!memcmp (head+4,"RED",3)) + parse_redcine(0,0); diff --git a/parse.c b/parse.c new file mode 100644 index 0000000..005c3b3 --- /dev/null +++ b/parse.c @@ -0,0 +1,1282 @@ +/* + Raw Photo Parser + Copyright 2004-2015 by Dave Coffin, dcoffin a cybercom o net + + This program displays raw metadata for all raw photo formats. + It is free for all uses. + + $Revision: 1.78 $ + $Date: 2018/06/01 21:26:34 $ + */ + +#include +#include +#include +#include + +#ifdef WIN32 +#include +typedef __int64 INT64; +#else +#include +typedef long long INT64; +#endif + +/* + TIFF and CIFF data blocks can be quite large. + Display only the first DLEN bytes. + */ +#ifndef DLEN +#define DLEN 768 +#endif + +#define ushort UshORt +typedef unsigned char uchar; +typedef unsigned short ushort; + +FILE *ifp; +short order; +char *fname, make[128], model[128], model2[128]; +int is_dng; + +ushort sget2 (uchar *s) +{ + if (order == 0x4949) /* "II" means little-endian */ + return s[0] | s[1] << 8; + else /* "MM" means big-endian */ + return s[0] << 8 | s[1]; +} +#define sget2(s) sget2((uchar *)s) + +ushort get2() +{ + uchar str[2] = { 0xff,0xff }; + fread (str, 1, 2, ifp); + return sget2(str); +} + +int sget4 (uchar *s) +{ + if (order == 0x4949) + return s[0] | s[1] << 8 | s[2] << 16 | s[3] << 24; + else + return s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]; +} +#define sget4(s) sget4((uchar *)s) + +int get4() +{ + uchar str[4] = { 0xff,0xff,0xff,0xff }; + fread (str, 1, 4, ifp); + return sget4(str); +} + +float int_to_float (int i) +{ + union { int i; float f; } u; + u.i = i; + return u.f; +} + +double get_double() +{ + union { char c[8]; double d; } u; + int i, rev; + + rev = 7 * ((order == 0x4949) == (ntohs(0x1234) == 0x1234)); + for (i=0; i < 8; i++) + u.c[i ^ rev] = fgetc(ifp); + return u.d; +} + +unsigned getbithuff (int nbits, const ushort *huff) +{ + static unsigned bitbuf=0; + static int vbits=0, reset=0; + unsigned c; + + if (nbits == -1) + return bitbuf = vbits = reset = 0; + if (nbits == 0 || vbits < 0) return 0; + while (vbits < nbits && (c = fgetc(ifp)) != EOF) { + bitbuf = (bitbuf << 8) + (uchar) c; + vbits += 8; + } + c = bitbuf << (32-vbits) >> (32-nbits); + if (huff) { + vbits -= huff[c] >> 8; + c = (uchar) huff[c]; + } else + vbits -= nbits; + return c; +} + +#define getbits(n) getbithuff(n,0) +#define gethuff(h) getbithuff(*h,h+1) + +int ljpeg_diff (ushort *huff) +{ + int len, diff; + + len = gethuff(huff); + diff = getbits(len); + if ((diff & (1 << (len-1))) == 0) + diff -= (1 << len) - 1; + return diff; +} + +void tiff_dump(int base, int tag, int type, int count, int level) +{ + int save, j, num, den; + uchar c; + int size[] = { 1,1,1,2,4,8,1,1,2,4,8,4,8 }; + + if (count * size[type < 13 ? type:0] > 4) + fseek (ifp, get4()+base, SEEK_SET); + save = ftell(ifp); + printf("%*stag=0x%x %d, type=%d, count=%d, offset=%06x, data=", + level*2, "", tag, tag, type, count, save); + if (tag == 34310) goto quit; + if (type==2) putchar('\"'); + for (j = 0; j < count && j < DLEN; j++) + switch (type) { + case 1: case 6: case 7: /* byte values */ + printf ("%c%02x",(j & 31) || count < 17 ? ' ':'\n', fgetc(ifp) & 0xff); + break; + case 2: /* null-terminated ASCII strings */ + c = fgetc(ifp); + putchar(isprint(c) ? c:'.'); + break; + case 3: case 8: /* word values */ + printf ("%c%04x",(j & 15) || count < 9 ? ' ':'\n', get2()); + break; + case 4: case 9: /* dword values */ + printf ("%c%08x",(j & 7) || count < 5 ? ' ':'\n', get4()); + break; + case 5: case 10: /* rationals */ + num = get4(); + den = get4(); + printf (" %d/%d", num, den); +// printf (" %lf", (double) num/den); + break; + } + if (type==2) putchar('\"'); +quit: + putchar('\n'); + fseek (ifp, save, SEEK_SET); +} + +void parse_nikon_capture_note (int length) +{ + unsigned sorder, offset, tag, j, size; + + puts (" Nikon Capture Note:"); + sorder = order; + order = 0x4949; + fseek (ifp, 22, SEEK_CUR); + for (offset=22; offset+22 < length; offset += 22+size) { + tag = get4(); + fseek (ifp, 14, SEEK_CUR); + size = get4()-4; + printf(" tag=0x%08x, size=%d", tag, size); + for (j=0; j < size; j++) + printf ("%s%02x", j & 31 ? " ":"\n\t", fgetc(ifp)); + puts(""); + } + order = sorder; +} + +void nikon_decrypt (uchar ci, uchar cj, int tag, int i, int size, uchar *buf) +{ + static const uchar xlat[2][256] = { + { 0xc1,0xbf,0x6d,0x0d,0x59,0xc5,0x13,0x9d,0x83,0x61,0x6b,0x4f,0xc7,0x7f,0x3d,0x3d, + 0x53,0x59,0xe3,0xc7,0xe9,0x2f,0x95,0xa7,0x95,0x1f,0xdf,0x7f,0x2b,0x29,0xc7,0x0d, + 0xdf,0x07,0xef,0x71,0x89,0x3d,0x13,0x3d,0x3b,0x13,0xfb,0x0d,0x89,0xc1,0x65,0x1f, + 0xb3,0x0d,0x6b,0x29,0xe3,0xfb,0xef,0xa3,0x6b,0x47,0x7f,0x95,0x35,0xa7,0x47,0x4f, + 0xc7,0xf1,0x59,0x95,0x35,0x11,0x29,0x61,0xf1,0x3d,0xb3,0x2b,0x0d,0x43,0x89,0xc1, + 0x9d,0x9d,0x89,0x65,0xf1,0xe9,0xdf,0xbf,0x3d,0x7f,0x53,0x97,0xe5,0xe9,0x95,0x17, + 0x1d,0x3d,0x8b,0xfb,0xc7,0xe3,0x67,0xa7,0x07,0xf1,0x71,0xa7,0x53,0xb5,0x29,0x89, + 0xe5,0x2b,0xa7,0x17,0x29,0xe9,0x4f,0xc5,0x65,0x6d,0x6b,0xef,0x0d,0x89,0x49,0x2f, + 0xb3,0x43,0x53,0x65,0x1d,0x49,0xa3,0x13,0x89,0x59,0xef,0x6b,0xef,0x65,0x1d,0x0b, + 0x59,0x13,0xe3,0x4f,0x9d,0xb3,0x29,0x43,0x2b,0x07,0x1d,0x95,0x59,0x59,0x47,0xfb, + 0xe5,0xe9,0x61,0x47,0x2f,0x35,0x7f,0x17,0x7f,0xef,0x7f,0x95,0x95,0x71,0xd3,0xa3, + 0x0b,0x71,0xa3,0xad,0x0b,0x3b,0xb5,0xfb,0xa3,0xbf,0x4f,0x83,0x1d,0xad,0xe9,0x2f, + 0x71,0x65,0xa3,0xe5,0x07,0x35,0x3d,0x0d,0xb5,0xe9,0xe5,0x47,0x3b,0x9d,0xef,0x35, + 0xa3,0xbf,0xb3,0xdf,0x53,0xd3,0x97,0x53,0x49,0x71,0x07,0x35,0x61,0x71,0x2f,0x43, + 0x2f,0x11,0xdf,0x17,0x97,0xfb,0x95,0x3b,0x7f,0x6b,0xd3,0x25,0xbf,0xad,0xc7,0xc5, + 0xc5,0xb5,0x8b,0xef,0x2f,0xd3,0x07,0x6b,0x25,0x49,0x95,0x25,0x49,0x6d,0x71,0xc7 }, + { 0xa7,0xbc,0xc9,0xad,0x91,0xdf,0x85,0xe5,0xd4,0x78,0xd5,0x17,0x46,0x7c,0x29,0x4c, + 0x4d,0x03,0xe9,0x25,0x68,0x11,0x86,0xb3,0xbd,0xf7,0x6f,0x61,0x22,0xa2,0x26,0x34, + 0x2a,0xbe,0x1e,0x46,0x14,0x68,0x9d,0x44,0x18,0xc2,0x40,0xf4,0x7e,0x5f,0x1b,0xad, + 0x0b,0x94,0xb6,0x67,0xb4,0x0b,0xe1,0xea,0x95,0x9c,0x66,0xdc,0xe7,0x5d,0x6c,0x05, + 0xda,0xd5,0xdf,0x7a,0xef,0xf6,0xdb,0x1f,0x82,0x4c,0xc0,0x68,0x47,0xa1,0xbd,0xee, + 0x39,0x50,0x56,0x4a,0xdd,0xdf,0xa5,0xf8,0xc6,0xda,0xca,0x90,0xca,0x01,0x42,0x9d, + 0x8b,0x0c,0x73,0x43,0x75,0x05,0x94,0xde,0x24,0xb3,0x80,0x34,0xe5,0x2c,0xdc,0x9b, + 0x3f,0xca,0x33,0x45,0xd0,0xdb,0x5f,0xf5,0x52,0xc3,0x21,0xda,0xe2,0x22,0x72,0x6b, + 0x3e,0xd0,0x5b,0xa8,0x87,0x8c,0x06,0x5d,0x0f,0xdd,0x09,0x19,0x93,0xd0,0xb9,0xfc, + 0x8b,0x0f,0x84,0x60,0x33,0x1c,0x9b,0x45,0xf1,0xf0,0xa3,0x94,0x3a,0x12,0x77,0x33, + 0x4d,0x44,0x78,0x28,0x3c,0x9e,0xfd,0x65,0x57,0x16,0x94,0x6b,0xfb,0x59,0xd0,0xc8, + 0x22,0x36,0xdb,0xd2,0x63,0x98,0x43,0xa1,0x04,0x87,0x86,0xf7,0xa6,0x26,0xbb,0xd6, + 0x59,0x4d,0xbf,0x6a,0x2e,0xaa,0x2b,0xef,0xe6,0x78,0xb6,0x4e,0xe0,0x2f,0xdc,0x7c, + 0xbe,0x57,0x19,0x32,0x7e,0x2a,0xd0,0xb8,0xba,0x29,0x00,0x3c,0x52,0x7d,0xa8,0x49, + 0x3b,0x2d,0xeb,0x25,0x49,0xfa,0xa3,0xaa,0x39,0xa7,0xc5,0xa7,0x50,0x11,0x36,0xfb, + 0xc6,0x67,0x4a,0xf5,0xa5,0x12,0x65,0x7e,0xb0,0xdf,0xaf,0x4e,0xb3,0x61,0x7f,0x2f } }; + uchar ck=0x60; + + if (strncmp ((char *)buf, "02", 2)) return; + ci = xlat[0][ci]; + cj = xlat[1][cj]; + printf("Decrypted tag 0x%x:\n%*s", tag, (i & 31)*3, ""); + for (; i < size; i++) + printf("%02x%c", buf[i] ^ (cj += ci * ck++), (i & 31) == 31 ? '\n':' '); + if (size & 31) puts(""); +} + +int parse_tiff_ifd (int base, int level); + +void parse_makernote (int base, int len, int level) +{ + int offset=0, entries, tag, type, count, val, save; + unsigned serial=0, key=0; + uchar buf91[630]="", buf97[608]="", buf98[31]=""; + short sorder; + char buf[10]; + +/* + The MakerNote might have its own TIFF header (possibly with + its own byte-order!), or it might just be a table. + */ + sorder = order; + fread (buf, 1, 10, ifp); + if (!strcmp (buf,"Nikon")) { /* starts with "Nikon\0\2\0\0\0" ? */ + base = ftell(ifp); + order = get2(); /* might differ from file-wide byteorder */ + val = get2(); /* should be 42 decimal */ + offset = get4(); + fseek (ifp, offset-8, SEEK_CUR); + } else if (!strcmp (buf,"OLYMPUS") || + !strcmp (buf,"PENTAX ")) { + base = ftell(ifp)-10; + fseek (ifp, -2, SEEK_CUR); + order = get2(); + if (buf[0] == 'O') get2(); + } else if (!strncmp (buf,"SONY",4) || + !strcmp (buf,"Panasonic")) { + goto nf; + } else if (!strncmp (buf,"FUJIFILM",8)) { + base = ftell(ifp)-10; +nf: order = 0x4949; + fseek (ifp, 2, SEEK_CUR); + } else if (!strcmp (buf,"OLYMP") || + !strcmp (buf,"LEICA") || + !strcmp (buf,"Ricoh") || + !strcmp (buf,"EPSON")) + fseek (ifp, -2, SEEK_CUR); + else if (!strcmp (buf,"AOC") || + !strcmp (buf,"QVC")) + fseek (ifp, -4, SEEK_CUR); + else { + fseek (ifp, -10, SEEK_CUR); + if (!strncmp(make,"SAMSUNG",7)) + base = ftell(ifp); + if (!strncmp (buf,"ev=",3)) { + while (len--) putchar (fgetc(ifp)); + putchar ('\n'); + } + } + + entries = get2(); + if (entries > 127) return; + printf ("%*sMakerNote:\n", level*2-2, ""); + while (entries--) { + save = ftell(ifp); + tag = get2(); + type = get2(); + count= get4(); + tiff_dump (base, tag, type, count, level); + if ((tag == 0x11 && !strncmp(make,"NIKON",5)) || + (tag >> 8 == 0x20 && !strncmp(buf ,"OLYMP",5)) || type == 13) { + if (count == 1) + fseek (ifp, get4()+base, SEEK_SET); + parse_tiff_ifd (base, level+1); + } + if (tag == 0x1d) + while ((val = fgetc(ifp)) && val != EOF) + serial = serial*10 + (isdigit(val) ? val - '0' : val % 10); + if (tag == 0x91) + fread (buf91, sizeof buf91, 1, ifp); + if (tag == 0x97) + fread (buf97, sizeof buf97, 1, ifp); + if (tag == 0x98) + fread (buf98, sizeof buf98, 1, ifp); + if (tag == 0xa7) + key = fgetc(ifp)^fgetc(ifp)^fgetc(ifp)^fgetc(ifp); + if (tag == 0xe01) + parse_nikon_capture_note (count); + if (tag == 0xb028) { + fseek (ifp, get4(), SEEK_SET); + parse_tiff_ifd (base, level+1); + } + fseek (ifp, save+12, SEEK_SET); + } + nikon_decrypt (serial, key, 0x91, 4, sizeof buf91, buf91); + if (!strncmp ((char *)buf97, "0205", 4)) + nikon_decrypt (serial, key, 0x97, 4, 284, buf97); + else + nikon_decrypt (serial, key, 0x97, 284, sizeof buf97, buf97); + nikon_decrypt (serial, key, 0x98, 4, sizeof buf98, buf98); + order = sorder; +} + +void parse_exif (int base, int level) +{ + int entries, tag, type, count, save; + + printf ("%*sEXIF table:\n", level*2-2, ""); + entries = get2(); + while (entries--) { + save = ftell(ifp); + tag = get2(); + type = get2(); + count= get4(); + tiff_dump (base, tag, type, count, level); + if (tag == 0x927c) + parse_makernote (base, count, level+1); + fseek (ifp, save+12, SEEK_SET); + } +} + +void parse_mos(int level); +void parse_minolta (int base); +void parse_tiff (int base, int level); + +void parse_thumb (int base, int level) +{ + int i=order; + order = 0x4d4d; + fseek (ifp, base, SEEK_SET); + if (get4()==0xffd8ffe1 && get2() && get4()==0x45786966 && !get2()) { + printf ("%*sEmbedded JPEG:\n", level*2, ""); + parse_tiff (ftell(ifp), level+1); + } + order = i; +} + +void sony_decrypt (unsigned *data, int len, int start, int key) +{ + static unsigned pad[128], p; + + if (start) { + for (p=0; p < 4; p++) + pad[p] = key = key * 48828125 + 1; + pad[3] = pad[3] << 1 | (pad[0]^pad[2]) >> 31; + for (p=4; p < 127; p++) + pad[p] = (pad[p-4]^pad[p-2]) << 1 | (pad[p-3]^pad[p-1]) >> 31; + for (p=0; p < 127; p++) + pad[p] = htonl(pad[p]); + } + while (len-- && p++) + *data++ ^= pad[(p-1) & 127] = pad[p & 127] ^ pad[(p+64) & 127]; +} + +int parse_tiff_ifd (int base, int level) +{ + int entries, tag, type, count, slen, save, save2, i; + unsigned *buf, sony_offset=0, sony_length=0, sony_key=0; + FILE *sfp; + + entries = get2(); + if (entries > 1024) return 1; + while (entries--) { + save = ftell(ifp); + tag = get2(); + type = get2(); + count= get4(); + slen = count; + if (slen > 128) slen = 128; + tiff_dump (base, tag, type, count, level); + if (type == 13) tag = 0x14a; + switch (tag) { + case 271: /* Make tag */ + fgets (make, slen, ifp); + break; + case 272: /* Model tag */ + fgets (model, slen, ifp); + break; + case 33405: /* Model2 tag */ + fgets (model2, slen, ifp); + break; + case 330: /* SubIFD tag */ + save2 = ftell(ifp); + for (i=0; i < count; i++) { + printf ("SubIFD #%d:\n", i+1); + fseek (ifp, save2 + i*4, SEEK_SET); + fseek (ifp, get4()+base, SEEK_SET); + parse_tiff_ifd (base, level+1); + } + break; + case 273: /* StripOffset */ + case 513: /* JpegIFOffset */ + case 61447: + fseek (ifp, get4()+base, SEEK_SET); + case 46: + parse_thumb (ftell(ifp), level); + break; + case 29184: sony_offset = get4(); break; + case 29185: sony_length = get4(); break; + case 29217: sony_key = get4(); break; + case 29264: + parse_minolta (ftell(ifp)); + break; + case 33424: + case 65024: + puts("Kodak private data:"); + fseek (ifp, get4()+base, SEEK_SET); + parse_tiff_ifd (base, level+1); + break; + case 34310: + parse_mos(0); + break; + case 34665: + fseek (ifp, get4()+base, SEEK_SET); + parse_exif (base, level+1); + break; + case 34853: + puts("GPS data:"); + fseek (ifp, get4()+base, SEEK_SET); + parse_tiff_ifd (base, level+1); + break; + case 50459: + i = order; + save2 = ftell(ifp); + order = get2(); + fseek (ifp, save2 + (get2(),get4()), SEEK_SET); + parse_tiff_ifd (save2, level+1); + order = i; + break; + case 50706: + is_dng = 1; + break; + case 50740: + if (is_dng) break; + parse_minolta (i = get4()+base); + fseek (ifp, i, SEEK_SET); + parse_tiff_ifd (base, level+1); + } + fseek (ifp, save+12, SEEK_SET); + } + if (sony_length && (buf = malloc(sony_length))) { + fseek (ifp, sony_offset, SEEK_SET); + fread (buf, sony_length, 1, ifp); + sony_decrypt (buf, sony_length/4, 1, sony_key); + sfp = ifp; + if ((ifp = tmpfile())) { + fwrite (buf, sony_length, 1, ifp); + fseek (ifp, 0, SEEK_SET); + puts ("Sony SR2 encrypted IFD:"); + parse_tiff_ifd (-sony_offset, level); + fclose (ifp); + } + ifp = sfp; + free (buf); + } + return 0; +} + +/* + Parse a TIFF file looking for camera model and decompress offsets. + */ +void parse_tiff (int base, int level) +{ + int doff, ifd=0, sorder=order; + + fseek (ifp, base, SEEK_SET); + order = get2(); + if (order != 0x4949 && order != 0x4d4d) return; + get2(); + while ((doff = get4())) { + fseek (ifp, doff+base, SEEK_SET); + printf ("%*sIFD #%d:\n", level*2, "", ifd++); + if (parse_tiff_ifd (base, level)) break; + } + order = sorder; +} + +void parse_minolta (int base) +{ + unsigned offset, save, len, j; + char tag[4]; + + fseek (ifp, base, SEEK_SET); + if (fgetc(ifp) || fgetc(ifp)-'M' || fgetc(ifp)-'R') return; + order = fgetc(ifp) * 0x101; + offset = base + get4() + 8; + while ((save=ftell(ifp)) < offset) { + fread (tag, 1, 4, ifp); + len = get4(); + printf ("Minolta tag %3.3s offset %06x length %06x", tag+1, save, len); + if (!strncmp (tag+1,"TTW",3)) { + putchar ('\n'); + parse_tiff (ftell(ifp),0); + } else { + for (j = 0; j < len/2 && j < 128; j++) + printf ("%c%04x",(j & 15) || len < 9 ? ' ':'\n', get2()); + putchar ('\n'); + } + fseek (ifp, save+len+8, SEEK_SET); + } +} + +/* + Parse the CIFF structure. + */ +void parse_ciff (int offset, int length, int level) +{ + int tboff, nrecs, i, j, type, len, dlen, roff, aoff=0, save; + char c, name[256]; + ushort key[2]; + + fseek (ifp, offset+length-4, SEEK_SET); + tboff = get4() + offset; + fseek (ifp, tboff, SEEK_SET); + nrecs = get2(); + if (nrecs > 100) return; + printf ("%*s%d records:\n", level*2, "", nrecs); + for (i = 0; i < nrecs; i++) { + save = ftell(ifp); + type = get2(); + printf ("%*stype=0x%04x", level*2, "", type); + if (type & 0x4000) { + len = 8; + type &= 0x3fff; + } else { + len = get4(); + roff = get4(); + aoff = offset + roff; + printf (", length=%d, reloff=%d, absoff=%d", + len, roff, aoff); + fseek (ifp, aoff, SEEK_SET); + } + if ((type & 0xe700) == 0) + printf (", data="); + if (type == 0x0032) /* display as words */ + type |= 0x1000; + dlen = len < DLEN ? len:DLEN; + switch (type >> 8) { + case 0x28: + case 0x30: + putchar('\n'); + parse_ciff (aoff, len, level+1); + fseek (ifp, save+10, SEEK_SET); + continue; + case 0x00: /* byte values */ + for (j = 0; j < dlen; j++) + printf ("%c%02x",(j & 31) || dlen < 16 ? ' ':'\n', fgetc(ifp) & 0xff); + break; + case 0x08: /* null-terminated ASCII strings */ + putchar('\"'); + for (j = 0; j < dlen; j++) { + c = fgetc(ifp); + putchar( isprint(c) ? c:'.'); + } + putchar('\"'); + break; + case 0x10: /* word values */ + key[0] = get2(); + fseek (ifp, -2, SEEK_CUR); + if (type == 0x1032 && key[0] == 1040) + key[1] = 17907; + else key[0] = key[1] = 0; + for (j = 0; j < dlen; j+=2) + printf ("%c%5u",(j & 31) || dlen < 16 ? ' ':'\n', + get2() ^ key[(j >> 1) & 1]); + break; + case 0x18: /* dword values */ + for (j = 0; j < dlen; j+=4) + printf ("%c%08x",(j & 31) || dlen < 16 ? ' ':'\n', get4()); + } + putchar('\n'); + fseek (ifp, save+10, SEEK_SET); + if (type == 0x080a) { /* Get the camera name */ + fseek (ifp, aoff, SEEK_SET); + fread (name, 256, 1, ifp); + strcpy (make, name); + strcpy (model, name + strlen(make)+1); + } + } +} + +int parse_jpeg (int offset) +{ + int len, save, hlen; + + fseek (ifp, offset, SEEK_SET); + if (fgetc(ifp) != 0xff || fgetc(ifp) != 0xd8) return 0; + + while (fgetc(ifp) == 0xff && fgetc(ifp) >> 4 != 0xd) { + order = 0x4d4d; + len = get2() - 2; + save = ftell(ifp); + order = get2(); + hlen = get4(); + if (get4() == 0x48454150) /* "HEAP" */ + parse_ciff (save+hlen, len-hlen, 0); + parse_tiff (save+6,0); + fseek (ifp, save+len, SEEK_SET); + } + return 1; +} + +void parse_riff (int level) +{ + unsigned i, size, end, save; + char tag[4], type[4], buf[64]; + + order = 0x4949; + fread (tag, 4, 1, ifp); + size = get4(); + if (isdigit(tag[0])) { + fseek (ifp, size, SEEK_CUR); + return; + } + printf ("%*.4s size %d", level*4+4, tag, size); + if (!memcmp(tag,"RIFF",4) || !memcmp(tag,"LIST",4)) { + end = ftell(ifp) + size; + fread (type, 4, 1, ifp); + printf (" type %.4s:\n", type); + while (ftell(ifp)+7 < end) + parse_riff (level+1); + } else { + save = ftell(ifp); + fread (buf, 1, 40, ifp); + printf (": "); + for (i=0; i < 40 && isprint(buf[i]); i++) + putchar (buf[i]); + putchar ('\n'); + fseek (ifp, save+size, SEEK_SET); + } +} + +void parse_mos(int level) +{ + char data[256]; + int i, skip, save; + char *cp; + + save = ftell(ifp); + while (1) { + if (get4() != 0x504b5453) break; + get4(); + printf ("%*sPKTS ", level, ""); + fread (data, 1, 40, ifp); + skip = get4(); + printf ("%s %d bytes: ", data, skip); + if (!strcmp(data,"pattern_ratation_angle")) { + printf ("%d\n", get2()); + continue; + } + if (!strcmp(data,"icc_camera_to_tone_matrix")) { + for (i=0; i < skip/4; i++) + printf ("%f ", int_to_float(get4())); + putchar('\n'); + continue; + } + fread (data, 1, sizeof data, ifp); + fseek (ifp, -sizeof data, SEEK_CUR); + data[sizeof data - 1] = 0; + while ((cp=strchr(data,'\n'))) + *cp = ' '; + printf ("%s\n",data); + parse_mos(level+2); + fseek (ifp, skip, SEEK_CUR); + } + fseek (ifp, save, SEEK_SET); +} + +void parse_rollei() +{ + char line[128], *val; + + fseek (ifp, 0, SEEK_SET); + do { + fgets (line, 128, ifp); + fputs (line, stdout); + if ((val = strchr(line,'='))) + *val++ = 0; + else + val = line + strlen(line); + } while (strncmp(line,"EOHD",4)); + strcpy (make, "Rollei"); + strcpy (model, "d530flex"); +} + +void get_utf8 (int offset, char *buf, int len) +{ + ushort c; + char *cp; + + fseek (ifp, offset, SEEK_SET); + for (cp=buf; (c = get2()) && cp+3 < buf+len; ) { + if (c < 0x80) + *cp++ = c; + else if (c < 0x800) { + *cp++ = 0xc0 + (c >> 6); + *cp++ = 0x80 + (c & 0x3f); + } else { + *cp++ = 0xe0 + (c >> 12); + *cp++ = 0x80 + (c >> 6 & 0x3f); + *cp++ = 0x80 + (c & 0x3f); + } + } + *cp = 0; +} + +void parse_foveon() +{ + unsigned entries, off, len, tag, save, i, j, k, pent, poff[256][2]; + char name[128], value[128], *camf, *pos, *cp, *dp; + unsigned val, wide, high, row, col, diff, type, num, ndim, dim[3]; + ushort huff[258], vpred[2][2], hpred[2]; + + order = 0x4949; /* Little-endian */ + fseek (ifp, -4, SEEK_END); + fseek (ifp, get4(), SEEK_SET); + if (get4() != 0x64434553) { /* SECd */ + printf ("Bad Section identifier at %6x\n", (int)ftell(ifp)-4); + return; + } + get4(); + entries = get4(); + while (entries--) { + off = get4(); + len = get4(); + tag = get4(); + save = ftell(ifp); + fseek (ifp, off, SEEK_SET); + printf ("%c%c%c%c at offset %06x, length %06x, ", + tag, tag >> 8, tag >> 16, tag >> 24, off, len); + if (get4() != (0x20434553 | (tag << 24))) { + printf ("Bad Section identifier at %6x\n", off); + return; + } + val = get4(); + printf ("version %d.%d, ",val >> 16, val & 0xffff); + switch (tag) { + case 0x32414d49: /* IMA2 */ + case 0x47414d49: /* IMAG */ + printf ("type %d, " , get4()); + printf ("format %2d, " , get4()); + printf ("columns %4d, " , get4()); + printf ("rows %4d, " , get4()); + printf ("rowsize %d\n" , get4()); + parse_jpeg (off+28); + order = 0x4949; + break; + case 0x464d4143: /* CAMF */ + type = get4(); + printf ("type %d\n", type); + get4(); get4(); + wide = get4(); + high = get4(); + if (type == 2) { + camf = malloc (len -= 28); + fread (camf, 1, len, ifp); + for (i=0; i < len; i++) { + high = (high * 1597 + 51749) % 244944; + val = high * (INT64) 301593171 >> 24; + camf[i] ^= ((((high << 8) - val) >> 1) + val) >> 17; + } + } else if (type == 4) { + camf = malloc (len = wide*high*3/2); + memset (huff, 0xff, sizeof huff); + huff[0] = 8; + for (i=0; i < 13; i++) { + tag = getc(ifp); + val = getc(ifp); + for (j=0; j < 256 >> tag; ) + huff[val+ ++j] = tag << 8 | i; + } + fseek (ifp, 6, SEEK_CUR); + getbits(-1); + vpred[0][0] = vpred[0][1] = + vpred[1][0] = vpred[1][1] = 512; + for (j=row=0; row < high; row++) { + for (col=0; col < wide; col++) { + diff = ljpeg_diff(huff); + if (col < 2) hpred[col] = vpred[row & 1][col] += diff; + else hpred[col & 1] += diff; + if (col & 1) { + camf[j++] = hpred[0] >> 4; + camf[j++] = hpred[0] << 4 | hpred[1] >> 8; + camf[j++] = hpred[1]; + } + } + } + } else { + printf ("Unknown CAMF type %d\n", type); + break; + } + for (pos=camf; (unsigned) (pos-camf) < len; pos += sget4(pos+8)) { + if (strncmp (pos, "CMb", 3)) goto done; + val = sget4(pos+4); + printf (" %4.4s version %d.%d: ", pos, val >> 16, val & 0xffff); + switch (pos[3]) { + case 'M': + cp = pos + sget4(pos+16); + type = sget4(cp); + ndim = sget4(cp+4); + dim[0] = dim[1] = dim[2] = 1; + printf ("%d-dimensonal array %s of type %d:\n Key: (", + ndim, pos+sget4(pos+12), sget4(cp)); + dp = pos + sget4(cp+8); + for (i=ndim; i--; ) { + cp += 12; + dim[i] = sget4(cp); + printf ("%s %d%s", pos+sget4(cp+4), dim[i], i ? ", ":")\n"); + } + for (i=0; i < dim[2]; i++) { + for (j=0; j < dim[1]; j++) { + printf (" "); + for (k=0; k < dim[0]; k++) + switch (type) { + case 5: + printf ("%7d", *(uchar *)dp++); + break; + case 0: + case 6: + printf ("%7d", (short) sget2(dp)); + dp += 2; + break; + case 1: + case 2: + printf (" %d", sget4(dp)); + dp += 4; + break; + case 3: + val = sget4(dp); + printf (" %9f", int_to_float(val)); + dp += 4; + } + printf ("\n"); + } + printf ("\n"); + } + break; + case 'P': + val = sget4(pos+16); + num = sget4(pos+val); + printf ("%s, %d parameters:\n", pos+sget4(pos+12), num); + cp = pos+val+8 + num*8; + for (i=0; i < num; i++) { + val += 8; + printf (" %s = %s\n", cp+sget4(pos+val), cp+sget4(pos+val+4)); + } + break; + case 'T': + cp = pos + sget4(pos+16); + printf ("%s = %.*s\n", pos+sget4(pos+12), sget4(cp), cp+4); + break; + default: + printf ("\n"); + } + } +done: free (camf); + break; + case 0x504f5250: /* PROP */ + printf ("entries %d, ", pent=get4()); + printf ("charset %d, ", get4()); + get4(); + printf ("nchars %d\n", get4()); + off += pent*8 + 24; + if ((unsigned) pent > 256) pent=256; + for (i=0; i < pent*2; i++) + poff[0][i] = off + get4()*2; + for (i=0; i < pent; i++) { + get_utf8 (poff[i][0], name, 128); + get_utf8 (poff[i][1], value, 128); + printf (" %s = %s\n", name, value); + if (!strcmp (name,"CAMMANUF")) + strcpy (make, value); + if (!strcmp (name,"CAMMODEL")) + strcpy (model, value); + } + } + fseek (ifp, save, SEEK_SET); + } +} + +void parse_fuji (int offset) +{ + int entries, tag, len; + + fseek (ifp, offset, SEEK_SET); + if (!(len = get4())) return; + printf ("Fuji Image %c:\n", offset < 100 ? 'S':'R'); + fseek (ifp, len, SEEK_SET); + entries = get4(); + if (entries > 255) return; + while (entries--) { + tag = get2(); + len = get2(); + printf ("Fuji tag=0x%x, len=%d, data =",tag,len); + while (len--) + printf (" %02x",fgetc(ifp)); + putchar ('\n'); + } +} + +void parse_phase_one (int base) +{ + unsigned entries, tag, type, len, data, save; + unsigned meta=0, wide=0, high=0, i, j; + char str[256]; + + fseek (ifp, base, SEEK_SET); + order = get4() & 0xffff; + if (get4() >> 8 != 0x526177) return; + fseek (ifp, base+get4(), SEEK_SET); + entries = get4(); + get4(); + while (entries--) { + tag = get4(); + type = get4(); + len = get4(); + data = get4(); + save = ftell(ifp); + printf ("Phase One tag=0x%x, type=%d, len=%2d, data = 0x%x", + tag, type, len, data); + if (type == 4 && len == 4 && data > 0xfffffff) + printf (" = %f", int_to_float(data)); + putchar ('\n'); + if (tag == 0x110) meta = base+data; + if (len > 4) + fseek (ifp, base+data, SEEK_SET); + if (type == 1 && len < 256) { + fread (str, 256, 1, ifp); + puts (str); + } + if (tag != 0x21c && type == 4 && len > 4) { + for ( ; len > 0; len -= 4) + printf ("%f ", int_to_float(get4())); + puts (""); + } + fseek (ifp, save, SEEK_SET); + } + strcpy (make, "Phase One"); + strcpy (model, "unknown"); + if (!meta) return; + fseek (ifp, meta, SEEK_SET); + order = get2(); + fseek (ifp, 6, SEEK_CUR); + fseek (ifp, meta+get4(), SEEK_SET); + entries = get4(); + get4(); + while (entries--) { + tag = get4(); + len = get4(); + data = get4(); + save = ftell(ifp); + printf ("Phase One meta tag=0x%x, len=%2d, offset = 0x%x, data = ", + tag, len, data); + if (!((0x000801f4 >> (tag-0x400)) & 1)) putchar ('\n'); + fseek (ifp, meta+data, SEEK_SET); + switch (tag) { + case 0x400: + for (i=0; i < len; i+=2) + printf ("%5u%c", get2(), (i & 6) == 6 || i == len-2 ? '\n':' '); + break; + case 0x401: + for (i=0; i < 16; i+=2) + printf ("%6u%c", get2(), (i & 14) == 14 || i == len-2 ? '\n':' '); + for (; i < len; i+=4) + printf ("%9.6f%c", int_to_float(get4()), + (i & 28) == 12 || i == len-4 ? '\n':' '); + break; + case 0x402: + printf ("%f\n", int_to_float (data)); + break; + case 0x404: case 0x405: case 0x406: case 0x407: + fread (str, 256, 1, ifp); + puts (str); + break; + case 0x408: case 0x413: + printf ("%lf\n", get_double()); + break; + case 0x40b: case 0x410: case 0x416: + for (i=0; i < len; i+=2) + printf ("%6u%c", get2(), (i & 14) == 14 || i == len-2 ? '\n':' '); + break; + case 0x40f: case 0x418: case 0x419: case 0x41a: + for (i=0; i < 4; i++) + printf ("%02X%c", fgetc(ifp), i == 3 ? '\n':' '); + for (; i < len; i+=4) + printf ("%e%c", int_to_float(get4()), i == len-4 ? '\n':' '); + break; + case 0x412: + for (i=0; i < 36; i+=4) { + printf ("%u ", j=get4()); + if (i == 4) wide = j; + if (i == 12) high = j*2; + } + printf ("%u\n", get2()); + for (i=0; i < wide*high; i++) + printf ("%9.6f%c", int_to_float(get4()), + i % wide == wide-1 ? '\n':' '); + for (i=0; i < wide*high; i++) + printf ("%5u%c", get2(), i % wide == wide-1 ? '\n':' '); + break; + default: + for (i=0; i < len; i++) + printf ("%02X%c", fgetc(ifp), + (i & 15) == 15 || i == len-1 ? '\n':' '); + } + fseek (ifp, save, SEEK_SET); + } +} + +void parse_uuid (int level) +{ + unsigned i, len, tag; + char buf[0x8000]; + + for (;;) { + len = get2(); + tag = get2(); + if (!len) break; + printf ("%*stag = 0x%x, len=%d, ", level*2, "", tag, len); + switch (tag >> 12) { + case 1: + if (len-4 < sizeof buf) { + fread (buf, 1,len-4, ifp); + printf ("\"%.*s\"", len-4, buf); + } + break; + case 2: + for (i=4; i < len; i+=4) + printf ("%f ",int_to_float(get4())); + break; + default: + for (i=4; i < len; i++) + printf ("%02x", getc(ifp)); + } + putchar ('\n'); + } +} + +void parse_redcine (off_t base, int level) +{ + unsigned i, len, tag, ulen, utag; + char c, ctag[4], buf[0x8000]; + + do { + fseeko (ifp, base, SEEK_SET); + len = get4(); + tag = get4(); + if (feof(ifp)) break; + for (i=0; i < 4; i++) { + ctag[i] = tag >> ((3-i) << 3); + if (!isprint(ctag[i])) ctag[i] = '.'; + } + printf ("%*soff=0x%llx, len=%d, tag=0x%x \"%.4s\"\n", + level*2, "", (INT64) base, len, tag, ctag); + switch (tag) { + case 0x52454431: /* RED1 */ + fseek (ifp, 59, SEEK_CUR); + fread (buf, 1, 256, ifp); + printf (" Original name: %s\n", buf); + break; + case 0x52454432: /* RED2 */ + fseek (ifp, 18, SEEK_CUR); + case 0x52444901: /* RDI */ + fseek (ifp, 88, SEEK_CUR); + parse_uuid (level+1); + base = -(-(base+len) & -4096); + continue; +#if 0 + case 0x52454441: /* REDA */ + fread (buf, 1, sizeof buf, ifp); + fwrite (buf+24, 1, len-32, stdout); + break; +#endif + case 0x52454456: /* REDV */ + printf (" seq = %d, time = %d\n", get4(), get4()); + parse_redcine (base+20, level+1); + break; + case 0x75756964: /* uuid */ + fseek (ifp, 16, SEEK_CUR); + parse_uuid (level+1); + } + base += len; + } while (len); +} + +void parse_crx (int level, int end) +{ + int i, uuid[4], size, save; + char tag[4], buf[400]; + + while ((save = ftell(ifp)) < end) { + order = 0x4d4d; + size = get4(); + if (size < 8 || save+size > end) { + fseek (ifp, -4, SEEK_CUR); + fread (buf, 1, 400, ifp); + printf (" ="); + for (i=0; i < 400 && i < end-save; i++) + printf ("%s%02x",i & 3 ? "":" ",buf[i] & 255); + fseek (ifp, end, SEEK_SET); + return; + } + fread (tag, 4, 1, ifp); + printf ("\n%*.4s size %d", level*2+4, tag, size); + memset (uuid, 0, 16); + if (!memcmp(tag,"uuid",4)) { + for (i=0; i < 4; i++) uuid[i] = get4(); + fseek (ifp, -16, SEEK_CUR); + printf(" = "); + for (i=0; i < 16; i++) + printf ("%s%02x",(0x550 >> i) & 1 ? "-":"", fgetc(ifp)); + } + if (!memcmp(tag,"stsd",4)) + fseek (ifp, 8, SEEK_CUR); + if (!memcmp(tag,"CMT",3)) { + putchar ('\n'); + parse_tiff (ftell(ifp),level+1); + } else parse_crx (level+1, save+size); + fseek (ifp, save+size, SEEK_SET); + } + if (!level) { + printf ("Finished parsing at offset 0x%lx, ",ftell(ifp)); + printf ("mdat %sfound\n", get4() == 0x6d646174 ? "":"not "); + } +} + +void parse_qt (int level, int end) +{ + unsigned i, lcase, size, save; + char tag[4], buf[64]; + + order = 0x4d4d; + while (ftell(ifp)+7 < end) { + save = ftell(ifp); + if ((size = get4()) < 8) return; + fread (tag, 4, 1, ifp); + printf ("%*.4s size %d", level*4+4, tag, size); + for (lcase=1, i=0; i < 4; i++) + if (!islower(tag[i])) lcase = 0; + if (lcase && memcmp(tag,"ftyp",4) && memcmp(tag,"tkhd",4) + && memcmp(tag,"mdat",4) + || !memcmp(tag,"CNOP",4) || !memcmp(tag,"CNTH",4)) { + putchar ('\n'); + parse_qt (level+1, save+size); + } else if (!memcmp(tag,"CNDA",4)) { + puts (" *** parsing JPEG thumbnail ..."); + parse_jpeg (ftell(ifp)); + } else { + fread (buf, 1, 40, ifp); + printf (" : "); + for (i=0; i < 40 && i < size-8; i++) + putchar (isprint(buf[i]) ? buf[i] : '.'); + putchar ('\n'); + } + fseek (ifp, save+size, SEEK_SET); + } +} + +char *memmem (char *haystack, size_t haystacklen, + char *needle, size_t needlelen) +{ + char *c; + for (c = haystack; c <= haystack + haystacklen - needlelen; c++) + if (!memcmp (c, needle, needlelen)) + return c; + return NULL; +} + +/* + Identify which camera created this file, and set global variables + accordingly. Return nonzero if the file cannot be decoded. + */ +void identify() +{ + char head[32], *cp; + unsigned hlen, fsize, toff, tlen; + + make[0] = model[0] = model2[0] = is_dng = 0; + order = get2(); + hlen = get4(); + fseek (ifp, 0, SEEK_SET); + fread (head, 1, 32, ifp); + fseek (ifp, 0, SEEK_END); + fsize = ftell(ifp); + if ((cp = memmem (head, 32, "MMMM", 4)) || + (cp = memmem (head, 32, "IIII", 4))) { + parse_phase_one (cp-head); + if (cp-head) parse_tiff (0,0); + } else if (order == 0x4949 || order == 0x4d4d) { + if (!memcmp(head+6,"HEAPCCDR",8)) { + parse_ciff (hlen, fsize - hlen, 0); + fseek (ifp, hlen, SEEK_SET); + } else + parse_tiff (0,0); + } else if (!memcmp (head,"NDF0",4)) { + parse_tiff (12,0); + } else if (!memcmp (head,"\0MRM",4)) { + parse_minolta (0); + } else if (!memcmp (head,"FUJIFILM",8)) { + fseek (ifp, 84, SEEK_SET); + toff = get4(); + tlen = get4(); + parse_fuji (92); + fseek (ifp, 100, SEEK_SET); + parse_tiff (get4(),0); + if (toff > 120) { + parse_fuji (120); + fseek (ifp, 128, SEEK_SET); + parse_tiff (get4(),0); + } + parse_thumb (toff,0); + } else if (!memcmp (head,"RIFF",4)) { + fseek (ifp, 0, SEEK_SET); + parse_riff(0); + } else if (!memcmp (head+4,"ftypcrx ",8)) { + fseek (ifp, 0, SEEK_SET); + parse_crx (0, fsize); + } else if (!memcmp (head+4,"ftypqt ",9)) { + fseek (ifp, 0, SEEK_SET); + parse_qt (0, fsize); + } else if (!memcmp (head+4,"RED",3)) + parse_redcine(0,0); + else if (!memcmp (head,"DSC-Image",9)) + parse_rollei(); + else if (!memcmp (head,"FOVb",4)) + parse_foveon(); + parse_jpeg(0); +} + +int main(int argc, char **argv) +{ + int arg; + + if (argc == 1) + { + fprintf (stderr, + "\nRaw Photo Parser" + "\nby Dave Coffin, dcoffin a cybercom o net" + "\n\nUsage: %s file1.crw file2.crw ...\n", argv[0]); + return 1; + } + for (arg=1; arg < argc; arg++) + { + fname = argv[arg]; + ifp = fopen (fname,"rb"); + if (!ifp) { + perror (fname); + continue; + } + printf ("\nParsing %s:\n", fname); + identify(); + fclose (ifp); + } + return 0; +} diff --git a/rawphoto.c b/rawphoto.c new file mode 100644 index 0000000..1be4dce --- /dev/null +++ b/rawphoto.c @@ -0,0 +1,355 @@ +/* + Raw photo loader plugin for The GIMP + by Dave Coffin at cybercom dot net, user dcoffin + http://www.cybercom.net/~dcoffin/ + + $Revision: 1.32 $ + $Date: 2008/09/16 05:41:39 $ + + This code is licensed under the same terms as The GIMP. + To simplify maintenance, it calls my command-line "dcraw" + program to do the actual decoding. + + To install locally: + gimptool --install rawphoto.c + + To install globally: + gimptool --install-admin rawphoto.c + + To build without installing: + gcc -o rawphoto rawphoto.c `gtk-config --cflags --libs` -lgimp -lgimpui + */ + +#include +#include +#include + +#include + +#include +#include + +#if GIMP_CHECK_VERSION(1,3,2) +#define GimpRunModeType GimpRunMode +#endif + +#if GIMP_CHECK_VERSION(1,3,17) +#define RAWPHOTO_CONST const +#else +#define RAWPHOTO_CONST +#endif + +#include +#include +#define _(String) gettext(String) + +#define PLUG_IN_VERSION "1.1.20 - 16 September 2008" + +static void query(void); +static void run(RAWPHOTO_CONST gchar *name, + gint nparams, + RAWPHOTO_CONST GimpParam *param, + gint *nreturn_vals, + GimpParam **return_vals); + +static gint load_dialog (gchar *name); +static gint32 load_image (gchar *filename); + +GimpPlugInInfo PLUG_IN_INFO = +{ + NULL, /* init_procedure */ + NULL, /* quit_procedure */ + query, /* query_procedure */ + run, /* run_procedure */ +}; + +static struct { + gboolean check_val[6]; + gfloat spin_val[2]; +} cfg = { + { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, + { 1, 0 } +}; + +MAIN () + +static void query (void) +{ + static GimpParamDef load_args[] = + { + { GIMP_PDB_INT32, "run_mode", "Interactive, non-interactive" }, + { GIMP_PDB_STRING, "filename", "The name of the file to load" }, + { GIMP_PDB_STRING, "raw_filename", "The name of the file to load" }, + }; + static GimpParamDef load_return_vals[] = + { + { GIMP_PDB_IMAGE, "image", "Output image" }, + }; + + static gint num_load_args = + sizeof load_args / sizeof load_args[0]; + static gint num_load_return_vals = + sizeof load_return_vals / sizeof load_return_vals[0]; + + gimp_install_procedure ("file_rawphoto_load", + "Loads raw digital camera files", + "This plug-in loads raw digital camera files.", + "Dave Coffin at cybercom dot net, user dcoffin", + "Copyright 2003-2008 by Dave Coffin", + PLUG_IN_VERSION, + "/rawphoto", + NULL, + GIMP_PLUGIN, + num_load_args, + num_load_return_vals, + load_args, + load_return_vals); + + gimp_register_load_handler ("file_rawphoto_load", + "3fr,arw,bay,bmq,cine,cr2,crw,cs1,dc2,dcr,dng,erf,fff,hdr,ia,jpg,k25,kc2,kdc,mdc,mef,mos,mrw,nef,nrw,orf,pef,pxn,qtk,raf,raw,rdc,rw2,sr2,srf,sti,tif,x3f", ""); +} + +static void run (RAWPHOTO_CONST gchar *name, + gint nparams, + RAWPHOTO_CONST GimpParam *param, + gint *nreturn_vals, + GimpParam **return_vals) +{ + static GimpParam values[2]; + GimpRunModeType run_mode; + GimpPDBStatusType status; + gint32 image_id = -1; + gchar *command, *fname; + int stat; + + *nreturn_vals = 1; + *return_vals = values; + + status = GIMP_PDB_CALLING_ERROR; + if (strcmp (name, "file_rawphoto_load")) goto done; + + status = GIMP_PDB_EXECUTION_ERROR; + fname = param[1].data.d_string; + command = g_malloc (strlen(fname)+20); + if (!command) goto done; +/* + Is the file really a raw photo? If not, try loading it + as a regular JPEG or TIFF. + */ + sprintf (command, "dcraw -i '%s'\n",fname); + fputs (command, stderr); + stat = system (command); + g_free (command); + if (stat) { + if (stat > 0x200) + g_message (_("The \"rawphoto\" plugin won't work because " + "there is no \"dcraw\" executable in your path.")); + if (!strcasecmp (fname + strlen(fname) - 4, ".jpg")) + *return_vals = gimp_run_procedure2 + ("file_jpeg_load", nreturn_vals, nparams, param); + else + *return_vals = gimp_run_procedure2 + ("file_tiff_load", nreturn_vals, nparams, param); + return; + } + gimp_get_data ("plug_in_rawphoto", &cfg); + status = GIMP_PDB_CANCEL; + run_mode = param[0].data.d_int32; + if (run_mode == GIMP_RUN_INTERACTIVE) + if (!load_dialog (param[1].data.d_string)) goto done; + + status = GIMP_PDB_EXECUTION_ERROR; + image_id = load_image (param[1].data.d_string); + if (image_id == -1) goto done; + + *nreturn_vals = 2; + values[1].type = GIMP_PDB_IMAGE; + values[1].data.d_image = image_id; + status = GIMP_PDB_SUCCESS; + gimp_set_data ("plug_in_rawphoto", &cfg, sizeof cfg); + +done: + values[0].type = GIMP_PDB_STATUS; + values[0].data.d_status = status; +} + +static gint32 load_image (gchar *filename) +{ + int tile_height, depth, width, height, row, nrows; + FILE *pfp; + gint32 image, layer; + GimpDrawable *drawable; + GimpPixelRgn pixel_region; + guchar *pixel; + char *command, nl; + + setlocale (LC_NUMERIC, "C"); + command = g_malloc (strlen(filename)+100); + if (!command) return -1; + sprintf (command, + "dcraw -c%s%s%s%s%s%s -b %0.2f -H %d '%s'\n", + cfg.check_val[0] ? " -q 0":"", + cfg.check_val[1] ? " -h":"", + cfg.check_val[2] ? " -f":"", + cfg.check_val[3] ? " -d":"", + cfg.check_val[4] ? " -a":"", + cfg.check_val[5] ? " -w":"", + cfg.spin_val[0], (int) cfg.spin_val[1], + filename ); + fputs (command, stderr); + pfp = popen (command, "r"); + g_free (command); + if (!pfp) { + perror ("dcraw"); + return -1; + } + + if (fscanf (pfp, "P%d %d %d 255%c", &depth, &width, &height, &nl) != 4 + || (depth-5)/2 ) { + pclose (pfp); + g_message ("Not a raw digital camera image.\n"); + return -1; + } + + depth = depth*2 - 9; + image = gimp_image_new (width, height, depth == 3 ? GIMP_RGB : GIMP_GRAY); + if (image == -1) { + pclose (pfp); + g_message ("Can't allocate new image.\n"); + return -1; + } + + gimp_image_set_filename (image, filename); + + /* Create the "background" layer to hold the image... */ + layer = gimp_layer_new (image, "Background", width, height, + depth == 3 ? GIMP_RGB_IMAGE : GIMP_GRAY_IMAGE, + 100, GIMP_NORMAL_MODE); + gimp_image_add_layer (image, layer, 0); + + /* Get the drawable and set the pixel region for our load... */ + drawable = gimp_drawable_get (layer); + gimp_pixel_rgn_init (&pixel_region, drawable, 0, 0, drawable->width, + drawable->height, TRUE, FALSE); + + /* Temporary buffers... */ + tile_height = gimp_tile_height(); + pixel = g_new (guchar, tile_height * width * depth); + + /* Load the image... */ + for (row = 0; row < height; row += tile_height) { + nrows = height - row; + if (nrows > tile_height) + nrows = tile_height; + fread (pixel, width * depth, nrows, pfp); + gimp_pixel_rgn_set_rect (&pixel_region, pixel, 0, row, width, nrows); + } + + pclose (pfp); + g_free (pixel); + + gimp_drawable_flush (drawable); + gimp_drawable_detach (drawable); + + return image; +} + +#if !GIMP_CHECK_VERSION(1,3,23) +/* this is set to true after OK click in any dialog */ +gboolean result = FALSE; + +static void callback_ok (GtkWidget * widget, gpointer data) +{ + result = TRUE; + gtk_widget_destroy (GTK_WIDGET (data)); +} +#endif + +#define NCHECK (sizeof cfg.check_val / sizeof (gboolean)) + +gint load_dialog (gchar * name) +{ + GtkWidget *dialog; + GtkWidget *table; + GtkObject *adj; + GtkWidget *widget; + int i; + static const char *label[9] = + { "Quick interpolation", "Half-size interpolation", + "Four color interpolation", "Grayscale document", + "Automatic white balance", "Camera white balance", + "Brightness", "Highlight mode" }; + + gimp_ui_init ("rawphoto", TRUE); + + dialog = gimp_dialog_new (_("Raw Photo Loader " PLUG_IN_VERSION), "rawphoto", +#if !GIMP_CHECK_VERSION(1,3,23) + gimp_standard_help_func, "rawphoto", + GTK_WIN_POS_MOUSE, + FALSE, TRUE, FALSE, + _("OK"), callback_ok, NULL, NULL, NULL, TRUE, + FALSE, _("Cancel"), gtk_widget_destroy, NULL, + 1, NULL, FALSE, TRUE, NULL); + gtk_signal_connect + (GTK_OBJECT(dialog), "destroy", GTK_SIGNAL_FUNC(gtk_main_quit), NULL); +#else + NULL, 0, + gimp_standard_help_func, "rawphoto", + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_OK, GTK_RESPONSE_OK, + NULL); +#endif + + table = gtk_table_new (9, 2, FALSE); + gtk_container_set_border_width (GTK_CONTAINER(table), 6); + gtk_box_pack_start + (GTK_BOX(GTK_DIALOG(dialog)->vbox), table, FALSE, FALSE, 0); + gtk_widget_show (table); + + for (i=0; i < NCHECK; i++) { + widget = gtk_check_button_new_with_label + (_(label[i])); + gtk_toggle_button_set_active + (GTK_TOGGLE_BUTTON (widget), cfg.check_val[i]); + gtk_table_attach + (GTK_TABLE(table), widget, 0, 2, i, i+1, GTK_FILL, GTK_FILL, 0, 0); + gtk_signal_connect (GTK_OBJECT (widget), "toggled", + GTK_SIGNAL_FUNC (gimp_toggle_button_update), + &cfg.check_val[i]); + gtk_widget_show (widget); + } + + for (i=NCHECK; i < NCHECK+2; i++) { + widget = gtk_label_new (_(label[i])); + gtk_misc_set_alignment (GTK_MISC (widget), 1.0, 0.5); + gtk_misc_set_padding (GTK_MISC (widget), 10, 0); + gtk_table_attach + (GTK_TABLE(table), widget, 0, 1, i, i+1, GTK_FILL, GTK_FILL, 0, 0); + gtk_widget_show (widget); + if (i == NCHECK+1) + widget = gimp_spin_button_new + (&adj, cfg.spin_val[i-NCHECK], 0, 9, 1, 9, 1, 1, 0); + else + widget = gimp_spin_button_new + (&adj, cfg.spin_val[i-NCHECK], 0.01, 4.0, 0.01, 0.1, 0.1, 0.1, 2); + gtk_table_attach + (GTK_TABLE(table), widget, 1, 2, i, i+1, GTK_FILL, GTK_FILL, 0, 0); + gtk_signal_connect (GTK_OBJECT (adj), "value_changed", + GTK_SIGNAL_FUNC (gimp_float_adjustment_update), + &cfg.spin_val[i-NCHECK]); + gtk_widget_show (widget); + } + + gtk_widget_show (dialog); + +#if !GIMP_CHECK_VERSION(1,3,23) + gtk_main(); + gdk_flush(); + + return result; +#else + i = gimp_dialog_run (GIMP_DIALOG (dialog)); + gtk_widget_destroy (dialog); + return i == GTK_RESPONSE_OK; +#endif +} diff --git a/update_dcraw b/update_dcraw new file mode 100644 index 0000000..5ecdedf --- /dev/null +++ b/update_dcraw @@ -0,0 +1,33 @@ +#! /bin/sh + +# Call this script to update dcraw files to latest version. +# "wget", "rcs" and "lynx" packages are required for the update + +wget -N https://www.dechifro.org/dcraw/parse.c +wget -N https://www.dechifro.org/dcraw/fujiturn.c +wget -N https://www.dechifro.org/dcraw/rawphoto.c +wget -N https://www.dechifro.org/dcraw/clean_crw.c +wget -N https://www.dechifro.org/dcraw/fuji_green.c +mv badpixels .badpixels +wget -N https://www.dechifro.org/dcraw/.badpixels +mv .badpixels badpixels +( URL="https://www.dechifro.org/dcraw/" ; echo -e "$URL:\n" ; LC_ALL=C lynx -display_charset=utf-8 -dump "$URL" | sed '1d;3,4d' ) >README +OLDVERSION=`sed -ne 's/^Version:[[:space:]]*\([0-9.]\+\)[[:space:]]*$/\1/p' dcraw.spec` +NEWVERSION=`lynx -dump https://www.dechifro.org/dcraw/archive/ | sed -n -e 's/^.*dcraw-\([0-9.]\+\)\.tar\.gz.*$/\1/p' |sort -nr |head -1` +wget -N https://www.dechifro.org/dcraw/archive/dcraw-${NEWVERSION}.tar.gz +sed -i -e "s/^\(Version:[[:space:]]*\)[0-9.]\+[[:space:]]*$/\1${NEWVERSION}/" dcraw.spec +tar --strip-components=1 -xf dcraw-${OLDVERSION}.tar.gz dcraw/dcraw.c +rm dcraw-${OLDVERSION}.tar.gz +wget -N https://www.dechifro.org/dcraw/RCS/dcraw.c,v +rlog dcraw.c >dcraw.log +rm -f dcraw.c dcraw.c,v +wget -N https://www.dechifro.org/dcraw/RCS/parse.c,v +rlog parse.c >parse.log +rm parse.c,v +echo +echo "********************************************************************" +echo "********************************************************************" +echo "Please check, whether packaged file list is up to date." +echo "You can look at dcraw.log and parse.log for the complete change log." +echo "Before submit, please call:" +echo "rm dcraw.log parse.log"