JPEG2000
				的实现
				kakadu
				中是用一个
				16
				位数来表示失真长度曲线的斜率;在整个编码过程中,使用斜率值的右移四位的标量量化值。
		
		
				编码的分配表面是按照块进行的,实际并是整个压缩过程考虑的。
		
		
				JPEG2000
				使用一个
				4096
				元素的量化斜率值数组来存储压缩过程中遇到的斜率值(
				quant_slope_rates
				)。
		
		
				当第一次编码的时候,从
				4096
				个元素找满足码率的斜率下限,实际上这个时候没有任何压缩,数组的所有元素都为
				0
				;所以开始的时候得到的斜率值是
				1
				。第一个
				block
				使用斜率值
				1
				作为块编码的依据。
		
		
				码块编码需要两个关于度量失真的参数:
				wmse
				和失真斜率。编码为每个编码过程定义了一个
				pass_wmse_change
				;这里面保存了码块每个编码过程中对斜率的贡献。如果使第一个
				block
				的第一个编码过程,那么采用
				-1
				的估计失真长度曲线斜率;否则采用一个斜率的对数值。
		
		
				
						1.  
				
				首先将
				wmse
				分成
				2
				的
				32
				次方等份,这个作为每个过程的
				pass_wmse_scale
				。这里分成这些等份的原因在于编码的时候使用的
				32bit
				的整数;当然最高位为符号位。每个编码过程的
				wmse
				的
				scale
				都不一样,当前过程的
				pass_wmse_scale
				是上个过程的四分之一。由于位平面编码并非从第
				30
				位开始,所以对于丢弃的
				msb
				,需要乘以指定数个
				1/4
				。
		
		
				注,这里不知道为什么要乘
				1/4
				。
		
		
				
						2.  
				
				进行一次过程编码后,根据当前过程的信息查表计算得到该过程对整个图像失真的改变值
				distortion_change
				。这个值于当前过程的
				pass_wmse_scale
				的乘积作为当前过程的
				wmse
				改进值存放到每个过程对应的
				pass_wmse_change
				数组中。
		
		
				
						3.  
				
				如果不是第一个
				block
				的第一个编码过程;那么预测的斜率门限值应该是大于
				0
				,那么检查并判断当前过程是否已经满足该斜率值了。基本按照如下方式计算:
		
		
				
						a)         
				
				每个过程由一个编码长度值
				pass_lengths
				和
				wmse
				的改进值:
				pass_wmse_changes
				;第一个作为长度的改进量,第二个作为失真的改进量。
		
		
				
						b)        
				
				如果斜率与上面长度改进量的乘积比失真改进量大,说明这个过程以后的斜率都要比预测的斜率值小了;那么这个时候可以停止该
				block
				的编码过程了。
		
		
				注,这一步实际上也算是比较耗时间的过程。
				
						
						
						
				
		
		
				
						4.  
				
				完成需要的编码过程后,对应编码过程应该已经由了失真信息和长度信息。这个时候需要来检查上面编码过程中那些过程结束是优化的,同时找出每个编码过程对应的斜率。这里以实际编码的过程作为参数。
		
		
				
						5.  
				
				开始的时候设置斜率位-
				1
				;然后累计第一个过程的长度和失真值(分别在
				pass_lengths
				和
				pass_wmse_change
				中),得到
				D
				和
				L
				的比值,这个作为当前过程的斜率;对于第二个过程需要累计第一个、第二个两个过程的值,得到一个斜率值;最终得到的值如果小于等于
				0
				;那么设置该过程的斜率为
				0
				;否则取上面值的对数作为当前过程的斜率值。
		
		
				
						6.  
				
				完成上面操作后,再检查保留的过程中,按照编码顺序后面的过程斜率是否比前一个过程的斜率大,如果大保留后面那个过程的斜率,小的值修改为
				0
				。因此在完成
				5
				和
				6
				之后,被保存下来的点值都大于
				0
				,二其他被抛弃的点斜率变为
				0
				。
		
		
				
						7.  
				
				在完成
				block
				编码后需要更新全局状态(其在
				kd_compressed_stats
				中。
		
		
				
						8.  
				
				首先我们将当前
				block
				的大小,也就是多少个样本添加到被编码过程的样本数中(
				num_coded_samples
				),第一个
				block
				时,这个值时
				0
				。这里需要这个值作为
				trim
				的依据和下个
				block
				编码时使用的值。
		
		
				
						9.  
				
				统计每个编码过程的斜率和长度值,并将斜率值量化为
				1/16
				作为数组
				quant_slope_rates
				(这是
				1
				个
				4096
				元素的数组,里面保存在该斜率下总共编码的长度,也就是说如果不同的
				block
				具有相同的斜率的过程长度值被累加到一起)入口;当然,如果那些斜率为
				0
				的点需要被跳过,其长度被累加到下个在曲线上的编码过程。同时更新一下当前可以使用的最大和最小斜率值。
		
		
				
						10.              
				
				在
				8
				中提到的
				num_coded_samples
				用来检查是否需要考虑
				trim
				多于的数据。多余数据被
				trim
				的检查点为总体样本的:
				2/16
				、
				3/16
				、
				4/16…
				处,后面都是按照、
				/16
				增加。
		
		
				
						11.              
				
				一旦需要
				trim
				的时候,首先按照总样本数量(注意这里不是已经编码的样本数量)和目标码率计算目标码流的长度,然后在
				quant_slope_rates
				中找到斜率,在这个斜率点所有
				block
				的所有过程长度的累加值比上面的总目标长度刚好大。而
				trim
				操作按照这个斜率值检查所有已经编码的
				block
				,
				trim
				掉所有比这个效率小的过程。可以看到在整个编码过程中,这样的
				trim
				操作最多需要进行
				15
				次,每次都一可能从所有块中将小于指定斜率的编码过程
				trim
				掉。上面的
				trim
				操作不会影响
				quant_slope_rates
				的值。
		
		
				
						12.              
				
				上面已经完成了一个
				block
				的编码;下面开始第二个
				block
				的时候稍微与第一个有点不同;主要的不同在于现在
				quant_slope_rates
				中已经包含斜率长度值了。根据
				num_coded_samples
				(这里保守增加了额外长度)和目标码率计算期望的编码长度;然后从
				quant_slope_rates
				中发现到这个长度的斜率值,这个值作为当前
				block
				编码的最低的斜率门限。