File indexing completed on 2025-01-05 03:57:01

0001 /* -*- C++ -*-
0002  * Copyright 2019-2021 LibRaw LLC (info@libraw.org)
0003  *
0004  LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder,
0005  dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net.
0006  LibRaw do not use RESTRICTED code from dcraw.c
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 "../../internal/dcraw_defs.h"
0020 
0021 /*
0022    Returns 1 for a Coolpix 2100, 0 for anything else.
0023  */
0024 int LibRaw::nikon_e2100()
0025 {
0026   uchar t[12];
0027   int i;
0028 
0029   fseek(ifp, 0, SEEK_SET);
0030   for (i = 0; i < 1024; i++)
0031   {
0032     fread(t, 1, 12, ifp);
0033     if (((t[2] & t[4] & t[7] & t[9]) >> 4 & t[1] & t[6] & t[8] & t[11] & 3) !=
0034         3)
0035       return 0;
0036   }
0037   return 1;
0038 }
0039 
0040 void LibRaw::nikon_3700()
0041 {
0042   int bits, i;
0043   uchar dp[24];
0044   static const struct
0045   {
0046     int bits;
0047     char t_make[12], t_model[15];
0048     int t_maker_idx;
0049   } table[] = {{0x00, "Pentax", "Optio 33WR", LIBRAW_CAMERAMAKER_Pentax},
0050                {0x03, "Nikon", "E3200", LIBRAW_CAMERAMAKER_Nikon},
0051                {0x32, "Nikon", "E3700", LIBRAW_CAMERAMAKER_Nikon},
0052                {0x33, "Olympus", "C-740UZ", LIBRAW_CAMERAMAKER_Olympus}};
0053 
0054   fseek(ifp, 3072, SEEK_SET);
0055   fread(dp, 1, 24, ifp);
0056   bits = (dp[8] & 3) << 4 | (dp[20] & 3);
0057   for (i = 0; i < int(sizeof table / sizeof *table); i++)
0058     if (bits == table[i].bits)
0059     {
0060       strcpy(make, table[i].t_make);
0061       maker_index = table[i].t_maker_idx;
0062       strcpy(model, table[i].t_model);
0063     }
0064 }
0065 
0066 /*
0067    Separates a Minolta DiMAGE Z2 from a Nikon E4300.
0068  */
0069 int LibRaw::minolta_z2()
0070 {
0071   int i, nz;
0072   char tail[424];
0073 
0074   fseek(ifp, -int(sizeof tail), SEEK_END);
0075   fread(tail, 1, sizeof tail, ifp);
0076   for (nz = i = 0; i < int(sizeof tail); i++)
0077     if (tail[i])
0078       nz++;
0079   return nz > 20;
0080 }
0081 
0082 int LibRaw::canon_s2is()
0083 {
0084   unsigned row;
0085 
0086   for (row = 0; row < 100; row++)
0087   {
0088     fseek(ifp, row * 3340 + 3284, SEEK_SET);
0089     if (getc(ifp) > 15)
0090       return 1;
0091   }
0092   return 0;
0093 }
0094 
0095 #ifdef LIBRAW_OLD_VIDEO_SUPPORT
0096 void LibRaw::parse_redcine()
0097 {
0098   unsigned i, len, rdvo;
0099 
0100   order = 0x4d4d;
0101   is_raw = 0;
0102   fseek(ifp, 52, SEEK_SET);
0103   width = get4();
0104   height = get4();
0105   fseek(ifp, 0, SEEK_END);
0106   fseek(ifp, -(i = ftello(ifp) & 511), SEEK_CUR);
0107   if (get4() != i || get4() != 0x52454f42)
0108   {
0109     fseek(ifp, 0, SEEK_SET);
0110     while ((len = get4()) != (unsigned)EOF)
0111     {
0112       if (get4() == 0x52454456)
0113         if (is_raw++ == shot_select)
0114           data_offset = ftello(ifp) - 8;
0115       fseek(ifp, len - 8, SEEK_CUR);
0116     }
0117   }
0118   else
0119   {
0120     rdvo = get4();
0121     fseek(ifp, 12, SEEK_CUR);
0122     is_raw = get4();
0123     fseeko(ifp, rdvo + 8 + shot_select * 4, SEEK_SET);
0124     data_offset = get4();
0125   }
0126 }
0127 #endif
0128 
0129 void LibRaw::parse_cine()
0130 {
0131   unsigned off_head, off_setup, off_image, i, temp;
0132 
0133   order = 0x4949;
0134   fseek(ifp, 4, SEEK_SET);
0135   is_raw = get2() == 2;
0136   fseek(ifp, 14, SEEK_CUR);
0137   is_raw *= get4();
0138   off_head = get4();
0139   off_setup = get4();
0140   off_image = get4();
0141   timestamp = get4();
0142   if ((i = get4()))
0143     timestamp = i;
0144   fseek(ifp, off_head + 4, SEEK_SET);
0145   raw_width = get4();
0146   raw_height = get4();
0147   switch (get2(), get2())
0148   {
0149   case 8:
0150     load_raw = &LibRaw::eight_bit_load_raw;
0151     break;
0152   case 16:
0153     load_raw = &LibRaw::unpacked_load_raw;
0154   }
0155   fseek(ifp, off_setup + 792, SEEK_SET);
0156   strcpy(make, "CINE");
0157   sprintf(model, "%d", get4());
0158   fseek(ifp, 12, SEEK_CUR);
0159   switch ((i = get4()) & 0xffffff)
0160   {
0161   case 3:
0162     filters = 0x94949494;
0163     break;
0164   case 4:
0165     filters = 0x49494949;
0166     break;
0167   default:
0168     is_raw = 0;
0169   }
0170   fseek(ifp, 72, SEEK_CUR);
0171   switch ((get4() + 3600) % 360)
0172   {
0173   case 270:
0174     flip = 4;
0175     break;
0176   case 180:
0177     flip = 1;
0178     break;
0179   case 90:
0180     flip = 7;
0181     break;
0182   case 0:
0183     flip = 2;
0184   }
0185   cam_mul[0] = getreal(LIBRAW_EXIFTAG_TYPE_FLOAT);
0186   cam_mul[2] = getreal(LIBRAW_EXIFTAG_TYPE_FLOAT);
0187   temp = get4();
0188   maximum = ~((~0u) << LIM(temp, 1, 31));
0189   fseek(ifp, 668, SEEK_CUR);
0190   shutter = get4() / 1000000000.0;
0191   fseek(ifp, off_image, SEEK_SET);
0192   if (shot_select < is_raw)
0193     fseek(ifp, shot_select * 8, SEEK_CUR);
0194   data_offset = (INT64)get4() + 8;
0195   data_offset += (INT64)get4() << 32;
0196 }
0197 
0198 void LibRaw::parse_qt(int end)
0199 {
0200   unsigned save, size;
0201   char tag[4];
0202 
0203   order = 0x4d4d;
0204   while (ftell(ifp) + 7 < end)
0205   {
0206     save = ftell(ifp);
0207     if ((size = get4()) < 8)
0208       return;
0209     if ((int)size < 0)
0210       return; // 2+GB is too much
0211     if (save + size < save)
0212       return; // 32bit overflow
0213     fread(tag, 4, 1, ifp);
0214     if (!memcmp(tag, "moov", 4) || !memcmp(tag, "udta", 4) ||
0215         !memcmp(tag, "CNTH", 4))
0216       parse_qt(save + size);
0217     if (!memcmp(tag, "CNDA", 4))
0218       parse_jpeg(ftell(ifp));
0219     fseek(ifp, save + size, SEEK_SET);
0220   }
0221 }
0222 
0223 void LibRaw::parse_smal(int offset, int fsize)
0224 {
0225   int ver;
0226 
0227   fseek(ifp, offset + 2, SEEK_SET);
0228   order = 0x4949;
0229   ver = fgetc(ifp);
0230   if (ver == 6)
0231     fseek(ifp, 5, SEEK_CUR);
0232   if (get4() != (unsigned)fsize)
0233     return;
0234   if (ver > 6)
0235     data_offset = get4();
0236   raw_height = height = get2();
0237   raw_width = width = get2();
0238   strcpy(make, "SMaL");
0239   sprintf(model, "v%d %dx%d", ver, width, height);
0240   if (ver == 6)
0241     load_raw = &LibRaw::smal_v6_load_raw;
0242   if (ver == 9)
0243     load_raw = &LibRaw::smal_v9_load_raw;
0244 }
0245 
0246 void LibRaw::parse_riff(int maxdepth)
0247 {
0248   unsigned i, size, end;
0249   char tag[4], date[64], month[64];
0250   static const char mon[12][4] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
0251                                   "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
0252   struct tm t;
0253   if (maxdepth < 1)
0254       throw LIBRAW_EXCEPTION_IO_CORRUPT;
0255 
0256   order = 0x4949;
0257   fread(tag, 4, 1, ifp);
0258   size = get4();
0259   end = ftell(ifp) + size;
0260   if (!memcmp(tag, "RIFF", 4) || !memcmp(tag, "LIST", 4))
0261   {
0262     int maxloop = 1000;
0263     get4();
0264     while (ftell(ifp) + 7 < end && !feof(ifp) && maxloop--)
0265       parse_riff(maxdepth-1);
0266   }
0267   else if (!memcmp(tag, "nctg", 4))
0268   {
0269     while (ftell(ifp) + 7 < end)
0270     {
0271         if (feof(ifp))
0272             break;
0273       i = get2();
0274       size = get2();
0275       if ((i + 1) >> 1 == 10 && size == 20)
0276         get_timestamp(0);
0277       else
0278         fseek(ifp, size, SEEK_CUR);
0279     }
0280   }
0281   else if (!memcmp(tag, "IDIT", 4) && size < 64)
0282   {
0283     fread(date, 64, 1, ifp);
0284     date[size] = 0;
0285     memset(&t, 0, sizeof t);
0286     if (sscanf(date, "%*s %s %d %d:%d:%d %d", month, &t.tm_mday, &t.tm_hour,
0287                &t.tm_min, &t.tm_sec, &t.tm_year) == 6)
0288     {
0289       for (i = 0; i < 12 && strcasecmp(mon[i], month); i++)
0290         ;
0291       t.tm_mon = i;
0292       t.tm_year -= 1900;
0293       if (mktime(&t) > 0)
0294         timestamp = mktime(&t);
0295     }
0296   }
0297   else
0298     fseek(ifp, size, SEEK_CUR);
0299 }
0300 
0301 void LibRaw::parse_rollei()
0302 {
0303   char line[128], *val;
0304   struct tm t;
0305 
0306   fseek(ifp, 0, SEEK_SET);
0307   memset(&t, 0, sizeof t);
0308   do
0309   {
0310     line[0] = 0;
0311     if (!fgets(line, 128, ifp))
0312       break;
0313     line[127] = 0;
0314     if(!line[0]) break; // zero-length
0315     if ((val = strchr(line, '=')))
0316       *val++ = 0;
0317     else
0318       val = line + strbuflen(line);
0319     if (!strcmp(line, "DAT"))
0320       sscanf(val, "%d.%d.%d", &t.tm_mday, &t.tm_mon, &t.tm_year);
0321     if (!strcmp(line, "TIM"))
0322       sscanf(val, "%d:%d:%d", &t.tm_hour, &t.tm_min, &t.tm_sec);
0323     if (!strcmp(line, "HDR"))
0324       thumb_offset = atoi(val);
0325     if (!strcmp(line, "X  "))
0326       raw_width = atoi(val);
0327     if (!strcmp(line, "Y  "))
0328       raw_height = atoi(val);
0329     if (!strcmp(line, "TX "))
0330       thumb_width = atoi(val);
0331     if (!strcmp(line, "TY "))
0332       thumb_height = atoi(val);
0333     if (!strcmp(line, "APT"))
0334       aperture = atof(val);
0335     if (!strcmp(line, "SPE"))
0336       shutter = atof(val);
0337     if (!strcmp(line, "FOCLEN"))
0338       focal_len = atof(val);
0339     if (!strcmp(line, "BLKOFS"))
0340       black = atoi(val) +1;
0341     if (!strcmp(line, "ORI"))
0342       switch (atoi(val)) {
0343       case 1:
0344         flip = 6;
0345         break;
0346       case 2:
0347         flip = 3;
0348         break;
0349       case 3:
0350         flip = 5;
0351         break;
0352       }
0353     if (!strcmp(line, "CUTRECT")) {
0354       sscanf(val, "%hu %hu %hu %hu",
0355              &imgdata.sizes.raw_inset_crops[0].cleft,
0356              &imgdata.sizes.raw_inset_crops[0].ctop,
0357              &imgdata.sizes.raw_inset_crops[0].cwidth,
0358              &imgdata.sizes.raw_inset_crops[0].cheight);
0359     }
0360   } while (strncmp(line, "EOHD", 4));
0361   data_offset = thumb_offset + thumb_width * thumb_height * 2;
0362   t.tm_year -= 1900;
0363   t.tm_mon -= 1;
0364   if (mktime(&t) > 0)
0365     timestamp = mktime(&t);
0366   strcpy(make, "Rollei");
0367   strcpy(model, "d530flex");
0368   thumb_format = LIBRAW_INTERNAL_THUMBNAIL_ROLLEI;
0369 }
0370 
0371 void LibRaw::parse_sinar_ia()
0372 {
0373   int entries, off;
0374   char str[8], *cp;
0375 
0376   order = 0x4949;
0377   fseek(ifp, 4, SEEK_SET);
0378   entries = get4();
0379   if (entries < 1 || entries > 8192)
0380     return;
0381   fseek(ifp, get4(), SEEK_SET);
0382   while (entries--)
0383   {
0384     off = get4();
0385     get4();
0386     fread(str, 8, 1, ifp);
0387     str[7] = 0; // Ensure end of string
0388     if (!strcmp(str, "META"))
0389       meta_offset = off;
0390     if (!strcmp(str, "THUMB"))
0391       thumb_offset = off;
0392     if (!strcmp(str, "RAW0"))
0393       data_offset = off;
0394   }
0395   fseek(ifp, meta_offset + 20, SEEK_SET);
0396   fread(make, 64, 1, ifp);
0397   make[63] = 0;
0398   if ((cp = strchr(make, ' ')))
0399   {
0400     strcpy(model, cp + 1);
0401     *cp = 0;
0402   }
0403   raw_width = get2();
0404   raw_height = get2();
0405   load_raw = &LibRaw::unpacked_load_raw;
0406   thumb_width = (get4(), get2());
0407   thumb_height = get2();
0408   thumb_format = LIBRAW_INTERNAL_THUMBNAIL_PPM;
0409   maximum = 0x3fff;
0410 }
0411 
0412 void LibRaw::parse_kyocera()
0413 {
0414 
0415   int c;
0416   static const ushort table[13] = {25,  32,  40,  50,  64,  80, 100,
0417                                    125, 160, 200, 250, 320, 400};
0418 
0419   fseek(ifp, 33, SEEK_SET);
0420   get_timestamp(1);
0421   fseek(ifp, 52, SEEK_SET);
0422   c = get4();
0423   if ((c > 6) && (c < 20))
0424     iso_speed = table[c - 7];
0425   shutter = libraw_powf64l(2.0f, (((float)get4()) / 8.0f)) / 16000.0f;
0426   FORC4 cam_mul[RGGB_2_RGBG(c)] = get4();
0427   fseek(ifp, 88, SEEK_SET);
0428   aperture = libraw_powf64l(2.0f, ((float)get4()) / 16.0f);
0429   fseek(ifp, 112, SEEK_SET);
0430   focal_len = get4();
0431 
0432   fseek(ifp, 104, SEEK_SET);
0433   ilm.MaxAp4CurFocal = libraw_powf64l(2.0f, ((float)get4()) / 16.0f);
0434   fseek(ifp, 124, SEEK_SET);
0435   stmread(ilm.Lens, 32, ifp);
0436   ilm.CameraMount = LIBRAW_MOUNT_Contax_N;
0437   ilm.CameraFormat = LIBRAW_FORMAT_FF;
0438   if (ilm.Lens[0])
0439   {
0440     ilm.LensMount = LIBRAW_MOUNT_Contax_N;
0441     ilm.LensFormat = LIBRAW_FORMAT_FF;
0442   }
0443 }
0444 
0445 int LibRaw::parse_jpeg(int offset)
0446 {
0447   int len, save, hlen, mark;
0448   fseek(ifp, offset, SEEK_SET);
0449   if (fgetc(ifp) != 0xff || fgetc(ifp) != 0xd8)
0450     return 0;
0451 
0452   while (fgetc(ifp) == 0xff && (mark = fgetc(ifp)) != 0xda)
0453   {
0454     order = 0x4d4d;
0455     len = get2() - 2;
0456     save = ftell(ifp);
0457     if (mark == 0xc0 || mark == 0xc3 || mark == 0xc9)
0458     {
0459       fgetc(ifp);
0460       raw_height = get2();
0461       raw_width = get2();
0462     }
0463     order = get2();
0464     hlen = get4();
0465     if (get4() == 0x48454150 && (save + hlen) >= 0 &&
0466         (save + hlen) <= ifp->size()) /* "HEAP" */
0467     {
0468       parse_ciff(save + hlen, len - hlen, 0);
0469     }
0470     if (parse_tiff(save + 6))
0471       apply_tiff();
0472     fseek(ifp, save + len, SEEK_SET);
0473   }
0474   return 1;
0475 }
0476 
0477 void LibRaw::parse_thumb_note(int base, unsigned toff, unsigned tlen)
0478 {
0479   unsigned entries, tag, type, len, save;
0480 
0481   entries = get2();
0482   while (entries--)
0483   {
0484     tiff_get(base, &tag, &type, &len, &save);
0485     if (tag == toff)
0486       thumb_offset = get4() + base;
0487     if (tag == tlen)
0488       thumb_length = get4();
0489     fseek(ifp, save, SEEK_SET);
0490   }
0491 }
0492 
0493 void LibRaw::parse_broadcom()
0494 {
0495 
0496   /* This structure is at offset 0xb0 from the 'BRCM' ident. */
0497   struct
0498   {
0499     uint8_t umode[32];
0500     uint16_t uwidth;
0501     uint16_t uheight;
0502     uint16_t padding_right;
0503     uint16_t padding_down;
0504     uint32_t unknown_block[6];
0505     uint16_t transform;
0506     uint16_t format;
0507     uint8_t bayer_order;
0508     uint8_t bayer_format;
0509   } header;
0510 
0511   header.bayer_order = 0;
0512   fseek(ifp, 0xb0 - 0x20, SEEK_CUR);
0513   fread(&header, 1, sizeof(header), ifp);
0514   raw_stride =
0515       ((((((header.uwidth + header.padding_right) * 5) + 3) >> 2) + 0x1f) &
0516        (~0x1f));
0517   raw_width = width = header.uwidth;
0518   raw_height = height = header.uheight;
0519   filters = 0x16161616; /* default Bayer order is 2, BGGR */
0520 
0521   switch (header.bayer_order)
0522   {
0523   case 0: /* RGGB */
0524     filters = 0x94949494;
0525     break;
0526   case 1: /* GBRG */
0527     filters = 0x49494949;
0528     break;
0529   case 3: /* GRBG */
0530     filters = 0x61616161;
0531     break;
0532   }
0533 }
0534 
0535 /*
0536    Returns 1 for a Coolpix 995, 0 for anything else.
0537  */
0538 int LibRaw::nikon_e995()
0539 {
0540   int i, histo[256];
0541   const uchar often[] = {0x00, 0x55, 0xaa, 0xff};
0542 
0543   memset(histo, 0, sizeof histo);
0544   fseek(ifp, -2000, SEEK_END);
0545   for (i = 0; i < 2000; i++)
0546     histo[fgetc(ifp)]++;
0547   for (i = 0; i < 4; i++)
0548     if (histo[often[i]] < 200)
0549       return 0;
0550   return 1;
0551 }
0552 
0553 /*
0554    Since the TIFF DateTime string has no timezone information,
0555    assume that the camera's clock was set to Universal Time.
0556  */
0557 void LibRaw::get_timestamp(int reversed)
0558 {
0559   struct tm t;
0560   char str[20];
0561   int i;
0562 
0563   str[19] = 0;
0564   if (reversed)
0565     for (i = 19; i--;)
0566       str[i] = fgetc(ifp);
0567   else
0568     fread(str, 19, 1, ifp);
0569   memset(&t, 0, sizeof t);
0570   if (sscanf(str, "%d:%d:%d %d:%d:%d", &t.tm_year, &t.tm_mon, &t.tm_mday,
0571              &t.tm_hour, &t.tm_min, &t.tm_sec) != 6)
0572     return;
0573   t.tm_year -= 1900;
0574   t.tm_mon -= 1;
0575   t.tm_isdst = -1;
0576   if (mktime(&t) > 0)
0577     timestamp = mktime(&t);
0578 }
0579 
0580 #ifdef USE_6BY9RPI
0581 void LibRaw::parse_raspberrypi()
0582 {
0583     //This structure is at offset 0xB0 from the 'BRCM' ident.
0584     struct brcm_raw_header {
0585         uint8_t name[32];
0586         uint16_t h_width;
0587         uint16_t h_height;
0588         uint16_t padding_right;
0589         uint16_t padding_down;
0590         uint32_t dummy[6];
0591         uint16_t transform;
0592         uint16_t format;
0593         uint8_t bayer_order;
0594         uint8_t bayer_format;
0595     };
0596     //Values taken from https://github.com/raspberrypi/userland/blob/master/interface/vctypes/vc_image_types.h
0597 #define BRCM_FORMAT_BAYER  33
0598 #define BRCM_BAYER_RAW8    2
0599 #define BRCM_BAYER_RAW10   3
0600 #define BRCM_BAYER_RAW12   4
0601 #define BRCM_BAYER_RAW14   5
0602 #define BRCM_BAYER_RAW16   6
0603 
0604     struct brcm_raw_header header;
0605     uint8_t brcm_tag[4];
0606 
0607     if (ftell(ifp) > 22LL) // 22 bytes is minimum jpeg size
0608     {
0609         thumb_length = ftell(ifp);
0610         thumb_offset = 0;
0611         thumb_width = thumb_height = 0;
0612         load_flags |= 0x4000; // flag: we have JPEG from beginning to meta_offset
0613     }
0614 
0615     // Sanity check that the caller has found a BRCM header
0616     if (!fread(brcm_tag, 1, sizeof(brcm_tag), ifp) ||
0617         memcmp(brcm_tag, "BRCM", sizeof(brcm_tag)))
0618         return;
0619 
0620     width = raw_width;
0621     data_offset = ftell(ifp) + 0x8000 - sizeof(brcm_tag);
0622 
0623     if (!fseek(ifp, 0xB0 - int(sizeof(brcm_tag)), SEEK_CUR) &&
0624         fread(&header, 1, sizeof(header), ifp)) {
0625         switch (header.bayer_order) {
0626         case 0: //RGGB
0627             filters = 0x94949494;
0628             break;
0629         case 1: //GBRG
0630             filters = 0x49494949;
0631             break;
0632         default:
0633         case 2: //BGGR
0634             filters = 0x16161616;
0635             break;
0636         case 3: //GRBG
0637             filters = 0x61616161;
0638             break;
0639         }
0640 
0641         if (header.format == BRCM_FORMAT_BAYER) {
0642             switch (header.bayer_format) {
0643             case BRCM_BAYER_RAW8:
0644                 load_raw = &LibRaw::rpi_load_raw8;
0645                 //1 pixel per byte
0646                 raw_stride = ((header.h_width + header.padding_right) + 31)&(~31);
0647                 width = header.h_width;
0648                 raw_height = height = header.h_height;
0649                 is_raw = 1;
0650                 order = 0x4d4d;
0651                 break;
0652             case BRCM_BAYER_RAW10:
0653                 load_raw = &LibRaw::nokia_load_raw;
0654                 //4 pixels per 5 bytes
0655                 raw_stride = (((((header.h_width + header.padding_right) * 5) + 3) >> 2) + 31)&(~31);
0656                 width = header.h_width;
0657                 raw_height = height = header.h_height;
0658                 is_raw = 1;
0659                 order = 0x4d4d;
0660                 break;
0661             case BRCM_BAYER_RAW12:
0662                 load_raw = &LibRaw::rpi_load_raw12;
0663                 //2 pixels per 3 bytes
0664                 raw_stride = (((((header.h_width + header.padding_right) * 3) + 1) >> 1) + 31)&(~31);
0665                 width = header.h_width;
0666                 raw_height = height = header.h_height;
0667                 is_raw = 1;
0668                 order = 0x4d4d;
0669                 break;
0670             case BRCM_BAYER_RAW14:
0671                 load_raw = &LibRaw::rpi_load_raw14;
0672                 //4 pixels per 7 bytes
0673                 raw_stride = (((((header.h_width + header.padding_right) * 7) + 3) >> 2) + 31)&(~31);
0674                 width = header.h_width;
0675                 raw_height = height = header.h_height;
0676                 is_raw = 1;
0677                 order = 0x4d4d;
0678                 break;
0679             case BRCM_BAYER_RAW16:
0680                 load_raw = &LibRaw::rpi_load_raw16;
0681                 //1 pixel per 2 bytes
0682                 raw_stride = (((header.h_width + header.padding_right) << 1) + 31)&(~31);
0683                 width = header.h_width;
0684                 raw_height = height = header.h_height;
0685                 is_raw = 1;
0686                 order = 0x4d4d;
0687                 break;
0688             default:
0689                 break;
0690             }
0691         }
0692     }
0693 }
0694 #endif