/*	
 *	clipvqtc.c
 *
 *	VQ埑弅僥僋僗僠儍
 *
 *	CLiP - Common Library for P/ECE
 *	Copyright (C) 2016 Naoyuki Sawa
 *
 *	* Mon Dec 19 21:58:37 JST 2016 Naoyuki Sawa
 *	- 1st 儕儕乕僗丅
 *	  傑偢偼専徹偺偨傔偵丄Windows忋偱GDI+傪巊偭偰偺丄埑弅揥奐儖乕僠儞傪嶌惉偟傑偟偨丅
 *	  dpbmpcnv.exe傊偺慻傒崬傒傗丄P/ECE梡偺昤夋儖乕僠儞偼丄偙偺偁偲嶌惉偡傞梊掕偱偡丅	佀{{2016/12/22僐儊儞僩捛婰:dpbmpcnv.exe傊偺慻傒崬傒,媦傃,P/ECE梡偺昤夋儖乕僠儞(framvqtd.c)傪嶌惉偟傑偟偨丅}}
 *	* Tue Dec 20 21:28:56 JST 2016 Naoyuki Sawa
 *	- k-means朄(,枖偼,k-means++朄)偺孞傝曉偟張棟偺丄懪偪愗傝忦審傪曄峏偟傑偟偨丅
 *	  徻嵶偼丄VqTc_EncodeImage()撪偺僐儊儞僩傪嶲徠偟偰壓偝偄丅
 *	* Wed Dec 21 21:39:53 JST 2016 Naoyuki Sawa
 *	- VQTC_DATAHEADER峔憿懱偺掕媊傪捛壛偟傑偟偨丅
 *	  dpbmpcnv.exe,媦傃,P/ECE梡偺昤夋儖乕僠儞偱嶲徠偟傑偡丅
 *	* Fri Dec 23 23:24:50 JST 2016 Naoyuki Sawa
 *	- 僐乕僪僽僢僋偺5僶僀僩偺埑弅僨乕僞偺丄1僶僀僩栚偺價僢僩媗傔偺弴彉傪媡偵偟傑偟偨丅
 *	  曄峏慜偼乽aabbccdd乿偱偟偨偑丄曄峏屻偼乽ddccbbaa乿偵側傝傑偟偨丅
 *	  VqTc_DecodeCell()娭悢偱4x4僺僋僙儖傪傑偲傔偰僨僐乕僪偡傞帪偼丄曄峏慜偺乽aabbccdd乿偺暲傃偺曽偑僔僼僩偲價僢僩憲傝傪摨帪偵峴偊偰岠棪偑椙偐偭偨偺偱偡偑丄
 *	  framvqtd.c偺PDW_Draw_VQTC()娭悢偱1儔僀儞4僺僋僙儖傪扨撈偱僨僐乕僪偡傞帪偼丄摿偵傾僙儞僽儔斉偺幚憰偵偍偄偰乽ddccbbaa乿偺暲傃偺曽偑岠棪偑椙偄帠偵婥晅偄偨偐傜偱偡丅
 *	  VqTc_DecodeCell()娭悢偼僣乕儖傗僥僗僩偱偟偐巊傢側偄偺偱懍搙偼廳梫偱偼側偔丄昤夋偱巊偆PDW_Draw_VQTC()娭悢傪崅懍壔偡傞曽偑廳梫側偺偱丄PDW_Draw_VQTC()娭悢偺崅懍壔傪桪愭偟偰乽ddccbbaa乿偵偟傑偟偨丅
 *	* Sat Dec 24 21:19:40 JST 2016 Naoyuki Sawa
 *	- 僐乕僪僽僢僋偵奿擺偡傞怓偺抣傪乽0=敀乣3=崟,4=摟柧乿佀乽0=摟柧,1=敀乣4=崟乿偵曄峏偟傑偟偨丅
 *	  曄峏偟偨娭悢偼丄clipvqtc.c偺VqTc_EncodeCell()偲VqTc_DecodeCell()丄媦傃丄framvqtd.c偺PDW_Draw_VQTC()偱偡丅
 *	  曄峏偟偨棟桼偼丄埲壓偺捠傝偱偡丅
 *	- framvqtd.c偺PDW_Draw_VQTC()偺彍嶼儖乕僾偵偍偄偰丄巆傝偺僺僋僙儖偑慡偰0側傜偽儖乕僾傪懪偪愗傞傛偆偵偟偰偍傝丄怓偺抣偑0偱偁傞僺僋僙儖偑懡偄傎偳昤夋偑憗偔側傝傑偡丅
 *	  堦斒揑偵丄僎乕儉偺夋憸偺僺僋僙儖偲偟偰偼丄敀傛傝傕摟柧偺曽偑懡偄偲巚偆偺偱丄摟柧傪0偲偡傞帠偵偟傑偟偨丅
 *	  摟柧偑柍偔敀偑懡偄夋憸偺応崌偼丄崱夞偺曄峏偼媡岠壥偱偁傝丄媝偭偰抶偔側偭偰偟傑偆偺偱偡偑丄堦斒揑偵偼憗偔側傞帠偺曽偑懡偄偲巚偄傑偡丅
 *	- 崅懍壔偺岠壥傪専徹偟偰傒傑偟偨丅
 *	  嬌抂側椺偲偟偰丄姰慡偵摟柧側夋憸偱丄夋柺慡懱(128x88)偵昤夋偟偨偲偙傠丄曄峏慜傛傝傕曄峏屻偺曽偑栺23%崅懍偵側傝傑偟偨丅
 *	  廬偭偰丄摟柧晹暘偺懡偝偵斾椺偟偰丄23%傪忋尷偲偟偰崅懍壔偺岠壥偑桳傞偲巚偄傑偡丅
 *	* Sun Dec 25 23:57:41 JST 2016 Naoyuki Sawa
 *	- 晞崋偺悢偺忋尷傪丄256佀65536偵曄峏偟傑偟偨丅
 *	  埑弅棪傪峫椂偡傞偲256掱搙偑揔愗側偺偱偡偑丄応崌偵傛偭偰偼256挻夁偺晞崋悢傕巊偄偨偄帠偑桳偭偨偐傜偱偡丅
 */
#include "clip.h"
/****************************************************************************
 *	
 ****************************************************************************/
#undef  VQTC_PRINT_PROGRESS
#define VQTC_PRINT_PROGRESS	//偙偺僔儞儃儖傪掕媊偡傞偲丄VqTc_EncodeImage()偑昗弨僄儔乕弌椡偵恑捇昞帵傪峴偄傑偡丅VqTc_EncodeImage()偺張棟帪娫偑挿偄偺偱丄懸偭偰偄偰晄埨偵側傜側偄傛偆偵偡傞偨傔偱偡丅恑捇昞帵偑晄梫側傜偽丄偙偺峴傪僐儊儞僩傾僂僩偟偰壓偝偄丅
/****************************************************************************
 *	
 ****************************************************************************/
