基本的にAndroid

Android初心者の備忘録のようなもの. 公開しているソースコードは主にgccでコンパイルされると想定されています.

zlib for Android

zlib の使い方
ZLIBの使い方は上記のリンクを読めばだいたいわかるであると思う.
サンプルコードも公開されている.

ZLIBはAndroid NDKでコンパイルしなくても使いえるライブラリであり, Javaのファイル操作でも使用が可能.
NDKをビルドするときは下記のものをAndroid.mkに追加する.

LOCAL_LDLIBS:= -llog -lz

今回作成しているアプリでは, 下のコードを使用している.
swfの解凍と, alpha値の解凍.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <zlib.h>
#include <assert.h>

#include <android/log.h>
#include <jni.h>

#define BUFFER_SIZE (4096)

int zlib_inflate(FILE *in, const char *output) {
  z_stream z;
  unsigned char in_buf[BUFFER_SIZE];
  unsigned char out_buf[BUFFER_SIZE];
  int err = 0;
  int flush = Z_NO_FLUSH, ret = 0;
  unsigned long int f_len = 0;
  FILE *out;

  if((out = fopen(output, "w")) == NULL) {
    return EOF;
  }
  
  z.zalloc = Z_NULL;
  z.zfree  = Z_NULL;
  z.opaque = Z_NULL;

  err = inflateInit(&z);
  if(err != Z_OK) {
    perror("inflateInit()");
    return EOF;
  }

  for(;;) {
    z.avail_in = fread(in_buf, sizeof(unsigned char),
        BUFFER_SIZE, in);

    if(z.avail_in == 0) break;
    if(feof(in) != 0)
      flush = Z_STREAM_END;
    z.next_in = in_buf;

    for(;;) {
      z.next_out = out_buf;
      z.avail_out = BUFFER_SIZE;

      ret = inflate(&z, Z_NO_FLUSH);
      assert(ret != Z_STREAM_ERROR);
      switch(ret) {
        case Z_STREAM_ERROR:
        case Z_NEED_DICT:
        case Z_MEM_ERROR:
        case Z_DATA_ERROR:
          break;
      }

      f_len = sizeof(out_buf) - z.avail_out;
      fwrite(out_buf, sizeof(unsigned char), f_len, out);
      if(z.avail_out != 0)
        break;
      if(ret == Z_STREAM_END) break;
    }

    if(ret == Z_STREAM_END) break;
  }
  fclose(out);
  inflateEnd(&z);

  return 1;
}