File indexing completed on 2025-01-05 03:56:49

0001 /* -*- C++ -*-
0002  * File: simple_dcraw.cpp
0003  * Copyright 2008-2021 LibRaw LLC (info@libraw.org)
0004  * Created: Sat Mar  8, 2008
0005  *
0006  * LibRaw simple C++ API:  emulates call to "dcraw  [-D]  [-T] [-v] [-e] [-4]"
0007 
0008 LibRaw is free software; you can redistribute it and/or modify
0009 it under the terms of the one of two licenses as you choose:
0010 
0011 1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1
0012    (See file LICENSE.LGPL provided in LibRaw distribution archive for details).
0013 
0014 2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
0015    (See file LICENSE.CDDL provided in LibRaw distribution archive for details).
0016 
0017 
0018  */
0019 #include <stdio.h>
0020 #include <string.h>
0021 #include <math.h>
0022 
0023 #include "libraw/libraw.h"
0024 
0025 #ifndef LIBRAW_WIN32_CALLS
0026 #include <unistd.h>
0027 #include <fcntl.h>
0028 #include <sys/stat.h>
0029 #include <sys/mman.h>
0030 #endif
0031 
0032 #ifdef LIBRAW_WIN32_CALLS
0033 #define snprintf _snprintf
0034 #endif
0035 
0036 int my_progress_callback(void *unused_data, enum LibRaw_progress state,
0037                          int iter, int expected)
0038 {
0039   if (iter == 0)
0040     printf("CB: state=%x, expected %d iterations\n", state, expected);
0041   return 0;
0042 }
0043 
0044 char *customCameras[] = {
0045     (char *)"43704960,4080,5356, 0, 0, 0, 0,0,148,0,0, Dalsa, FTF4052C Full,0",
0046     (char *)"42837504,4008,5344, 0, 0, 0, 0,0,148,0,0,Dalsa, FTF4052C 3:4",
0047     (char *)"32128128,4008,4008, 0, 0, 0, 0,0,148,0,0,Dalsa, FTF4052C 1:1",
0048     (char *)"24096096,4008,3006, 0, 0, 0, 0,0,148,0,0,Dalsa, FTF4052C 4:3",
0049     (char *)"18068064,4008,2254, 0, 0, 0, 0,0,148,0,0,Dalsa, FTF4052C 16:9",
0050     (char *)"67686894,5049,6703, 0, 0, 0, 0,0,148,0,0,Dalsa, FTF5066C Full",
0051     (char *)"66573312,4992,6668, 0, 0, 0, 0,0,148,0,0,Dalsa, FTF5066C 3:4",
0052     (char *)"49840128,4992,4992, 0, 0, 0, 0,0,148,0,0,Dalsa, FTF5066C 1:1",
0053     (char *)"37400064,4992,3746, 0, 0, 0, 0,0,148,0,0,Dalsa, FTF5066C 4:3",
0054     (char *)"28035072,4992,2808, 0, 0, 0, 0,0,148,0,0,Dalsa, FTF5066C 16:9",
0055     NULL};
0056 
0057 int main(int ac, char *av[])
0058 {
0059   int i, ret, verbose = 0, output_thumbs = 0, output_all_thumbs = 0;
0060 
0061   // don't use fixed size buffers in real apps!
0062   char outfn[1024], thumbfn[1024];
0063 
0064   LibRaw* RawProcessor = new LibRaw;
0065   RawProcessor->imgdata.rawparams.custom_camera_strings = customCameras;
0066   if (ac < 2)
0067   {
0068     printf("simple_dcraw - LibRaw %s sample. Emulates dcraw [-D] [-T] [-v] "
0069            "[-e] [-E]\n"
0070            " %d cameras supported\n"
0071            "Usage: %s [-D] [-T] [-v] [-e] raw-files....\n"
0072            "\t-4 - 16-bit mode\n"
0073            "\t-L - list supported cameras and exit\n"
0074            "\t-v - verbose output\n"
0075            "\t-T - output TIFF files instead of .pgm/ppm\n"
0076            "\t-e - extract thumbnails (same as dcraw -e in separate run)\n"
0077            "\t-E - extract all thumbnails\n",
0078            LibRaw::version(), LibRaw::cameraCount(), av[0]);
0079     delete RawProcessor;
0080     return 0;
0081   }
0082 
0083   putenv((char *)"TZ=UTC"); // dcraw compatibility, affects TIFF datestamp field
0084 
0085 #define P1 RawProcessor->imgdata.idata
0086 #define S RawProcessor->imgdata.sizes
0087 #define C RawProcessor->imgdata.color
0088 #define T RawProcessor->imgdata.thumbnail
0089 #define P2 RawProcessor->imgdata.other
0090 #define OUT RawProcessor->imgdata.params
0091 
0092   for (i = 1; i < ac; i++)
0093   {
0094     if (av[i][0] == '-')
0095     {
0096       if (av[i][1] == 'T' && av[i][2] == 0)
0097         OUT.output_tiff = 1;
0098       if (av[i][1] == 'v' && av[i][2] == 0)
0099         verbose++;
0100       if (av[i][1] == 'e' && av[i][2] == 0)
0101         output_thumbs++;
0102       if (av[i][1] == 'E' && av[i][2] == 0)
0103       {
0104         output_thumbs++;
0105         output_all_thumbs++;
0106       }
0107       if (av[i][1] == '4' && av[i][2] == 0)
0108         OUT.output_bps = 16;
0109       if (av[i][1] == 'C' && av[i][2] == 0)
0110         RawProcessor->set_progress_handler(my_progress_callback, NULL);
0111       if (av[i][1] == 'L' && av[i][2] == 0)
0112       {
0113         const char **clist = LibRaw::cameraList();
0114         const char **cc = clist;
0115         while (*cc)
0116         {
0117           printf("%s\n", *cc);
0118           cc++;
0119         }
0120         delete RawProcessor;
0121         exit(0);
0122       }
0123       continue;
0124     }
0125 
0126     if (verbose)
0127       printf("Processing file %s\n", av[i]);
0128 
0129     if ((ret = RawProcessor->open_file(av[i])) != LIBRAW_SUCCESS)
0130     {
0131       fprintf(stderr, "Cannot open_file %s: %s\n", av[i], libraw_strerror(ret));
0132       continue; // no recycle b/c open file will recycle itself
0133     }
0134 
0135     if (!output_thumbs) // No unpack for thumb extraction
0136       if ((ret = RawProcessor->unpack()) != LIBRAW_SUCCESS)
0137       {
0138         fprintf(stderr, "Cannot unpack %s: %s\n", av[i], libraw_strerror(ret));
0139         continue;
0140       }
0141 
0142     // thumbnail unpacking and output in the middle of main
0143     // image processing - for test purposes!
0144     if(output_all_thumbs)
0145     {
0146       if (verbose)
0147         printf("Extracting %d thumbnails\n", RawProcessor->imgdata.thumbs_list.thumbcount);
0148       for (int t = 0; t < RawProcessor->imgdata.thumbs_list.thumbcount; t++)
0149       {
0150         if ((ret = RawProcessor->unpack_thumb_ex(t)) != LIBRAW_SUCCESS)
0151           fprintf(stderr, "Cannot unpack_thumb #%d from %s: %s\n", t, av[i], libraw_strerror(ret));
0152         if (LIBRAW_FATAL_ERROR(ret))
0153           break; // skip to next file
0154         snprintf(thumbfn, sizeof(thumbfn), "%s.thumb.%d.%s", av[i], t,
0155                  T.tformat == LIBRAW_THUMBNAIL_JPEG ? "jpg" : "ppm");
0156         if (verbose)
0157           printf("Writing thumbnail file %s\n", thumbfn);
0158         if (LIBRAW_SUCCESS != (ret = RawProcessor->dcraw_thumb_writer(thumbfn)))
0159         {
0160           fprintf(stderr, "Cannot write %s: %s\n", thumbfn, libraw_strerror(ret));
0161           if (LIBRAW_FATAL_ERROR(ret))
0162             break;
0163         }
0164       }
0165       continue;
0166     }
0167     else if (output_thumbs)
0168     {
0169       if ((ret = RawProcessor->unpack_thumb()) != LIBRAW_SUCCESS)
0170       {
0171         fprintf(stderr, "Cannot unpack_thumb %s: %s\n", av[i],
0172                 libraw_strerror(ret));
0173         if (LIBRAW_FATAL_ERROR(ret))
0174           continue; // skip to next file
0175       }
0176       else
0177       {
0178         snprintf(thumbfn, sizeof(thumbfn), "%s.%s", av[i],
0179                  T.tformat == LIBRAW_THUMBNAIL_JPEG ? "thumb.jpg"
0180                                                     : (T.tcolors == 1? "thumb.pgm" : "thumb.ppm"));
0181         if (verbose)
0182           printf("Writing thumbnail file %s\n", thumbfn);
0183         if (LIBRAW_SUCCESS != (ret = RawProcessor->dcraw_thumb_writer(thumbfn)))
0184         {
0185           fprintf(stderr, "Cannot write %s: %s\n", thumbfn,
0186                   libraw_strerror(ret));
0187           if (LIBRAW_FATAL_ERROR(ret))
0188             continue;
0189         }
0190       }
0191       continue;
0192     }
0193 
0194     ret = RawProcessor->dcraw_process();
0195 
0196     if (LIBRAW_SUCCESS != ret)
0197     {
0198       fprintf(stderr, "Cannot do postprocessing on %s: %s\n", av[i],
0199               libraw_strerror(ret));
0200       if (LIBRAW_FATAL_ERROR(ret))
0201         continue;
0202     }
0203     snprintf(outfn, sizeof(outfn), "%s.%s", av[i],
0204              OUT.output_tiff ? "tiff" : (P1.colors > 1 ? "ppm" : "pgm"));
0205 
0206     if (verbose)
0207       printf("Writing file %s\n", outfn);
0208 
0209     if (LIBRAW_SUCCESS != (ret = RawProcessor->dcraw_ppm_tiff_writer(outfn)))
0210       fprintf(stderr, "Cannot write %s: %s\n", outfn, libraw_strerror(ret));
0211 
0212     RawProcessor->recycle(); // just for show this call
0213   }
0214   
0215   delete RawProcessor;
0216   return 0;
0217 }