diff --git a/README b/README index 5136395..379777a 100644 --- a/README +++ b/README @@ -3,9 +3,11 @@ http://www.cybercom.net/~dcoffin/dcraw/: [1]Back to Dave Coffin's Home Page [2]en Esperanto + [3]em Portugues + [4]na russkom Welcome! If you are wondering how to connect your digital camera and - download images to a Linux PC, go to the [3]gPhoto homepage. My + download images to a Linux PC, go to the [5]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. @@ -30,14 +32,14 @@ http://www.cybercom.net/~dcoffin/dcraw/: decodes any raw image from any digital camera on any computer running any operating system. - That program is called [4]dcraw (pronounced "dee-see-raw"), and it's + That program is called [6]dcraw (pronounced "dee-see-raw"), and it's become a standard tool within and without the Open Source world. It's - small (about 7000 lines), portable (standard C libraries only), free + small (about 8000 lines), portable (standard C libraries only), free (both "gratis" and "libre"), and when used skillfully, produces - [5]better quality [6]output than the tools provided by the camera + [7]better quality [8]output than the tools provided by the camera vendor. - [7]Here's my resume. I do freelance consulting related to dcraw, and + [9]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 @@ -45,11 +47,11 @@ http://www.cybercom.net/~dcoffin/dcraw/: News and Interviews - [8]Essay for Digital Outback Photo, 25 April 2003 - [9]Article in News.com, 21 April 2005 - [10]Interview with Digital Photography Review, 27 April 2005 - [11]Interview with Thorsten Schnebeck, 10 June 2006 - [12]Interview with Ladinamo, 16 June 2006 + [10]Essay for Digital Outback Photo, 25 April 2003 + [11]Article in News.com, 21 April 2005 + [12]Interview with Digital Photography Review, 27 April 2005 + [13]Interview with Thorsten Schnebeck, 10 June 2006 + [14]Interview with Ladinamo, 16 June 2006 My Code @@ -62,53 +64,54 @@ http://www.cybercom.net/~dcoffin/dcraw/: "fuji_green", "fujiturn", and "fujiturn16". My shell scripts are dangerous and should only be installed in a "doc" directory without execute permission. - * [13]dcraw.c -- decodes raw photos, extracts thumbnails, and + * [15]dcraw.c -- decodes raw photos, extracts thumbnails, and displays metadata - Supports 260 cameras at last count. Compile with "gcc -o dcraw -O4 + Supports 268 cameras at last count. Compile with "gcc -o dcraw -O4 dcraw.c -lm -ljpeg -llcms" or "gcc -o dcraw -O4 dcraw.c -lm -DNO_JPEG -DNO_LCMS". Run with no arguments to see a usage message. - Don't complain that 16-bit output is too dark -- read the FAQ! - * [14]UNIX manpage for dcraw + Don't complain that 16-bit output is too dark -- read the [16]FAQ! + * [17]UNIX manpage for dcraw This is dcraw's official user documentation, updated in lockstep with the source code. - * [15]rawphoto.c -- basic plugin for GIMP 1.2 & 2.0 + * [18]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. [16]Udi Fuchs and [17]Joseph Heled have written much nicer + Gimp. [19]Udi Fuchs and [20]Joseph Heled have written much nicer plugins, with live preview, histograms, and color curves. - * [18].badpixels -- my camera's "hot pixels" + * [21].badpixels -- my camera's "hot pixels" This file tells dcraw which pixels have died and when, so that it can interpolate around them. - * [19]dcraw.c,v -- complete unabridged RCS file + * [22]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, - [20]download it here. - * [21]parse.c -- read image data structures + [23]download it here. + * [24]parse.c -- read image data structures This program displays CIFF and TIFF data structures in a very cryptic format. - * [22]clean_crw.c -- clean Canon CRW files + * [25]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. - * [23]fujiturn.c -- rotate Fuji Super CCD images + * [26]fujiturn.c -- rotate Fuji Super CCD images An alternative to dcraw's built-in Fuji rotation. - * [24]fuji_green.c -- convert Fuji green pixels to PGM + * [27]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: - * [25]decompress.c is a simple reference decompressor for CRW files. - * [26]sony_clear.c decrypts SRF files from the Sony DSC-F828. + * [28]decompress.c is a simple reference decompressor for CRW files. + * [29]sony_clear.c decrypts SRF files from the Sony DSC-F828. Internationalization To install dcraw with support for non-English languages, download the - latest tarball [27]from this directory and run the "install" script. - The currently supported languages are Esperanto, Russian, French, - Italian, German, Portuguese, Spanish, Dutch, Polish, and Chinese (both - Traditional and Simplified). + latest tarball [30]from this directory and run the "install" script. + The currently supported languages are [31]Esperanto, [32]Russian, + [33]French, [34]Italian, [35]German, [36]Portuguese, [37]Spanish, + [38]Dutch, [39]Polish, [40]Hungarian, and Chinese (both [41]Traditional + and [42]Simplified). - To add another language, send me translations of [28]this manpage and - [29]this message table in UTF-8 encoding. Translate only from my + To add another language, send me translations of [43]this manpage and + [44]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. @@ -139,102 +142,106 @@ http://www.cybercom.net/~dcoffin/dcraw/: 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: - * [30]ACDSee - * [31]Adobe Photoshop - * [32]BR's PhotoArchiver by Baard Riiber - * [33]BreezeBrowser by Chris Breeze - * [34]Conceiva Lightbox - * [35]cPicture by Juergen Eidt - * [36]Cumulus by Canto - * [37]dcRAW-X by Bryan Chang - * [38]DCRawUI by Sune Trudslev - * [39]Directory Opus Plugin by Leo Davidson(with C++ source code) - * [40]DeepSkyStacker by Luc Coiffier - * [41]dpMagic by Mikhail Stolpner - * [42]EasyRaw Studio - * [43]GraphicConverter by Thorsten Lemke - * [44]GVBox from JCO Consulting - * [45]ImageLab from Aragon System - * [46]IrfanView by Irfan Skiljan - * [47]IRIS image processor for astronomers - * [48]KA Photoservice - * [49]Lightbox by Josh Anon - * [50]LightZone by Anton Kast - * [51]Mixpo by Mixpo Portfolio Broadcasting Inc. - * [52]Photo Companion by Jeff Moore - * [53]Photo Jockey by Davie Lee Reed who also wrote a [54]dcraw + * [45]ACDSee + * [46]Adobe Photoshop + * [47]BR's PhotoArchiver by Baard Riiber + * [48]BreezeBrowser by Chris Breeze + * [49]Conceiva Lightbox + * [50]cPicture by Juergen Eidt + * [51]Cumulus by Canto + * [52]dcRAW-X by Bryan Chang + * [53]DCRawUI by Sune Trudslev + * [54]Directory Opus Plugin by Leo Davidson(with C++ source code) + * [55]DeepSkyStacker by Luc Coiffier + * [56]dpMagic by Mikhail Stolpner + * [57]EasyRaw Studio + * [58]GraphicConverter by Thorsten Lemke + * [59]GVBox from JCO Consulting + * [60]ImageLab from Aragon System + * [61]IrfanView by Irfan Skiljan + * [62]IRIS image processor for astronomers + * [63]KA Photoservice + * [64]Lightbox by Josh Anon + * [65]LightZone by Anton Kast + * [66]MediaRECOVER File Recovery Software + * [67]Mixpo by Mixpo Portfolio Broadcasting Inc. + * [68]Photo Companion by Jeff Moore + * [69]Photo Jockey by Davie Lee Reed who also wrote a [70]dcraw interface for Delphi programmers. - * [55]Photo Organizer by Balint Kis - * [56]PhotoReviewer by Ben Haller - * [57]Photovault by Harri Kaimio - * [58]Picasa from Google - * [59]Picture Arena by Felix Schwarz - * [60]PixInsight by Pleiades Software - * [61]PiXPO by PiXPO Inc. - * [62]PolyView by Polybytes - * [63]PowerShovel-II by Luc Minnebo - * [64]RAW Developer by Iridient Digital - * [65]Raw Magick - * [66]RawConvert by Jason Swain - * [67]RawDrop by Frank Siegert - * [68]RawShooter from pixmantec - * [69]RawView by Jari Savolainen - * [70]Serif PhotoPlus, PanoramaPlus, and AlbumPlus - * [71]SharpRaw by Duane DeSieno - * [72]SilverFast DCPro by LaserSoft Imaging - * [73]StudioLine Photo by H&M Software - * [74]ViewIt by Zdzislaw Losvik - * [75]Viewer n5 by Dmitry Fedorov - * [76]VueScan by Ed Hamrick + * [71]Photo Organizer by Balint Kis + * [72]PhotoRescue from DataRescue + * [73]PhotoReviewer by Ben Haller + * [74]Photovault by Harri Kaimio + * [75]Picasa from Google + * [76]Picture Arena by Felix Schwarz + * [77]PixInsight by Pleiades Software + * [78]PiXPO by PiXPO Inc. + * [79]PolyView by Polybytes + * [80]PowerShovel-II by Luc Minnebo + * [81]RAW Developer by Iridient Digital + * [82]Raw Magick + * [83]RawConvert by Jason Swain + * [84]RawDrop by Frank Siegert + * [85]RawShooter from pixmantec + * [86]RawView by Jari Savolainen + * [87]Serif PhotoPlus, PanoramaPlus, and AlbumPlus + * [88]SharpRaw by Duane DeSieno + * [89]SilverFast DCPro by LaserSoft Imaging + * [90]StudioLine Photo by H&M Software + * [91]ViewIt by Zdzislaw Losvik + * [92]Viewer n5 by Dmitry Fedorov + * [93]VueScan by Ed Hamrick + * [94]Xara Xtreme Pro Frequently Asked Questions I don't have a C compiler. Could you send me an executable? No, but Francisco Montilla provides Mac OS and Windows - executables [77]on his website. And Benjamin Lebsanft has - volunteered to maintain [78]Windows executables optimized for - specific CPUs. + executables [95]on his website. And Benjamin Lebsanft has + volunteered to maintain [96]Windows executables optimized for + specific CPUs. Dcraw has also been ported to [97]Amiga, + [98]MorphOS, [99]BeOS, [100]OS/2, and [101]RISC OS. If you're familiar with the DOS command line but don't know C, - you can install this [79]free C compiler for Windows and compile - dcraw.c quite easily. + you can install this [102]free C compiler for Windows and + compile dcraw.c quite easily. Why does dcraw say "Out of memory" in Windows Vista? This is an arbitrary limitation of Windows Vista that will be fixed in Service Pack 1. Thomas Nicely (of Pentium FDIV fame) - has a [80]page describing the problem. At the moment, the only + has a [103]page describing the problem. At the moment, the only workaround is to build dcraw.exe with a Microsoft compiler instead of a GNU compiler. How can I read the EXIF data (shutter speed, aperture, etc.)? - [81]Phil Harvey's ExifTool provides a unified Perl-based EXIF + [104]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 [82]this simple program for + Dcraw only supports cameras. Try [105]this simple program for scanners. How can I read Nikon Dust Off images (NDF files)? - [83]Use this program. + [106]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 - [84]TIFF spec, the [85]TIFF/EP spec, the [86]Adobe DNG spec, the - [87]CIFF (CRW) spec, and the [88]X3F spec. + [107]TIFF spec, the [108]TIFF/EP spec, the [109]Adobe DNG spec, + the [110]CIFF (CRW) spec, and the [111]X3F spec. Where can I get an assortment of raw photos to test my software? - [89]This website is a good place to exchange sample raw photos. - For the complete dcraw test suite (every camera supported by - dcraw), I sell a 2-DVD set for $600 and web-based updates for - $300/year. + Try [112]raw.fotosite.pl, [113]www.rawsamples.ch, and [114]Glass + Lantern RAWpository. For the complete dcraw test suite (every + camera supported by dcraw), I sell a 2-DVD set for $600 and + 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 [90]LibTIFF v3.8.2 and apply [91]this patch. Then use - [92]this C program as a template for converting your photos to - valid [93]Adobe DNG files. + Download [115]LibTIFF v3.8.2 and apply [116]this patch. Then use + [117]this C program as a template for converting your photos to + valid [118]Adobe DNG files. Why are dcraw output images larger than camera JPEGs? Any algorithm that combines each pixel with its neighbors is @@ -256,11 +263,11 @@ http://www.cybercom.net/~dcoffin/dcraw/: 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 [94]Photoshop and - [95]CinePaint, but it's no good for most image viewers. + professional image editors such as [119]Photoshop and + [120]CinePaint, but it's no good for most image viewers. What does the "-f" (four color RGB) option do? - If you see patterns like [96]this or [97]this in your output + If you see patterns like [121]this or [122]this in your output images, first try "dcraw -a". If these patterns persist, use "dcraw -f" to get rid of them. @@ -274,8 +281,9 @@ 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 [98]Netpbm toolkit in these examples. [99]ImageMagick - also does command-line format conversions. Both are free. + I used the [123]Netpbm toolkit in these examples. + [124]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 @@ -288,7 +296,7 @@ dcraw -c crw_0001.crw | cjpeg > crw_0001.jpeg 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 [100]explains this + it as a separate process. Eric Raymond [125]explains this technique here. Why are there false colors along edges within the image? @@ -300,27 +308,27 @@ dcraw -c crw_0001.crw | cjpeg > crw_0001.jpeg 2. Reconstruct the original three-color image as best you can from the remaining one color per pixel. - Dcraw currently gives a choice of three methods: Bilinear, - Variable Number of Gradients (VNG), and Adaptive - Homogeneity-Directed (AHD). + Dcraw currently gives a choice of four methods: Bilinear, + Variable Number of Gradients (VNG), Patterned Pixel Grouping + (PPG), and Adaptive Homogeneity-Directed (AHD). - [101]The Foveon X3 Capture chip requires a different kind of + [126]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 the Canon PowerShot A610, A620, and others, [102]go here. + For the Canon PowerShot A610, A620, and others, [127]go here. For some Nikon Coolpix cameras, you need to enable a - [103]special "DIAG RAW" mode. - For Casio cameras, see [104]Maurice Delaney's website or read - [105]this discussion on dpreview. - For the Minolta DiMAGE G400, G500, G530, or G600, go [106]here - (in Russian) or [107]here (in English). + [128]special "DIAG RAW" mode. + For Casio cameras, see [129]Maurice Delaney's website or read + [130]this discussion on dpreview. + For the Minolta DiMAGE G400, G500, G530, or G600, go [131]here + (in Russian) or [132]here (in English). For the Minolta DiMAGE Z2 and Nikon Coolpix 2100/3100/3700, - [108]go here. - For SMaL cameras, see the [109]camerahacking Forum. + [133]go here. + For SMaL cameras, see the [134]camerahacking Forum. For other cameras, refer to the User's Manual. @@ -328,7 +336,7 @@ dcraw -c crw_0001.crw | cjpeg > crw_0001.jpeg Most likely, yes. If your camera is not on the list below, try dcraw anyway. If it doesn't work, post a raw image to a website and e-mail me the URL. If you don't have a website, use - [110]Dropload or [111]YouSendIt. + [135]Dropload or [136]YouSendIt. Ideally, your sample image should show a standard white card or color chart in direct sunlight, with other colors in the @@ -351,6 +359,7 @@ dcraw -c crw_0001.crw | cjpeg > crw_0001.jpeg * Canon PowerShot A620 * Canon PowerShot A630 * Canon PowerShot A640 + * Canon PowerShot A710 IS * Canon PowerShot Pro70 * Canon PowerShot Pro90 IS * Canon PowerShot G1 @@ -418,15 +427,16 @@ dcraw -c crw_0001.crw | cjpeg > crw_0001.jpeg * Fuji FinePix S6000fd * Fuji FinePix S7000 * Fuji FinePix S9000/S9500 + * Hasselblad CFV * Imacon Ixpress 16-megapixel * Imacon Ixpress 22-megapixel * Imacon Ixpress 39-megapixel * ISG 2020x1520 - * Kodak DC20 (see [112]Oliver Hartman's page) - * Kodak DC25 (see [113]Jun-ichiro Itoh's page) + * Kodak DC20 (see [137]Oliver Hartman's page) + * Kodak DC25 (see [138]Jun-ichiro Itoh's page) * Kodak DC40 * Kodak DC50 - * Kodak DC120 (also try [114]kdc2tiff) + * Kodak DC120 (also try [139]kdc2tiff) * Kodak DCS200 * Kodak DCS315C * Kodak DCS330C @@ -453,6 +463,7 @@ dcraw -c crw_0001.crw | cjpeg > crw_0001.jpeg * Kodak DCS Pro 14nx * Kodak DCS Pro SLR/c * Kodak DCS Pro SLR/n + * Kodak C330 * Kodak P850 * Kodak P880 * Kodak KAI-0340 @@ -460,8 +471,10 @@ dcraw -c crw_0001.crw | cjpeg > crw_0001.jpeg * Konica KD-510Z * Leaf Aptus 17 * Leaf Aptus 22 + * Leaf Aptus 54S * Leaf Aptus 65 * Leaf Aptus 75 + * Leaf Aptus 75S * Leaf Cantare * Leaf CatchLight * Leaf CMost @@ -500,7 +513,9 @@ dcraw -c crw_0001.crw | cjpeg > crw_0001.jpeg * Nikon D2H * Nikon D2Hs * Nikon D2X + * Nikon D2Xs * Nikon D40 + * Nikon D40X * Nikon D50 * Nikon D70 * Nikon D70s @@ -542,6 +557,7 @@ dcraw -c crw_0001.crw | cjpeg > crw_0001.jpeg * Olympus E-400 * Olympus E-410 * Olympus E-500 + * Olympus E-510 * Olympus SP310 * Olympus SP320 * Olympus SP350 @@ -603,115 +619,140 @@ References 1. http://www.cybercom.net/~dcoffin/ 2. http://www.cybercom.net/~dcoffin/dcraw/index_eo.html - 3. http://gphoto.sourceforge.net/ - 4. http://www.cybercom.net/~dcoffin/dcraw/dcraw.c - 5. http://www.insflug.org/raw/ - 6. http://www.aim-dtp.net/aim/digicam/dcraw/ - 7. http://www.cybercom.net/~dcoffin/resume.html - 8. http://www.outbackphoto.com/artofraw/raw_07/essay.html - 9. http://news.com.com/Nikons+photo+encryption+reported+broken/2100-1030_3-5679848.html - 10. http://www.dpreview.com/news/0504/05042701davecoffininterview.asp - 11. http://www.schnebeck.de/interview-with-dave-coffin-creator-of-dcraw - 12. http://www.ladinamo.org/english/raw-format-the-captive-photo.php - 13. http://www.cybercom.net/~dcoffin/dcraw/dcraw.c - 14. http://www.cybercom.net/~dcoffin/dcraw/dcraw.1.html - 15. http://www.cybercom.net/~dcoffin/dcraw/rawphoto.c - 16. http://ufraw.sourceforge.net/ - 17. http://pages.quicksilver.net.nz/pepe/ - 18. http://www.cybercom.net/~dcoffin/dcraw/.badpixels - 19. http://www.cybercom.net/~dcoffin/dcraw/RCS/dcraw.c,v - 20. http://www.cs.purdue.edu/homes/trinkle/RCS/ - 21. http://www.cybercom.net/~dcoffin/dcraw/parse.c - 22. http://www.cybercom.net/~dcoffin/dcraw/clean_crw.c - 23. http://www.cybercom.net/~dcoffin/dcraw/fujiturn.c - 24. http://www.cybercom.net/~dcoffin/dcraw/fuji_green.c - 25. http://www.cybercom.net/~dcoffin/dcraw/decompress.c - 26. http://www.cybercom.net/~dcoffin/dcraw/sony_clear.c - 27. http://www.cybercom.net/~dcoffin/dcraw/archive/ - 28. http://www.cybercom.net/~dcoffin/dcraw/dcraw.1 - 29. http://www.cybercom.net/~dcoffin/dcraw/dcraw_eo.po - 30. http://www.acdsystems.com/ - 31. http://www.adobe.com/products/photoshop/cameraraw.html - 32. http://www.br-software.com/ - 33. http://www.breezesys.com/ - 34. http://www.conceiva.com/ - 35. http://cpicture.net/en/t_raw.html - 36. http://www.canto.com/ - 37. http://frostyplace.com/dcraw/ - 38. http://www.tanis.dk/wiki/index.php/DCRawUI - 39. http://www.pretentiousname.com/jp2raw/ - 40. http://deepskystacker.free.fr/ - 41. http://www.dpmagic.com/ - 42. http://www.easyraw.com/ - 43. http://www.lemkesoft.com/ - 44. http://jcoconsulting.com/index.asp?Section=GVOCX - 45. http://www.aragonsystem.com/ - 46. http://www.irfanview.com/ - 47. http://www.astrosurf.com/buil/us/iris/iris.htm - 48. http://www.kaorg.com/photoservice.asp - 49. http://www.lightboxsoftware.com/ - 50. http://sonic.net/~rat/lightcrafts/ - 51. http://www.mixpo.com/ - 52. http://www.wildcape.com/ - 53. http://photojockey.com/ - 54. http://smatters.com/dcraw/ - 55. http://www.k-i-s.net/ - 56. http://www.sticksoftware.com/software/PhotoReviewer.html - 57. http://www.photovault.org/ - 58. http://www.picasa.com/ - 59. http://www.picturearena.com/ - 60. http://pleiades-astrophoto.com/ - 61. http://www.pixpo.com/ - 62. http://www.polybytes.com/ - 63. http://lens.liteserv.com/download/powershovel2.php - 64. http://www.iridientdigital.com/ - 65. http://www.rawmagick.com/ - 66. http://www.i-graph.com/ - 67. http://www.wizards.de/rawdrop - 68. http://www.pixmantec.com/ - 69. http://www.through-the-lens.net/ - 70. http://www.serif.com/ - 71. http://www.logicaldesigns.com/ - 72. http://www.silverfast.com/ - 73. http://www.studioline.net/ - 74. http://www.hexcat.com/viewit/ - 75. http://www.dimin.net/software/viewer/ - 76. http://www.hamrick.com/ - 77. http://www.insflug.org/raw/ - 78. http://www.lebsanft.org/blog/index.php?cat=9 - 79. http://www.delorie.com/djgpp/ - 80. http://www.trnicely.net/misc/vista.html - 81. http://www.sno.phy.queensu.ca/~phil/exiftool/ - 82. http://www.cybercom.net/~dcoffin/dcraw/scan.c - 83. http://www.cybercom.net/~dcoffin/dcraw/read_ndf.c - 84. http://partners.adobe.com/asn/developer/PDFS/TN/TIFF6.pdf - 85. http://www.map.tu.chiba-u.ac.jp/IEC/100/TA2/recdoc/N4378.pdf - 86. http://www.adobe.com/products/dng/pdfs/dng_spec.pdf - 87. http://xyrion.org/ciff/ - 88. http://www.x3f.info/technotes/FileDocs/X3F_Format.pdf - 89. http://raw.fotosite.pl/ - 90. http://dl.maptools.org/dl/libtiff/tiff-3.8.2.tar.gz - 91. http://www.cybercom.net/~dcoffin/dcraw/libtiff.patch - 92. http://www.cybercom.net/~dcoffin/dcraw/elphel_dng.c - 93. http://www.adobe.com/products/dng/main.html - 94. http://www.adobe.com/products/photoshop/main.html - 95. http://cinepaint.sourceforge.net/ - 96. http://www.cybercom.net/~dcoffin/dcraw/ahd_maze.png - 97. http://www.cybercom.net/~dcoffin/dcraw/vng_grid.png - 98. http://netpbm.sourceforge.net/ - 99. http://www.imagemagick.org/ - 100. http://www.faqs.org/docs/artu/multiprogramchapter.html - 101. http://www.dpreview.com/news/0202/02021101foveonx3.asp - 102. http://digicanon.narod.ru/ - 103. http://e2500.narod.ru/raw_format_e.htm - 104. http://www.inweb.ch/foto/rawformat.html - 105. http://forums.dpreview.com/forums/read.asp?forum=1015&message=4961779 - 106. http://myfototest.narod.ru/ - 107. http://forums.dpreview.com/forums/read.asp?forum=1024&message=11773287 - 108. http://tester13.nm.ru/nikon/ - 109. http://www.camerahacking.com/ - 110. http://dropload.com/ - 111. http://yousendit.com/ - 112. http://www.planet-interkom.de/oliver.hartmann/dc20secr.htm - 113. http://www.itojun.org/diary/19961113/index.eng.html - 114. http://kdc2tiff.sourceforge.net/ + 3. http://www.cybercom.net/~dcoffin/dcraw/index_pt.html + 4. http://www.cybercom.net/~dcoffin/dcraw/index_ru.html + 5. http://gphoto.sourceforge.net/ + 6. http://www.cybercom.net/~dcoffin/dcraw/dcraw.c + 7. http://www.insflug.org/raw/ + 8. http://www.aim-dtp.net/aim/digicam/dcraw/ + 9. http://www.cybercom.net/~dcoffin/resume.html + 10. http://www.outbackphoto.com/artofraw/raw_07/essay.html + 11. http://news.com.com/Nikons+photo+encryption+reported+broken/2100-1030_3-5679848.html + 12. http://www.dpreview.com/news/0504/05042701davecoffininterview.asp + 13. http://www.schnebeck.de/interview-with-dave-coffin-creator-of-dcraw + 14. http://www.ladinamo.org/english/raw-format-the-captive-photo.php + 15. http://www.cybercom.net/~dcoffin/dcraw/dcraw.c + 16. http://www.cybercom.net/~dcoffin/dcraw/#faq + 17. http://www.cybercom.net/~dcoffin/dcraw/dcraw.1.html + 18. http://www.cybercom.net/~dcoffin/dcraw/rawphoto.c + 19. http://ufraw.sourceforge.net/ + 20. http://pages.quicksilver.net.nz/pepe/ + 21. http://www.cybercom.net/~dcoffin/dcraw/.badpixels + 22. http://www.cybercom.net/~dcoffin/dcraw/RCS/dcraw.c,v + 23. http://www.cs.purdue.edu/homes/trinkle/RCS/ + 24. http://www.cybercom.net/~dcoffin/dcraw/parse.c + 25. http://www.cybercom.net/~dcoffin/dcraw/clean_crw.c + 26. http://www.cybercom.net/~dcoffin/dcraw/fujiturn.c + 27. http://www.cybercom.net/~dcoffin/dcraw/fuji_green.c + 28. http://www.cybercom.net/~dcoffin/dcraw/decompress.c + 29. http://www.cybercom.net/~dcoffin/dcraw/sony_clear.c + 30. http://www.cybercom.net/~dcoffin/dcraw/archive/ + 31. http://www.cybercom.net/~dcoffin/dcraw/dcraw_eo.1.html + 32. http://www.cybercom.net/~dcoffin/dcraw/dcraw_ru.1.html + 33. http://www.cybercom.net/~dcoffin/dcraw/dcraw_fr.1.html + 34. http://www.cybercom.net/~dcoffin/dcraw/dcraw_it.1.html + 35. http://www.cybercom.net/~dcoffin/dcraw/dcraw_de.1.html + 36. http://www.cybercom.net/~dcoffin/dcraw/dcraw_pt.1.html + 37. http://www.cybercom.net/~dcoffin/dcraw/dcraw_es.1.html + 38. http://www.cybercom.net/~dcoffin/dcraw/dcraw_nl.1.html + 39. http://www.cybercom.net/~dcoffin/dcraw/dcraw_pl.1.html + 40. http://www.cybercom.net/~dcoffin/dcraw/dcraw_hu.1.html + 41. http://www.cybercom.net/~dcoffin/dcraw/dcraw_zh_TW.1.html + 42. http://www.cybercom.net/~dcoffin/dcraw/dcraw_zh_CN.1.html + 43. http://www.cybercom.net/~dcoffin/dcraw/dcraw.1 + 44. http://www.cybercom.net/~dcoffin/dcraw/dcraw_eo.po + 45. http://www.acdsystems.com/ + 46. http://www.adobe.com/products/photoshop/cameraraw.html + 47. http://www.br-software.com/ + 48. http://www.breezesys.com/ + 49. http://www.conceiva.com/ + 50. http://cpicture.net/en/t_raw.html + 51. http://www.canto.com/ + 52. http://frostyplace.com/dcraw/ + 53. http://www.tanis.dk/wiki/index.php/DCRawUI + 54. http://www.pretentiousname.com/jp2raw/ + 55. http://deepskystacker.free.fr/ + 56. http://www.dpmagic.com/ + 57. http://www.easyraw.com/ + 58. http://www.lemkesoft.com/ + 59. http://jcoconsulting.com/index.asp?Section=GVOCX + 60. http://www.aragonsystem.com/ + 61. http://www.irfanview.com/ + 62. http://www.astrosurf.com/buil/us/iris/iris.htm + 63. http://www.kaorg.com/photoservice.asp + 64. http://www.lightboxsoftware.com/ + 65. http://sonic.net/~rat/lightcrafts/ + 66. http://www.mediarecover.com/ + 67. http://www.mixpo.com/ + 68. http://www.wildcape.com/ + 69. http://photojockey.com/ + 70. http://smatters.com/dcraw/ + 71. http://www.k-i-s.net/ + 72. http://www.datarescue.com/photorescue/ + 73. http://www.sticksoftware.com/software/PhotoReviewer.html + 74. http://www.photovault.org/ + 75. http://www.picasa.com/ + 76. http://www.picturearena.com/ + 77. http://pleiades-astrophoto.com/ + 78. http://www.pixpo.com/ + 79. http://www.polybytes.com/ + 80. http://lens.liteserv.com/download/powershovel2.php + 81. http://www.iridientdigital.com/ + 82. http://www.rawmagick.com/ + 83. http://www.i-graph.com/ + 84. http://www.wizards.de/rawdrop + 85. http://www.pixmantec.com/ + 86. http://www.through-the-lens.net/ + 87. http://www.serif.com/ + 88. http://www.logicaldesigns.com/ + 89. http://www.silverfast.com/ + 90. http://www.studioline.net/ + 91. http://www.hexcat.com/viewit/ + 92. http://www.dimin.net/software/viewer/ + 93. http://www.hamrick.com/ + 94. http://www.xara.com/products/xtreme/ + 95. http://www.insflug.org/raw/ + 96. http://www.lebsanft.org/blog/index.php?cat=9 + 97. http://aminet.net/search?query=dcraw + 98. http://amis.flatrate.ru/dcraw/ + 99. http://www.pidcock.co.uk/beos/index.html + 100. http://hobbes.nmsu.edu/cgi-bin/h-search?key=dcraw + 101. http://www.riscos.info/unix/indexes/graphics.html + 102. http://www.delorie.com/djgpp/ + 103. http://www.trnicely.net/misc/vista.html + 104. http://www.sno.phy.queensu.ca/~phil/exiftool/ + 105. http://www.cybercom.net/~dcoffin/dcraw/scan.c + 106. http://www.cybercom.net/~dcoffin/dcraw/read_ndf.c + 107. http://partners.adobe.com/asn/developer/PDFS/TN/TIFF6.pdf + 108. http://www.map.tu.chiba-u.ac.jp/IEC/100/TA2/recdoc/N4378.pdf + 109. http://www.adobe.com/products/dng/pdfs/dng_spec.pdf + 110. http://xyrion.org/ciff/ + 111. http://www.x3f.info/technotes/FileDocs/X3F_Format.pdf + 112. http://raw.fotosite.pl/ + 113. http://www.rawsamples.ch/ + 114. http://www.glasslantern.com/RAWpository/ + 115. http://dl.maptools.org/dl/libtiff/tiff-3.8.2.tar.gz + 116. http://www.cybercom.net/~dcoffin/dcraw/libtiff.patch + 117. http://www.cybercom.net/~dcoffin/dcraw/elphel_dng.c + 118. http://www.adobe.com/products/dng/main.html + 119. http://www.adobe.com/products/photoshop/main.html + 120. http://cinepaint.sourceforge.net/ + 121. http://www.cybercom.net/~dcoffin/dcraw/ahd_maze.png + 122. http://www.cybercom.net/~dcoffin/dcraw/vng_grid.png + 123. http://netpbm.sourceforge.net/ + 124. http://www.imagemagick.org/ + 125. http://www.faqs.org/docs/artu/multiprogramchapter.html + 126. http://www.dpreview.com/news/0202/02021101foveonx3.asp + 127. http://digicanon.narod.ru/ + 128. http://e2500.narod.ru/raw_format_e.htm + 129. http://www.inweb.ch/foto/rawformat.html + 130. http://forums.dpreview.com/forums/read.asp?forum=1015&message=4961779 + 131. http://myfototest.narod.ru/ + 132. http://forums.dpreview.com/forums/read.asp?forum=1024&message=11773287 + 133. http://tester13.nm.ru/nikon/ + 134. http://www.camerahacking.com/ + 135. http://dropload.com/ + 136. http://yousendit.com/ + 137. http://www.planet-interkom.de/oliver.hartmann/dc20secr.htm + 138. http://www.itojun.org/diary/19961113/index.eng.html + 139. http://kdc2tiff.sourceforge.net/ diff --git a/dcraw.1 b/dcraw.1 index 02c22a7..a95c466 100644 --- a/dcraw.1 +++ b/dcraw.1 @@ -9,7 +9,7 @@ .\" dcoffin a cybercom o net .\" http://www.cybercom.net/~dcoffin .\" -.TH dcraw 1 "May 3, 2007" +.TH dcraw 1 "July 23, 2007" .LO 1 .SH NAME dcraw - command-line decoder for raw digital photos @@ -64,9 +64,12 @@ Output a half-size color image. Twice as fast as .B -q 0 Use high-speed, low-quality bilinear interpolation. .TP -.B -q 2 +.B -q 1 Use Variable Number of Gradients (VNG) interpolation. .TP +.B -q 2 +Use Patterned Pixel Grouping (PPG) interpolation. +.TP .B -q 3 Use Adaptive Homogeneity-Directed (AHD) interpolation. .TP @@ -126,6 +129,21 @@ no white balance option Use a fixed white balance based on a color chart illuminated with a standard D65 lamp. .TP +.BR +M " or " -M +Use (or don't use) any color matrix from the camera metadata. +The default is +.B +M +if +.B -w +is set, +.B -M +otherwise. +This option only affects Olympus, Leaf, and Phase One cameras. +.TP +.B -C red_mag blue_mag +Enlarge the raw red and blue layers by the given factors, +typically 0.999 to 1.001, to correct chromatic aberration. +.TP .B -H 0 Clip all highlights to solid white (default). .TP @@ -186,8 +204,8 @@ applies the flip specified by the camera. .B -t 0 disables all flipping. .TP -.B -s [0-99] -Select which raw image to decode if the file contains more than one. +.BR "-s [0..N-1]" " or " "-s all" +If a file contains N raw images, choose one or "all" to decode. For example, Fuji\ Super\ CCD\ SR cameras generate a second image underexposed four stops to show detail in the highlights. .TP @@ -196,13 +214,6 @@ For Fuji\ Super\ CCD cameras, show the image tilted 45 degrees. For cameras with non-square pixels, do not stretch the image to its correct aspect ratio. In any case, this option guarantees that each output pixel corresponds to one raw pixel. -.TP -.B "" -If they don't apply to your camera, -.B -s -and -.B -j -are silently ignored. .SH FILES .TP \:./.badpixels, ../.badpixels, ../../.badpixels, ... diff --git a/dcraw.c b/dcraw.c index 8e6066c..3de7c98 100644 --- a/dcraw.c +++ b/dcraw.c @@ -18,11 +18,11 @@ *If you have not modified dcraw.c in any way, a link to my homepage qualifies as "full source code". - $Revision: 1.379 $ - $Date: 2007/05/03 06:15:16 $ + $Revision: 1.390 $ + $Date: 2007/08/01 17:39:28 $ */ -#define VERSION "8.71" +#define VERSION "8.77" #define _GNU_SOURCE #define _USE_MATH_DEFINES @@ -55,6 +55,7 @@ #endif #ifndef DJGPP #define fgetc getc_unlocked +#define fseek fseeko #endif #ifdef __CYGWIN__ #include @@ -95,28 +96,30 @@ typedef unsigned short ushort; */ FILE *ifp; short order; -char *ifname, make[64], model[64], model2[64], *meta_data, cdesc[5]; +char *ifname, *meta_data; +char cdesc[5], desc[512], make[64], model[64], model2[64], artist[64]; float flash_used, canon_ev, iso_speed, shutter, aperture, focal_len; time_t timestamp; unsigned shot_order, kodak_cbpp, filters, exif_cfa, unique_id; -unsigned profile_offset, profile_length, *oprof; -unsigned thumb_offset, thumb_length, thumb_misc; -unsigned data_offset, strip_offset, curve_offset, meta_offset, meta_length; -unsigned tiff_nifds, tiff_samples, tiff_bps, tiff_compress, tile_length; +off_t strip_offset, data_offset, curve_offset; +off_t thumb_offset, meta_offset, profile_offset; +unsigned thumb_length, meta_length, profile_length; +unsigned thumb_misc, *oprof, fuji_layout, shot_select=0, multi_out=0; +unsigned tiff_nifds, tiff_samples, tiff_bps, tiff_compress; unsigned black, maximum, mix_green, raw_color, use_gamma, zero_is_bad; unsigned zero_after_ff, is_raw, dng_version, is_foveon, data_error; +unsigned tile_width, tile_length; ushort raw_height, raw_width, height, width, top_margin, left_margin; ushort shrink, iheight, iwidth, fuji_width, thumb_width, thumb_height; int flip, tiff_flip, colors; -double pixel_aspect; +double pixel_aspect, aber[4]={1,1,1,1}; ushort (*image)[4], white[8][8], curve[0x1000], cr2_slice[3]; float bright=1, user_mul[4]={0,0,0,0}, threshold=0; int half_size=0, four_color_rgb=0, document_mode=0, highlight=0; -int verbose=0, use_auto_wb=0, use_camera_wb=0; +int verbose=0, use_auto_wb=0, use_camera_wb=0, use_camera_matrix=-1; int output_color=1, output_bps=8, output_tiff=0; -int fuji_layout, fuji_secondary, shot_select=0; unsigned greybox[4] = { 0, 0, UINT_MAX, UINT_MAX }; -float cam_mul[4], pre_mul[4], rgb_cam[3][4]; /* RGB from camera color */ +float cam_mul[4], pre_mul[4], cmatrix[3][4], rgb_cam[3][4]; const double xyz_rgb[3][3] = { /* XYZ from RGB */ { 0.412453, 0.357580, 0.180423 }, { 0.212671, 0.715160, 0.072169 }, @@ -418,7 +421,7 @@ void CLASS canon_600_auto_wb() for (i=0; i < 8; i++) total[st][i] += test[i]; count[st]++; -next: continue; +next: ; } if (count[0] | count[1]) { st = count[0]*200 < count[1]; @@ -481,8 +484,8 @@ void CLASS canon_600_load_raw() black = black / ((raw_width - width) * height) - 4; for (row=0; row < height; row++) for (col=0; col < width; col++) { - val = (BAYER(row,col) - black) * mul[row & 3][col & 1] >> 9; - if (val < 0) val = 0; + if ((val = BAYER(row,col) - black) < 0) val = 0; + val = val * mul[row & 3][col & 1] >> 9; BAYER(row,col) = val; } canon_600_fixed_wb(1311); @@ -790,7 +793,7 @@ void CLASS canon_compressed_load_raw() enough to decode Canon, Kodak and Adobe DNG images. */ struct jhead { - int bits, high, wide, clrs, restart, vpred[4]; + int bits, high, wide, clrs, psv, restart, vpred[4]; struct decode *huff[4]; ushort *row; }; @@ -820,6 +823,7 @@ int CLASS ljpeg_start (struct jhead *jh, int info_only) jh->high = data[1] << 8 | data[2]; jh->wide = data[3] << 8 | data[4]; jh->clrs = data[5]; + if (len == 9 && !dng_version) getc(ifp); break; case 0xffc4: if (info_only) break; @@ -828,13 +832,16 @@ int CLASS ljpeg_start (struct jhead *jh, int info_only) dp = make_decoder (++dp, 0); } break; + case 0xffda: + jh->psv = data[1+data[0]*2]; + break; case 0xffdd: jh->restart = data[0] << 8 | data[1]; } } while (tag != 0xffda); if (info_only) return 1; - jh->row = (ushort *) calloc (jh->wide*jh->clrs, 2); - merror (jh->row, " jpeg_start()"); + jh->row = (ushort *) calloc (jh->wide*jh->clrs, 4); + merror (jh->row, "ljpeg_start()"); return zero_after_ff = 1; } @@ -853,10 +860,10 @@ int CLASS ljpeg_diff (struct decode *dindex) return diff; } -void CLASS ljpeg_row (int jrow, struct jhead *jh) +ushort * CLASS ljpeg_row (int jrow, struct jhead *jh) { - int col, c, diff; - ushort mark=0, *outp=jh->row; + int col, c, diff, pred; + ushort mark=0, *row[3]; if (jrow * jh->wide % jh->restart == 0) { FORC4 jh->vpred[c] = 1 << (jh->bits-1); @@ -865,13 +872,26 @@ void CLASS ljpeg_row (int jrow, struct jhead *jh) while (c != EOF && mark >> 4 != 0xffd); getbits(-1); } + FORC3 row[c] = jh->row + jh->wide*jh->clrs*((jrow+c) & 1); for (col=0; col < jh->wide; col++) for (c=0; c < jh->clrs; c++) { diff = ljpeg_diff (jh->huff[c]); - *outp = diff = col ? outp[-jh->clrs]+diff : (jh->vpred[c] += diff); - if (diff >> jh->bits) derror(); - outp++; + if (!col) pred = (jh->vpred[c] += diff) - diff; + else pred = row[0][-jh->clrs]; + if (jrow && col) switch (jh->psv) { + case 1: break; + case 2: pred = row[1][0]; break; + case 3: pred = row[1][-jh->clrs]; break; + case 4: pred = pred + row[1][0] - row[1][-jh->clrs]; break; + case 5: pred = pred + ((row[1][0] - row[1][-jh->clrs]) >> 1); break; + case 6: pred = row[1][0] + ((pred - row[1][-jh->clrs]) >> 1); break; + case 7: pred = (pred + row[1][0]) >> 1; break; + default: pred = 0; + } + if ((**row = pred + diff) >> jh->bits) derror(); + row[0]++; row[1]++; } + return row[2]; } void CLASS lossless_jpeg_load_raw() @@ -879,14 +899,15 @@ void CLASS lossless_jpeg_load_raw() int jwide, jrow, jcol, val, jidx, i, j, row=0, col=0; struct jhead jh; int min=INT_MAX; + ushort *rp; if (!ljpeg_start (&jh, 0)) return; jwide = jh.wide * jh.clrs; for (jrow=0; jrow < jh.high; jrow++) { - ljpeg_row (jrow, &jh); + rp = ljpeg_row (jrow, &jh); for (jcol=0; jcol < jwide; jcol++) { - val = jh.row[jcol]; + val = *rp++; if (jh.bits <= 12) val = curve[val]; if (cr2_slice[0]) { @@ -923,7 +944,7 @@ void CLASS adobe_copy_pixel (int row, int col, ushort **rp) r = row -= top_margin; c = col -= left_margin; - if (fuji_secondary && shot_select) (*rp)++; + if (is_raw == 2 && shot_select) (*rp)++; if (filters) { if (fuji_width) { r = row + fuji_width - 1 - (col >> 1); @@ -931,47 +952,41 @@ void CLASS adobe_copy_pixel (int row, int col, ushort **rp) } if (r < height && c < width) BAYER(r,c) = **rp < 0x1000 ? curve[**rp] : **rp; - *rp += 1 + fuji_secondary; + *rp += is_raw; } else { if (r < height && c < width) for (c=0; c < tiff_samples; c++) image[row*width+col][c] = (*rp)[c] < 0x1000 ? curve[(*rp)[c]]:(*rp)[c]; *rp += tiff_samples; } - if (fuji_secondary && shot_select) (*rp)--; + if (is_raw == 2 && shot_select) (*rp)--; } void CLASS adobe_dng_load_raw_lj() { - int save, twide, trow=0, tcol=0, jrow, jcol; + unsigned save, trow=0, tcol=0, jwide, jrow, jcol, row, col; struct jhead jh; ushort *rp; - while (1) { + while (trow < raw_height) { save = ftell(ifp); if (tile_length < INT_MAX) fseek (ifp, get4(), SEEK_SET); if (!ljpeg_start (&jh, 0)) break; - if (trow >= raw_height) break; - if (jh.high > raw_height-trow) - jh.high = raw_height-trow; - twide = jh.wide; - if (filters) twide *= jh.clrs; - else colors = jh.clrs; - if (fuji_secondary) twide /= 2; - if (twide > raw_width-tcol) - twide = raw_width-tcol; - - for (jrow=0; jrow < jh.high; jrow++) { - ljpeg_row (jrow, &jh); - for (rp=jh.row, jcol=0; jcol < twide; jcol++) - adobe_copy_pixel (trow+jrow, tcol+jcol, &rp); + jwide = jh.wide; + if (filters) jwide *= jh.clrs; + jwide /= is_raw; + for (row=col=jrow=0; jrow < jh.high; jrow++) { + rp = ljpeg_row (jrow, &jh); + for (jcol=0; jcol < jwide; jcol++) { + adobe_copy_pixel (trow+row, tcol+col, &rp); + if (++col >= tile_width || col >= raw_width) + row += 1 + (col = 0); + } } fseek (ifp, save+4, SEEK_SET); - if ((tcol += twide) >= raw_width) { - tcol = 0; - trow += jh.high; - } + if ((tcol += tile_width) >= raw_width) + trow += tile_length + (tcol = 0); free (jh.row); } } @@ -1529,14 +1544,15 @@ unsigned CLASS ph1_bits (int nbits) static UINT64 bitbuf=0; static int vbits=0; - if (nbits == 0) + if (nbits == -1) return bitbuf = vbits = 0; + if (nbits == 0) return 0; if (vbits < nbits) { bitbuf = bitbuf << 32 | get4(); vbits += 32; } vbits -= nbits; - return bitbuf << (64 - nbits - vbits) >> (64 - nbits); + return bitbuf << (64-nbits-vbits) >> (64-nbits); } void CLASS phase_one_load_raw_c() @@ -1560,7 +1576,7 @@ void CLASS phase_one_load_raw_c() curve[i] = i*i / 3.969 + 0.5; for (row=0; row < raw_height; row++) { fseek (ifp, data_offset + offset[row], SEEK_SET); - ph1_bits(0); + ph1_bits(-1); pred[0] = pred[1] = 0; for (col=0; col < raw_width; col++) { if (col >= (raw_width & -8)) @@ -1590,6 +1606,33 @@ void CLASS phase_one_load_raw_c() maximum = 0xfffc - ph1.black; } +void CLASS hasselblad_load_raw() +{ + struct jhead jh; + struct decode *dindex; + int row, col, pred[2], len[2], diff, i; + + if (!ljpeg_start (&jh, 0)) return; + free (jh.row); + ph1_bits(-1); + for (row=0; row < height; row++) { + pred[0] = pred[1] = 0x8000; + for (col=0; col < width; col+=2) { + for (i=0; i < 2; i++) { + for (dindex=jh.huff[0]; dindex->branch[0]; ) + dindex = dindex->branch[ph1_bits(1)]; + len[i] = dindex->leaf; + } + for (i=0; i < 2; i++) { + diff = ph1_bits(len[i]); + if ((diff & (1 << (len[i]-1))) == 0) + diff -= (1 << len[i]) - 1; + BAYER(row,col+i) = pred[i] += diff; + } + } + } +} + void CLASS leaf_hdr_load_raw() { ushort *pixel; @@ -1813,22 +1856,6 @@ void CLASS minolta_rd175_load_raw() maximum = 0xff << 1; } -void CLASS eight_bit_load_raw() -{ - uchar *pixel; - int row, col; - - pixel = (uchar *) calloc (raw_width, sizeof *pixel); - merror (pixel, "eight_bit_load_raw()"); - for (row=0; row < height; row++) { - if (fread (pixel, 1, raw_width, ifp) < raw_width) derror(); - for (col=0; col < width; col++) - BAYER(row,col) = pixel[col]; - } - free (pixel); - maximum = 0xff; -} - void CLASS casio_qv5700_load_raw() { uchar data[3232], *dp; @@ -2121,27 +2148,26 @@ void CLASS kodak_dc120_load_raw() maximum = 0xff; } -void CLASS kodak_easy_load_raw() +void CLASS eight_bit_load_raw() { uchar *pixel; - unsigned row, col, val; + unsigned row, col, val, lblack=0; - if (raw_width > width) - black = 0; pixel = (uchar *) calloc (raw_width, sizeof *pixel); - merror (pixel, "kodak_easy_load_raw()"); + merror (pixel, "eight_bit_load_raw()"); + fseek (ifp, top_margin*raw_width, SEEK_CUR); for (row=0; row < height; row++) { if (fread (pixel, 1, raw_width, ifp) < raw_width) derror(); for (col=0; col < raw_width; col++) { val = curve[pixel[col]]; if ((unsigned) (col-left_margin) < width) BAYER(row,col-left_margin) = val; - else black += val; + else lblack += val; } } free (pixel); - if (raw_width > width) - black /= (raw_width - width) * height; + if (raw_width > width+1) + black = lblack / ((raw_width - width) * height); if (!strncmp(model,"DC2",3)) black = 0; maximum = curve[0xff]; @@ -3498,10 +3524,11 @@ void CLASS wavelet_denoise() void CLASS scale_colors() { - unsigned bottom, right, row, col, x, y, c, sum[8]; + unsigned bottom, right, size, row, col, ur, uc, i, x, y, c, sum[8]; int val, dblack; double dsum[8], dmin, dmax; - float scale_mul[4]; + float scale_mul[4], fr, fc; + ushort *img=0, *pix; if (user_mul[0]) memcpy (pre_mul, user_mul, sizeof pre_mul); @@ -3527,8 +3554,7 @@ void CLASS scale_colors() if (filters) break; } for (c=0; c < 8; c++) dsum[c] += sum[c]; -skip_block: - continue; +skip_block: ; } FORC4 if (dsum[c]) pre_mul[c] = dsum[c+4] / dsum[c]; } @@ -3565,15 +3591,40 @@ skip_block: FORC4 fprintf (stderr, " %f", pre_mul[c]); fputc ('\n', stderr); } - for (row=0; row < iheight; row++) - for (col=0; col < iwidth; col++) - FORC4 { - val = image[row*iwidth+col][c]; - if (!val) continue; - val -= black; - val *= scale_mul[c]; - image[row*iwidth+col][c] = CLIP(val); + size = iheight*iwidth; + for (i=0; i < size*4; i++) { + val = image[0][i]; + if (!val) continue; + val -= black; + val *= scale_mul[i & 3]; + image[0][i] = CLIP(val); + } + if ((aber[0] != 1 || aber[2] != 1) && colors == 3) { + if (verbose) + fprintf (stderr,_("Correcting chromatic aberration...\n")); + for (c=0; c < 4; c+=2) { + if (aber[c] == 1) continue; + img = (ushort *) malloc (size * sizeof *img); + merror (img, "scale_colors()"); + for (i=0; i < size; i++) + img[i] = image[i][c]; + for (row=0; row < iheight; row++) { + ur = fr = (row - iheight*0.5) * aber[c] + iheight*0.5; + if (ur > iheight-2) continue; + fr -= ur; + for (col=0; col < iwidth; col++) { + uc = fc = (col - iwidth*0.5) * aber[c] + iwidth*0.5; + if (uc > iwidth-2) continue; + fc -= uc; + pix = img + ur*iwidth + uc; + image[row*iwidth+col][c] = + (pix[ 0]*(1-fc) + pix[ 1]*fc) * (1-fr) + + (pix[iwidth]*(1-fc) + pix[iwidth+1]*fc) * fr; + } } + free(img); + } + } } void CLASS pre_interpolate() @@ -3585,7 +3636,6 @@ void CLASS pre_interpolate() if (half_size) { height = iheight; width = iwidth; - filters = 0; } else { img = (ushort (*)[4]) calloc (height*width, sizeof *img); merror (img, "unshrink()"); @@ -3608,6 +3658,7 @@ void CLASS pre_interpolate() filters &= ~((filters & 0x55555555) << 1); } } + if (half_size) filters = 0; } void CLASS border_interpolate (int border) @@ -3809,6 +3860,76 @@ void CLASS vng_interpolate() free (code[0][0]); } +/* + Patterned Pixel Grouping Interpolation by Alain Desbiolles +*/ +void CLASS ppg_interpolate() +{ + int gr[4], dir[5] = { 1, width, -1, -width, 1 }; + int row, col, avg, diff[2], guess[2], c, d, i; + static const short sort[] = { 0,2,1,3,0,1,2,3 }; + ushort (*pix)[4]; + + border_interpolate(3); + if (verbose) fprintf (stderr,_("PPG interpolation...\n")); + +/* Fill in the green layer with gradients and pattern recognition: */ + for (row=3; row < height-3; row++) + for (col=3+(FC(row,3) & 1), c=FC(row,col); col < width-3; col+=2) { + pix = image + row*width+col; + for (avg=i=0; i < 4; i++) + avg += gr[i] = pix[dir[i]][1] << 2; + avg >>= 2; + for (i=0; i < 8; i+=2) + if (gr[sort[i]] > gr[sort[i+1]]) + SWAP(gr[sort[i]],gr[sort[i+1]]) + for (d=0; d < 4; d++) { + for (i=-2; i < 2; i++) + if (pix[i*dir[d] + (i+1)*dir[d+1]][1] <= avg) break; + if (i == 2) { + pix[0][1] = (gr[1]+gr[2]) >> 3; + goto next_pixel; + } + } + for (i=0; (d=dir[i]) > 0; i++) { + guess[i] = (pix[-d][1] + pix[0][c] + pix[d][1]) * 2 + - pix[-2*d][c] - pix[2*d][c]; + diff[i] = ( ABS(pix[-2*d][c] - pix[ 0][c]) + + ABS(pix[ 2*d][c] - pix[ 0][c]) + + ABS(pix[ -d][1] - pix[ d][1]) ) * 3 + + ( ABS(pix[ 3*d][1] - pix[ d][1]) + + ABS(pix[-3*d][1] - pix[-d][1]) ) * 2; + } + d = dir[i = diff[0] > diff[1]]; + pix[0][1] = ULIM(guess[i] >> 2, pix[d][1], pix[-d][1]); +next_pixel: ; + } +/* Calculate red and blue for each green pixel: */ + for (row=1; row < height-1; row++) + for (col=1+(FC(row,2) & 1), c=FC(row,col+1); col < width-1; col+=2) { + pix = image + row*width+col; + for (i=0; (d=dir[i]) > 0; c=2-c, i++) + pix[0][c] = CLIP((pix[-d][c] + pix[d][c] + 2*pix[0][1] + - pix[-d][1] - pix[d][1]) >> 1); + } +/* Calculate blue for red pixels and vice versa: */ + for (row=1; row < height-1; row++) + for (col=1+(FC(row,1) & 1), c=2-FC(row,col); col < width-1; col+=2) { + pix = image + row*width+col; + for (i=0; (d=dir[i]+dir[i+1]) > 0; i++) { + diff[i] = ABS(pix[-d][c] - pix[d][c]) + + ABS(pix[-d][1] - pix[0][1]) + + ABS(pix[ d][1] - pix[0][1]); + guess[i] = pix[-d][c] + pix[d][c] + 2*pix[0][1] + - pix[-d][1] - pix[d][1]; + } + if (diff[0] != diff[1]) + pix[0][c] = CLIP(guess[diff[0] > diff[1]] >> 1); + else + pix[0][c] = CLIP((guess[0]+guess[1]) >> 2); + } +} + /* Adaptive Homogeneity-Directed interpolation is based on the work of Keigo Hirakawa, Thomas Parks, and Paul Lee. @@ -4117,7 +4238,7 @@ void CLASS parse_makernote (int base, int uptag) 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 } }; unsigned offset=0, entries, tag, type, len, save, c; - unsigned ver97=0, serial=0, i, wb[4]={0,0,0,0}; + unsigned ver97=0, serial=0, i, wbi=0, wb[4]={0,0,0,0}; uchar buf97[324], ci, cj, ck; short sorder; char buf[10]; @@ -4181,17 +4302,20 @@ void CLASS parse_makernote (int base, int uptag) aperture = pow (2, i/64.0); if ((i=get2()) != 0xffff) shutter = pow (2, (short) i/-32.0); - shot_order = (get4(),get2(),get2()); + wbi = (get2(),get2()); + shot_order = (get2(),get2()); } if (tag == 8 && type == 4) shot_order = get4(); + if (tag == 9 && !strcmp(make,"Canon")) + fread (artist, 64, 1, ifp); if (tag == 0xc && len == 4) { cam_mul[0] = getrat(); cam_mul[2] = getrat(); } if (tag == 0x10 && type == 4) unique_id = get4(); - if (tag == 0x11 && is_raw) { + if (tag == 0x11 && is_raw && !strncmp(make,"NIKON",5)) { fseek (ifp, get4()+base, SEEK_SET); parse_tiff_ifd (base); } @@ -4199,6 +4323,8 @@ void CLASS parse_makernote (int base, int uptag) fseek (ifp, 1248, SEEK_CUR); goto get2_256; } + if (tag == 0x15 && type == 2 && is_raw) + fread (model, 64, 1, ifp); if (strstr(make,"PENTAX")) { if (tag == 0x1b) tag = 0x1018; if (tag == 0x1c) tag = 0x1017; @@ -4247,6 +4373,10 @@ void CLASS parse_makernote (int base, int uptag) fread (buf97, 324, 1, ifp); } } + if (tag == 0xa4 && type == 3) { + fseek (ifp, wbi*48, SEEK_CUR); + FORC3 cam_mul[c] = get2(); + } if (tag == 0xa7 && ver97 >> 8 == 2) { ci = xlat[0][serial & 0xff]; cj = xlat[1][fgetc(ifp)^fgetc(ifp)^fgetc(ifp)^fgetc(ifp)]; @@ -4291,11 +4421,9 @@ void CLASS parse_makernote (int base, int uptag) else goto next; goto get2_256; } - if (((tag == 0x1011 && len == 9) || tag == 0x20400200) && use_camera_wb) { + if ((tag == 0x1011 && len == 9) || tag == 0x20400200) for (i=0; i < 3; i++) - FORC3 rgb_cam[i][c] = ((short) get2()) / 256.0; - raw_color = rgb_cam[0][0] < 1; - } + FORC3 cmatrix[i][c] = ((short) get2()) / 256.0; if ((tag == 0x1012 || tag == 0x20400600) && len == 4) for (black = i=0; i < 4; i++) black += get2() << 2; @@ -4340,7 +4468,6 @@ void CLASS get_timestamp (int reversed) char str[20]; int i; - if (timestamp) return; str[19] = 0; if (reversed) for (i=19; i--; ) str[i] = fgetc(ifp); @@ -4395,10 +4522,10 @@ void CLASS romm_coeff (float romm_cam[3][3]) { -0.008565, -0.153273, 1.161839 } }; int i, j, k; - for (raw_color = i=0; i < 3; i++) + for (i=0; i < 3; i++) for (j=0; j < 3; j++) - for (rgb_cam[i][j] = k=0; k < 3; k++) - rgb_cam[i][j] += rgb_romm[i][k] * romm_cam[k][j]; + for (cmatrix[i][j] = k=0; k < 3; k++) + cmatrix[i][j] += rgb_romm[i][k] * romm_cam[k][j]; } void CLASS parse_mos (int offset) @@ -4431,7 +4558,12 @@ void CLASS parse_mos (int offset) if ((unsigned) i < sizeof mod / sizeof (*mod)) strcpy (model, mod[i]); } - if (!strcmp(data,"CaptProf_color_matrix") && use_camera_wb) { + if (!strcmp(data,"icc_camera_to_tone_matrix")) { + for (i=0; i < 9; i++) + romm_cam[0][i] = int_to_float(get4()); + romm_coeff (romm_cam); + } + if (!strcmp(data,"CaptProf_color_matrix")) { for (i=0; i < 9; i++) fscanf (ifp, "%f", &romm_cam[0][i]); romm_coeff (romm_cam); @@ -4558,6 +4690,9 @@ int CLASS parse_tiff_ifd (int base) case 262: /* PhotometricInterpretation */ tiff_ifd[ifd].phint = get2(); break; + case 270: /* ImageDescription */ + fread (desc, 512, 1, ifp); + break; case 271: /* Make */ fgets (make, 64, ifp); break; @@ -4600,12 +4735,21 @@ int CLASS parse_tiff_ifd (int base) case 306: /* DateTime */ get_timestamp(0); break; + case 315: /* Artist */ + fread (artist, 64, 1, ifp); + break; + case 322: /* TileWidth */ + tile_width = getint(type); + break; case 323: /* TileLength */ tile_length = getint(type); break; case 324: /* TileOffsets */ tiff_ifd[ifd].offset = len > 1 ? ftell(ifp) : get4(); - if (len == 4) load_raw = &CLASS sinar_4shot_load_raw; + if (len == 4) { + load_raw = &CLASS sinar_4shot_load_raw; + is_raw = 5; + } break; case 330: /* SubIFDs */ if (!strcmp(model,"DSLR-A100") && tiff_ifd[ifd].width == 3872) { @@ -4710,6 +4854,11 @@ int CLASS parse_tiff_ifd (int base) width = raw_width - left_margin - (get4() & 7); top_margin = get4() & 7; height = raw_height - top_margin - (get4() & 7); + if (raw_width == 7262) { + height = 5444; + width = 7244; + left_margin = 7; + } fseek (ifp, 52, SEEK_CUR); FORC3 cam_mul[c] = getreal(11); fseek (ifp, 114, SEEK_CUR); @@ -4718,6 +4867,13 @@ int CLASS parse_tiff_ifd (int base) if (flip % 180 == 90) SWAP(width,height); filters = flip = 0; } + sprintf (model, "Ixpress %d-Mp", height*width/1000000); + load_raw = &CLASS imacon_full_load_raw; + if (filters) { + if (left_margin & 1) filters = 0x61616161; + load_raw = &CLASS unpacked_load_raw; + } + maximum = 0xffff; break; case 50454: /* Sinar tag */ case 50455: @@ -4728,6 +4884,17 @@ int CLASS parse_tiff_ifd (int base) sscanf (cp+8, "%f %f %f", cam_mul, cam_mul+1, cam_mul+2); free (cbuf); break; + case 50459: /* Hasselblad tag */ + i = order; + j = ftell(ifp); + c = tiff_nifds; + order = get2(); + fseek (ifp, j+(get2(),get4()), SEEK_SET); + parse_tiff_ifd (j); + maximum = 0xffff; + tiff_nifds = c; + order = i; + break; case 50706: /* DNGVersion */ FORC4 dng_version = (dng_version << 8) + fgetc(ifp); break; @@ -4880,7 +5047,6 @@ void CLASS parse_tiff (int base) data_offset = tiff_ifd[i].offset; tiff_flip = tiff_ifd[i].flip; tiff_samples = tiff_ifd[i].samples; - fuji_secondary = tiff_samples == 2; raw = i; } } @@ -4919,6 +5085,8 @@ void CLASS parse_tiff (int base) if (!dng_version && tiff_samples == 3) if (tiff_ifd[raw].bytes && tiff_bps != 14 && tiff_bps != 2048) is_raw = 0; + if (!dng_version && tiff_bps == 8 && tiff_compress == 1 && + tiff_ifd[raw].phint == 1) is_raw = 0; for (i=0; i < tiff_nifds; i++) if (i != raw && tiff_ifd[i].samples == max_samp && tiff_ifd[i].width * tiff_ifd[i].height / SQR(tiff_ifd[i].bps+1) > @@ -5077,6 +5245,8 @@ void CLASS parse_ciff (int offset, int length) if ((((type >> 8) + 8) | 8) == 0x38) parse_ciff (ftell(ifp), len); /* Parse a sub-table */ + if (type == 0x0810) + fread (artist, 64, 1, ifp); if (type == 0x080a) { fread (make, 64, 1, ifp); fseek (ifp, strlen(make) - 63, SEEK_CUR); @@ -5259,7 +5429,7 @@ void CLASS parse_phase_one (int base) romm_coeff (romm_cam); break; case 0x107: - FORC3 cam_mul[c] = pre_mul[c] = getreal(11); + FORC3 cam_mul[c] = getreal(11); break; case 0x108: raw_width = data; break; case 0x109: raw_height = data; break; @@ -5402,6 +5572,57 @@ void CLASS parse_smal (int offset, int fsize) if (ver == 9) load_raw = &CLASS smal_v9_load_raw; } +void CLASS parse_cine() +{ + unsigned off_head, off_setup, off_image, i; + + order = 0x4949; + fseek (ifp, 4, SEEK_SET); + is_raw = get2() == 2; + fseek (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); + 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); + strcpy (make, "CINE"); + sprintf (model, "%d", get4()); + fseek (ifp, 12, SEEK_CUR); + switch ((i=get4()) & 0xffffff) { + case 3: filters = 0x94949494; break; + case 4: filters = 0x49494949; break; + default: is_raw = 0; + } + fseek (ifp, 40, SEEK_CUR); + cam_mul[0] = 1/getreal(11); + cam_mul[2] = 1/getreal(11); + fseek (ifp, 24, SEEK_CUR); + switch ((get4()+3600) % 360) { + case 270: flip = 4; break; + case 180: flip = 1; break; + case 90: flip = 7; break; + case 0: flip = 2; + } + fseek (ifp, 8, SEEK_CUR); + maximum = ~(-1 << get4()); + fseek (ifp, 668, SEEK_CUR); + shutter = get4()/1000000000.0; + fseek (ifp, off_image, SEEK_SET); + if (shot_select < is_raw) + fseek (ifp, shot_select*8, SEEK_CUR); + data_offset = (INT64) get4() + 8; + data_offset += (INT64) get4() << 32; +} + char * CLASS foveon_gets (int offset, char *str, int len) { int i; @@ -5506,6 +5727,8 @@ void CLASS adobe_coeff (char *make, char *model) const char *prefix; short black, trans[12]; } table[] = { + { "Apple QuickTake", 0, /* DJC */ + { 17576,-3191,-3318,5210,6733,-1942,9031,1280,-124 } }, { "Canon EOS D2000", 0, { 24542,-10860,-3401,-1490,11370,-297,2858,-605,3225 } }, { "Canon EOS D6000", 0, @@ -5530,6 +5753,8 @@ void CLASS adobe_coeff (char *make, char *model) { 6517,-602,-867,-8180,15926,2378,-1618,1771,7633 } }, { "Canon EOS-1D Mark II N", 0, { 6240,-466,-822,-8180,15825,2500,-1801,1938,8042 } }, + { "Canon EOS-1D Mark III", 0, + { 6291,-540,-976,-8350,16145,2311,-1714,1858,7326 } }, { "Canon EOS-1D Mark II", 0, { 6264,-582,-724,-8312,15948,2504,-1744,1919,8664 } }, { "Canon EOS-1DS", 0, @@ -5574,8 +5799,16 @@ void CLASS adobe_coeff (char *make, char *model) { 15591,-6402,-1592,-5365,13198,2168,-1300,1824,5075 } }, { "Canon PowerShot A620", 0, /* DJC */ { 15265,-6193,-1558,-4125,12116,2010,-888,1639,5220 } }, + { "Canon PowerShot A640", 0, /* DJC */ + { 13124,-5329,-1390,-3602,11658,1944,-1612,2863,4885 } }, { "Canon PowerShot S3 IS", 0, /* DJC */ { 14062,-5199,-1446,-4712,12470,2243,-1286,2028,4836 } }, + { "CINE 650", 0, + { 3390,480,-500,-800,3610,340,-550,2336,1192 } }, + { "CINE 660", 0, + { 3390,480,-500,-800,3610,340,-550,2336,1192 } }, + { "CINE", 0, + { 20183,-4295,-423,-3940,15330,3985,-280,4870,9800 } }, { "Contax N Digital", 0, { 7777,1285,-1053,-9280,16543,2916,-3677,5679,7060 } }, { "EPSON R-D1", 0, @@ -5595,7 +5828,7 @@ void CLASS adobe_coeff (char *make, char *model) { "FUJIFILM FinePix S3Pro", 0, { 11807,-4612,-1294,-8927,16968,1988,-2120,2741,8006 } }, { "FUJIFILM FinePix S5Pro", 0, - { 11807,-4612,-1294,-8927,16968,1988,-2120,2741,8006 } }, + { 12300,-5110,-1304,-9117,17143,1998,-1947,2448,8100 } }, { "FUJIFILM FinePix S5000", 0, { 8754,-2732,-1019,-7204,15069,2276,-1702,2334,6982 } }, { "FUJIFILM FinePix S5100", 0, @@ -5708,6 +5941,8 @@ void CLASS adobe_coeff (char *make, char *model) { 5710,-901,-615,-8594,16617,2024,-2975,4120,6830 } }, { "NIKON D2X", 0, { 10231,-2769,-1255,-8301,15900,2552,-797,680,7148 } }, + { "NIKON D40X", 0, + { 8819,-2543,-911,-9025,16928,2151,-1329,1213,8449 } }, { "NIKON D40", 0, { 6992,-1668,-806,-8138,15748,2543,-874,850,7897 } }, { "NIKON D50", 0, @@ -5762,8 +5997,12 @@ void CLASS adobe_coeff (char *make, char *model) { 8961,-2473,-1084,-7979,15990,2067,-2319,3035,8249 } }, { "OLYMPUS E-400", 0, { 6169,-1483,-21,-7107,14761,2536,-2904,3580,8568 } }, + { "OLYMPUS E-410", 0, + { 8856,-2582,-1026,-7761,15766,2082,-2009,2575,7469 } }, { "OLYMPUS E-500", 0, { 8136,-1968,-299,-5481,13742,1871,-2556,4205,6630 } }, + { "OLYMPUS E-510", 0, + { 8856,-2582,-1026,-7761,15766,2082,-2009,2575,7469 } }, { "OLYMPUS SP350", 0, { 12078,-4836,-1069,-6671,14306,2578,-786,939,7418 } }, { "OLYMPUS SP3", 0, @@ -5772,6 +6011,8 @@ void CLASS adobe_coeff (char *make, char *model) { 9493,-3415,-666,-5211,12334,3260,-1548,2262,6482 } }, { "OLYMPUS SP510UZ", 0, { 10593,-3607,-1010,-5881,13127,3084,-1200,1805,6721 } }, + { "OLYMPUS SP550UZ", 0, + { 11597,-4006,-1049,-5432,12799,2957,-1029,1750,6516 } }, { "PENTAX *ist DL2", 0, { 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } }, { "PENTAX *ist DL", 0, @@ -5800,6 +6041,14 @@ void CLASS adobe_coeff (char *make, char *model) { 10704,-4187,-1230,-8314,15952,2501,-920,945,8927 } }, { "Panasonic DMC-LX2", 0, /* aka "LEICA D-LUX3" */ { 8048,-2810,-623,-6450,13519,3272,-1700,2146,7049 } }, + { "Phase One H 20", 0, /* DJC */ + { 1313,1855,-109,-6715,15908,808,-327,1840,6020 } }, + { "Phase One P 2", 0, + { 2905,732,-237,-8134,16626,1476,-3038,4253,7517 } }, + { "Phase One P 30", 0, + { 4516,-245,-37,-7020,14976,2173,-3206,4671,7087 } }, + { "Phase One P 45", 0, + { 5053,-24,-117,-5684,14076,1702,-2619,4492,5849 } }, { "SAMSUNG GX-1", 0, { 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } }, { "Sinar", 0, /* DJC */ @@ -5884,6 +6133,8 @@ void CLASS identify() { 62464, "Kodak", "DC20" ,0 }, { 124928, "Kodak", "DC20" ,0 }, { 1652736, "Kodak", "DCS200" ,0 }, + { 4159302, "Kodak", "C330" ,0 }, + { 4162462, "Kodak", "C330" ,0 }, { 311696, "ST Micro", "STV680 VGA" ,0 }, /* SPYz */ { 614400, "Kodak", "KAI-0340" ,0 }, { 787456, "Creative", "PC-CAM 600" ,0 }, @@ -5941,21 +6192,22 @@ void CLASS identify() tiff_flip = flip = filters = -1; /* 0 is valid, so -1 is unknown */ raw_height = raw_width = fuji_width = fuji_layout = cr2_slice[0] = 0; maximum = height = width = top_margin = left_margin = 0; - make[0] = model[0] = model2[0] = cdesc[0] = 0; + cdesc[0] = desc[0] = artist[0] = make[0] = model[0] = model2[0] = 0; iso_speed = shutter = aperture = focal_len = unique_id = 0; memset (white, 0, sizeof white); thumb_offset = thumb_length = thumb_width = thumb_height = 0; load_raw = thumb_load_raw = 0; write_thumb = &CLASS jpeg_thumb; data_offset = meta_length = tiff_bps = tiff_compress = 0; - kodak_cbpp = zero_after_ff = dng_version = fuji_secondary = 0; + kodak_cbpp = zero_after_ff = dng_version = 0; timestamp = shot_order = tiff_samples = black = is_foveon = 0; mix_green = profile_length = data_error = zero_is_bad = 0; pixel_aspect = is_raw = raw_color = use_gamma = 1; - tile_length = INT_MAX; + tile_width = tile_length = INT_MAX; for (i=0; i < 4; i++) { cam_mul[i] = i == 1; pre_mul[i] = i < 3; + FORC3 cmatrix[c][i] = 0; FORC3 rgb_cam[c][i] = c == i; } colors = 3; @@ -6011,8 +6263,8 @@ void CLASS identify() parse_fuji (get4()); if (thumb_offset > 120) { fseek (ifp, 120, SEEK_SET); - fuji_secondary = (i = get4()) && 1; - if (fuji_secondary && shot_select) + is_raw += (i = get4()) && 1; + if (is_raw == 2 && shot_select) parse_fuji (i); } fseek (ifp, 100, SEEK_SET); @@ -6029,6 +6281,8 @@ void CLASS identify() parse_minolta(0); else if (!memcmp (head,"FOVb",4)) parse_foveon(); + else if (!memcmp (head,"CI",2)) + parse_cine(); else for (i=0; i < sizeof table / sizeof *table; i++) if (fsize == table[i].fsize) { @@ -6054,7 +6308,7 @@ void CLASS identify() memmove (model, model+i, 64-i); if (!strncmp (model,"Digital Camera ",15)) strcpy (model, model+15); - make[63] = model[63] = model2[63] = 0; + desc[511] = artist[63] = make[63] = model[63] = model2[63] = 0; if (!is_raw) goto notraw; if (!maximum) maximum = (1 << tiff_bps) - 1; @@ -6071,8 +6325,8 @@ void CLASS identify() } if (dng_version) { if (filters == UINT_MAX) filters = 0; - if (!filters) - colors = tiff_samples; + if (filters) is_raw = tiff_samples; + else colors = tiff_samples; if (tiff_compress == 1) load_raw = &CLASS adobe_dng_load_raw_nc; if (tiff_compress == 7) @@ -6383,11 +6637,11 @@ cp_e2500: flip = 6; } else maximum = 0x3e00; - if (fuji_secondary && shot_select) + if (is_raw == 2 && shot_select) maximum = 0x2f00; top_margin = (raw_height - height)/2; left_margin = (raw_width - width )/2; - if (fuji_secondary) + if (is_raw == 2) data_offset += (shot_select > 0) * ( fuji_layout ? (raw_width *= 2) : raw_height*raw_width*2 ); fuji_width = width >> !fuji_layout; @@ -6557,14 +6811,9 @@ konica_400z: strcpy (make, "ISG"); model[0] = 0; } - } else if (!strcmp(make,"Imacon")) { - sprintf (model, "Ixpress %d-Mp", height*width/1000000); - load_raw = &CLASS imacon_full_load_raw; - if (filters) { - if (left_margin & 1) filters = 0x61616161; - load_raw = &CLASS unpacked_load_raw; - } - maximum = 0xffff; + } else if (!strcmp(make,"Hasselblad")) { + if (load_raw == lossless_jpeg_load_raw) + load_raw = hasselblad_load_raw; } else if (!strcmp(make,"Sinar")) { if (!memcmp(head,"8BPS",4)) { fseek (ifp, 14, SEEK_SET); @@ -6600,6 +6849,7 @@ konica_400z: filters = 0x16161616; } if (!cam_mul[0] || model[0] == 'V') filters = 0; + else is_raw = tiff_samples; } else if (width == 2116) { strcpy (model, "Valeo 6"); height -= 2 * (top_margin = 30); @@ -6614,66 +6864,62 @@ konica_400z: } else if (!strcmp(make,"LEICA") || !strcmp(make,"Panasonic")) { maximum = 0xfff0; load_raw = &CLASS unpacked_load_raw; - if (width == 2568) { - adobe_coeff ("Panasonic","DMC-LC1"); - } else if (width == 3130) { - left_margin = 4; - goto fz8_common; - } else if (width == 3170) { - height = 2326; - top_margin = 13; - left_margin = 18; - filters = 0x49494949; -fz8_common: - width = 3096; - load_raw = &CLASS olympus_e300_load_raw; - maximum = 0xf7f; - adobe_coeff ("Panasonic","DMC-FZ8"); - zero_is_bad = 1; - } else if (width == 3177) { - maximum = 0xf7fc; - width -= 10; - filters = 0x49494949; - adobe_coeff ("Panasonic","DMC-L1"); - zero_is_bad = 1; - } else if (width == 3304) { - maximum = 0xf94c; - width -= 16; - adobe_coeff ("Panasonic","DMC-FZ30"); - zero_is_bad = 1; - } else if (width == 3690) { - maximum = 0xf7f0; - height -= 3; - width = 3672; - left_margin = 3; - filters = 0x49494949; - adobe_coeff ("Panasonic","DMC-FZ50"); - zero_is_bad = 1; - } else if (width == 3770) { - height = 2760; - width = 3672; - top_margin = 15; - left_margin = 17; - adobe_coeff ("Panasonic","DMC-FZ50"); - zero_is_bad = 1; - } else if (width == 3880) { - maximum = 0xf7f0; - width -= 22; - left_margin = 6; - adobe_coeff ("Panasonic","DMC-LX1"); - zero_is_bad = 1; - } else if (width == 4290) { - height--; - width = 4248; - left_margin = 3; - filters = 0x49494949; - adobe_coeff ("Panasonic","DMC-LX2"); - } else if (width == 4330) { - height = 2400; - width = 4248; - top_margin = 15; - left_margin = 17; - adobe_coeff ("Panasonic","DMC-LX2"); + switch (width) { + case 2568: + adobe_coeff ("Panasonic","DMC-LC1"); break; + case 3130: + left_margin = -14; + case 3170: + left_margin += 18; + width = 3096; + if (height > 2326) { + height = 2326; + top_margin = 13; + filters = 0x49494949; + } + load_raw = &CLASS olympus_e300_load_raw; + maximum = 0xf7f; + zero_is_bad = 1; + adobe_coeff ("Panasonic","DMC-FZ8"); break; + case 3177: + width -= 10; + filters = 0x49494949; + maximum = 0xf7fc; + zero_is_bad = 1; + adobe_coeff ("Panasonic","DMC-L1"); break; + case 3304: + width -= 16; + maximum = 0xf94c; + zero_is_bad = 1; + adobe_coeff ("Panasonic","DMC-FZ30"); break; + case 3690: + height += 36; + left_margin = -14; + filters = 0x49494949; + maximum = 0xf7f0; + case 3770: + width = 3672; + if ((height -= 39) == 2760) + top_margin = 15; + left_margin += 17; + zero_is_bad = 1; + adobe_coeff ("Panasonic","DMC-FZ50"); break; + case 3880: + width -= 22; + left_margin = 6; + maximum = 0xf7f0; + zero_is_bad = 1; + adobe_coeff ("Panasonic","DMC-LX1"); break; + case 4290: + height += 38; + left_margin = -14; + filters = 0x49494949; + case 4330: + width = 4248; + if ((height -= 39) == 2400) + top_margin = 15; + left_margin += 17; + adobe_coeff ("Panasonic","DMC-LX2"); break; } } else if (!strcmp(model,"C770UZ")) { height = 1718; @@ -6737,6 +6983,19 @@ fz8_common: maximum = 0xfeb; } else if (!strncmp(model,"P850",4)) { maximum = 0xf7c; + } else if (!strcmp(model,"C330")) { + height = 1744; + width = 2336; + raw_height = 1779; + raw_width = 2338; + top_margin = 33; + left_margin = 1; + order = 0x4949; + if ((data_offset = fsize - raw_height*raw_width)) { + fseek (ifp, 168, SEEK_SET); + read_shorts (curve, 256); + } else use_gamma = 0; + load_raw = &CLASS eight_bit_load_raw; } else if (!strcasecmp(make,"KODAK")) { if (filters == UINT_MAX) filters = 0x61616161; if (!strncmp(model,"NC2000",6)) { @@ -6767,8 +7026,6 @@ fz8_common: colors = 1; filters = 0; } - if (load_raw == &CLASS eight_bit_load_raw) - load_raw = &CLASS kodak_easy_load_raw; if (strstr(model,"DC25")) { strcpy (model, "DC25"); data_offset = 15424; @@ -6789,7 +7046,7 @@ fz8_common: pre_mul[1] = 1.179; pre_mul[2] = 1.209; pre_mul[3] = 1.036; - load_raw = &CLASS kodak_easy_load_raw; + load_raw = &CLASS eight_bit_load_raw; } else if (!strcmp(model,"40")) { strcpy (model, "DC40"); height = 512; @@ -7225,7 +7482,7 @@ void CLASS gamma_lut (uchar lut[0x10000]) perc = width * height * 0.01; /* 99th percentile white point */ if (fuji_width) perc /= 2; - if (highlight) perc = -1; + if (highlight && highlight != 2) perc = -1; FORCC { for (val=0x2000, total=0; --val > 32; ) if ((total += histogram[c][val]) > perc) break; @@ -7255,13 +7512,13 @@ struct tiff_hdr { ushort order, magic; int ifd; ushort pad, ntag; - struct tiff_tag tag[15]; + struct tiff_tag tag[22]; int nextifd; ushort pad2, nexif; struct tiff_tag exif[4]; short bps[4]; - int rat[6]; - char make[64], model[64], soft[32], date[20]; + int rat[10]; + char desc[512], make[64], model[64], soft[32], date[20], artist[64]; }; void CLASS tiff_set (ushort *ntag, @@ -7290,6 +7547,7 @@ void CLASS tiff_head (struct tiff_hdr *th, int full) th->magic = 42; th->ifd = 10; if (full) { + tiff_set (&th->ntag, 254, 4, 1, 0); tiff_set (&th->ntag, 256, 4, 1, width); tiff_set (&th->ntag, 257, 4, 1, height); tiff_set (&th->ntag, 258, 3, colors, output_bps); @@ -7299,6 +7557,7 @@ void CLASS tiff_head (struct tiff_hdr *th, int full) tiff_set (&th->ntag, 259, 3, 1, 1); tiff_set (&th->ntag, 262, 3, 1, 1 + (colors > 1)); } + tiff_set (&th->ntag, 270, 2, 512, TOFF(th->desc)); tiff_set (&th->ntag, 271, 2, 64, TOFF(th->make)); tiff_set (&th->ntag, 272, 2, 64, TOFF(th->model)); if (full) { @@ -7309,8 +7568,13 @@ void CLASS tiff_head (struct tiff_hdr *th, int full) tiff_set (&th->ntag, 279, 4, 1, height*width*colors*output_bps/8); } else tiff_set (&th->ntag, 274, 3, 1, "12435867"[flip]-'0'); + tiff_set (&th->ntag, 282, 5, 1, TOFF(th->rat[6])); + tiff_set (&th->ntag, 283, 5, 1, TOFF(th->rat[8])); + tiff_set (&th->ntag, 284, 3, 1, 1); + tiff_set (&th->ntag, 296, 3, 1, 2); tiff_set (&th->ntag, 305, 2, 32, TOFF(th->soft)); tiff_set (&th->ntag, 306, 2, 20, TOFF(th->date)); + tiff_set (&th->ntag, 315, 2, 64, TOFF(th->artist)); tiff_set (&th->ntag, 34665, 4, 1, TOFF(th->nexif)); if (psize) tiff_set (&th->ntag, 34675, 7, psize, sizeof *th); tiff_set (&th->nexif, 33434, 5, 1, TOFF(th->rat[0])); @@ -7321,12 +7585,16 @@ void CLASS tiff_head (struct tiff_hdr *th, int full) th->rat[0] *= shutter; th->rat[2] *= aperture; th->rat[4] *= focal_len; + th->rat[6] = th->rat[8] = 300; + th->rat[7] = th->rat[9] = 1; + strncpy (th->desc, desc, 512); strncpy (th->make, make, 64); strncpy (th->model, model, 64); strcpy (th->soft, "dcraw v"VERSION); t = gmtime (×tamp); sprintf (th->date, "%04d:%02d:%02d %02d:%02d:%02d", t->tm_year+1900,t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec); + strncpy (th->artist, artist, 64); } void CLASS jpeg_thumb (FILE *tfp) @@ -7398,7 +7666,7 @@ int CLASS main (int argc, char **argv) int arg, status=0, user_flip=-1, user_black=-1, user_qual=-1; int timestamp_only=0, thumbnail_only=0, identify_only=0; int use_fuji_rotate=1, write_to_stdout=0, quality, i, c; - char opt, *ofname, *sp, *cp, *dark_frame=0; + char opm, opt, *ofname, *sp, *cp, *dark_frame=0; const char *write_ext; struct utimbuf ut; FILE *ofp = stdout; @@ -7430,6 +7698,8 @@ int CLASS main (int argc, char **argv) puts(_("-a Average the whole image for white balance")); puts(_("-A Average a grey box for white balance")); puts(_("-r Set custom white balance")); + puts(_("+M/-M Use/don't use an embedded color matrix")); + puts(_("-C Correct chromatic aberration")); puts(_("-b Adjust brightness (default = 1.0)")); puts(_("-n Set threshold for wavelet denoising")); puts(_("-k Set black point")); @@ -7447,17 +7717,17 @@ int CLASS main (int argc, char **argv) puts(_("-q [0-3] Set the interpolation quality")); puts(_("-h Half-size color image (twice as fast as \"-q 0\")")); puts(_("-f Interpolate RGGB as four colors")); - puts(_("-s [0-99] Select a different raw image from the same file")); + puts(_("-s [0..N-1] Select one raw image or \"all\" from each file")); puts(_("-4 Write 16-bit linear instead of 8-bit with gamma")); puts(_("-T Write TIFF instead of PPM")); puts(""); return 1; } argv[argc] = ""; - for (arg=1; argv[arg][0] == '-'; ) { + for (arg=1; (((opm = argv[arg][0]) - 2) | 2) == '+'; ) { opt = argv[arg++][1]; - if ((cp = strchr (sp="nbrktqsHA", opt))) - for (i=0; i < "114111114"[cp-sp]-'0'; i++) + if ((cp = strchr (sp="nbrktqHAC", opt))) + for (i=0; i < "114111142"[cp-sp]-'0'; i++) if (!isdigit(argv[arg+i][0])) { fprintf (stderr,_("Non-numeric argument to \"-%c\"\n"), opt); return 1; @@ -7467,11 +7737,16 @@ int CLASS main (int argc, char **argv) case 'b': bright = atof(argv[arg++]); break; case 'r': FORC4 user_mul[c] = atof(argv[arg++]); break; + case 'C': aber[0] = 1 / atof(argv[arg++]); + aber[2] = 1 / atof(argv[arg++]); break; case 'k': user_black = atoi(argv[arg++]); break; case 't': user_flip = atoi(argv[arg++]); break; case 'q': user_qual = atoi(argv[arg++]); break; - case 's': shot_select = atoi(argv[arg++]); break; case 'H': highlight = atoi(argv[arg++]); break; + case 's': + shot_select = abs(atoi(argv[arg])); + multi_out = !strcmp(argv[arg++],"all"); + break; case 'o': if (isdigit(argv[arg][0]) && !argv[arg][1]) output_color = atoi(argv[arg++]); @@ -7493,6 +7768,7 @@ int CLASS main (int argc, char **argv) case 'A': FORC4 greybox[c] = atoi(argv[arg++]); case 'a': use_auto_wb = 1; break; case 'w': use_camera_wb = 1; break; + case 'M': use_camera_matrix = (opm == '+'); break; case 'D': case 'd': document_mode = 1 + (opt == 'D'); case 'j': use_fuji_rotate = 0; break; @@ -7504,6 +7780,8 @@ int CLASS main (int argc, char **argv) return 1; } } + if (use_camera_matrix < 0) + use_camera_matrix = use_camera_wb; if (arg == argc) { fprintf (stderr,_("No files to process.\n")); return 1; @@ -7582,6 +7860,8 @@ int CLASS main (int argc, char **argv) printf (_("\nFilename: %s\n"), ifname); printf (_("Timestamp: %s"), ctime(×tamp)); printf (_("Camera: %s %s\n"), make, model); + if (artist[0]) + printf (_("Owner: %s\n"), artist); if (dng_version) { printf (_("DNG Version: ")); for (i=24; i >= 0; i -= 8) @@ -7594,9 +7874,8 @@ int CLASS main (int argc, char **argv) printf (_("%0.1f sec\n"), shutter); printf (_("Aperture: f/%0.1f\n"), aperture); printf (_("Focal length: %0.1f mm\n"), focal_len); - printf (_("Secondary pixels: %s\n"), fuji_secondary ? _("yes"):_("no")); printf (_("Embedded ICC profile: %s\n"), profile_length ? _("yes"):_("no")); - printf (_("Decodable with dcraw: %s\n"), is_raw ? _("yes"):_("no")); + printf (_("Number of raw images: %d\n"), is_raw); if (pixel_aspect != 1) printf (_("Pixel Aspect Ratio: %0.6f\n"), pixel_aspect); if (thumb_offset) @@ -7605,7 +7884,8 @@ int CLASS main (int argc, char **argv) } else if (!is_raw) fprintf (stderr,_("Cannot decode file %s\n"), ifname); if (!is_raw) goto next; - shrink = (half_size || threshold) && filters; + shrink = filters && + (half_size || threshold || aber[0] != 1 || aber[2] != 1); iheight = (height + shrink) >> shrink; iwidth = (width + shrink) >> shrink; if (identify_only) { @@ -7644,6 +7924,10 @@ next: fclose(ifp); continue; } + if (use_camera_matrix && cmatrix[0][0] > 0.25) { + memcpy (rgb_cam, cmatrix, sizeof cmatrix); + raw_color = 0; + } image = (ushort (*)[4]) calloc (iheight*iwidth, sizeof *image); merror (image, "main()"); if (meta_length) { @@ -7651,8 +7935,11 @@ next: merror (meta_data, "main()"); } if (verbose) - fprintf (stderr, - _("Loading %s %s image from %s ...\n"), make, model, ifname); + fprintf (stderr,_("Loading %s %s image from %s ...\n"), + make, model, ifname); + if (shot_select >= is_raw) + fprintf (stderr,_("%s: \"-s %d\" requests a nonexistent image!\n"), + ifname, shot_select); fseek (ifp, data_offset, SEEK_SET); (*load_raw)(); if (zero_is_bad) remove_zeroes(); @@ -7670,8 +7957,10 @@ next: if (filters && !document_mode) { if (quality == 0) lin_interpolate(); - else if (quality < 3 || colors > 3) - vng_interpolate(); + else if (quality == 1 || colors > 3) + vng_interpolate(); + else if (quality == 2) + ppg_interpolate(); else ahd_interpolate(); } if (mix_green && (colors = 3)) @@ -7692,13 +7981,16 @@ thumbnail: write_ext = ".tiff"; else write_ext = ".pgm\0.ppm\0.ppm\0.pam" + colors*5-5; - ofname = (char *) malloc (strlen(ifname) + 16); + ofname = (char *) malloc (strlen(ifname) + 64); merror (ofname, "main()"); if (write_to_stdout) strcpy (ofname,_("standard output")); else { strcpy (ofname, ifname); if ((cp = strrchr (ofname, '.'))) *cp = 0; + if (multi_out) + sprintf (ofname+strlen(ofname), "_%0*d", + snprintf(0,0,"%d",is_raw-1), shot_select); if (thumbnail_only) strcat (ofname, ".thumb"); strcat (ofname, write_ext); @@ -7719,6 +8011,10 @@ cleanup: if (ofname) free (ofname); if (oprof) free (oprof); if (image) free (image); + if (multi_out) { + if (++shot_select < is_raw) arg--; + else shot_select = 0; + } } return status; } diff --git a/dcraw.changes b/dcraw.changes index 86a7275..e9006a9 100644 --- a/dcraw.changes +++ b/dcraw.changes @@ -1,3 +1,26 @@ +------------------------------------------------------------------- +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 diff --git a/dcraw.spec b/dcraw.spec index ba1e632..a74d678 100644 --- a/dcraw.spec +++ b/dcraw.spec @@ -1,5 +1,5 @@ # -# spec file for package dcraw (Version 1.379) +# spec file for package dcraw (Version 1.390) # # Copyright (c) 2007 SUSE LINUX Products GmbH, Nuernberg, Germany. # This file and all modifications and additions to the pristine @@ -12,7 +12,7 @@ Name: dcraw BuildRequires: libjpeg-devel liblcms-devel -Version: 1.379 +Version: 1.390 Release: 1 License: Any permissive Group: Productivity/Graphics/Convertors @@ -76,6 +76,26 @@ rm -rf $RPM_BUILD_ROOT %doc %_mandir/man*/* %changelog +* Fri Aug 03 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 03 2007 - postadal@suse.cz - updated to RCS 1.379 * Offer blended highlights with the "-H 2" option diff --git a/parse.c b/parse.c index 0304dd6..e5a99e5 100644 --- a/parse.c +++ b/parse.c @@ -5,8 +5,8 @@ This program displays raw metadata for all raw photo formats. It is free for all uses. - $Revision: 1.64 $ - $Date: 2007/04/29 04:00:59 $ + $Revision: 1.65 $ + $Date: 2007/05/15 06:16:12 $ */ #include @@ -198,7 +198,7 @@ void nikon_decrypt (uchar ci, uchar cj, int tag, int i, int size, uchar *buf) int parse_tiff_ifd (int base, int level); -void parse_makernote (base) +void parse_makernote (int base, int level) { int offset=0, entries, tag, type, count, val, save; unsigned serial=0, key=0; @@ -246,10 +246,10 @@ void parse_makernote (base) tag = get2(); type = get2(); count= get4(); - tiff_dump (base, tag, type, count, 2); - if (tag == 0x11 || type == 13) { + tiff_dump (base, tag, type, count, level); + if ((tag == 0x11 && !strncmp(make,"NIKON",5)) || type == 13) { fseek (ifp, get4()+base, SEEK_SET); - parse_tiff_ifd (base, 3); + parse_tiff_ifd (base, level+1); } if (tag == 0x1d) while ((val = fgetc(ifp)) && val != EOF) @@ -263,12 +263,12 @@ void parse_makernote (base) if (tag == 0xa7) key = fgetc(ifp)^fgetc(ifp)^fgetc(ifp)^fgetc(ifp); if (!strcmp (buf,"OLYMP") && tag >> 8 == 0x20) - parse_tiff_ifd (base, 3); + parse_tiff_ifd (base, level+1); if (tag == 0xe01) parse_nikon_capture_note (count); if (tag == 0xb028) { fseek (ifp, get4(), SEEK_SET); - parse_tiff_ifd (base, 3); + parse_tiff_ifd (base, level+1); } fseek (ifp, save+12, SEEK_SET); } @@ -281,7 +281,7 @@ void parse_makernote (base) order = sorder; } -void parse_exif(int base) +void parse_exif (int base, int level) { int entries, tag, type, count, save; @@ -292,9 +292,9 @@ void parse_exif(int base) tag = get2(); type = get2(); count= get4(); - tiff_dump (base, tag, type, count, 1); + tiff_dump (base, tag, type, count, level); if (tag == 0x927c) - parse_makernote (base); + parse_makernote (base, level+1); fseek (ifp, save+12, SEEK_SET); } } @@ -366,7 +366,15 @@ int parse_tiff_ifd (int base, int level) break; case 34665: fseek (ifp, get4()+base, SEEK_SET); - parse_exif (base); + parse_exif (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;