//晞崋偺悢偐傜丄晞崋堦偮摉偨傝偺價僢僩悢傪媮傔傞丅
//[in]
//  //{{2016/12/25曄峏:晞崋偺悢偺忋尷傪丄256佀65536偵曄峏偟傑偟偨丅
//  //	k		晞崋偺悢			1乣256
//  伀2016/12/25曄峏:晞崋偺悢偺忋尷傪丄256佀65536偵曄峏偟傑偟偨丅
//	k		晞崋偺悢			1乣65536
//  //}}2016/12/25曄峏:晞崋偺悢偺忋尷傪丄256佀65536偵曄峏偟傑偟偨丅
//[out]
//	栠傝抣		晞崋堦偮摉偨傝偺價僢僩悢	1乣8
#ifndef PIECE
int VqTc_CalculateCodeBits(int k) {
	int bits;
//{{2016/12/25曄峏:晞崋偺悢偺忋尷傪丄256佀65536偵曄峏偟傑偟偨丅
//	if((k < 1) || (k > 256)) { DIE(); }	//晞崋偺悢偼1乣256偺斖埻偱側偔偰偼側傜側偄丅埑弅傾儖僑儕僘儉帺懱偼256傪挻偊傞晞崋偺悢偵傕懳墳壜擻偱偡偑丄僨僐乕僟傪崅懍壔偡傞偨傔偵晞崋傪8價僢僩埲壓偵惂尷偟偨偄偐傜偱偡丅
//	bits = 8 - xscan1(swap(k - 1));		//bits=8(129亝k亝256),7(65亝k亝128),6(33亝k亝64),5(17亝k亝32),4(9亝k亝16),3(5亝k亝8),2(3亝k亝4),1(k亖2),-24(k亖1)
//	if(bits < 0) { bits = 0; }		//bits=8(129亝k亝256),7(65亝k亝128),6(33亝k亝64),5(17亝k亝32),4(9亝k亝16),3(5亝k亝8),2(3亝k亝4),1(k亖2),  0(k亖1)
//伀2016/12/25曄峏:晞崋偺悢偺忋尷傪丄256佀65536偵曄峏偟傑偟偨丅
	if((k < 1) || (k > 65536)) { DIE(); }	//晞崋偺悢偼1乣65536偺斖埻偱側偔偰偼側傜側偄丅
	bits = 16 - xscan1((k - 1) << 16);	//bits=16(32769亝k亝65536),15(16385亝k亝32768),14(8193亝k亝16384),13(4097亝k亝8192),12(2049亝k亝4096),11(1025亝k亝2048),10(513亝k亝1024),9(257亝k亝512),8(129亝k亝256),7(65亝k亝128),6(33亝k亝64),5(17亝k亝32),4(9亝k亝16),3(5亝k亝8),2(3亝k亝4),1(k亖2),-16(k亖1)
	if(bits < 0) { bits = 0; }		//bits=16(32769亝k亝65536),15(16385亝k亝32768),14(8193亝k亝16384),13(4097亝k亝8192),12(2049亝k亝4096),11(1025亝k亝2048),10(513亝k亝1024),9(257亝k亝512),8(129亝k亝256),7(65亝k亝128),6(33亝k亝64),5(17亝k亝32),4(9亝k亝16),3(5亝k亝8),2(3亝k亝4),1(k亖2),  0(k亖1)
//}}2016/12/25曄峏:晞崋偺悢偺忋尷傪丄256佀65536偵曄峏偟傑偟偨丅
	return bits;
}
#else //PIECE
int VqTc_CalculateCodeBits(int k);
asm("
		.code
		.align		1
		.global		VqTc_CalculateCodeBits
VqTc_CalculateCodeBits:
		;//%r12 := k
;//{{2016/12/25曄峏:晞崋偺悢偺忋尷傪丄256佀65536偵曄峏偟傑偟偨丅
;//		sub		%r12, 1			;//%r12        :=                        k - 1
;//		swap		%r10, %r12		;//%r10[31:24] :=                        k - 1
;//		scan1		%r10, %r10		;//%r10        :=            xscan1(swap(k - 1))
;//		not		%r10, %r10		;//%r10        :=           ~xscan1(swap(k - 1))
;//		ret.d					;//return         bits
;//		add		%r10, 9			;//%r10        := bits = 8 - xscan1(swap(k - 1))	*delay*
;//伀2016/12/25曄峏:晞崋偺悢偺忋尷傪丄256佀65536偵曄峏偟傑偟偨丅
		sub		%r12, 1			;//%r12   :=                     k - 1
		xsla		%r12, 16		;//%r12   :=                    (k - 1) << 16
		scan1		%r10, %r12		;//劉
		sll		%r12, %r10		;//劌%r10 :=             xscan1((k - 1) << 16)
		scan1		%r9, %r12		;//劆
		add		%r10, %r9		;//劊
		not		%r10, %r10		;//%r10   :=            ~xscan1((k - 1) << 16)
		ret.d					;//return    bits
		add		%r10, 17		;//%r10   := bits = 16 - xscan1((k - 1) << 16)		*delay*
;//}}2016/12/25曄峏:晞崋偺悢偺忋尷傪丄256佀65536偵曄峏偟傑偟偨丅
");
#endif//PIECE
/*--------------------------------------------------------------------------*/
//夋憸偺暆偲崅偝,媦傃,晞崋偺悢偐傜丄晞崋攝楍偺僶僀僩悢傪媮傔傞丅
//[in]
//	w		夋憸偺暆			1乣
//	h		夋憸偺崅偝			1乣
//  //{{2016/12/25曄峏:晞崋偺悢偺忋尷傪丄256佀65536偵曄峏偟傑偟偨丅
//  //	k		晞崋偺悢			1乣256
//  //伀2016/12/25曄峏:晞崋偺悢偺忋尷傪丄256佀65536偵曄峏偟傑偟偨丅
//	k		晞崋偺悢			1乣65536
//  //}}2016/12/25曄峏:晞崋偺悢偺忋尷傪丄256佀65536偵曄峏偟傑偟偨丅
//[out]
//	栠傝抣		晞崋攝楍偺僶僀僩悢		4乣
//[note]
//	- 晞崋攝楍偼bitarray偲偟偰憖嶌偡傞偨傔丄摉娭悢偑晞崋攝楍偺僶僀僩悢傪4偺攞悢偵愗傝忋偘傑偡丅
//	- bitarray偲偟偰憖嶌偡傞偨傔偺僒僀僘偺梫審偼摉娭悢偵偰扴曐偟傑偡偑丄惍楍偺梫審偼傾僾儕働乕僔儑儞懁偵偰扴曐偟偰壓偝偄丅
//	  嬶懱揑偵偼丄晞崋攝楍傪4偺攞悢偺傾僪儗僗偵攝抲偟偰壓偝偄丅
int VqTc_CalculateCodeBytes(int w, int h, int k) {
	int cols, rows, bits, bytes;
	if((w < 1) || (h < 1)) { DIE(); }	//嬻偺夋憸傪巜掕偟偰偼偄偗側偄丅
	cols = (w + 3) / 4;
	rows = (h + 3) / 4;
	bits = VqTc_CalculateCodeBits(k);
	bits = (cols * rows) * bits;
	bytes = (bits + 7) / 8;
	bytes = (bytes + 3) & ~3;		//bitarray padding
	return bytes;
}
/****************************************************************************
 *	
 ****************************************************************************/
//旕埑弅偺16僺僋僙儖傪丄5僶僀僩偺埑弅僨乕僞偵曄姺偡傞丅
//[in]
//	src		16僺僋僙儖偺擖椡僨乕僞				0=敀,1=柧,2=埫,3=敀,4乣255=摟夁
//	dst		5僶僀僩偺埑弅僨乕僞傪奿擺偡傞僶僢僼傽
//[note]
//	- 16僺僋僙儖偺暲傃弴偼4亊4僺僋僙儖傪憐掕偟偰偄傞偑丄摉娭悢偺摦嶌帺懱偵偼僺僋僙儖偺暲傃弴偼娭學柍偄丅
//	- 埑弅宍幃偺徻嵶偵偮偄偰:
//	  傕偟丄僐乕僪僽僢僋(僙儖)傪埑弅柍偟偱奿擺偡傞偲丄1僺僋僙儖摉偨傝怓2價僢僩亄摟夁1價僢僩=3價僢僩側偺偱丄4x4僺僋僙儖偱6僶僀僩梫偟傑偡丅
//	  偟偐偟丄摟夁僺僋僙儖偵懳偡傞怓價僢僩偼柍懯偱偁傞帠傪峫椂偟偰丄摟夁僺僋僙儖傪怓斣崋4偲偟偰奿擺偡傟偽丄4僺僋僙儖摉偨傝log2(5^4)=10價僢僩丄4x4僺僋僙儖偱5僶僀僩偱嵪傒傑偡丅
//	  4僺僋僙儖扨埵偱埑弅偟偨棟桼偼丄1僙儖(=4x4僺僋僙儖)偐傜丄1儔僀儞偯偮屄暿偵庢摼偟堈偄峔憿偵偟偰偍偔曽偑丄僨僐乕僟偑嶌傝堈偄偐傜偱偡丅
//  //{{2016/12/23曄峏:僐乕僪僽僢僋偺5僶僀僩偺埑弅僨乕僞偺丄1僶僀僩栚偺價僢僩媗傔偺弴彉傪媡偵偟傑偟偨丅
//  //	- 5僶僀僩亊4儔僀儞偺奿擺宍幃偵偮偄偰:
//  //	  劇劅劅劅劅劅劅劅劅劅劅劅劍劅劅劅劅劅劅劅劅劅劅劅劍劅劅劅劅劅劅劅劅劅劅劅劍劅劅劅劅劅劅劅劅劅劅劅劉
//  //	  劆1儔僀儞栚偺忋埵2價僢僩劆2儔僀儞栚偺忋埵2價僢僩劆3儔僀儞栚偺忋埵2價僢僩劆4儔僀儞栚偺忋埵2價僢僩劆
//  //	  劌劅劅劅劅劅劅劅劅劅劅劅劏劅劅劅劅劅劅劅劅劅劅劅劏劅劅劅劅劅劅劅劅劅劅劅劏劅劅劅劅劅劅劅劅劅劅劅劎
//  //	  劆丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂1儔僀儞栚偺壓埵8價僢僩丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂劆
//  //	  劌劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劎
//  //	  劆丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂2儔僀儞栚偺壓埵8價僢僩丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂劆
//  //	  劌劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劎
//  //	  劆丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂3儔僀儞栚偺壓埵8價僢僩丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂劆
//  //	  劌劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劎
//  //	  劆丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂4儔僀儞栚偺壓埵8價僢僩丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂劆
//  //	  劋劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劊
//  //伀2016/12/23曄峏:僐乕僪僽僢僋偺5僶僀僩偺埑弅僨乕僞偺丄1僶僀僩栚偺價僢僩媗傔偺弴彉傪媡偵偟傑偟偨丅
//	- 5僶僀僩亊4儔僀儞偺奿擺宍幃偵偮偄偰:
//	  劇劅劅劅劅劅劅劅劅劅劅劅劍劅劅劅劅劅劅劅劅劅劅劅劍劅劅劅劅劅劅劅劅劅劅劅劍劅劅劅劅劅劅劅劅劅劅劅劉
//	  劆4儔僀儞栚偺忋埵2價僢僩劆3儔僀儞栚偺忋埵2價僢僩劆2儔僀儞栚偺忋埵2價僢僩劆1儔僀儞栚偺忋埵2價僢僩劆
//	  劌劅劅劅劅劅劅劅劅劅劅劅劏劅劅劅劅劅劅劅劅劅劅劅劏劅劅劅劅劅劅劅劅劅劅劅劏劅劅劅劅劅劅劅劅劅劅劅劎
//	  劆丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂1儔僀儞栚偺壓埵8價僢僩丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂劆
//	  劌劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劎
//	  劆丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂2儔僀儞栚偺壓埵8價僢僩丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂劆
//	  劌劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劎
//	  劆丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂3儔僀儞栚偺壓埵8價僢僩丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂劆
//	  劌劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劎
//	  劆丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂4儔僀儞栚偺壓埵8價僢僩丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂丂劆
//	  劋劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劊
//  //}}2016/12/23曄峏:僐乕僪僽僢僋偺5僶僀僩偺埑弅僨乕僞偺丄1僶僀僩栚偺價僢僩媗傔偺弴彉傪媡偵偟傑偟偨丅
void VqTc_EncodeCell(const unsigned char src[16], unsigned char dst[5]) {
	int c, i, j, x[4];
	for(i = 0; i < 4; i++) {
		x[i] = 0;
		for(j = 3; j >= 0; j--) {
			c = src[j];
//{{2016/12/24曄峏:僐乕僪僽僢僋偵奿擺偡傞怓偺抣傪乽0=敀乣3=崟,4=摟柧乿佀乽0=摟柧,1=敀乣4=崟乿偵曄峏偟傑偟偨丅
//			if(c > 4) { c = 4; }	//5乣255傕4(摟夁)偲摨偠偲尒側偡丅
//伀2016/12/24曄峏:僐乕僪僽僢僋偵奿擺偡傞怓偺抣傪乽0=敀乣3=崟,4=摟柧乿佀乽0=摟柧,1=敀乣4=崟乿偵曄峏偟傑偟偨丅
			if(++c > 4) { c = 0; }	//乽0=敀,1=柧,2=埫,3=敀,4乣255=摟夁乿佀乽0=摟夁,1=敀,2=柧,3=埫,4=崟乿偵曄姺偡傞丅
//}}2016/12/24曄峏:僐乕僪僽僢僋偵奿擺偡傞怓偺抣傪乽0=敀乣3=崟,4=摟柧乿佀乽0=摟柧,1=敀乣4=崟乿偵曄峏偟傑偟偨丅
			x[i] = (x[i] * 5) + c;
		}
		if((unsigned)x[i] > 0x270/*=(5^4)-1*/) { DIE(); }	//僶僌
		src += 4;
	}
//{{2016/12/23曄峏:僐乕僪僽僢僋偺5僶僀僩偺埑弅僨乕僞偺丄1僶僀僩栚偺價僢僩媗傔偺弴彉傪媡偵偟傑偟偨丅
//	*dst++ = ((x[0] & 0x300) >> 2) |
//	         ((x[1] & 0x300) >> 4) |
//	         ((x[2] & 0x300) >> 6) |
//	         ((x[3] & 0x300) >> 8);
//伀2016/12/23曄峏:僐乕僪僽僢僋偺5僶僀僩偺埑弅僨乕僞偺丄1僶僀僩栚偺價僢僩媗傔偺弴彉傪媡偵偟傑偟偨丅
	*dst++ = ((x[0] & 0x300) >> 8) |
	         ((x[1] & 0x300) >> 6) |
	         ((x[2] & 0x300) >> 4) |
	         ((x[3] & 0x300) >> 2);
//}}2016/12/23曄峏:僐乕僪僽僢僋偺5僶僀僩偺埑弅僨乕僞偺丄1僶僀僩栚偺價僢僩媗傔偺弴彉傪媡偵偟傑偟偨丅
	*dst++ =   x[0];
	*dst++ =   x[1];
	*dst++ =   x[2];
	*dst++ =   x[3];
}
/*--------------------------------------------------------------------------*/
//5僶僀僩偺埑弅僨乕僞傪丄旕埑弅偺16僺僋僙儖偵曄姺偡傞丅
//[in]
//	src		5僶僀僩偺埑弅僨乕僞
//	dst		16僺僋僙儖偺弌椡僨乕僞傪奿擺偡傞僶僢僼傽	0=敀,1=柧,2=埫,3=敀,4=摟夁
//[note]
//	- 16僺僋僙儖偺暲傃弴偼4亊4僺僋僙儖傪憐掕偟偰偄傞偑丄摉娭悢偺摦嶌帺懱偵偼僺僋僙儖偺暲傃弴偼娭學柍偄丅
//	- 埑弅宍幃偺徻嵶丆媦傃丆5僶僀僩亊4儔僀儞偺奿擺宍幃偵偮偄偰偼丄VqTc_EncodeCell()偺[note]傪嶲徠偣傛丅
//{{2016/12/23曄峏:僐乕僪僽僢僋偺5僶僀僩偺埑弅僨乕僞偺丄1僶僀僩栚偺價僢僩媗傔偺弴彉傪媡偵偟傑偟偨丅
//void VqTc_DecodeCell(const unsigned char src[5], unsigned char dst[16]) {
//	int a, c, i, j, x;
//	a = *src++;			//a = 00000000 00000000 00000000 aabbccdd
//	for(i = 0; i < 4; i++) {
//		a <<= 2;		//a = 00000000 00000000 000000aa bbccdd00
//		x = a & 0x300;		//x = 00000000 00000000 000000aa 00000000
//		x |= *src++;		//x = 00000000 00000000 000000aa AAAAAAAA
//		if((unsigned)x > 0x270/*=(5^4)-1*/) { DIE(); }
//		for(j = 0; j < 4; j++) {
//			c = x % 5;
//			x = x / 5;
//			*dst++ = c;
//		}
//	}
//}
//伀2016/12/23曄峏:僐乕僪僽僢僋偺5僶僀僩偺埑弅僨乕僞偺丄1僶僀僩栚偺價僢僩媗傔偺弴彉傪媡偵偟傑偟偨丅
void VqTc_DecodeCell(const unsigned char src[5], unsigned char dst[16]) {
	int a, c, i, j, x;
	a = *src++;			//a = 00000000 00000000 00000000 ddccbbaa
	for(i = 0; i < 4; i++) {
		x = a & 3;		//x = 00000000 00000000 00000000 000000aa
		x <<= 8;		//x = 00000000 00000000 000000aa 00000000
		x |= *src++;		//x = 00000000 00000000 000000aa AAAAAAAA
		if((unsigned)x > 0x270/*=(5^4)-1*/) { DIE(); }
		for(j = 0; j < 4; j++) {
			c = x % 5;
			x = x / 5;
//{{2016/12/24捛壛:僐乕僪僽僢僋偵奿擺偡傞怓偺抣傪乽0=敀乣3=崟,4=摟柧乿佀乽0=摟柧,1=敀乣4=崟乿偵曄峏偟傑偟偨丅
			if(--c < 0) { c = 4; }	//乽0=摟夁,1=敀,2=柧,3=埫,4=崟乿佀乽0=敀,1=柧,2=埫,3=敀,4=摟夁乿偵曄姺偡傞丅
//}}2016/12/24捛壛:僐乕僪僽僢僋偵奿擺偡傞怓偺抣傪乽0=敀乣3=崟,4=摟柧乿佀乽0=摟柧,1=敀乣4=崟乿偵曄峏偟傑偟偨丅
			*dst++ = c;
		}
		a >>= 2;		//a = 00000000 00000000 00000000 00ddccbb
	}
}
//}}2016/12/23曄峏:僐乕僪僽僢僋偺5僶僀僩偺埑弅僨乕僞偺丄1僶僀僩栚偺價僢僩媗傔偺弴彉傪媡偵偟傑偟偨丅
/****************************************************************************
 *	
 ****************************************************************************/
static double VqTc_EncodeImage_distance(const void* vector, const void* center) {
	const unsigned char* v = (const unsigned char*)vector;
	const unsigned char* c = (const unsigned char*)center;
	double d = 0.0;
	int i;
	for(i = 0; i < 16; i++) {
		int a = *v++;
		int b = *c++;
		if(a > 4) { a = 4; }	//劍5乣255傕4(摟夁)偲摨偠偲尒側偡丅
		if(b > 4) { b = 4; }	//劊
		//怓偑堘偭偨傜乧
		if(a != b) {
			//曅曽偑摟柧偱丄傕偆曅曽偑摟柧偱側偗傟偽乧
			if((a == 4) || (b == 4)) {
				d += ((3 * 3) * 16) + 1;	//嵟戝偺怓堘偄(3)偺2忔(3*3)偑慡僺僋僙儖偱敪惗偟偨応崌((3*3)*16)傛傝傕丄1僺僋僙儖偺摟夁堘偄偺曽偑廳偄偲偟偨丅(挷惍壜)
			//偳偪傜傕摟柧偱側偔丄怓偑堘偭偨傜乧
			} else {
				d += (a - b) * (a - b);		//(1*1) or (2*2) or (3*3)
			}
		}
	}
	return d;
}
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
//夋憸傪埑弅偡傞丅
//[in]
//	image		夋憸					(in)		0=敀,1=柧,2=埫,3=敀,4乣255=摟夁
//	w		夋憸偺暆				(in)		1乣
//	h		夋憸偺崅偝				(in)		1乣
//	stride		夋憸偺1儔僀儞摉偨傝偺僶僀僩悢		(in)		w乣
//	codebook	僐乕僪僽僢僋傪奿擺偡傞僶僢僼傽		(out)		摉娭悢偺嶌嬈椞堟偲偟偰(k*5)僶僀僩昁梫偱偡丅弌椡僨乕僞偺幚岠僒僀僘偼(栠傝抣*5)僶僀僩偱偡丅
//  //{{2016/12/25曄峏:晞崋偺悢偺忋尷傪丄256佀65536偵曄峏偟傑偟偨丅
//  //	k		晞崋偺悢偺栚昗抣			(in)		1乣256丅幚嵺偺晞崋偺悢(=摉娭悢偺栠傝抣)偼丄偙傟埲壓偺悢偵側傝傑偡丅
//  //伀2016/12/25曄峏:晞崋偺悢偺忋尷傪丄256佀65536偵曄峏偟傑偟偨丅
//	k		晞崋偺悢偺栚昗抣			(in)		1乣65536丅幚嵺偺晞崋偺悢(=摉娭悢偺栠傝抣)偼丄偙傟埲壓偺悢偵側傝傑偡丅
//  //}}2016/12/25曄峏:晞崋偺悢偺忋尷傪丄256佀65536偵曄峏偟傑偟偨丅
//	code		晞崋攝楍傪奿擺偡傞僶僢僼傽		(out)		摉娭悢偺嶌嬈椞堟偲偟偰(VqTc_CalculateCodeBytes(w,h,k))僶僀僩昁梫偱偡丅弌椡僨乕僞偺幚岠僒僀僘偼(VqTc_CalculateCodeBytes(w,h,栠傝抣))僶僀僩偱偡丅
//[out]
//	栠傝抣		幚嵺偺晞崋偺悢						1乣k
int VqTc_EncodeImage(const void* image/*[stride*h]*/, int w, int h, int stride, void* codebook/*[k*5]*/, int k, void* code/*[VqTc_CalculateCodeBytes(w,h,k)]*/) {
	int c, i, j, l, n, x1, y1, x2, y2, col, row, cols, rows, bits1, bits2, relabel, sum[16], cnt[16];
	unsigned char *vector/*[n][16]*/, *center/*[k][16]*/;
	int* label/*[n]*/;
	if((w < 1) || (h < 1)) { DIE(); }	//嬻偺夋憸傪巜掕偟偰偼偄偗側偄丅
//{{2016/12/25曄峏:晞崋偺悢偺忋尷傪丄256佀65536偵曄峏偟傑偟偨丅
//	if((k < 1) || (k > 256)) { DIE(); }	//晞崋偺悢偼1乣256偺斖埻偱側偔偰偼側傜側偄丅埑弅傾儖僑儕僘儉帺懱偼256傪挻偊傞晞崋偺悢偵傕懳墳壜擻偱偡偑丄僨僐乕僟傪崅懍壔偡傞偨傔偵晞崋傪8價僢僩埲壓偵惂尷偟偨偄偐傜偱偡丅
//伀2016/12/25曄峏:晞崋偺悢偺忋尷傪丄256佀65536偵曄峏偟傑偟偨丅
	if((k < 1) || (k > 65536)) { DIE(); }	//晞崋偺悢偼1乣65536偺斖埻偱側偔偰偼側傜側偄丅
//}}2016/12/25曄峏:晞崋偺悢偺忋尷傪丄256佀65536偵曄峏偟傑偟偨丅
	//尦夋憸傪4x4僺僋僙儖偺僙儖偵暘妱偟偰丄埑弅尦偺儀僋僩儖偲偡傞丅
	{
		cols = (w + 3) / 4;	//僙儖楍悢
		rows = (h + 3) / 4;	//僙儖峴悢
		n = cols * rows;	//慡僙儖悢
		vector = malloc(n * 16);		//儀僋僩儖偺攝楍偺儊儌儕傪妋曐偡傞丅
		if(!vector) { DIE(); }
		for(row = 0; row < rows; row++) {
			for(col = 0; col < cols; col++) {
				i = (cols * row) + col;
				for(y1 = 0; y1 < 4; y1++) {
					y2 = (row * 4) + y1;
					for(x1 = 0; x1 < 4; x1++) {
						x2 = (col * 4) + x1;
						if((x2 < w) && (y2 < h)) {
							c = ((const unsigned char*)image)[(stride * y2) + x2];
							if(c > 4) { c = 4; }	//5乣255傕4(摟夁)偲摨偠偲尒側偡丅
						} else {
							c = 4;			//僷僨傿儞僌晹暘偼4(摟夁)偲尒側偡丅
						}
						vector[(i * 16) + ((y1 * 4) + x1)] = c;
					}
				}
			}
		}
	}
	//VQ埑弅傪峴偆丅
	{
#ifdef  VQTC_PRINT_PROGRESS
		int newMsgLen, oldMsgLen = 0;
#endif//VQTC_PRINT_PROGRESS
//{{2016/12/20曄峏:k-means朄(,枖偼,k-means++朄)偺孞傝曉偟張棟偺丄懪偪愗傝忦審傪曄峏偟傑偟偨丅
//		int iTry;
//伀2016/12/20曄峏:k-means朄(,枖偼,k-means++朄)偺孞傝曉偟張棟偺丄懪偪愗傝忦審傪曄峏偟傑偟偨丅
		unsigned char sha1[20/*SHA-1*/];	//label[]偺SHA-1傪媮傔傞僶僢僼傽
		ght_hash_table_t* ht_sha1;		//弌尰偟偨SHA-1傪婰榐偡傞僴僢僔儏僥乕僽儖
		ght_set_rehash((ht_sha1 = ght_create(0)), 1);	//僴僢僔儏僥乕僽儖傪嶌惉偡傞丅
//}}2016/12/20曄峏:k-means朄(,枖偼,k-means++朄)偺孞傝曉偟張棟偺丄懪偪愗傝忦審傪曄峏偟傑偟偨丅
		center = malloc(k * 16);		//僋儔僗僞拞怱偺儊儌儕傪妋曐偡傞丅
		if(!center) { DIE(); }
		label = malloc(n * sizeof(int));	//儔儀儖偺儊儌儕傪妋曐偡傞丅
		if(!label) { DIE(); }
		//k-means++朄偺弶婜壔張棟傪幚峴偡傞丅
#ifdef  VQTC_PRINT_PROGRESS
		newMsgLen = fprintf(stderr, "\rVqTc_EncodeImage: calling k_means_clustering_init");
		if(oldMsgLen > newMsgLen) { fprintf(stderr, "%*s", oldMsgLen - newMsgLen, ""); } oldMsgLen = newMsgLen;
#endif//VQTC_PRINT_PROGRESS
		k_means_clustering_init(vector, n, center/*僟儈乕*/, k, label, 16, VqTc_EncodeImage_distance);
		//k-means朄(,枖偼,k-means++朄)偺孞傝曉偟張棟傪幚峴偡傞丅
		// - 嬌抂偵廂懇偑埆偔偰張棟偑廔椆偟側偄働乕僗偺媬嵪偺偨傔偵丄'偁傞掱搙偺夞悢'偱懪偪愗傞帠偵偟偨丅
		//   '偁傞掱搙偺夞悢'偺揔愗側抣傪寛傔傞曽朄偼柍偄偑丄偲傝偁偊偢壓婰偺擇埬傪専摙偟偨傒偨丅
		//   亊埬1. 儀僋僩儖悢傪丄孞傝曉偟夞悢偺忋尷偲偡傞丅
		//   劆儔儀儖偺晅偗懼偊悢偑枅夞堦屄偢偮敪惗偡傞働乕僗傪憐掕偟偨応崌丄儀僋僩儖悢傪孞傝曉偟夞悢偺忋尷偲偡傞埬偑峫偊傜傟傞丅
		//   劆尩枾偵偼丄堦搙晅偗懼偊偨儔儀儖偑嵞搙晅偗懼偊傜傟傞壜擻惈傕桳傞偺偱丄儀僋僩儖悢傛傝傕懡偄夞悢偐偐偭偰廂懇偡傞壜擻惈傕桳傞丅
		//   劆幚嵺偵帋偟偰傒偨強丄戝偒側夋憸(懡偄儀僋僩儖悢)偱丄栚昗僋儔僗僞悢偑彫偝偄応崌丄偄偮傑偱傕晅偗懼偊偑廂懇偟側偄帠偑敪惗偟偨丅
		//   劆偙偺応崌丄孞傝曉偟夞悢偺忋尷(儀僋僩儖悢)偑戝偒偄偺偱丄柍懯偵挿帪娫偐偐偭偰偟傑偆丅
		//   劆廬偭偰丄偙偺埬偼椙偔側偄丅
		//   乑埬2. 栚昗僋儔僗僞悢傪丄孞傝曉偟夞悢偺忋尷偲偡傞丅
		//   劆摿偵崻嫆偼柍偄偺偩偑丄偙偪傜偺曽朄偺曽偑椙偄偲巚偭偨丅
		//   劆慜弎偺捠傝丄幚嵺偵偼栚昗僋儔僗僞悢偑彫偝偄掱廂懇偑抶偄孹岦偑桳傞偺偱丄偙偺埬偼偦偺媡偵側偭偰偟傑偭偰偄傞偺偩偑丄
		//   劆忋庤偔廂懇偡傞応崌偼廫夞掱搙偱廂懇偡傞帠偑懡偄偺偱丄偦傟傪挻偊偰懪偪愗偭偨偲偟偰傕懪偪愗傝偑憗夁偓傞偲尵偆帠偼柍偄偩傠偆丅
		//   劆幚嵺偺強丄摿偵帪娫偑妡偐傞偺偼k_means_clustering_init()偱偁傝丄k_means_clustering_step()堦夞摉偨傝偺帪娫偼偝傎偳挿偔側偄丅
		//   劆栚昗僋儔僗僞悢偺忋尷偼丄崅乆256偱偁傞偐傜丄尰幚揑側帪娫撪偵廔椆偡傞偩傠偆丅	佀{{2016/12/25僐儊儞僩捛婰:晞崋偺悢偺忋尷傪丄256佀65536偵曄峏偟傑偟偨丅}}
		//   劆(偨偩偟k_means_clustering_init()偼挿帪娫妡偐傞偺偱丄慡懱偺帪娫偼傗偼傝挿偄偺偩偑乧)
		// * Tue Dec 20 21:28:56 JST 2016 Naoyuki Sawa
		// - k-means朄(,枖偼,k-means++朄)偺孞傝曉偟張棟偺丄懪偪愗傝忦審傪曄峏偟傑偟偨丅
		//   忋婰偺埬1,埬2偼丄幚嵺偵巊偭偰傒偨強丄偳偪傜傕丄柍懯偵挿偔張棟傪宲懕偟偰偟傑偆帠偑懡偔偰丄傗偭傁傝椙偔側偄偲巚偄傑偟偨丅
		//   偦傟傛傝傕丄摨偠儔儀儖妱傝摉偰偑擇夞弌尰偟偨帪偵(=忬懺偑儖乕僾偟偨帪偵)懪偪愗傞偺偑揔愗偩偲巚偄丄曄峏偡傞帠偵偟傑偟偨丅
		// - 儔儀儖妱傝摉偰偺忬懺傪婰榐偡傞曽朄偲偟偰偼丄SHA-1傪巊梡偟傑偟偨丅
		//   尩枾偵偼丄label[]傪偦偺傑傑搊榐偡傋偒側偺偱偡偑丄儊儌儕愡栺偺偨傔偵丄SHA-1傪巊偆帠偵偟傑偟偨丅
		//   SHA-1偱傕丄傑偢丄徴撍偡傞帠偼柍偄偲巚偄傑偡丅
//{{2016/12/20曄峏:k-means朄(,枖偼,k-means++朄)偺孞傝曉偟張棟偺丄懪偪愗傝忦審傪曄峏偟傑偟偨丅
//	    //{{偳偪傜偐傪慖戰偣傛丅
//	    //	for(iTry = 0; iTry < n; iTry++) {	//亊埬1
//		for(iTry = 0; iTry < k; iTry++) {	//乑埬2
//	    //}}偳偪傜偐傪慖戰偣傛丅
//伀2016/12/20曄峏:k-means朄(,枖偼,k-means++朄)偺孞傝曉偟張棟偺丄懪偪愗傝忦審傪曄峏偟傑偟偨丅
		for(;;) {
//}}2016/12/20曄峏:k-means朄(,枖偼,k-means++朄)偺孞傝曉偟張棟偺丄懪偪愗傝忦審傪曄峏偟傑偟偨丅
			//僋儔僗僞拞怱傪媮傔傞丅
			for(j = 0; j < k; j++) {				//奺僋儔僗僞偵偮偄偰乧
				memset(sum, 0, sizeof sum);
				memset(cnt, 0, sizeof cnt);
				for(i = 0; i < n; i++) {			//奺儀僋僩儖偵偮偄偰乧
					if(label[i] == j) {			//偙偺儀僋僩儖偑丄偙偺僋儔僗僞偵懏偡傞側傜偽乧
						for(l = 0; l < 16; l++) {	//奺僺僋僙儖偵偮偄偰乧
							c = vector[(i * 16) + l];	//偙偺儀僋僩儖偺丄僺僋僙儖傪庢摼偡傞丅
							if(c != 4) {		//摟柧偱側偗傟偽乧
								sum[l] += c;	//偙偺埵抲偺丄怓傪壛嶼偡傞丅
								cnt[l]++;	//偙偺埵抲偺丄摟柧偱側偄僺僋僙儖偺悢傪憹傗偡丅
							}
						}
					}
				}
				for(l = 0; l < 16; l++) {			//奺僺僋僙儖偵偮偄偰乧
					if(cnt[l]) {				//偙偺埵抲偺丄摟柧偱側偄僺僋僙儖偑桳傟偽乧
						center[(j * 16) + l] = lround((double)sum[l] / (double)cnt[l]);	//怓偺暯嬒傪媮傔傞丅
					} else {				//偙偺埵抲偺丄摟柧偱側偄僺僋僙儖偑柍偗傟偽乧
						center[(j * 16) + l] = 4;	//摟柧偲偡傞丅
					}
				}
			}
			//k-means朄(,枖偼,k-means++朄)偺孞傝曉偟張棟傪1僗僥僢僾幚峴偡傞丅
			//嵟傕嬤偄僋儔僗僞偺晅偗懼偊偑敪惗偟側偗傟偽(枖偼彮側偗傟偽)丄廔椆偡傞丅
#ifdef  VQTC_PRINT_PROGRESS
			newMsgLen = fprintf(stderr, "\rVqTc_EncodeImage: calling k_means_clustering_step");
			if(oldMsgLen > newMsgLen) { fprintf(stderr, "%*s", oldMsgLen - newMsgLen, ""); } oldMsgLen = newMsgLen;
#endif//VQTC_PRINT_PROGRESS
			relabel = k_means_clustering_step(vector, n, center, k, label, 16, VqTc_EncodeImage_distance);
#ifdef  VQTC_PRINT_PROGRESS
			newMsgLen = fprintf(stderr, "\rVqTc_EncodeImage: k_means_clustering_step returns %d", relabel);
			if(oldMsgLen > newMsgLen) { fprintf(stderr, "%*s", oldMsgLen - newMsgLen, ""); } oldMsgLen = newMsgLen;
#endif//VQTC_PRINT_PROGRESS
			if(relabel <= 0/*挷惍壜*/) { break; }
//{{2016/12/20捛壛:k-means朄(,枖偼,k-means++朄)偺孞傝曉偟張棟偺丄懪偪愗傝忦審傪曄峏偟傑偟偨丅
			sha1_digest(sha1, label, n * sizeof(int));				//label[]偺SHA-1傪媮傔傞丅杮摉偼label[]傪偦偺傑傑搊榐偡傋偒側偺偩偑丄儊儌儕愡栺偺偨傔偵SHA-1傪巊偆帠偵偟偨丅傑偢徴撍偡傞帠偼柍偄偩傠偆丅
			if(ght_insert(ht_sha1, sha1/*僟儈乕*/, 20/*SHA-1*/, sha1)) { break; }	//label[]偺SHA-1傪搊榐偡傞丅婛偵搊榐偝傟偰偄偨傜(摨偠忬懺偑2夞栚偵弌尰偟偨傜)丄ght_insert()偑幐攕偟偰旕0偺抣傪曉偡偺偱丄儖乕僾傪敳偗傞丅
//}}2016/12/20捛壛:k-means朄(,枖偼,k-means++朄)偺孞傝曉偟張棟偺丄懪偪愗傝忦審傪曄峏偟傑偟偨丅
		}
#ifdef  VQTC_PRINT_PROGRESS
		newMsgLen = fprintf(stderr, "\rVqTc_EncodeImage: k_means_clustering_step done");
		if(oldMsgLen > newMsgLen) { fprintf(stderr, "%*s", oldMsgLen - newMsgLen, ""); } putc('\n', stderr); oldMsgLen = 0;
#endif//VQTC_PRINT_PROGRESS
//{{2016/12/20捛壛:k-means朄(,枖偼,k-means++朄)偺孞傝曉偟張棟偺丄懪偪愗傝忦審傪曄峏偟傑偟偨丅
		ght_finalize(ht_sha1);	//僴僢僔儏僥乕僽儖傪嶍彍偡傞丅
//}}2016/12/20捛壛:k-means朄(,枖偼,k-means++朄)偺孞傝曉偟張棟偺丄懪偪愗傝忦審傪曄峏偟傑偟偨丅
	}
	//幚嵺偵巊梡偝傟偰偄傞僋儔僗僞偩偗偵晞崋傪怳傝捈偟丄摨帪偵丄偦偺僋儔僗僞偺僐乕僪僽僢僋(僙儖)傪埑弅偟偰奿擺偡傞丅
	{
		bits1 = VqTc_CalculateCodeBits(k);				//壖偺晞崋價僢僩悢傪媮傔傞丅
		k = 0;								//晞崋傪0偐傜怳傝捈偡丅
		for(i = 0; i < n; i++) {					//奺儀僋僩儖偵偮偄偰乧
			l = label[i];						//偙偺儀僋僩儖偑懏偡傞僋儔僗僞斣崋傪庢摼偡傞丅
			if(label[i] != -1) {					//偙偺儀僋僩儖偑婛偵張棟偝傟偰偄側偗傟偽乧
				for(j = i; j < n; j++) {			//偙偺儀僋僩儖帺恎偐傜丄嵟屻偺儀僋僩儖傑偱乧
					if(label[j] == l) {			//偙偺儀僋僩儖傕丄摨偠僋儔僗僞斣崋偵懏偟偰偄偨傜乧
						label[j] = -1;			//偙偺儀僋僩儖偑婛偵張棟偝傟偨帠傪儅乕僋偡傞丅
						bitarray_lsb1st_set(code, j * bits1, bits1, k);	//怳傝捈偟偨晞崋傪奿擺偡傞丅	偙偙偱偼壖偺晞崋價僢僩悢扨埵偱奿擺偟偰偍偒丄晞崋偺悢偑寛傑偭偨屻偱丄幚岠晞崋價僢僩悢偵崌傢偣偰媗傔捈偡丅
					}
				}
				VqTc_EncodeCell(&center[l * 16], &((unsigned char*)codebook)[k * 5]);	//偙偺儀僋僩儖偺旕埑弅偺16僺僋僙儖傪丄5僶僀僩偺埑弅僨乕僞偵曄姺偟偰奿擺偡傞丅
				k++;						//晞崋偺抣傪憹傗偡丅
			}
		}
		bits2 = VqTc_CalculateCodeBits(k);				//幚岠晞崋價僢僩悢傪媮傔傞丅
		for(i = 0; i < n; i++) {					//劉
			j = bitarray_lsb1st_get(code, i * bits1, bits1);	//劌晞崋偺價僢僩悢偵崌傢偣偰丄晞崋傪媗傔捈偡丅
			    bitarray_lsb1st_set(code, i * bits2, bits2, j);	//劆
		}								//劊
	}
	//儊儌儕傪夝曻偡傞丅
	{
		free(vector);	//儀僋僩儖偺攝楍偺儊儌儕傪夝曻偡傞丅
		free(center);	//僋儔僗僞拞怱偺攝楍偺儊儌儕傪夝曻偡傞丅
		free(label);	//儔儀儖偺攝楍偺儊儌儕傪夝曻偡傞丅
	}
	//晞崋偺悢傪曉偡丅
	return k;
}
/*--------------------------------------------------------------------------*/
//夋憸傪揥奐偡傞丅
//[in]
//	image		夋憸傪奿擺偡傞僶僢僼傽			(out)		0=敀,1=柧,2=埫,3=敀,4=摟夁
//	w		夋憸偺暆				(in)		1乣丅埑弅帪偲摨偠抣傪巜掕偟偰壓偝偄丅
//	h		夋憸偺崅偝				(in)		1乣丅埑弅帪偲摨偠抣傪巜掕偟偰壓偝偄丅
//	stride		夋憸偺1儔僀儞摉偨傝偺僶僀僩悢		(in)		w乣丅埑弅帪偲堎側傞抣偱傕峔偄傑偣傫丅
//	codebook	僐乕僪僽僢僋				(in)		VqTc_EncodeImage()偑弌椡偟偨僐乕僪僽僢僋偺僨乕僞傪巜掕偟偰壓偝偄丅
//	k		晞崋偺悢				(in)		VqTc_EncodeImage()偺栠傝抣傪巜掕偟偰壓偝偄丅
//	code		晞崋攝楍				(in)		VqTc_EncodeImage()偑弌椡偟偨晞崋攝楍偺僨乕僞傪巜掕偟偰壓偝偄丅
void VqTc_DecodeImage(void* image/*[stride*h]*/, int w, int h, int stride, const void* codebook/*[k*5]*/, int k, const void* code/*[VqTc_CalculateCodeBytes(w,h,k)]*/) {
	int c, i, x, y, col, row, cols, rows, bits;
	unsigned char cell[16];
	if((w < 1) || (h < 1)) { DIE(); }	//嬻偺夋憸傪巜掕偟偰偼偄偗側偄丅
//{{2016/12/25曄峏:晞崋偺悢偺忋尷傪丄256佀65536偵曄峏偟傑偟偨丅
//	if((k < 1) || (k > 256)) { DIE(); }	//晞崋偺悢偼1乣256偺斖埻偱側偔偰偼側傜側偄丅埑弅傾儖僑儕僘儉帺懱偼256傪挻偊傞晞崋偺悢偵傕懳墳壜擻偱偡偑丄僨僐乕僟傪崅懍壔偡傞偨傔偵晞崋傪8價僢僩埲壓偵惂尷偟偨偄偐傜偱偡丅
//伀2016/12/25曄峏:晞崋偺悢偺忋尷傪丄256佀65536偵曄峏偟傑偟偨丅
	if((k < 1) || (k > 65536)) { DIE(); }	//晞崋偺悢偼1乣65536偺斖埻偱側偔偰偼側傜側偄丅
//}}2016/12/25曄峏:晞崋偺悢偺忋尷傪丄256佀65536偵曄峏偟傑偟偨丅
	cols = (w + 3) / 4;
	rows = (h + 3) / 4;
	bits = VqTc_CalculateCodeBits(k);
	for(col = 0; col < cols; col++) {
		for(row = 0; row < rows; row++) {
			i = bitarray_lsb1st_get(code, ((cols * row) + col) * bits, bits);
			if((unsigned)i >= (unsigned)k) { DIE(); }	//僶僌,枖偼,僨乕僞攋懝
			VqTc_DecodeCell(&((unsigned char*)codebook)[i * 5], cell);
			for(x = 0; x < 4; x++) {
				for(y = 0; y < 4; y++) {
					c = cell[(y * 4) + x];
					((unsigned char*)image)[(((row * 4) + y) * stride) + ((col * 4) + x)] = c;
				}
			}
		}
	}
}
/*--------------------------------------------------------------------------*/
#if 0
//仭巊梡椺:/clip/test.win/app.cpp偺WndProc()偩偗傪埲壓偺傛偆偵抲偒姺偊偰幚峴偟偰壓偝偄丅(梫GDI+)
#ifdef  __cplusplus
#ifdef  USE_GDIPLUS
static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
	static Bitmap *srcBmp, *dstBmp;
	static BitmapData data;
	switch(uMsg) {
	case WM_CREATE:
		{static const int MaxSize = 4096, K = 256/*1乣65536偺斖埻偱挷惍壜丅2^N偱側偔偰傕椙偄丅*/;
		static unsigned char image[MaxSize][MaxSize];
		//埑弅
		srcBmp = new Bitmap(L"C:/usr/PIECE/docs/TUTORIAL/AYAKA/A.BMP"/*曄峏壜*/); if(srcBmp->GetLastStatus()) { DIE(); }
		if(srcBmp->LockBits(NULL, ImageLockModeWrite, PixelFormat8bppIndexed, &data)) { DIE(); }
		void* codebook = malloc(K * 5); if(!codebook) { DIE(); }
		void* code = malloc(VqTc_CalculateCodeBytes((int)data.Width, (int)data.Height, K)); if(!code) { DIE(); }
		int k = VqTc_EncodeImage(data.Scan0, data.Width, data.Height, data.Stride, codebook, K, code);
		if(srcBmp->UnlockBits(&data)) { DIE(); }
		//揥奐僥僗僩
		VqTc_DecodeImage(&image[0][0], data.Width, data.Height, MaxSize, codebook, k, code);
		free(codebook);
		free(code);
		dstBmp = new Bitmap(data.Width, data.Height); if(dstBmp->GetLastStatus()) { DIE(); }
		for(int x = 0; x < (int)data.Width; x++) {
			for(int y = 0; y < (int)data.Height; y++) {
				Color c; switch(image[y][x]) {
				case 3:  c = Color(255,255,255); break; //劍A.BMP偼鎫挷偑媡側偺偱偙偙傕媡偵偟偰偄傑偡丅
				case 2:  c = Color(170,170,170); break; //劆杮摉偼(敀:0佁3:崟)偱偡丅
				case 1:  c = Color( 85, 85, 85); break; //劆
				case 0:  c = Color(  0,  0,  0); break; //劊
				default: c = Color(  0,255,  0); break;
				} if(dstBmp->SetPixel(x, y, c)) { DIE(); }
			}
		}}return 0;
	case WM_PAINT:
		{PAINTSTRUCT ps; HDC hDC = BeginPaint(hWnd, &ps);
		Graphics* graphics = new Graphics(hDC); if(graphics->GetLastStatus()) { DIE(); }
		if(graphics->Clear(Color.Red)) { DIE(); }
		graphics->DrawImage(srcBmp, 0, 0, data.Width, data.Height); //尦夋憸
		graphics->DrawImage(dstBmp, data.Width + 5, 0, data.Width, data.Height); //埑弅偟偰揥奐偟偨夋憸
		delete graphics; EndPaint(hWnd, &ps);
		}return 0;
	case WM_DESTROY:
		delete srcBmp; delete dstBmp;
		PostQuitMessage(0);
		return 0;
	}
	return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
#endif//USE_GDIPLUS
#endif//__cplusplus
#endif
