JNIEXPORT jint JNICALL Java_UCIDec_UCIDecode(JNIEnv* jenv, jclass jcls, jbyteArray j_src, jint j_srclen, jobjectArray j_dsts, jintArray j_stride, jintArray j_w, jintArray j_h, jintArray j_b) { jcls; const void* const src = (*jenv)->GetByteArrayElements(jenv, j_src, 0); const void* dst = 0; int stride, w, h, b; const int r = UCIDecode(src, (int)j_srclen, (j_dsts && (*jenv)->GetArrayLength(jenv, j_dsts) > 0) ? &dst : 0, &stride, &w, &h, &b); (*jenv)->ReleaseByteArrayElements(jenv, j_src, src, JNI_ABORT); if(r >= 0) { if(dst) { const int dstlen = stride * h; const jbyteArray j_dst = (*jenv)->NewByteArray(jenv, dstlen); (*jenv)->SetByteArrayRegion(jenv, j_dst, 0, dstlen, dst); UCIFree(dst); (*jenv)->SetObjectArrayElement(jenv, j_dsts, 0, j_dst); } if(j_stride && (*jenv)->GetArrayLength(jenv, j_stride) > 0) (*jenv)->SetIntArrayRegion(jenv, j_stride, 0, 1, &stride); if(j_w && (*jenv)->GetArrayLength(jenv, j_w ) > 0) (*jenv)->SetIntArrayRegion(jenv, j_w , 0, 1, &w ); if(j_h && (*jenv)->GetArrayLength(jenv, j_h ) > 0) (*jenv)->SetIntArrayRegion(jenv, j_h , 0, 1, &h ); if(j_b && (*jenv)->GetArrayLength(jenv, j_b ) > 0) (*jenv)->SetIntArrayRegion(jenv, j_b , 0, 1, &b ); } return (jint)r; }
__declspec(dllexport) int __stdcall GetPictureInfo(const char* filename, int len, unsigned flag, PictureInfo* pi) { FILE* fp = fopen(filename, "rb"); if(fp) { int bit; unsigned char buf[12] = {0}; fread(buf, 1, 12, fp); fclose(fp); memset(pi, 0, sizeof(PictureInfo)); if(UCIDecode(buf, 12, 0, 0, &pi->width, &pi->height, &bit) < 0) return 2; pi->bit = (short)bit; } return 1; }
__declspec(dllexport) int __stdcall GetPicture(const char* filename, int len, unsigned flag, HLOCAL* hbi, HLOCAL* hbm, void* lpPrgressCallback, int lData) { int ret = 1; FILE* fp = 0; unsigned char* src = 0, *dst = 0; unsigned char* pdst, *pbmp; BITMAPINFOHEADER* bih; int wide, dst_stride, bmp_stride; *hbi = 0; *hbm = 0; if((flag & 7) == 0) // disk file { fp = fopen(filename, "rb"); if(!fp) goto err_; fseek(fp, 0, SEEK_END); len = ftell(fp); fseek(fp, 0, SEEK_SET); src = (unsigned char*)malloc(len); if(!src) goto err_; if((int)fread(src, 1, len, fp) != len) goto err_; fclose(fp); fp = 0; } else if((flag & 7) == 1) // image on memory src = (unsigned char*)filename; else goto err_; *hbi = LocalAlloc(LMEM_MOVEABLE, sizeof(BITMAPINFOHEADER)); if(!*hbi) goto err_; bih = (BITMAPINFOHEADER*)LocalLock(*hbi); if(!bih) goto err_; if(UCIDecode(src, len, &dst, &dst_stride, (int*)&bih->biWidth, (int*)&bih->biHeight, (int*)&wide) < 0) goto err_; bih->biSize = sizeof(BITMAPINFOHEADER); bih->biPlanes = 1; bih->biBitCount = (WORD)wide; bih->biCompression = BI_RGB; bih->biSizeImage = 0; bih->biXPelsPerMeter= 0; bih->biYPelsPerMeter= 0; bih->biClrUsed = 0; bih->biClrImportant = 0; if((char*)src != filename) { free(src); src = 0; } wide = wide / 8 * bih->biWidth; bmp_stride = (wide + 3) & 0xfffffffc; *hbm = LocalAlloc(LMEM_MOVEABLE, bmp_stride * bih->biHeight); if(!*hbm) goto err_; pbmp = (unsigned char*)LocalLock(*hbm); if(!pbmp) goto err_; pdst = dst + dst_stride * (bih->biHeight - 1); while(pdst >= dst) { memcpy(pbmp, pdst, wide); pbmp += bmp_stride; pdst -= dst_stride; } ret = 0; err_: if(ret != 0) { if(*hbm) { LocalFree(*hbm); *hbm = 0; } if(*hbi) { LocalFree(*hbi); *hbi = 0; } } else { LocalUnlock(*hbm); LocalUnlock(*hbi); } if(dst) UCIFree(dst); if(src && (char*)src != filename) free(src); if(fp) fclose(fp); return ret; }
_MY_C_HEAD_ #include "LZMA/7zVersion.h" #include "LZMA/Alloc.h" #include "LZMA/Lzma86.h" _MY_C_TAIL_ void __cdecl main2(int argc, wchar_t **argv) { if (argc < 3) { printf("Too few parameters\n"); return; } Byte *outBuffer, FileType, bLZMA; SizeT inSize, outSize, outMaxSize; WCHAR szFileName[MAX_PATH]; WCHAR *szFileType[] = { L"UCA", L"UCI", L"AAC", L"M4A", L"Unknown" }; PBYTE pbFile; DWORD dwFileNumber, dwErrorCount, dwMaxNumber, dwFileSize, dwRead; DWORD dwBufferSize, dwMaxFileNumber, dwMethod[] = {'ACU', 'ICU', 'CAA', 'A4M', 'KNU'}; HANDLE hFind, hHeap, hFile, hDestFile; WIN32_FIND_DATAW wfd; TSpiArchiveInfo *pSpiArcInfo; LARGE_INTEGER liFrequency, liStart, liStop; setlocale(LC_CTYPE, ""); hDestFile = CreateFileW(argv[2], GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hDestFile == INVALID_HANDLE_VALUE) { wprintf(L"Can't create %s\n", argv[2]); return; } swprintf(szFileName, L"%s\\*.*", argv[1]); hFind = FindFirstFileW(szFileName, &wfd); if (hFind == INVALID_HANDLE_VALUE) { wprintf(L"Can't find %s\n", szFileName); return; } outMaxSize = 0; dwBufferSize = 0; dwErrorCount = 0; dwFileNumber = 0; dwMaxNumber = 1000; hHeap = GetProcessHeap(); pbFile = (PBYTE)HeapAlloc(hHeap, 0, 0); outBuffer = (Byte *)HeapAlloc(hHeap, 0, 0); pSpiArcInfo = (TSpiArchiveInfo *)HeapAlloc(hHeap, HEAP_ZERO_MEMORY, dwMaxNumber * sizeof(*pSpiArcInfo)); WriteFile(hDestFile, pSpiArcInfo, 0x10, &dwRead, NULL); bLZMA = argc >= 4 ? (Byte)wcstoul(argv[3], NULL, 10) : 1; dwMaxFileNumber = argc == 5 ? wcstoul(argv[4], NULL, 10) : -1; QueryPerformanceFrequency(&liFrequency); QueryPerformanceCounter(&liStart); do { if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) continue; swprintf(szFileName, L"%s\\%s", argv[1], wfd.cFileName); hFile = CreateFileW(szFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { wprintf(L"Open %s failed.\n", szFileName); ++dwErrorCount; continue; } if (dwFileNumber >= dwMaxNumber) { dwMaxNumber = dwMaxNumber + (dwMaxNumber >> 1); pSpiArcInfo = (TSpiArchiveInfo *)HeapReAlloc(hHeap, HEAP_ZERO_MEMORY, pSpiArcInfo, dwMaxNumber * sizeof(*pSpiArcInfo)); } dwFileSize = GetFileSize(hFile, NULL); if (dwFileSize > dwBufferSize) { dwBufferSize = dwFileSize; pbFile = (PBYTE)HeapReAlloc(hHeap, 0, pbFile, dwBufferSize); } ReadFile(hFile, pbFile, dwFileSize, &dwRead, NULL); CloseHandle(hFile); FileType = CheckFileType(pbFile); wprintf(L"Packing %s ... %s ", szFileName, szFileType[FileType]); pSpiArcInfo[dwFileNumber].position = SetFilePointer(hDestFile, 0, 0, FILE_CURRENT); if (dwFileSize > 300 && bLZMA && FileType != UCI && FileType != M4A && FileType != AAC) { outSize = dwFileSize / 20 * 21 + (1 << 16) + 4; if (outSize > outMaxSize) { outMaxSize = outSize; outBuffer = (Byte *)HeapReAlloc(hHeap, 0, outBuffer, outSize); } Lzma86_Encode(outBuffer, &outSize, (Byte *)pbFile, dwFileSize, 9, 1 << 27, 0); pSpiArcInfo[dwFileNumber].compsize = outSize; WriteFile(hDestFile, outBuffer, outSize, &dwRead, NULL); wprintf(L"@ compressed ... "); } else { if (FileType != UCI && FileType != UCA) { WriteFile(hDestFile, &dwFileSize, 4, &dwRead, NULL); } WriteFile(hDestFile, pbFile, dwFileSize, &dwRead, NULL); pSpiArcInfo[dwFileNumber].compsize = dwFileSize; } if (FileType != UNKNOWN) { *(LPDWORD)&pSpiArcInfo[dwFileNumber].method = dwMethod[FileType]; } int w, h, b; CHAR *p; HSTREAM hStream; static BOOL bBassInit = FALSE; WideCharToMultiByte(936, 0, wfd.cFileName, -1, pSpiArcInfo[dwFileNumber].filename, sizeof(pSpiArcInfo[dwFileNumber].filename), NULL, NULL); if (FileType == UNKNOWN) { CHAR *pExt = PathFindExtensionA(pSpiArcInfo[dwFileNumber].filename); if (pExt++) { lstrcpynA((LPSTR)pSpiArcInfo[dwFileNumber].method, pExt, sizeof(pSpiArcInfo->method)); } else { *(LPDWORD)&pSpiArcInfo[dwFileNumber].method = 'KNU'; } } p = PathFindExtensionA(pSpiArcInfo[dwFileNumber].filename); switch (FileType) { case UCA: UCADecode(pbFile, dwFileSize, NULL,(int *)&pSpiArcInfo[dwFileNumber].filesize); if (p) { lstrcpyA(p + 1, "wav"); } printf("OK!"); break; case UCI: UCIDecode(pbFile, dwFileSize, NULL, NULL, &w, &h, &b); pSpiArcInfo[dwFileNumber].filesize = (w * b / 8 + (b == 0x18 ? (w & 3) : 0)) * h + sizeof(TBitMapHeader); if (p) { lstrcpyA(p + 1, "bmp"); } printf("OK!"); break; case AAC: case M4A: if (bBassInit == FALSE) { bBassInit = TRUE; if (BASS_Init(0, 44100, 0, NULL, NULL) == FALSE) { ++dwErrorCount; printf("failed!"); break; } } hStream = FileType == AAC ? BASS_AAC_StreamCreateFile(TRUE, pbFile, 0, dwFileSize, BASS_STREAM_DECODE) : BASS_MP4_StreamCreateFile(TRUE, pbFile, 0, dwFileSize, BASS_STREAM_DECODE); if (hStream) { pSpiArcInfo[dwFileNumber].filesize = (DWORD)BASS_ChannelGetLength(hStream, BASS_POS_BYTE) + + sizeof(TWaveHeader); BASS_StreamFree(hStream); if (p) { lstrcpyA(p + 1, "wav"); } printf("OK!"); } else { ++dwErrorCount; printf("failed!"); } break; default: pSpiArcInfo[dwFileNumber].filesize = dwFileSize; printf("OK!"); } wprintf(L"\n"); ++dwFileNumber; } while (dwFileNumber < dwMaxFileNumber && FindNextFileW(hFind, &wfd));