unsigned int mime_len;

typedef union {
	unsigned int	data;
	unsigned char	xyz[4];
} Union_data_t;

static long codetovalue(unsigned char c)
{
	if( (c >= (unsigned char)'A') && (c <= (unsigned char)'Z') ) {
		return (long)(c - (unsigned char)'A');
	}
	else if( (c >= (unsigned char)'a') && (c <= (unsigned char)'z') ) {
		return ((long)(c - (unsigned char)'a') +26);
	}
	else if( (c >= (unsigned char)'0') && (c <= (unsigned char)'9') ) {
		return ((long)(c - (unsigned char)'0') +52);
	}
	else if( (unsigned char)'+' == c ) {
		return (long)62;
	}
	else if( (unsigned char)'/' == c ) {
		return (long)63;
	}
	else if( (unsigned char)'=' == c ) {--mime_len;
		return (long)0;
	}
	else {//ShowMessage("OO");
		return -1;
	}
}

int decode_str(int enc_ptr, const unsigned char *src, unsigned char *dest)
{
	int					i, j;
	unsigned	long	base64 = 0;
	unsigned	char	x;
	Union_data_t		bb;

	for (i = enc_ptr; i < enc_ptr + 4; i++) {
		x = codetovalue(src[i]);
		base64 |= x;
		if ((i - enc_ptr) != 3) base64 <<= 6;
	}
        dest[2]=base64&255;
        dest[1]=(base64>>8)&255;
        dest[0]=(base64>>16)&255;
/*	base64 <<= 8;

	bb.data = base64;

	for(j = 0, i = 3; i >= 1; i--) {
		dest[j++] = bb.xyz[i];
	}*/

	return 0;
}

int decode(const unsigned char *src, unsigned char *dest)
{
	int					i = 0,j;
	int					srclen;
	unsigned char				tmp[4];
        mime_len=0;

	/* NULL pointer */
	if (src == NULL)
		return -1;

	/**/
	srclen = strlen(src);

	if (!srclen % 4)
		return -2;

        unsigned char *p,*q;p=dest;
        mime_len=(srclen/4)*3;
	while(srclen) {
                q=tmp;for(j=0;j<4;j++)*(q++)=0;
		decode_str(i, src, tmp);
//		printf("i = %d, srclen = %d, tmp = %s\n", i, srclen, tmp);
                for(j=0;j<3;j++)*(p++)=tmp[j];
//		strcat(dest, tmp);
		i+=4;srclen-=4;
	}

//	printf("★ dest = %s\n", dest);

	return 0;
}


static unsigned char *base64 = (unsigned char *)"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

static void enclode_char(unsigned long bb, int srclen, unsigned char *dest, int j)
{
	int					x, i, base;

	/* 最終位置の計算 */
	for ( i = srclen; i < 2; i++ )
		bb <<= 8;

	/* BASE64変換 */
	for ( base = 18, x = 0; x < srclen + 2; x++, base -= 6) {
		dest[j++] = base64[ (unsigned long)((bb>>base) & 0x3F) ];
	}

	/* 端数の判断 */
	for ( i = x; i < 4; i++ ) {
		dest[j++] = (unsigned char)'=';		/* 端数 */
	}

}

static void enclode(const unsigned char *src, unsigned char *dest,int len1)
{
	unsigned	char	*p = (char *)src;
	unsigned	long	bb = (unsigned long)0;
	int					i = 0, j = 0;

	while (len1)
	{
		bb <<= 8;
		bb |= (unsigned long)*p;

		/* 24bit単位に編集 */
		if (i == 2) {
			enclode_char(bb, i, dest, j);

			j = j + 4;
			i = 0;
			bb = 0;
		} else
			i++;

		p++;--len1;
	}

	/* 24bitに満たない場合 */
	if (i)
		enclode_char(bb, i - 1, dest, j);

}

