Unity 3D : 解富士 RAF 檔案

我使用 X-H1 無反

破解到一半,可以執行與出圖,但效果可能不是很好

未完待續…

using System.IO;
using UnityEngine;
using UnityEngine.UI;

public class Decoder : MonoBehaviour
{

    // Use this for initialization
    void Start()
    {
        byte[] b = File.ReadAllBytes("C:/A/_DSF0719.RAF");

        // ---

        string identify = "";

        for (int i = 0; i < 16; i++)
        {
            identify += (char)b[i];
        }

        // ---

        string version = "";

        for (int i = 16; i < 20; i++)
        {
            version += (char)b[i];
        }

        // ---

        string CameraNumberID = "";

        for (int i = 20; i < 28; i++)
        {
            CameraNumberID += (char)b[i];
        }

        // ---

        string CameraBodyName = "";

        for (int i = 28; i < 60; i++)
        {
            CameraBodyName += (char)b[i];
        }

        // ---

        string DirectoryVersion = "";

        for (int i = 60; i < 64; i++)
        {
            DirectoryVersion += (char)b[i];
        }

        // ---

        int JpegImageOffset = b[84] << 24 | b[85] << 16 | b[86] << 8 | b[87];
        int JpegImageLength = b[88] << 24 | b[89] << 16 | b[90] << 8 | b[91];

        int CFAHeaderOffset = b[92] << 24 | b[93] << 16 | b[94] << 8 | b[95];
        int CFAHeaderLength = b[96] << 24 | b[97] << 16 | b[98] << 8 | b[99];

        int CFAOffset = b[100] << 24 | b[101] << 16 | b[102] << 8 | b[103];
        int CFALength = b[104] << 24 | b[105] << 16 | b[106] << 8 | b[107];

        // ---

        //int A = b[CFAHeaderOffset] << 24 | b[CFAHeaderOffset+1] << 16 | b[CFAHeaderOffset+2] << 8 | b[CFAHeaderOffset+3];


        string A = "";

        for (int i = CFAOffset; i < CFAOffset + 2047; i++)
        {
            A += (char)b[i];
        }

        // ---

        print("Magic Word ( Identify ) : " + identify);

        // 0200: Fuji S2
        // 0201: Fuji S3
        print("Format Version : " + version);

        print("Camera number ID : " + CameraNumberID);

        print("Camera Body Name : " + CameraBodyName);


        print("Directory Version : " + DirectoryVersion);

        print("Jpeg Image Offset : " + JpegImageOffset);
        print("Jpeg Image Length : " + JpegImageLength);

        print("CFA Header Offset : " + CFAHeaderOffset);
        print("CFA Header Length : " + CFAHeaderLength);

        print("CFA Offset : " + CFAOffset);
        print("CFA Length : " + CFALength);

        print(A);

        // ------------------------------
        // 保存 JPG 預覽圖 :

        //byte[] PreviewImageByte = new byte[PreviewImageLength];

        //for (int i = PreviewImageIndex, k = 0; i < PreviewImageIndex + PreviewImageLength; i++, k++) {
        //    PreviewImageByte[k] = b[i];
        //}

        //File.WriteAllBytes("C:/A/My.jpg", PreviewImageByte);

        // ------------------------------

        CFAOffset += 2047; // 有可能是 : CFALength - ( RAW_Width * RAW_Height ) - 1

        Texture2D t = new Texture2D(6160, 4032);

        int BlackLevel = 1023; // 黑電平數值
        int colorMaxValue = 16383;

        int i2 = 0;

        for (int y = t.height - 1; y > 0; y--)
        {
            for (int x = 0; x < t.width; x++)
            {
                //int k2 = (x + t.width * y ) * 2;
                //int c = b[CFAOffset + k2] << 8 | b[CFAOffset + k2 + 1];

                int c = b[CFAOffset + i2] << 8 | b[CFAOffset + i2 + 1];

                // 黑電平校正-----                
                c -= BlackLevel;
                c = (int)(c * (colorMaxValue + BlackLevel) / (float)colorMaxValue);
                //----------------

                i2 += 2;

                float c2 = c / (float)colorMaxValue;

                //c2 *= 3f;

                t.SetPixel(x, y, new Color(c2, c2, c2, 1));
            }
        }

        t.Apply();

        // ------------------------------
        // RBGBRG/GGRGGB/GGBGGR/BRGRBG/GGBGGR/GGRGGB

        // if (false)
        for (int y = 0, y2 = t.height - 1; y2 > 0; y++, y2--)
        {
            for (int x = 0; x < t.width; x++)
            {
                int x2 = x + 1;

                Color c = t.GetPixel(x2, y2);

                // Red Balance  : 2.059603
                // Blue Balance : 2.294702                
                //                c = new Color(c.r * 2.059603f, c.g, c.b * 2.294702f);

                //c = new Color(c.r * 1.963576f, c.g, c.b * 1.976821f);

                // c = new Color(c.r * 1.33333f, c.g, c.b * 1.46478f);

                c = new Color(c.r * 1.7258f, c.g, c.b * 1.7258f);

                if (y % 6 == 0) // 第一行 RBGBRG
                {
                    if (x % 6 == 0 || x % 6 == 4)
                    {
                        t.SetPixel(x2, y2, new Color(c.r, 0, 0, 1));
                    }
                    else if (x % 6 == 1 || x % 6 == 3)
                    {
                        t.SetPixel(x2, y2, new Color(0, 0, c.b, 1));
                    }
                    else if (x % 6 == 2 || x % 6 == 5)
                    {
                        t.SetPixel(x2, y2, new Color(0, c.g, 0, 1));
                    }
                }
                else if (y % 6 == 1 || y % 6 == 5) // 第二行 GGRGGB
                {
                    if (x % 6 == 2)
                    {
                        t.SetPixel(x2, y2, new Color(c.r, 0, 0, 1));
                    }
                    else if (x % 6 == 5)
                    {
                        t.SetPixel(x2, y2, new Color(0, 0, c.b, 1));
                    }
                    else if (x % 6 == 0 || x % 6 == 1 || x % 6 == 3 || x % 6 == 4)
                    {
                        t.SetPixel(x2, y2, new Color(0, c.g, 0, 1));
                    }
                }
                else if (y % 6 == 2 || y % 6 == 4) // 第三行 GGBGGR
                {
                    if (x % 6 == 5)
                    {
                        t.SetPixel(x2, y2, new Color(c.r, 0, 0, 1));
                    }
                    else if (x % 6 == 2)
                    {
                        t.SetPixel(x2, y2, new Color(0, 0, c.b, 1));
                    }
                    else if (x % 6 == 0 || x % 6 == 1 || x % 6 == 3 || x % 6 == 4)
                    {
                        t.SetPixel(x2, y2, new Color(0, c.g, 0, 1));
                    }
                }
                else if (y % 6 == 3) // 第四行 BRGRBG
                {
                    if (x % 6 == 1 || x % 6 == 3)
                    {
                        t.SetPixel(x2, y2, new Color(c.r, 0, 0, 1));
                    }
                    else if (x % 6 == 0 || x % 6 == 4)
                    {
                        t.SetPixel(x2, y2, new Color(0, 0, c.b, 1));
                    }
                    else if (x % 6 == 2 || x % 6 == 5)
                    {
                        t.SetPixel(x2, y2, new Color(0, c.g, 0, 1));
                    }
                }
            }
        }

        t.Apply();

        // ------------------------------
        // B G G R G G     
        // R G G B G G
        // G B R G R B
        // R G G B G G
        // B G G R G G
        // G R B G B R

        //if (false)
        for (int y = 0; y < t.height; y++)
        {
            int y2 = t.height - y - 1;

            for (int x = 0; x < t.width; x++)
            {

                int x2 = x + 1;

                float R = 0, G = 0, B = 0;

                //                if (y == 0 && x == 0)

                if (y % 6 == 0)
                {
                    if (x % 6 == 0)
                    {
                        B = (t.GetPixel(x2 + 1, y2).b + t.GetPixel(x2 + 2, y2 - 2).b) / 2f;

                        R = (t.GetPixel(x2, y2).r + t.GetPixel(x2 + 2, y2 - 1).r) / 2f;

                        G = (t.GetPixel(x2 + 2, y2).g
                            + t.GetPixel(x2, y2 - 1).g
                            + t.GetPixel(x2 + 1, y2 - 1).g
                            + t.GetPixel(x2, y2 - 2).g
                            + t.GetPixel(x2 + 1, y2 - 2).g) / 5f;

                        Color color = new Color(R, G, B);

                        t.SetPixel(x2, y2, color);
                        t.SetPixel(x2 + 1, y2, color);
                        t.SetPixel(x2 + 2, y2, color);

                        t.SetPixel(x2, y2 - 1, color);
                        t.SetPixel(x2 + 1, y2 - 1, color);
                        t.SetPixel(x2 + 2, y2 - 1, color);

                        t.SetPixel(x2, y2 - 2, color);
                        t.SetPixel(x2 + 1, y2 - 2, color);
                        t.SetPixel(x2 + 2, y2 - 2, color);
                    }

                    if (x % 6 == 3)
                    {
                        R = (t.GetPixel(x2 + 1, y2).r + t.GetPixel(x2 + 2, y2 - 2).r) / 2f;

                        B = (t.GetPixel(x2, y2).b + t.GetPixel(x2 + 2, y2 - 1).b) / 2f;

                        G = (t.GetPixel(x2 + 2, y2).g
                            + t.GetPixel(x2, y2 - 1).g
                            + t.GetPixel(x2 + 1, y2 - 1).g
                            + t.GetPixel(x2, y2 - 2).g
                            + t.GetPixel(x2 + 1, y2 - 2).g) / 5f;

                        Color color = new Color(R, G, B);

                        t.SetPixel(x2, y2, color);
                        t.SetPixel(x2 + 1, y2, color);
                        t.SetPixel(x2 + 2, y2, color);

                        t.SetPixel(x2, y2 - 1, color);
                        t.SetPixel(x2 + 1, y2 - 1, color);
                        t.SetPixel(x2 + 2, y2 - 1, color);

                        t.SetPixel(x2, y2 - 2, color);
                        t.SetPixel(x2 + 1, y2 - 2, color);
                        t.SetPixel(x2 + 2, y2 - 2, color);
                    }
                }
                else if (y % 6 == 3)
                {
                    if (x % 6 == 0)
                    {
                        R = (t.GetPixel(x2 + 1, y2).r + t.GetPixel(x2 + 2, y2 - 2).r) / 2f;

                        B = (t.GetPixel(x2, y2).b + t.GetPixel(x2 + 2, y2 - 1).b) / 2f;

                        G = (t.GetPixel(x2 + 2, y2).g
                            + t.GetPixel(x2, y2 - 1).g
                            + t.GetPixel(x2 + 1, y2 - 1).g
                            + t.GetPixel(x2, y2 - 2).g
                            + t.GetPixel(x2 + 1, y2 - 2).g) / 5f;

                        Color color = new Color(R, G, B);

                        t.SetPixel(x2, y2, color);
                        t.SetPixel(x2 + 1, y2, color);
                        t.SetPixel(x2 + 2, y2, color);

                        t.SetPixel(x2, y2 - 1, color);
                        t.SetPixel(x2 + 1, y2 - 1, color);
                        t.SetPixel(x2 + 2, y2 - 1, color);

                        t.SetPixel(x2, y2 - 2, color);
                        t.SetPixel(x2 + 1, y2 - 2, color);
                        t.SetPixel(x2 + 2, y2 - 2, color);
                    }

                    if (x % 6 == 3)
                    {
                        B = (t.GetPixel(x2 + 1, y2).b + t.GetPixel(x2 + 2, y2 - 2).b) / 2f;

                        R = (t.GetPixel(x2, y2).r + t.GetPixel(x2 + 2, y2 - 1).r) / 2f;

                        G = (t.GetPixel(x2 + 2, y2).g
                            + t.GetPixel(x2, y2 - 1).g
                            + t.GetPixel(x2 + 1, y2 - 1).g
                            + t.GetPixel(x2, y2 - 2).g
                            + t.GetPixel(x2 + 1, y2 - 2).g) / 5f;

                        Color color = new Color(R, G, B);

                        t.SetPixel(x2, y2, color);
                        t.SetPixel(x2 + 1, y2, color);
                        t.SetPixel(x2 + 2, y2, color);

                        t.SetPixel(x2, y2 - 1, color);
                        t.SetPixel(x2 + 1, y2 - 1, color);
                        t.SetPixel(x2 + 2, y2 - 1, color);

                        t.SetPixel(x2, y2 - 2, color);
                        t.SetPixel(x2 + 1, y2 - 2, color);
                        t.SetPixel(x2 + 2, y2 - 2, color);
                    }
                }
            }
        }

        t.Apply();

        outputImg.texture = t;

        File.WriteAllBytes("C:/A/My.png", t.EncodeToPNG());
    }


    public RawImage outputImg;


}

參考 :

http://fileformats.archiveteam.org/wiki/Fujifilm_RAF
https://libopenraw.freedesktop.org/wiki/Fuji_RAF/
https://pixinsight.com/forum/index.php?topic=7242.0
https://web.archive.org/web/20090214101740/http://crousseau.free.fr/imgfmt_raw.htm
http://www.rawsamples.ch/index.php/en/fuji

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值