精华内容
下载资源
问答
  • 一个完整2维矢量图形软件源代码 从pudn上面下载的。。。 欢迎大家下载
  • 计算机网络高级软件编程技术 Ethernet帧结构解析程序源代码
  • 分享一个远程控制软件源代码

    万次阅读 2016-11-19 10:00:43
    代码是2013年研究远程控制软件的时候基于gh0st3.6的源代码上面修改的。没有怎么去优化,也不免杀,有很多Bug遗留。放出代码也仅仅是为了给远程控制爱好者作为入门级的参考。 因为现在很久没有用C++做windows上面...

    开门见山给地址
    下载链接

    效果如图所示
    这里写图片描述

    代码是2013年研究远程控制软件的时候基于gh0st3.6的源代码上面修改的。没有怎么去优化,也不免杀,有很多Bug遗留。放出代码也仅仅是为了给远程控制爱好者作为入门级的参考。

    因为现在很久没有用C++做windows上面的开发了。电脑上也没安装visual studio。就简单的介绍下这个代码。运行目录如下图所示
    这里写图片描述

    使用方法
    在控制端运行Gh0st.exe程序。
    这里写图片描述
    上线地址填写控制端所在的IP地址。(新手要注意内网和外网的区别!没有外网IP的,可以研究下向日葵内网上线的课题,这里就不引述了。)
    反正也只是用于学习远程控制软件的运行机制,所以默认的端口和一些参数就不用改了。

    点击生成服务端。(记得一定要关闭杀毒软件呀!什么361,卡巴死你之类的都给他关掉,服务器端记得关闭防火墙。)。

    生成服务端后,就在当前目录下生成AeroServer.exe程序。

    双击AeroServer.exe,就会发现在Gh0st3.8主界面中已经上线了。

    软件运行的大概流程是很清晰的:

    1.服务器端(控制机)Gh0st采用windows环境下的高效完成端口IOCP来处理网络数据,启动程序后IOCP初始化并监听1990端口,等待连接和处理网络数据。
    2.客户端(肉鸡)被运行后,去连接指定的上线IP/或域名对应的端口(这里是1990)。
    3.连接成功,运行在肉鸡上的程序和服务端里应外合。开始黑暗的特洛伊之旅。

    指令流程:

    控制机发送一条指令给肉鸡,在我们这个代码中就是 Gh0st.exe 发送指令到AeroServer.exe
    肉鸡接收到这条指令后。解析对应的指令,然后执行相应的命令
    执行完的结果进行回传给控制端。控制端才知道执行的结果是成功抑或是失败。

    需要解决的问题:

    1.网络数据包的传输
    windows网络编程,需要解决数据粘包问题,需要解决掉线重连的问题。需要解决网络延时问题。

    2.远程屏幕的查看。原理是被控端程序扫描整个屏幕,生成一张图,将这张图压缩后通过网络传输到控制端。控制端收到这个网络包,通过网络协议中的约定去解析。发现是一个远程桌面信息的包,解包后在本地进行展示。绘制出这张图。大家知道24帧/s的速度就能够产生连续的动画。在远程控制中也是这个原理,不间断的更新远程桌面,就能够产生连续的视觉效果。

    如果想要了解更多的方法,可以去了解远程控制软件VNC。它的远程帧缓冲。查看这里了解远程帧缓冲相关的文章

    3.在远程屏幕的传输中,屏幕扫描算法非常重要。因为它影响到传输包的大小、频率。比如被控端桌面长期保持不变,还有必要进行全屏扫描吗?比如被控制端桌面只开了个小的聊天窗口,其他的全都没有变化,如果只扫描、变更那个聊天窗口的内容,需要传输的网络数据是否就会少很多,在同等的带宽下,会让画面更清晰流畅?所以我们用不同的远程控制软件,会感觉有不同的控制效果。有些远程控制界面卡、画质渣。而有些效果就很好。流畅、反应迅速。比如teamview,windows自带的mstsc工具等。

    远程控制软件中需要解决的问题有很多。涉及到系统的方方面面,除了网络传输,数据压缩,音视频的处理,服务器编程,EXE文件格式的处理等等。这不是一篇文章所能概述完成的。有兴趣的朋友可以自行了解相关的知识。

    witch_soya
    2016年11月19日10:00:15

    展开全文
  • 飞鸽源代码下载及英文源代码解析
  • String源代码解析

    千次阅读 2018-07-14 00:41:32
    2.string源码解析 3jdk8相对于jdk7的不同 4.补充 二.String中的享元模式 享元模式(Flyweight)可以粗略的理解为缓存(cache),是设计中的种优化策列。 1.常量与常量池 在这里需要引入常量池这简单的概念...

    一.简介

    1.关于string设计中的享元模式

    2.string源码解析

    3jdk8相对于jdk7的不同

    4.补充

    二.String中的享元模式

    享元模式(Flyweight)可以粗略的理解为缓存(cache),是设计中的一种优化策列。

    1.常量与常量池

    在这里需要引入常量池这个简单的概念。

    常量池(constant pool)指的是在编译期被确定,并被保存在已编译的.class文件中的一些数据。

    它包括了关于类、方法、接口等中的常量,也包括字符串常量。

    看例1:

    首先,我们要知结果Java会确保一个字符串常量只有一个拷贝。

    因为例子中的a0和a1都是字符串常量,它们在编译期就被确定了,所以a0==a1为true;

    而”learning ”和”String”也都是字符串常量,当一个字符串由多个字符串常量连接而成时

    ,它自己肯定也是字符串常量,所以a2也同样在编译期就被解析为一个字符串常量,

    所以as2也是常量池中”learning String”的一个引用。所以我们得出a0==a1==a2;

    到这里我们就可以理解string通过这种常量池中相同常量共享对象的方式实现了类似于缓存的享元模式设计

    2.String的构造方法

    用new String() 创建的字符串不是常量,不能在编译期就确定,所以new String() 创建的字符串不放入常量池中,

    它们有自己的地址空间。

    a0还是常量池中”learning String”的应用,a1因为无法在编译期确定,所以是运行时创建的新对象”learning String”

    的引用,a2因为有后半部分new String(“String”)所以也无法在编译期确定,所以也是一个新创建对象”learning String”

    的应用;明白了这些也就知道为何得出此结果了。

     

    3. String.intern()扩充常量池:

    存在于.class文件中的常量池,在运行期被JVM装载,并且可以扩充。String的intern()方法就是扩充常量池的一个方法;

    当一个String实例str调用intern()方法时,Java查找常量池中是否有相同Unicode的字符串常量,如果有,

    则返回其的引用,如果没有,则在常量池中增加一个Unicode等于str的字符串并返回它的引用;

    这里需要说明另外一点:

    在这里常量池中一开始是没有”learning String”的,当我们调用a0.intern()后就在常量池中新添加了

    一个”learning String”常量,原来的a0常量”kvill”地址仍然存在,所以两个的地址相同是false,

    也就不是“将自己的地址注册到常量池中”了。

     

    三.string源码解析

    1.类和成员变量

    我们看到string是个使用final 声明的不可变类,这个会在补充中涉及到,以及实现了几个接口,

    这个会在后面的方法中涉及到。这里需要先提及的是

    private final char value[];是string的值,所以string字符串声明后值属性是不可变的;

    2.string众多构造函数

    //不含参数的构造函数,一般没什么用,因为value是不可变量
    public String() {
        this.value = new char[0];
    }
    //参数为String类型
    public String(String original) {
        this.value = original.value;
        this.hash = original.hash;
    }
    //参数为char数组,使用java.utils包中的Arrays类复制
    public String(char value[]) {
        this.value = Arrays.copyOf(value, value.length);
    }
    //从bytes数组中的offset位置开始,将长度为length的字节,以charsetName格式编码,拷贝到value
    public String(byte bytes[], int offset, int length, String charsetName)
            throws UnsupportedEncodingException {
        if (charsetName == null)
            throw new NullPointerException("charsetName");
        checkBounds(bytes, offset, length);
        this.value = StringCoding.decode(charsetName, bytes, offset, length);
    }
    //调用public String(byte bytes[], int offset, int length, String charsetName)构造函数
    public String(byte bytes[], String charsetName)
            throws UnsupportedEncodingException {
        this(bytes, 0, bytes.length, charsetName);
    }

    这里需要注意的一点是,String不属于8种基本数据类型,String是一个对象。

    因为对象的默认值是null,所以String的默认值也是null;

    但它又是一种特殊的对象,有其它对象没有的一些特性。

    比如构造方法new String()和new String(“”)都会返回一个空字符串而不是null。

     

    3.intern()

    intern在上面讲到过,这里需要注意的一点是,它是通过native调用的,

    native关键字说明其修饰的方法是一个原生态方法,方法对应的实现不是在当前文件,而是在用其他语言(如C和C++)实现的文件中。

    Java语言本身不能对操作系统底层进行访问和操作,但是可以通过JNI接口调用其他语言来实现对底层的访问。

    JNI是Java本机接口(Java Native Interface),是一个本机编程接口,它是Java软件开发工具箱(java Software Development Kit,

    SDK)的一部分。JNI允许Java代码使用以其他语言编写的代码和代码库。Invocation API(JNI的一部分)

    可以用来将Java虚拟机(JVM)嵌入到本机应用程序中,从而允许程序员从本机代码内部调用Java代码。

     

    4.trim()

    作用是去掉字符串的前后空格,在字符串传值比较中比较常用

    public String trim() {
        int len = value.length;
        int st = 0;
        char[] val = value;    /* avoid getfield opcode */
        //找到字符串前段没有空格的位置
        while ((st < len) && (val[st] <= ' ')) {
            st++;
        }
        //找到字符串末尾没有空格的位置
        while ((st < len) && (val[len - 1] <= ' ')) {
            len--;
        }
        //如果前后都没有出现空格,返回字符串本身
        return ((st > 0) || (len < value.length)) ? substring(st, len) : this;
    }
     

     

    5.int compareTo(String anotherString)

    public int compareTo(String anotherString) {
        //自身对象字符串长度len1
        int len1 = value.length;
        //被比较对象字符串长度len2
        int len2 = anotherString.value.length;
        //取两个字符串长度的最小值lim
        int lim = Math.min(len1, len2);
        char v1[] = value;
        char v2[] = anotherString.value;

        int k = 0;
        //从value的第一个字符开始到最小长度lim处为止,如果字符不相等,返回自身(对象不相等处字符-被比较对象不相等字符)
        while (k < lim) {
            char c1 = v1[k];
            char c2 = v2[k];
            if (c1 != c2) {
                return c1 - c2;
            }
            k++;
        }
        //如果前面都相等,则返回(自身长度-被比较对象长度)
        return len1 - len2;
    }

    这个方法在比较字符串类型的时间时可以起到作用,通过两个值a0.compareTo(a1)比较的结果>0,<0,=0,分别可以知道a0>a1,a0<a1,a0=a1.

     

    6.boolean equals(Object anObject)

    public boolean equals(Object anObject) {
        //如果引用的是同一个对象,返回真
        if (this == anObject) {
            return true;
        }
        //如果不是String类型的数据,返回假
        if (anObject instanceof String) {
            String anotherString = (String) anObject;
            int n = value.length;
            //如果char数组长度不相等,返回假
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                //从后往前单个字符判断,如果有不相等,返回假
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                            return false;
                    i++;
                }
                //每个字符都相等,返回真
                return true;
            }
        }
        return false;
    }

     

    三千多行的代码,String中还有很多方法,这里就不一一列举了。

     

    四.jdk8相对于jdk7的不同

     

    1.jdk8去掉的方法

    int hash32()

     

    private transient int hash32 = 0;
    int hash32() {
        int h = hash32;
        if (0 == h) {
           // harmless data race on hash32 here.
           h = sun.misc.Hashing.murmur3_32(HASHING_SEED, value, 0, value.length);

           // ensure result is not zero to avoid recalcing
           h = (0 != h) ? h : 1;

           hash32 = h;
        }

        return h;
    }

    在JDK1.7中,Hash相关集合类在String类作key的情况下,不再使用hashCode方式离散数据,而是采用hash32方法。

    这个方法默认使用系统当前时间,String类地址,System类地址等作为因子计算得到hash种子,

    通过hash种子在经过hash得到32位的int型数值。

    2.jdk8新加的方法

    public static String join(CharSequence delimiter, CharSequence... elements) {

    Objects.requireNonNull(delimiter);

    Objects.requireNonNull(elements);

    // Number of elements not likely worth Arrays.stream overhead.

    StringJoiner joiner = new StringJoiner(delimiter);

    for (CharSequence cs: elements) {

    joiner.add(cs);

    }

    return joiner.toString();

    }

    使用方法

    public static String join(CharSequence delimiter,

    Iterable<? extends CharSequence> elements) {

    Objects.requireNonNull(delimiter);

    Objects.requireNonNull(elements);

    StringJoiner joiner = new StringJoiner(delimiter);

    for (CharSequence cs: elements) {

    joiner.add(cs);

    }

    return joiner.toString();

    }

    四.补充

    1.关于equals()和==:

    这个对于String简单来说就是比较两字符串的Unicode序列是否相当,如果相等返回true;而==是比较两字符串的地址是否相同

    ,也就是是否是同一个字符串的引用。

     

    2. 关于String是不可变的

    String的实例一旦生成就不会再改变了,比如说:String str=”kv”+”ill”+” “+”ans”;

    就是有4个字符串常量,首先”kv”和”ill”生成了”kvill”存在内存中,然后”kvill”又和” “ 生成 ”kvill “存在内存中,

    最后又和生成了”kvill ans”;并把这个字符串的地址赋给了str,就是因为String的“不可变”产生了很多临时变量,

    这也就是为什么建议用StringBuffer的原因了,因为StringBuffer是可改变的。

     

    3.String类被设计成不可变的原因

    1.字符串常量池的需要

    字符串常量池(String pool, String intern pool, String保留池) 是Java方法区中一个特殊的存储区域,

    当创建一个String对象时,假如此字符串值已经存在于常量池中,则不会创建一个新的对象,而是引用已经存在的对象。

    如下面的代码所示,将会在堆内存中只创建一个实际String对象.
    代码如下:
    String s1 = "abcd"; String s2 = "abcd";

    假若字符串对象允许改变,那么将会导致各种逻辑错误,比如改变一个对象会影响到另一个独立对象. 严格来说,

    这种常量池的思想,是一种优化手段.

    String s1= "ab" + "cd"; String s2= "abc" + "d";

    也许这个问题违反新手的直觉, 但是考虑到现代编译器会进行常规的优化, 所以他们都会指向常量池中的同一个对象.

    或者,你可以用 jd-gui 之类的工具查看一下编译后的class文件.

    2. 允许String对象缓存HashCode

    Java中String对象的哈希码被频繁地使用, 比如在hashMap 等容器中。

    字符串不变性保证了hash码的唯一性,因此可以放心地进行缓存.这也是一种性能优化手段,意味着不必每次都去计算新的哈希码.

    3. 安全性

    String被许多的Java类(库)用来当做参数,例如 网络连接地址URL,文件路径path,还有反射机制所需要的String参数等,

    假若String不是固定不变的,将会引起各种安全隐患。

    假如有如下的代码:boolean connect(string s){ if (!isSecure(s)) {throw new SecurityException();}

    // 如果在其他地方可以修改String,那么此处就会引起各种预料不到的问题/错误 causeProblem(s);}

    4. 线程安全

    因为字符串是不可变的,所以是多线程安全的,同一个字符串实例可以被多个线程共享。这样便不用因为线程安全问题而使用同步。

    字符串自己便是线程安全的。

    总体来说, String不可变的原因包括 设计考虑,效率优化问题,以及安全性这三大方面.

     

    4. 如何实现一个不可变类

    既然不可变类有这么多优势,那么我们借鉴String类的设计,自己实现一个不可变类。

    不可变类的设计通常要遵循以下几个原则:

    1. 将类声明为final,所以它不能被继承。
    2. 将所有的成员声明为私有的,这样就不允许直接访问这些成员。
    3. 对变量不要提供setter方法。
    4. 将所有可变的成员声明为final,这样只能对它们赋值一次。
    5. 通过构造器初始化所有成员,进行深拷贝(deep copy)。
    6. 在getter方法中,不要直接返回对象本身,而是克隆对象,并返回对象的拷贝。

     

    写在最后,我在学习的过程中,喜欢结合自己的理解记录在我的有道云笔记中,在这里我重新整理了关于String的学习理解,写篇博客,如果有一些地方存在歧义,希望能够有人指出,并在后期改正,同时希望对Java学习者有所帮助。

    展开全文
  • 用友软件源代码 非常详细 相应有解析 财务会计 进销存
  • 经典电路分析软件spice3f源代码
  • VC++编写的组态软件源代码

    热门讨论 2012-08-01 09:10:44
    使用VC++6.0完成的组态软件,包含完整源代码
  • cloudcompare软件款开源的点云处理软件,其源代码对编写点云处理程序的同学有所帮助。
  • 嵌入式系统编程源代码解析书籍的配套光盘,有源代码和一些软件
  • 代码是《解析Windows2000的IDT扩展机制》配套代码 关键字:IDT,hook,软件中断,钩子
  • 开放源代码软件

    千次阅读 2012-08-11 16:02:15
    开放源代码软件 百科名片 开放源码软件《open-source》是一个新名词,它被定义为描述其源码可以被公众使用的软件,并且此软件的使用,修改和分发也不受许可证的限制。开放源码软件通常是有copyright的,它...

    开放源代码软件

    百科名片

    开放源码软件《open-source》是一个新名词,它被定义为描述其源码可以被公众使用的软件,并且此软件的使用,修改和分发也不受许可证的限制。开放源码软件通常是有copyright的,它的许可证可能包含这样一些限制: 著意的保护它的开放源码状态,著者身份的公告,或者开发的控制。“开放源码”正在被公众利益软件组织注册为认证标记,这也是创立正式的开放源码定义的一种手段。

     

    简介

      开放源码软件主要被散布在全世界的编程者队伍所开发,但是同时一些大学,政府机构承包商,协会和商业公司也开发它。开放源码软件在历史上曾经与 UNIXInternet联系得非常 紧密。在这些系统中许多不同的硬件需要支持,而且源码分发是实现交叉平台 可移植性的唯一实际可行的办法。在 DOSWindowsMacintosh平台上仅仅有很少的用户有可用的 编译器,开放源码软件更加不普遍。对开放源码开发模式的更详细的讨论请看Eric Raymond写的“The Cathedral and the Bazaar”。

    为什么open-source软件与软件市场有关系

      传统的商业软件有巨大的广告和商标预算,在这些背后给了它太多的关注,已经远远超出了它的重要性。传统的商业软件事实上只是所有软件的很小的一部分。Lion(狮子)是被各种组织开发,并且是为了它们自己内部的需要。内部开发源码,特别是被美国政府所命令的重要 源码的共享是具有开发源码牌照的。这实际上是由于绝大多数软件专家不编写 商业软件
      要去定量的描述开放源码软件的整个影响和平均利益是困难的,但是很明显这两者都被公众广泛传播又低估其价值。现在,许多开放源码软件由商业开发支持。同时,开放源码经营模式的成功和开放源码开发的高生产效率及高质量都说服Netscape(公司名)在1998年年初决定要将它的 浏览器开发在开放源码许可之下。
      现在有巨大的动力推动着开放源码的运动。看到如此多的传统商业开发者们为了与他同步不得不谋取发展是很有趣的。计算机工业早已看到了几个激动人心的发展和革新的浪潮,例如,二十世纪七十年代的第一台微机,以及八十年代中期到现在对日用微机的大量生产,还有同一时期 Internet(互联网)的 崛起。使用开放源码模式的商业软件可能是下一个重要的新 潮流

    怎样区别开放源码软件和免费软件

      历史上许多人开发过这样一种软件(也就是免费软件基础)简称为“free software”,而媒介一般称它为“freeware”。不幸的是这两种 术语都被证明是不明确的且含糊的。
      对于大多数人来说“free”仅仅用于购买的费用。比这个初始花费更重要的是由于缺乏许可证限制而带来的费用。这些是几种有可能是免费的软件类型,但是明显不是open-source software,因为它们具有某些 限制或是缺乏公开的源码:

    Shareware

      通常是由个人开发的,一般没有支持且没有公开的源码,它希望得到使用者的 资助

    Demos/"Crippleware":

      免费或低费用试用的软件,是商业软件的一部分,它没有自由可用的源码,没有支持,通常缺乏关键特征。

    Bundled Software:

      它由商业软件携带并且不用增加额外的费用,但是它一般具有很有限的使用许可,没有自由可用的源码。例如:Microsoft Internet Explore. "Consortium-Ware": 源码由公司内部人员共享,但是对公众没有自由可用的源码。例如:Motif. "Non-commercial use only": 这是可以免费从Internet网 下载的典型软件,甚至连同源码,但是同时它有严格的许可证限制它的使用。例如:1998年以前的Netscape的浏览器一些Open-source许可证类型
      BSD(Berkeley Source Distribution)许可证:它要求 版权和著者身份申明

    GPL

      通用公共许可证("CopyLeft")禁止派生或分发产品的限制。

    LGPL

      库通用许可证,它不同于 GPL许可证,在这个许可证下,库(函数库)可以自由的联接到私有软件。

    Artistic License:

      使作者保持对进一步开发的控制。

    NPL(Netscape Public Lincense)

      基于GPL精神的新的许可证,但是保持了对源码更多的控制和所有权(请看下面的“Netscape发展什么”这一节)
      Public Domain/Not Copyrighted/No Restrictions: 通常用于决定性的算法以鼓励广泛使用,通常由美国政府使用。
      Open-source 软件的一些例子
      现在有几百种成熟的open-source产品被广泛使用。这而是一些最著名的:

    Corncart

      由OSIC信息技术有限公司最新开发的开源电子软件,集合之前所有电子开源软件的所有优点。目前尚处于二次开发阶段。

    BSD UNⅨ:

      由California大学Berkeley分校开发的基于"BSD"许可证的软件。许多UNⅨ商业版本是直接基于BSD源码或者大多从它的设计中借用来的。
      Linux: 它从一个芬兰的大学生的研究项目成长为近六年最流行的非Microsoft 操作系统。最初它仅仅是为PCs机设计的,可现在它支持Palm Pilots(小型掌中平台),大型的64位Digital Alphas芯片的超级计算机,和在这两者之间的几乎任何事物。与传统操作系统相比它的 效率更高,更可靠,更先进。它包括编译程序,库,和来自于FreeSoftware Foundation的各种工具,还有成千上万的open-source产品,Linux平台是一个小的但是却在快速成长的商业产业的基础,还是软件革新的温床。它由商业公司和散布在全世界的自由编程人员基于GPL所开发。

    Perl语言

      "Internet的传输带”,大多数web服务器的动态内容的基础,广泛用于脚本语言编程和自动化文档处理。它由Perl研究所基于Artistic 许可协议开发。

    GCC:

      GNU C 编译器是许多Unix平台上首选的C/ C++ 编译器,也可以在其他平台上运行;因为支持几乎每种处理器,所以它也被作为一个跨平台的工具而广为流行;它由FSF基于GPL维护、开发。

    X Window 系统

      使用最广的非microsoft窗口系统,具有先进的跨平台远程执行特性,性能优良,灵活度高;由MIT和X Consortium在类 BSD许可协议下开发;其他的增强功能由The XFree86 Project公司开发。
      Internet 主干:
      BIND: Berkeley Internet Name Daemon; 为几乎所有的Internet域名解析服务器使用,其行为如同一个分散全球的分布式数据库;由ISC(Internet Software Consortium)维护。
      BSD SendMail: 邮件传输代理的最高标准。没有任何一家商业竞争者能和它匹敌,绝对安全、健壮;负责处理Internet上超过75%的邮件传输任务,包括象 AOL这样的巨型站点---每天有数百万的消息。由SendMail公司基于BSD许可协议维护。
      INN:InterNet新闻服务器,操纵Internet上的决大多数Usenet新闻还包括许多企业网。被ISC(BSD)所维护(BSD许可协议)。
      Apache: 超过半数的 web服务器的动力(远远超出Microsoft和Netscape加起来的数量),早在1998年用于超过百万的web服务器。由Apache组织开发(类BSD许可证维护)。
      WU-FTPD: 在Internet网上最流行的FTP服务器,几乎使用于所有的 FTP站点。最初是由Bryan O'Connor在Washington大学Louis大街开发的,现在被Academ Consulting Services和许多自愿者维护(BSD许可)。

    使用Open-Source的优点

      降低 风险:拥有源代码使顾客们可以控制那些他们的业务所赖以生存的工具。当一个open-source产品的开发者提高价格,增加了难以接收的限制,或者使用了一些使顾客不满意的方法,另一个不同的组织将使用该源代码开始开发新的产品以解决原来机构的问题。顾客也能自己维护或找别人改进它以达到自己的要求。顾客控制软件,这在传统私有软件模式下是 闻所未闻的事情。即使是一些财大气粗的顾客也可能缓解由于传统软件商自己内部的问题而导致严重的金融危机或公司被别的公司收购的风险。

    质量

      一些研究已经显示了open-source软件与别的可比商业软件具有可靠性上的极大优势。更加有效的开发模式,更多的独立同行对代码和设计的双重审查,以及大部分作者对自己作品的极大 荣誉感,都对其优良的质量有所贡献。一些公司甚至给予发现Bug者以 物质 奖励

    透明度

      私有软件有很多“阴暗的死角”,隐藏着许多Bug。源码对于查错和理解产品工作原理来说是很重要的。在大的软件公司,只有极少数人能接触到源码,而这些能接触源码的人通常用户都无法直接接触。能接触源码对于修补安全漏洞来说,也是非常重要的。

    正确的特性

      一些开放源码的产品--包括上面列举的一些产品--是如此成功,以至于其商业竞争者无法存活。

    剪裁

      开放源码给用户极大自由,使他们能够按照自己的业务需求定制软件。大型组织能从即使很小的定制行为中削减大量开支和人力成本。用户的挑错和改进反过来对标准开放源码软件包也是个贡献。这在传统的私有软件开发中是不可能得到的。
      有利的版权许可和价格:定义为开放源码使得软件在版权许可方面比私有软件具有更大的灵活性。这可以大大削减更多安装带来的花费和时间,对那些采购过程费时费力的机构更加有利。它也能给用户安装软件以更大的自由度。
      什么时候不使用开放源码软件

    错误的特性

      如果一个开放源码产品不能很好地满足一个组织的需求,而另外的一个 私有软件却可以,并且得到一个满足特性的私有软件的成本比再开发修改一个开放源码产品的成本高的话,最好不使用开放源码软件。但参考上面的“剪裁”。

    支持:

      一些open-source软件传统的付费支持和电话支持。事实上,无论怎样,这都没有一个既没有源代码且无支持的产品严重。请看支持和open source软件一节。

    错误的平台

      大部分open-source软件主要是支持UNⅨ和Linux系统的,有时也支持Windows NT。另一些平台,例如大型机,对于移植开放源码软件是个巨大挑战。移植软件从UNⅨ到Windows NT上要付出很大代价。然而。开放源码的优点几乎可以使平台转换显得更划算。

    缺乏技术人员

      安装open-source软件有时需要一些更多的技术经验,例如,可以配置或编译源代码的能力。有源代码的优点在一些没有软件开发专家的公司被降低了。open-source的定制也要求有配置管理经验。无论如何,那些充分具有上述技术能力的任何组织都会很好地享受open-source的优点。

    惰性

      如果现存的所有系统都被很好的支持并完成,就没有必要去改变它们。然而,时常的去检讨这个决定是很重要,因为新技术经常会使它们变得过时。
      值得怀疑的避免open-source软件的原因
      这些论据常被作为避免使用open-source软件的借口,但是通常经不起 推敲
      ---对未知的恐惧。
      正如你在上面的“open-source软件的例子”一节所看到的,许多的组织已经严重的依赖open-source软件,不管他们的决策者是否意识到这一点。这个问题由于open-source开发者宣传和使用市场的增加,以及更多的拥护者的出现变得比较容易解决。
      ---在购买商业软件包上我们已经拥有巨大的投资。
      这仅仅是“必然花费 谬误”的一种形式。软件许可证,好像为写字楼付的租金,是一些消费,但不是投资。如果别的产品能很好的以较低的成本实现你的组织的需要,那么过去把钱花费在低级的软件上对
      决策不应该产生影响。记住,你可能面临严重的政治上的反对,它来自于那些选择了赞成使用昂贵的,低级的产品,而不愿意承认他们的错误的守旧者。同时,考虑到它们可能被再次扩展,在训练职员和相关基础设施上的投资是完全合理的。
      ---如果出了问题,我们需要有人负责。
      尽管理论上这听起来很合理,但如果我们一开始就使用可信赖的软件产品,远比在遭受经济损失之后才去控告软件供应商要好的多。几乎所有的主要软件公司都利用最终用户许可证的支持来解决一些由于他们软件的问题而带来的可能要负责的困扰。Microsoft和IBM公司有著庞大的,一流的 法律职员,使得顾客的控诉不可能成功。在将来法律可能会越来越偏向软件供应商。

    open-source和软件技术支持

      商业支持和同几乎是那些正在使用open-source软件的公司最关心的问题了。付费支持是正当的问题,但是这对于open-source产品通常是可用的,而且一般都过高估计了它的重要性。
      ---许多主要的open-source产品都有可用的技术支持合同。
      例如,Red Hat 和Caldera公司对他们销售的linux有电话支持。 Cygnus,Collective Technologies和许多小的顾问公司靠支持和增强open-source软件,生意也做的不错。而且越来越多的open-source软件在保持其开放源码状态的同时,也获得了大量商业维护和支持。
      ---电子邮件和Usenet新闻支持时非常有效的。
      几乎所有开发open-source软件的组织都提供免费的 电子邮件支持,提供邮件列表和Usenet 新闻组。这些机制比电话支持更加实际有效。在一个有许多软件供应商所支持的调查中,“Linux用户协会”在1997年获得“最好的技术支持奖”,同时也暴露了许多对传统的软件开发商的服务质量的大量不满意见。
      ---对传统商业软件的支持经常是有限的并且是低质量的。
      例如Microsoft公司仅仅提供了为它的所有产品仅仅提供了一个技术支持电话号码:900。许多市场商业销售支持人员把 注意力集中在帮助初学者上手上,无法回答使用 手册上没有包括的问题。许多软件公司认为传统的电话支持是很昂贵的代价,而因此消减它,这就导致了质量下降。

    Netscape的发展趋势

      一个著名的计算机工业杂志报道Netscape是“受大量免费和共享软件许可的启发”。事实上,Netscape正在与许多著名的UNⅨ自由软件开发者互通信息,现在看起来已经非常接近BSD和GPL许可证了。Nescape Public License和GPL有所不同,它使得Nescape对源码的开发和 商标上有更多的控制。
      Netscape的弃子战术是很聪明的。首先,浏览器的销售在Netscape的业务中已经只占很少一部分了。浏览器的开放源码状态不会对它有太大的冲击,另外有些想要正式 技术支持的买家仍然愿意付钱。第二,它真正按照某个开放源码的许可证发放,从而完全改变了Microsoft免费派送Explorer造成的被动局面。这将有助于提高Nescape浏览器的市场份额。最后,Netscape的立场从开放源码社群中获得了友谊,信任度和潜在的巨大革新。Netscape的未来还不能让人放心,尤其是在 NT的Web服务器上;但它为Communicator采用的勇敢的、戏剧性的许可证政策不会带来任何损失。

    开源软件的类型

    web服务器

      WEB服务器也称为WWW(WORLD WIDE WEB)服务器,主要功能是提供网上信息浏览服务。WWW 是 Internet 的多媒体信息查询工具,是 Internet 上近年才发展起来的服务,也是发展最快和目前用的最广泛的服务。正是因为有了WWW工具,才使得近年来 Internet 迅速发展,且用户数量飞速增长。
      开源的web服务器软件包括 apachekanglenginx等。

    应用服务器

      应用服务器定是指通过各种协议把商业逻辑曝露给客户端的程序。它提供了访问商业逻辑的途径以供客户端应用程序使用。应用服务器使用此商业逻辑就像调用对象的一个方法一样。简单的说能实现动态网页技术的服务器叫做应用服务器。
      开源的应用服务器软件包括Enhydra (Java)、JBoss (Java)、Open3 (XML)等。

    消息服务器/消息平台

      消息服务器作为网络的节点,专门用来存储、转发网络上的数据、信息(例如:聊天信息)。做一个形象的比喻:消息服务器就像是邮局的交换机,而微机、笔记本、PDA、手机等固定或移动的网络终端,就如散落在家庭、各种办公场所、公共场所等处的电话机。我们与外界日常的生活、工作中的电话交流、沟通,必须经过交换机,才能到达目标电话;同样如此,我们利用个人电脑,PDA,手机等,发送消息,也必须经过消息服务器,因此也可以说是消息服务器在“组织”和“领导”这些接收消息设备。
      开源的消息服务器软件包括ArsDigita (Tcl & Java)、Exolab Group (J2EE,整合OpenEJB,OpenJMS,OpenORA,Tyrex)、Zend (PHP)等。

    企业应用程序

      企业应用程序是一个泛指的概念,细分下来可分为企业资源计划(ERP)、客户关联管理、项目管理、内容管理、人力资源管理、自动化采购软件、信息仓库(CIW)、生产计划、库存管理、群组软体、B2B和图书馆资源整合系统(ILS)。
      开源的企业应用程序包括Compiere (ERP+CRM)、Compiere、Gnome Planner 、ArsDigita、phpgroupware、J2EE、Akopia、Compiere (ERP+CRM)、openapplications、OpenBiblio等。

    Blog

      Blog 全名Web log,中文意思是“网络日志”,后来缩写为Blog。它是继Email、BBS、IM之后出现的第四种网络交流方式,是网络时代的个人“读者文摘”,是以超级链接为武器的网络日记,是代表着新的生活方式和新的工作方式,更代表着新的学习方式。简言之,Blog 就是以网络作为载体,简易迅速便捷地发布自己的心得,及时有效轻松地与他人进行交流,再集丰富多彩的个性化展示于一体的综合性平台。
      开源的Blog软件有b2evolution (PHP+MySQL)、BLOG:CMS (PHP、基于Nucleus CMS)、BLOG:CMS (PHP、基于Nucleus CMS)等。

    无线

      所谓无线网络,既包括允许用户建立远距离无线连接的全球语音和数据网络,也包括为近距离无线连接进行优化的红外线技术及射频技术,与有线网络的用途十分类似,最大的不同在于传输媒介的不同,利用无线电技术取代网线,可以和有线网络互为备份。
      开源的无线应用程序有kannel、Jwap、Ophelia等。

    论坛

      论坛又名网络论坛BBS,全称为Bulletin Board System(电子公告板)或者Bulletin Board Service(公告板服务)。是Internet上的一种电子信息服务系统。它提供一块公共电子白板,每个用户都可以在上面书写,可发布信息或提出看法。它是一种交互性强,内容丰富而即使的Internet电子信息服务系统。用户在BBS站点上可以获得各种信息服务,发布信息,进行讨论,聊天等等。
      开源的论坛应用软件包括phpbb、BMForum、phpwind[等。

    数据库

      数据库(Database)是按照数据结构来组织、存储和管理数据的仓库,它产生于距今五十年前,随着信息技术和市场的发展,特别是二十世纪九十年代以后,数据管理不再仅仅是存储和管理数据,而转变成用户所需要的各种数据管理的方式。数据库有很多种类型,从最简单的存储有各种数据的表格到能够进行海量数据存储的大型数据库系统都在各个方面得到了广泛的应用。
      开源的数据库软件有BerkelayDB、MySQL、SQLite等。

    桌面环境类

      “桌面环境”可能仅仅是一个简单的窗口管理器,也可能是一个像 KDE 或者 GNOME这样的完整桌面应用程序套件。
      开源的桌面环境类软件包括GNOME、GNUstep、KDE等。

    窗口管理类

      窗口管理,又名用户界面,电子计算机系统中实现用户与计算机信息交换的软件、硬件部分。软件部分包括用户与计算机信息交换的约定、操作命令等处理软件,硬件部分包括输入装置和输出装置。目前常用的是图形用户界面,它采用多窗口系统,显示直接形象,操作简便。
      开源的窗口管理类软件有Afterstep、Twm、fvwm、Window Maker等。

    CD-刻录类

      CD刻录机的功能是:可以刻录CD,读取CD,但是却无法读取/写入DVD,功能上次于COMBO,又次于DVD刻录机。现在多数人使用的是DVDROM,COMBO,DVD刻录机。性能方面:读取——CDROM=CD刻录机<DVDROM=COMBO=DVD刻录机;写入——CD刻录机<COMBO<DVD刻录机。
      开源的CD刻录软件有CD Record、Freeburn、Xfburn等。

    文件编辑类

      文件编辑类软件是一个泛指的概念,细分下来包括办公软件套件、记事本、PDF相关软件、科技文本编辑器、文本编辑器、WYSIWYG和文件处理。
      开源的文件编辑类软件包括Gnome Office、KeyNote、FPDF、GNU TeXmacs、FreeDOS edlin、HTMLarea、AbiWord等。

    教育类软件

      教育类软件是一个泛指的概念,细分下来包括学习支持软件、语言相关软件、数学相关软件、科学研究软件、打字软件和其他教育软件。
      开源的教育类软件包括ILIAS、FlashKard、KBruch、BioJava、GNU Typist、KEduca等。

    金融相关软件

      从广义上说,政府、个人、组织等市场主体通过募集、配置和使用资金而产生的所有资本流动都可称之为金融。因此,不仅是金融业者,有关政府的财政,行业企业的行为、以及个人的理财都是金融的一部分。
      开源的金融相关软件有GnuCash、JCash、JMoney等。

    游戏类软件

      游戏有很多种,在不同的媒体会以不同型式出现,使用的道具或参与的人数不一样也会衍生出不同类型的游戏。其中包括:人手游戏、桌上游戏、版图游戏、纸上游戏、纸牌游戏、群体游戏、电子游戏、角色扮演游戏、益智类游戏和其他。
      开源的游戏类软件有Abuse、Falcon's Eye、Java Risk、UFO2000、XulMine等。

    网络及因特网类

      网络及因特网类软件是一个泛指的概念,细分下来包括电子邮件、即时通讯软件、通讯相关软件、文件传输软件、P2P文件共享软件、远程登录、网页浏览器、Webcam、Webgrabber、网络相关软件和其他网络软件。
      络及因特网类软件有Magic Mail Monitor 3、AMSN、Slrn、Samba、eMule、RealVNC、Galeon、Dorgem、HTTrack、Apache Tomcat、OpenLDAP等。

    数学软件类

      是专门用来进行数学运算、数学规划、统计运算、工程运算、绘制数学图形或制作数学动画的软件。
      开源的数学类软件包括GAP、MAⅪMA、SINGULAR等。

    媒体类

      体类软件是一个泛指的概念,细分下来包括音频编辑软件/音频管理软件、图形类/图片浏览类、媒体播放器类、视频剪辑类。
      源的媒体类软件包括CD-DA X-Tractor、GOCR/JOCR、JCDSee、CoolPlayer、GNU VCDImager等。

    操作系统类

      操作系统(英语:Operating System,简称OS)是一管理电脑硬件与电脑软件资源的程序,同时也是计算机系统的核心与基石。操作系统身负诸如管理与配置内存、决定系统资源供需的优先次序、控制输入与输出设备、操作网上与管理文件系统等基本事务。操作系统也提供一个让用户与系统交互的操作接口。
      开源的操作系统类软件有开源Unix(System V/BSD)、FreeDOS、Linux、Menuet等。

    密码管理类

      围绕用户账号密码安全和管理的软件或者硬件的集合。
      开源的密码管理类软件包括Password Safe、PINs等。

    个人信息管理类

      个人信息管理系统是一种提供个人信息组织管理功能的应用软件。其目的是为了便于记录、跟踪和管理各种个人信息。
      开源的个人信息管理类软件有Elephant Memory、KAddressbook、KOrganizer等。

    编程语言类

      计算机语言的种类非常的多,总的来说可以分成机器语言,汇编语言,高级语言三大类。如果按语种分,可以分为英文符号语言和汉语符号语言两类。(典型的如:易语言、易语言.飞扬) 电脑每做的一次动作,一个步骤,都是按照已经用计算机语言编好的程序来执行的,程序是计算机要执行的指令的集合,而程序全部都是用我们所掌握的语言来编写的。所以人们要控制计算机一定要通过计算机语言向计算机发出命令。目前通用的编程语言有两种形式:汇编语言和高级语言。
      开源的编程语言类软件包括DJGPP、GCC、Open64、Objective CAML、PHP等。

    屏幕保护软件

      屏幕保护程序是电脑程序,原意是通过将画面空白,或在画面上填满移动的图像,避免电脑显示器在静止的情况下产生磷质烙印,从而减低其寿命。现在,屏幕保护程序被用作娱乐或保安用途。
      开源的屏幕保护软件有Flurry、KISS Image Screen Saver、Really Slick Screensavers、xmatrix等。

    安全软件

      安全软件是一个泛指的概念,细分下来包括杀毒软件、加密软件、防火墙、SSH、其他安全软件。
      开源的安全软件包括Open Antivirus、GnuPG、Coyote Linux、OpenSSH、Stunnel等。

    其他软件

      下面列举一些难于分类的开源软件:
      Active2
      AstroGrep — 有GUI图形界面的Grep
      Autopackage — Linux上的软件包管理系统
      BibleTime — 圣经学习软件
      Bochs — PC积累器
      Cygwin — Win32的开源Unix模拟环境
      Link Checker — 检查HTML文档的坏连接
      Memtest86 — 内存检查软件
      Open Scene Graph
      Sun Grid Engine — 计算机集群软件
      TeX — 排版系统
      Vitrite — Windows 2000/XP 上使窗口透明的软件
      WINE — 在Linux/BSD上运行Windows软件
      XFree86 — 视窗系统
      gEDA自动化电器设计工具
      GPAI 通用公共人工智能平台
    展开全文
  • 本文分析MediaInfo中解码JPEG信息的...在这里分析一下解码JPEG文件的代码。其他格式如BMP,GIF等解析的思路基本上是类似的。   File_Jpeg.h的File_Jpeg类的定义如下所示: //****************************************

    =====================================================

    MediaInfo源代码分析系列文章列表:

    MediaInfo源代码分析 1:整体结构
    MediaInfo源代码分析 2:API函数
    MediaInfo源代码分析 3:Open()函数
    MediaInfo源代码分析 4:Inform()函数
    MediaInfo源代码分析 5:JPEG解析代码分析

    =====================================================


    本文分析MediaInfo中解码JPEG信息的模块。之前写了几篇文章都是关于MediaInfo主程序的,并没有分析其具体是如何解析不同多媒体文件信息的。在这里分析一下解码JPEG文件的代码。其他格式如BMP,GIF等解析的思路基本上是类似的。

     

    File_Jpeg.h的File_Jpeg类的定义如下所示:

    //***************************************************************************
    // Class File_Jpeg
    //***************************************************************************
    //继承 File__Analyze
    class File_Jpeg : public File__Analyze
    {
    public :
        //In
        stream_t StreamKind;
        bool     Interlaced;
    
        //Constructor/Destructor
        File_Jpeg();
    
    private :
        //Streams management
        void Streams_Accept();
    
        //Buffer - File header
        bool FileHeader_Begin();
    
        //Buffer - Synchro
        bool Synchronize();
        bool Synched_Test();
        void Synched_Init();
    
        //Buffer - Demux
        #if MEDIAINFO_DEMUX
        bool Demux_UnpacketizeContainer_Test() {return Demux_UnpacketizeContainer_Test_OneFramePerFile();}
        #endif //MEDIAINFO_DEMUX
    
        //Buffer - Global
        void Read_Buffer_Unsynched();
        #if MEDIAINFO_SEEK
        size_t Read_Buffer_Seek (size_t Method, int64u Value, int64u ID) {return Read_Buffer_Seek_OneFramePerFile(Method, Value, ID);}
        #endif //MEDIAINFO_SEEK
    
        //Buffer - Per element
    	//解析头
        void Header_Parse();
        bool Header_Parser_Fill_Size();
    	//解析数据
        void Data_Parse();
    
        //Elements
    	//JPEG中的单元
    	//解析相应的单元,并获得信息
        void TEM () {};
        void SOC () {}
        void SIZ ();
        void COD ();
        void COC () {Skip_XX(Element_Size, "Data");}
        void TLM () {Skip_XX(Element_Size, "Data");}
        void PLM () {Skip_XX(Element_Size, "Data");}
        void PLT () {Skip_XX(Element_Size, "Data");}
        void QCD ();
        void QCC () {Skip_XX(Element_Size, "Data");}
        void RGN () {Skip_XX(Element_Size, "Data");}
        void PPM () {Skip_XX(Element_Size, "Data");}
        void PPT () {Skip_XX(Element_Size, "Data");}
        void CME () {Skip_XX(Element_Size, "Data");}
        void SOT () {Skip_XX(Element_Size, "Data");}
        void SOP () {Skip_XX(Element_Size, "Data");}
        void EPH () {Skip_XX(Element_Size, "Data");}
        void SOD ();
        void SOF_();
        void S0F0() {SOF_();};
        void S0F1() {SOF_();};
        void S0F2() {SOF_();};
        void S0F3() {SOF_();}
        void DHT () {Skip_XX(Element_Size, "Data");}
        void S0F5() {SOF_();}
        void S0F6() {SOF_();}
        void S0F7() {SOF_();}
        void JPG () {Skip_XX(Element_Size, "Data");}
        void S0F9() {SOF_();}
        void S0FA() {SOF_();}
        void S0FB() {SOF_();}
        void DAC () {Skip_XX(Element_Size, "Data");}
        void S0FD() {SOF_();}
        void S0FE() {SOF_();}
        void S0FF() {SOF_();}
        void RST0() {};
        void RST1() {};
        void RST2() {};
        void RST3() {};
        void RST4() {};
        void RST5() {};
        void RST6() {};
        void RST7() {};
        void SOI () {};
        void EOI () {};
        void SOS ();
        void DQT () {Skip_XX(Element_Size, "Data");}
        void DNL () {Skip_XX(Element_Size, "Data");}
        void DRI () {Skip_XX(Element_Size, "Data");}
        void DHP () {Skip_XX(Element_Size, "Data");}
        void EXP () {Skip_XX(Element_Size, "Data");}
        void APP0();
        void APP0_AVI1();
        void APP0_JFIF();
        void APP0_JFFF();
        void APP0_JFFF_JPEG();
        void APP0_JFFF_1B();
        void APP0_JFFF_3B();
        void APP1();
        void APP1_EXIF();
        void APP2() {Skip_XX(Element_Size, "Data");}
        void APP3() {Skip_XX(Element_Size, "Data");}
        void APP4() {Skip_XX(Element_Size, "Data");}
        void APP5() {Skip_XX(Element_Size, "Data");}
        void APP6() {Skip_XX(Element_Size, "Data");}
        void APP7() {Skip_XX(Element_Size, "Data");}
        void APP8() {Skip_XX(Element_Size, "Data");}
        void APP9() {Skip_XX(Element_Size, "Data");}
        void APPA() {Skip_XX(Element_Size, "Data");}
        void APPB() {Skip_XX(Element_Size, "Data");}
        void APPC() {Skip_XX(Element_Size, "Data");}
        void APPD() {Skip_XX(Element_Size, "Data");}
        void APPE();
        void APPE_Adobe0();
        void APPF() {Skip_XX(Element_Size, "Data");}
        void JPG0() {Skip_XX(Element_Size, "Data");}
        void JPG1() {Skip_XX(Element_Size, "Data");}
        void JPG2() {Skip_XX(Element_Size, "Data");}
        void JPG3() {Skip_XX(Element_Size, "Data");}
        void JPG4() {Skip_XX(Element_Size, "Data");}
        void JPG5() {Skip_XX(Element_Size, "Data");}
        void JPG6() {Skip_XX(Element_Size, "Data");}
        void JPG7() {Skip_XX(Element_Size, "Data");}
        void JPG8() {Skip_XX(Element_Size, "Data");}
        void JPG9() {Skip_XX(Element_Size, "Data");}
        void JPGA() {Skip_XX(Element_Size, "Data");}
        void JPGB() {Skip_XX(Element_Size, "Data");}
        void JPGC() {Skip_XX(Element_Size, "Data");}
        void JPGD() {Skip_XX(Element_Size, "Data");}
        void COM () {Skip_XX(Element_Size, "Data");}
    
        //Temp
        int8u APPE_Adobe0_transform;
        bool  APP0_JFIF_Parsed;
        bool  SOS_SOD_Parsed;
    };


    上面代码有以下几个特点:

    1.继承了File__Analyze类

    2.包含了很多JPEG中的数据单元的解析:DHT(),DQT()等等


    下面来分别仔细看看源代码:

    1.File__Analyze类代码巨多无比,先不分析。他继承了继承了File__Base

    2.看一个解码具体单元的代码:SOF_()

    注:SOF0(Start of Image,图像开始)。

    SOF0,Start of Frame,帧图像开始

                            标记代码                   2字节     固定值0xFFC0

                           包含9个具体字段:
                                          ① 数据长度           2字节     ①~⑥六个字段的总长度
                                                                                          即不包括标记代码,但包括本字段
                                         ② 精度                 1字节     每个数据样本的位数
                                                                                        通常是8位,一般软件都不支持 12位和16位
                                        ③ 图像高度           2字节     图像高度(单位:像素),如果不支持 DNL 就必须 >0
                                        ④ 图像宽度           2字节     图像宽度(单位:像素),如果不支持 DNL 就必须 >0
                                        ⑤ 颜色分量数        1字节     只有3个数值可选
                                                                         1:灰度图;3:YCrCb或YIQ;4:CMYK
                                                                         而JFIF中使用YCrCb,故这里颜色分量数恒为3
                                       ⑥颜色分量信息      颜色分量数×3字节(通常为9字节)
                                                           a)         颜色分量ID                 1字节    
                                                           b)        水平/垂直采样因子      1字节            高4位:水平采样因子
                                                                      低4位:垂直采样因子
                                                                    (曾经看到某资料把这两者调转了)
                                                           c)        量化表                         1字节            当前分量使用的量化表的ID

               本标记段中,字段⑥应该重复出现,有多少个颜色分量(字段⑤),就出现多少次(一般为3次)。

    =====================================

    void File_Jpeg::SOF_()
    {
        //Parsing
        vector<Jpeg_samplingfactor> SamplingFactors;
        int16u Height, Width;
        int8u  Resolution, Count;
        Get_B1 (Resolution,                                         "P - Sample precision");
        Get_B2 (Height,                                             "Y - Number of lines");
        Get_B2 (Width,                                              "X - Number of samples per line");
        Get_B1 (Count,                                              "Nf - Number of image components in frame");
        for (int8u Pos=0; Pos<Count; Pos++)
        {
            Jpeg_samplingfactor SamplingFactor;
            Element_Begin1("Component");
            Get_B1 (   SamplingFactor.Ci,                           "Ci - Component identifier"); if (SamplingFactor.Ci>Count) Element_Info1(Ztring().append(1, (Char)SamplingFactor.Ci)); else Element_Info1(SamplingFactor.Ci);
            BS_Begin();
            Get_S1 (4, SamplingFactor.Hi,                           "Hi - Horizontal sampling factor"); Element_Info1(SamplingFactor.Hi);
            Get_S1 (4, SamplingFactor.Vi,                           "Vi - Vertical sampling factor"); Element_Info1(SamplingFactor.Vi);
            BS_End();
            Skip_B1(                                                "Tqi - Quantization table destination selector");
            Element_End0();
    
            //Filling list of HiVi
            SamplingFactors.push_back(SamplingFactor);
        }
    
        FILLING_BEGIN_PRECISE();
            if (Frame_Count==0 && Field_Count==0)
            {
                Accept("JPEG");
                Fill("JPEG");
    
                if (Count_Get(StreamKind_Last)==0)
                    Stream_Prepare(StreamKind_Last);
                Fill(StreamKind_Last, 0, Fill_Parameter(StreamKind_Last, Generic_Format), "JPEG");
                Fill(StreamKind_Last, 0, Fill_Parameter(StreamKind_Last, Generic_Codec), "JPEG");
                if (StreamKind_Last==Stream_Image)
                    Fill(Stream_Image, 0, Image_Codec_String, "JPEG", Unlimited, true, true); //To Avoid automatic filling
                if (StreamKind_Last==Stream_Video)
                    Fill(Stream_Video, 0, Video_InternetMediaType, "video/JPEG", Unlimited, true, true);
                Fill(StreamKind_Last, 0, Fill_Parameter(StreamKind_Last, Generic_BitDepth), Resolution);
                Fill(StreamKind_Last, 0, "Height", Height*(Interlaced?2:1));
                Fill(StreamKind_Last, 0, "Width", Width);
    
                //ColorSpace from http://docs.oracle.com/javase/1.4.2/docs/api/javax/imageio/metadata/doc-files/jpeg_metadata.html
                switch (APPE_Adobe0_transform)
                {
                    case 0x01 :
                                if (Count==3)
                                    Fill(StreamKind_Last, 0, "ColorSpace", "YUV");
                    case 0x02 :
                                if (Count==4)
                                    Fill(StreamKind_Last, 0, "ColorSpace", "YCCB");
                                break;
                    default   :
                                {
                                int8u Ci[256];
                                memset(Ci, 0, 256);;
                                for (int8u Pos=0; Pos<Count; Pos++)
                                    Ci[SamplingFactors[Pos].Ci]++;
    
                                switch (Count)
                                {
                                    case 1 :    Fill(StreamKind_Last, 0, "ColorSpace", "Y"); break;
                                    case 2 :    Fill(StreamKind_Last, 0, "ColorSpace", "YA"); break;
                                    case 3 :
                                                     if (!APP0_JFIF_Parsed && Ci['R']==1 && Ci['G']==1 && Ci['B']==1)                                                       //RGB
                                                    Fill(StreamKind_Last, 0, "ColorSpace", "RGB");
                                                else if ((Ci['Y']==1 && ((Ci['C']==1 && Ci['c']==1)                                                                         //YCc
                                                                      || Ci['C']==2))                                                                                       //YCC
                                                      || APP0_JFIF_Parsed                                                                                                   //APP0 JFIF header present so YCC
                                                      || APPE_Adobe0_transform==0                                                                                           //transform set to YCC
                                                      || (SamplingFactors[0].Ci==0 && SamplingFactors[1].Ci==1 && SamplingFactors[2].Ci==2)                                 //012
                                                      || (SamplingFactors[0].Ci==1 && SamplingFactors[1].Ci==2 && SamplingFactors[2].Ci==3))                                //123
                                                    Fill(StreamKind_Last, 0, "ColorSpace", "YUV");
                                                break;
                                    case 4 :
                                                     if (!APP0_JFIF_Parsed && Ci['R']==1 && Ci['G']==1 && Ci['B']==1 && Ci['A']==1)                                         //RGBA
                                                    Fill(StreamKind_Last, 0, "ColorSpace", "RGBA");
                                                else if ((Ci['Y']==1 && Ci['A']==1 && ((Ci['C']==1 && Ci['c']==1)                                                           //YCcA
                                                                                    || Ci['C']==2))                                                                         //YCCA
                                                      || APP0_JFIF_Parsed                                                                                                   //APP0 JFIF header present so YCCA
                                                      || (SamplingFactors[0].Ci==0 && SamplingFactors[1].Ci==1 && SamplingFactors[2].Ci==2 && SamplingFactors[3].Ci==3)     //0123
                                                      || (SamplingFactors[0].Ci==1 && SamplingFactors[1].Ci==2 && SamplingFactors[2].Ci==3 && SamplingFactors[3].Ci==4))    //1234
                                                    Fill(StreamKind_Last, 0, "ColorSpace", "YUVA");
                                                else if (APPE_Adobe0_transform==0)                                                                                          //transform set to CMYK
                                                    Fill(StreamKind_Last, 0, "ColorSpace", "YCCB");
                                                break;
                                    default:    ;
                                }
                                }
                }
    
                //Chroma subsampling
                if ((SamplingFactors.size()==3 || SamplingFactors.size()==4) && SamplingFactors[1].Hi==1 && SamplingFactors[2].Hi==1 && SamplingFactors[1].Vi==1 && SamplingFactors[2].Vi==1)
                {
                    string ChromaSubsampling;
                    switch (SamplingFactors[0].Hi)
                    {
                        case 1 :
                                switch (SamplingFactors[0].Vi)
                                {
                                    case 1 : ChromaSubsampling="4:4:4"; break;
                                    default: ;
                                }
                                break;
                        case 2 :
                                switch (SamplingFactors[0].Vi)
                                {
                                    case 1 : ChromaSubsampling="4:2:2"; break;
                                    case 2 : ChromaSubsampling="4:2:0"; break;
                                    default: ;
                                }
                                break;
                        case 4 :
                                switch (SamplingFactors[0].Vi)
                                {
                                    case 1 : ChromaSubsampling="4:1:1"; break;
                                    default: ;
                                }
                                break;
                        default: ;
                    }
                    if (!ChromaSubsampling.empty())
                    {
                        if (SamplingFactors.size()==4)
                        {
                            if (ChromaSubsampling=="4:4:4" && SamplingFactors[3].Hi==1 && SamplingFactors[3].Vi==1)
                                ChromaSubsampling+=":4";
                            else
                                ChromaSubsampling+=":?";
                        }
                        Fill(StreamKind_Last, 0, "ChromaSubsampling", ChromaSubsampling);
                    }
                }
            }
        FILLING_END();
    }
    


    从代码的含义可知,提取出了图像的宽,高,采样方式等信息。

    详细的代码暂时没有时间研究了,先这样了。



    展开全文
  • 2015年Google发布了一个很有意思的东西,叫做Deep Dream,网上瞬间掀起了Deep Dream的热潮,各种各样有着Deep Dream效果的图片漫天飞,下面就直观来看下什么是Deep Dream。 由于这些图片充满着幻觉和梦境,...
  • 一个程序从源代码到可执行程序的过程

    万次阅读 多人点赞 2018-06-26 10:45:13
    一个源程序到一个可执行程序的过程:预编译、编译、汇编、链接。 其中,编译是主要部分,其中又分为六个部分:词法分析、语法分析、语义分析、中间代码生成、目标代码生成和优化。 链接中,分为静态链接和动态链接...
  • 如何读懂源代码!如何看懂源代码!如何读懂别人的代码,分析源代码方法,有利于编程!比较适合莱鸟!当然较深的高手也可以看看!
  • 本文记录HEVC官方参考软件HM的源代码结构。HM相比于JM来说,采用了面向对象的编程方法,因而结构相对更加清晰。HM包含了视频解码器TAppDecoder和视频编码器TAppEncoder。本文记录视频解码器TAppDecoder的结构。函数...
  • 斗地主ai源代码

    2015-12-28 14:22:47
    斗地主ai源代码,实现AI自动出牌功能,娱乐性强 C++代码
  • octave源代码安装之——依赖关系解析(致数学爱好者) 我的系统是gentoo 3. 0 .6, gnome-3 ,gcc-4.5.3, 安装好系统,和一些必要的autotool, 就可以下载octave 安装,   有些教程(Programming Abstractions in ...
  • 二、原理+源代码解析 三、中文分词尝试 四、注意 五、优势与缺点(个人理解)   、简介 AIML,全名为Artificial Intelligence Markup Language(人工智能标记语言),是种创建自然语言软件代理的XML语言...
  • clamAV源代码分析

    2011-04-11 20:15:51
    关于开源病毒防护软件clamAV的源代码的分析。
  • H.264官方软件JM源代码简单分析-解码器ldecod

    万次阅读 多人点赞 2015-11-17 20:07:41
    最近看了一下H.264官方参考软件JM的源代码,在这里总结一下它的结构。JM编解码H.264的速度相对于FFmpeg来说是非常慢的,但是它的代码写得清晰易懂,更适合做学术方面的研究。JM包含了视频解码器ldecod和视频编码器...
  • 彩翼系列-彩票分析软件源代码(双色球,排三,排五,3D,22选5,30选7)源代码 蝎子: 开发时间2008年,偶是最早发现有叫蓝天使的彩票公司写的烂东西,狗屁公司还出书,扯淡,感觉彩神通还是界面样子还凑合,官方...
  • 源代码实例

    千次阅读 2016-12-30 11:44:36
    一个针对iOS模块化开发的解决方案 快速搭建项目源代码 模仿网易新闻做的精仿网易新闻 支付宝高仿版 高仿百度传课iOS版 模仿一元云购 wordpress源代码 v2ex源代码(文章类型...
  • 如何看懂源代码--(分析源代码方法)

    万次阅读 多人点赞 2018-01-12 16:40:26
    不管是参考也好,从开源抓下来研究也好,为了了解中含意,在有限的时间下,不免会对庞大的源代码解读感到压力。  网路上有篇关于分析看代码的方法,做为程式设计师的您,不妨参考看看,  换角度来分析。 也...
  • java dom4j解析XML读取数据源配置的代码实例 源代码下载地址:http://www.zuidaima.com/share/1796449490865152.htm
  • Android的编译环境作为深入学习Android的基础,不可或缺,能够完整下载Android源代码并编译成功,对深入学习Android是非常关键和重要的一步。
  • GRBL源代码分析

    万次阅读 多人点赞 2018-03-27 16:11:41
    这段日子喜事连连,暂时把写博客的事情放下了,有...借着安静的周五,加上最近一个多月研究GRBL源代码的心得,写下这篇博客,供后来者参考学习。网上关于GRBL源代码分析的资料几乎找不到,这篇博客里的内容大多是...
  • Mozilla FireFox Gecko内核源代码解析 (1.nsParser) 中科院计算技术研究所网络数据科学与工程研究中心-信息抽取小组 耿耘 gengyun@sohu.com 前言: 在Web信息抽取的工作过程中,我们主要处理的都是经过各种处理...
  • 源代码审计(

    千次阅读 2020-08-17 22:39:07
    代码安全测试简介 定义 就是从安全的角度对代码进行的安全测试评估。同时结合丰富的安全知识、编程经验、测试技术,利用静态分析和人工审核的方法寻找代码在架构和编码上的安全缺陷,在代码形成软件产品前将...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 149,276
精华内容 59,710
关键字:

怎么解析一个软件的源代码