Androidサンプル ローカルにファイルを保存する

Androidでローカルにファイルを保存する方法についてです。

ファイル書き込みを許可する

ファイルアクセスを許可するため、AndroidManifest.xmlに以下のタグを追加します。

      <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
ローカルディレクトリを確認する

パースペクティブをDDMSにします。右側の画面でディレクトリ内をチェックできます。

ディレクトリを作成する

ローカルにファイルを保存したい場合、アクセスできる場所が限られていまして、

/data/data//files

にしかファイル入出力はできないようです。
例えば、パッケージ名がcom.java.yourdomainなら

/data/data/com.java.yourdomain/files

となります。パッケージ名はContextクラスのgetPackageNameで得られます。(ちなみにActivityはContextを継承している)

        String path = "/data/data/" + context_.getPackageName() + "/files";
        File file = new File(path);
        file.mkdir();
ファイルを作成する

FileOutputStreamを使います。(例外処理省略)

    public boolean writeFile(String fileName) throws IOException
    {
            FileOutputStream fileOutputStream = context_.openFileOutput(fileName, Context.MODE_PRIVATE);
            String buffer = "12345";
            fileOutputStream.write(buffer.getBytes());
    	return true;
    }
ファイルを読み込む

同様にFileInputStreamを使います。

    public boolean readFile(String fileName) throws IOException
    {
            FileInputStream fileInputStream = context_.openFileInput(fileName);
            byte[] buffer = new byte[5];
            fileInputStream.read(buffer, 0, 5);
            String string = new String(buffer);
     }

Xcode4の使い方メモ 〜 ターゲットを作る

Xcodeではプロジェクト1つに対して複数のターゲットを追加できるみたいなので、自前makefileを使ってビルドできるようにしてみます。
まずC++のCommandLineToolプロジェクト"Multiple_targets"を作成しておきます。→//MultipleTargets.xcodeproj

ターゲットを追加する

File>New>New Target>Other>External Build System>ターゲット名"SecondTarget"
Product>Edit Scheme>Build>"+">新規作成したターゲット名"SecondTarget">"Add"でターゲットが追加されます。
makefileを指定するにはTARGETS>"SecondTarget">Info>Directoryにmakeを実行するディレクトリを入力します。
(例えばmakefileの場所が//MultipleTargets/makefileなら"//MultipleTargets"を入力)
main.cppはそのままにして、makefileを用意します。

CXX = g++
TARGET=test_program
SRCS= main.cpp
OBJS= main.o
RM= rm -f
$(TARGET): $(OBJS)
	$(CXX)  -o $(TARGET) $(OBJS)
	$(RM) $(OBJS)
.cpp.o:
	$(CXX) -c $< -o $@
clean:
	$(RM) $(TARGET) $(OBJS)

ビルドしてみるとtest_programが作成されます。実行してコンソールにHelloWorldが出力されていればOK.

新しいスキームを作成する

デフォルトでは既存のスキームが適用されていますので、新規のスキームを作ってみます。
Project>New Scheme>Second Target>OK
Run Test>Info>Executable>test_programを選択。
これでRunボタンを押すとtest_programが実行され、コンソールにHelloWorldが出力されます。また、ProfileやAnalyzeも同様に設定することができます。

iOSで静的ライブラリを使う

Objective-CC++の両方を混在させてみます。※(注)環境はiOS SDK4.3, Xcode4.1, 動作確認はシミュレータのみ

Static Library用プロジェクトを作成する

File>New>NewProject>iOS>Framework & Libraries>CocoaTouch>StaticLib.xcodeprojを/に作成
→//StaticLib/StaticLib.xcodeprojというプロジェクトが作成される
//StaticLib/StaticLib/test.h,test.cppを作成してプロジェクトStaticLib.xcodeprojに追加します
test.h

#ifndef _test_h
#define _test_h
class Sample{
public:
    void test();
};
#endif

test.cpp

#include "test.h"
#include <stdio.h>
void Sample::test(){
    printf("Sample::test was called\n");
}

C++を記述するソースの拡張子を.mmに修正、C++で記述されたヘッダをインクルードしているObjective-Cのヘッダを.hhに修正します。
StaticLib.h→StaticLib.hhにする

#import <Foundation/Foundation.h>
@interface StaticLib : NSObject
-(void)test;
@end

StaticLib.m→StaticLib.mmにする

#import "StaticLib.hh"
#import "test.h"

@implementation StaticLib
- (id)init
{
    self = [super init];
    if (self) {
        
    }
    return self;
}
-(void)test
{
    NSLog(@"[StaticLib test] was called\n");
    Sample sample;
    sample.test();
}
@end

ビルドするとlibStaticLib.aが作成されます。

ライブラリを使用するプロジェクトを作成する

File>New>NewProject>iOS>Applications>適当に選択>StaticLibUse.xcodeprojを作成
→//StaticLibUse/StaticLib.xcodeprojというプロジェクトが作成される
File>Add Files to "StaticLibUse.xcodeproj"> StaticLib.xcodeprojのパスを選択>Add
StaticLibUse.xcodeprojに入れ子状にStaticLib.xcodeprojが追加される
StaticLibUse.xcodeprojのTARGET>Build Phases>Link Binary With Libaries>"+">libStaticLib.a>Doneでライブラリを追加
同様にTarget Dependency>"+">StaticLibでプロジェクトの依存関係を追加
Edit Scheme>Build>"+">StaticLibでビルド対象となるターゲットStaticLibを追加
StaticLibUse.xcodeprojからtest.h,StaticLib.hを読み込むためにインクルードパスを設定します。例えば"//StaticLib/StaticLib"
StaticLibUse.xcodeproj選択>TARGET>Build Settings>Serach Headers>"+">ヘッダパス入力 再帰検索ならRecursiveにチェック>Done

ライブラリを使用する

C++を使うので同様にStaticLibUseAppDelegate.mの拡張子をmmに変更しておきます。
StaticLibUseAppDelegate.mm

#import "StaticLibUseAppDelegate.h"
// その他デフォルトのヘッダ→略

// ライブラリのヘッダインクルード
#import "test.h"
#import "StaticLib.h"

@implementation StaticLibUseAppDelegate
//  メンバ、メソッド定義→略
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    Sample sample;
    sample.test();
    StaticLib* staticLib = [[StaticLib alloc]init];
    [staticLib test];
    [staticLib release];
   //  略
    return YES;
}

以上で、Objective-CC++の両方のIFを呼び出すことができます。実行して両方とも呼び出されれば成功です。

Sample::test was called
[StaticLib test] was called
Sample::test was called

FreeType2をインストールして使ってみる

OSXfreetypeを使った手順について。
※環境はMacOSX10.7、freetype2.4.6です。他にbzip2-v1.0.6、zlib1.2.5も用意しておきます。
※ビルドした静的ライブラリをインストールせずに持ち運んで使ってみます

freetype2のビルド

http://freetype.sourceforge.net/index2.htmlからDownloads stable release を選択>
http://sourceforge.net/projects/freetype/files/からfreetype-2.4.6.tar.bz2をダウンロードして展開します。展開したディレクトリに移動してターミナルで以下のコマンドを実行

./configure
make

objs/.libs/libfreetype.a、libfreetype.6.dylibが作成されています。

Xcodeで利用する

C++のCommandLineToolsプロジェクトを作成します。(例えば//Sample.xcodeproj)
ライブラリとヘッダをコピーします。
//lib/libfreetype.a
//include/ft2build.h
//include/freetype (internalディレクトリは不要)
Link Binary With Librariresでlibfreetype.aをプロジェクトに追加
Search Paths>Search Header PathとLibrary Pathでインクルードパスとライブラリパスをプロジェクトに追加
この時点でmain.cppで適当に関数を呼んでビルドすると、以下のようなリンクエラーになります。

Undefined symbols for architecture x86_64:
  "_inflateInit2_", referenced from:
      _FT_Stream_OpenGzip in libfreetype.a(ftgzip.o)
  "_inflateEnd", referenced from:
      _FT_Stream_OpenGzip in libfreetype.a(ftgzip.o)
      _ft_gzip_stream_close in libfreetype.a(ftgzip.o)
  "_inflate", referenced from:
      _ft_gzip_file_fill_output in libfreetype.a(ftgzip.o)
  "_inflateReset", referenced from:
      _ft_gzip_file_io in libfreetype.a(ftgzip.o)
  "_BZ2_bzDecompressInit", referenced from:
      _FT_Stream_OpenBzip2 in libfreetype.a(ftbzip2.o)
      _ft_bzip2_stream_io in libfreetype.a(ftbzip2.o)
  "_BZ2_bzDecompressEnd", referenced from:
      _ft_bzip2_stream_io in libfreetype.a(ftbzip2.o)
      _ft_bzip2_stream_close in libfreetype.a(ftbzip2.o)
  "_BZ2_bzDecompress", referenced from:
      _ft_bzip2_file_fill_output in libfreetype.a(ftbzip2.o)
ld: symbol(s) not found for architecture x86_64

zlibが足りないので、ビルドして作成したlibz.aを//lib/にコピー、Link Binary With Librariesでターゲットに追加します。これでもまだエラーが出たままなので、さらにbzip2を追加します。

  "_BZ2_bzDecompressInit", referenced from:
      _FT_Stream_OpenBzip2 in libfreetype.a(ftbzip2.o)
      _ft_bzip2_stream_io in libfreetype.a(ftbzip2.o)
  "_BZ2_bzDecompressEnd", referenced from:
      _ft_bzip2_stream_io in libfreetype.a(ftbzip2.o)
      _ft_bzip2_stream_close in libfreetype.a(ftbzip2.o)
  "_BZ2_bzDecompress", referenced from:
      _ft_bzip2_file_fill_output in libfreetype.a(ftbzip2.o)
ld: symbol(s) not found for architecture x86_64

libbzip2.aをビルドして、Link Binary With Librariesでターゲットに追加
さらに//include/bzlib.hをコピー
これでエラーがなくなります。

FreeType2を使ってみる

正確な情報はこちらを参照してください。↓
http://freetype.sourceforge.net/freetype2/docs/tutorial/step1.html

ヘッダのインクルード

下の2つのヘッダをインクルードします。(FT_FREETYPE_Hはヘッダのパスを定義したマクロ)

#include <ft2build.h>
#include FT_FREETYPE_H
初期化

ライブラリを表すFT_Libraryオブジェクトに対してFT_Init_FreeTypeを実行します。ここではFT_Libraryをグローバルに保持しておきます。FreetypeAPIはFT_Error型のエラーコードがかえってきます。エラーが無い場合はFT_Err_Okです。

FT_Library  s_library;
int main{
    FT_Error error = FT_Init_FreeType( &s_library );
フォント読み込み

適当なフォントを用意しておいて、FT_New_Faceを実行します。引数にFT_Face型のfaceオブジェクトを渡します。こちらもグローバルに定義しておきます。

FT_Face     s_face
int main(){
   //  略
error = FT_New_Face( s_library, "/yourFontPath/MyFavoriteFont.ttf", 0, &s_face );

※フォントの場所はOSXのバージョンによって異なる。v10.7では/Libary/Fonts内にあります。

文字サイズを設定する
error = FT_Set_Char_Size( s_face,
            0, 
            16*64,  // 幅と高さ
            300,      // 水平解像度
            300 );    // 垂直解像度
字体を作成する

まずFT_Get_Char_Indexでアスキーコードに対応する字体番号を取得します。文字が用意されていないなら0がかえります。この番号を渡してFT_Load_Glyphを呼ぶと実際に字体が取得されます。取得した字体をレンダリングするにはFT_Render_Glyphを呼び出します。これで内部にレンダリングされたビットマップが作成されています。ちなみに字体の各パラメータはFT_Face構造体のglyphメンバ(FT_GlyphSlot型)に保存されます。

glyph_index = FT_Get_Char_Index( s_face, 'q' );
error = FT_Load_Glyph( s_face, glyph_index, FT_LOAD_DEFAULT );
FT_GlyphSlot slot = s_face->glyph;
error = FT_Render_Glyph( slot, FT_RENDER_MODE_NORMAL );

リンダリングの種類を選ぶこともできます。(FT_RENDER_MODE_NORMALはRGB, FT_RENDER_MODE_MONOが2値画像など)

ビットマップを取り出す

FT_GlyphSlotのbitmapメンバ(FT_Bitmap型)でビットマップを取り出します。FT_Bitmapのbufferメンバがバッファのアドレスになります。

FT_GlyphSlot slot = s_face->glyph;
if( slot->format != FT_GLYPH_FORMAT_BITMAP ) // error
FT_Bitmap bitmap = slot->bitmap;
// ビットマップの情報を取り出す
width = bitmap.width;
height = bitmap.rows;
rawData = bitmap.buffer;

あとは画像データを出力したりテクスチャに利用することができます。

グリフの情報を取り出す

描画位置の補正値やペンの動きなども取得できます。

FT_GlyphSlot slot = s_face->glyph;
slot->bitmap_left; // x + slot->bitmap_left , y + slot->bitmap_topに描画すればOK
slot->bitmap_top; //
int advanceX = slot->advance.x >> 6; // x方向にペンを動かすべき距離
int advanceY = slot->advance.y >> 6; // y方向にペンを動かすべき距離

※その他、追記するかもしれません

OpenGLサンプル テクスチャ

OpenGLでテクスチャを表示する手順です。複数枚でブレンディングを有効にして表示してみます。

画像を読み込む

代表的な読み込み方は
・ライブラリを利用して直接読み込む( OpenCVのcvLoad, linpng, libjpgなど。または自作するなど)
フレームワーク付属のクラスを利用してraw dataを取り出す。
ここでは読み込んだと仮定して、画像を自動生成することにします。
画像のデータをまとめてグローバルに定義しておきます。

static const int RGB = 3;
static const int RGBA = 4;
struct image_t{
    int width;
    int height;
    int channels;
    void*buffer;
    ~image_t(){
        if(buffer)::free(buffer);
    }
};
image_t image1 = {64, 64, RGB, 0};
image_t image2 = {64, 64, RGBA, 0};  // ブレンディング対象

画像の読み込みの代わりの関数を作成します。左上端に目印を付けて表示が正しいか判断することにします。画像データの配列は、R,G,BあるいはR,G,B,Aの順で作成します。読み込むときも同様なので、BGR型の配列を読み込んだときは順序を変換しないといけません。

void *loadTexture(int width, int height, int channels, const char* filePathDummy){
    // 画像を読み込む(ここでは仮として自動生成する)
    typedef unsigned char* iterator_t;
    int image_size = width * height * channels * sizeof(unsigned char);
    void *image = ::malloc( image_size ); // nullチェック略
    iterator_t itr_dest = iterator_t(image);
    iterator_t itr_dest_end = itr_dest + image_size;
    //  ストライプ作成
    int pixel = 0; int stride = 3;
    while (itr_dest != itr_dest_end) {
        *itr_dest++ = 255-50 * pixel ;
        *itr_dest++ = 255-50 * pixel ;
        *itr_dest++ = 255-10 * pixel ;
        if (channels == RGBA) {
            *itr_dest++ = 100;  //  半透明
        }
        pixel = ++pixel % stride;
    }
    // 上左端に目印をつける
    itr_dest = iterator_t(image);
    for(int i = 0 ; i < width / 3; i++){
        *itr_dest++ = 50;  // cyan
        *itr_dest++ = 255;
        *itr_dest++ = 255;
        if (channels == RGBA) {
            *itr_dest++ = 100;
        }
    }
    return image;
}
int main(int argc, char **argv){
    //略

    // load image data
    image1.buffer = loadTexture(image1.width, image1.height, image1.channels, "icon1.png");
    image2.buffer = loadTexture(image2.width, image2.height, image2.channels, "icon2.png");
テクスチャの管理

各テクスチャはGLuint型の番号で管理します。複数枚のときはGLuint型の配列を用意しておきます。こちらも画像とセットでグローバルに定義しておきます。

const int TEXTURES = 2;
GLuint textureArray[TEXTURES];
テクスチャ領域の確保と解放

glGenTextures・glDeleteTexturesを使います。

int main(int argc, char **argv){
    //略...

    glEnable(GL_TEXTURE_2D);
    glGenTextures( TEXTURES, textureArray );
    // ...
}
void onExit(){
    glDeleteTextures(TEXTURES, textureArray);
    glDisable(GL_TEXTURE_2D);
}

先ほどの配列と対応した領域が内部に作成されます。今後特定のテクスチャを指定するときはGLuint型の番号textureArray[i]を用います。特定のテクスチャに関する処理を実行するときも引数にGLuint型の番号を入れます。

テクスチャの作成

glBindTextureで現在のテクスチャを指定、glPixelStorei、glTexParameterf、glTexEnviなどでテクスチャの各パラメータを指定、glTexImage2Dで画像からテクスチャを作成します。glTexImage2Dのの引数formatには内部フォーマットを、次の引数formatには画像のフォーマットを指定します。ブレンド処理に対応させるときは双方にGL_RGBAを入れておきます。

void textureFromImage(GLuint textureId, image_t* image){
    // IDによって現在のテクスチャを指定する
    glBindTexture(GL_TEXTURE_2D, textureId );
   // パラメータ設定(例)
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_NEAREST );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );	// texture environment
    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
    // 画像からテクスチャ作成
    GLenum format = GL_RGB;
    if(image->channels == RGBA){
        format = GL_RGBA;  //  4channelのときはGL_RGBAを引数にする
    }
    glTexImage2D(GL_TEXTURE_2D, 0, format, image->width, image->height, 0, format, GL_UNSIGNED_BYTE, image->buffer );
}
テクスチャの描画

glVertexPointerで描画位置を指定、glTexCoordPointerでテクスチャマッピング座標を指定します。その後にglDrawArraysで描画します。テクスチャマッピングを行う前に、glBindTextureでどのテクスチャに適用するのか指定しておきます。

void drawTexture(GLuint textureId, float x, float y, float width, float height ){
    static const int VERTEX_DIMENSION	= 2;
    static const int NUM_VERTICES	= 4;
    
    //	描画位置
    float vertexArray[ ] = {
        x, y,                 // 左下
        x + width, y,         // 右下
        x, y + height,        // 左上
        x + width, y + height // 右上
    };
    glEnableClientState(GL_VERTEX_ARRAY);
    glVertexPointer( VERTEX_DIMENSION, GL_FLOAT, 0, vertexArray );
    
    //  texture mapping座標
    static const float textureCoordArray[] = {
		0.0f, 1.0f,				// 左下
		1.0f, 1.0f,				// 右下
		0.0f, 0.0f,				// 左上
		1.0f, 0.0f,				// 右上
    };
    glEnable(GL_TEXTURE_2D);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glBindTexture(GL_TEXTURE_2D, textureId );
    glTexCoordPointer(2, GL_FLOAT, 0, textureCoordArray);
    // 描画
    glDrawArrays(GL_TRIANGLE_STRIP, 0, NUM_VERTICES);
    
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    glDisable(GL_TEXTURE_2D);
}
ブレンディングの設定

ブレンディングの種類を予め指定しておきます。

    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

以上で、画像1はそのまま、画像2が半透明で描画されます。
(参考)サンプル全体のコード。

#include <stdlib.h>
#include <GLUT/glut.h> // OSX上で実行
// テクスチャ
const int TEXTURES = 2;
GLuint textureArray[TEXTURES];
// 画像
static const int RGB = 3;
static const int RGBA = 4;
struct image_t{
    int width;
    int height;
    int channels;
    void*buffer;
    ~image_t(){ if(buffer){ ::free(buffer);} }
};
image_t image1 = {64, 64, RGB, 0};
image_t image2 = {64, 64, RGBA, 0};  // ブレンディング対象
// 関数
void *loadTexture(int width, int height, int channels, const char* filePath = "");
void drawTexture(GLuint textureId, float x, float y, float width, float height );
void textureFromImage(GLuint textureId, image_t* image);
void drawScene();
void onExit();

int main(int argc, char **argv){
    glutInit( &argc, argv );                
    glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
    glutInitWindowSize(500, 500);
    glutCreateWindow( "glut window" );
    glutDisplayFunc( drawScene );
    ::atexit(onExit);
    // init openGL
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    // load image data
    image1.buffer = loadTexture(image1.width, image1.height, image1.channels, "icon1.png");
    image2.buffer = loadTexture(image2.width, image2.height, image2.channels, "icon2.png");
    // generate textures
    glEnable(GL_TEXTURE_2D);
    glGenTextures( TEXTURES, textureArray );
    // convert image to texture
    GLuint textureID1 = textureArray[0];
    GLuint textureID2 = textureArray[1];    
    textureFromImage(textureID1, &image1);
    textureFromImage(textureID2, &image2);

    glutMainLoop();
    return 0;
}
void onExit(){
    glDeleteTextures(TEXTURES, textureArray);
    glDisable(GL_TEXTURE_2D);
    glDisable(GL_BLEND);
}
// 描画
void drawScene(){
    glClearColor( 0.0f, 0.0f, 0.0f, 1.0f);
    glClear( GL_COLOR_BUFFER_BIT );
    // draw textues
    GLuint textureID1 = textureArray[0];
    GLuint textureID2 = textureArray[1];
    drawTexture(textureID1, 0.1f, 0.1f, 0.2f, 0.2f);
    drawTexture(textureID2, -0.3f, -0.3f, 0.5f, 0.5f);
    
    glutSwapBuffers();
}
//  テクスチャ描画
void drawTexture(GLuint textureId, float x, float y, float width, float height ){
    static const int VERTEX_DIMENSION	= 2;
    static const int NUM_VERTICES	= 4;
    //	描画位置
    float vertexArray[ ] = {
        x, y,                 // 左下
        x + width, y,         // 右下
        x, y + height,        // 左上
        x + width, y + height // 右上
    };
    glEnableClientState(GL_VERTEX_ARRAY);
    glVertexPointer( VERTEX_DIMENSION, GL_FLOAT, 0, vertexArray );
    //  texture mapping座標
    static const float textureCoordArray[] = {
		0.0f, 1.0f,				// 左下
		1.0f, 1.0f,				// 右下
		0.0f, 0.0f,				// 左上
		1.0f, 0.0f,				// 右上
    };
    glEnable(GL_TEXTURE_2D);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glBindTexture(GL_TEXTURE_2D, textureId );
    glTexCoordPointer(2, GL_FLOAT, 0, textureCoordArray);
    // 描画
    glDrawArrays(GL_TRIANGLE_STRIP, 0, NUM_VERTICES);
    
    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    glDisable(GL_TEXTURE_2D);
}
void textureFromImage(GLuint textureId, image_t* image){
    // IDによって現在のテクスチャを指定する
    glBindTexture(GL_TEXTURE_2D, textureId );
    // パラメータ設定(例)
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
    // 画像からテクスチャ作成
    GLenum format = GL_RGB;
    if(image->channels == RGBA){
        format = GL_RGBA;  //  4channelのときはGL_RGBAを引数にする
    }
    glTexImage2D(GL_TEXTURE_2D, 0, format, image->width, image->height, 0, format, GL_UNSIGNED_BYTE, image->buffer );
}
// 画像を読み込む(ここでは仮として自動生成する)
void *loadTexture(int width, int height, int channels, const char* filePathDummy){
    typedef unsigned char* iterator_t;
    int image_size = width * height * channels * sizeof(unsigned char);
    void *image = ::malloc( image_size ); // nullチェック略
    iterator_t itr_dest = iterator_t(image);
    iterator_t itr_dest_end = itr_dest + image_size;
    // ストライプ作成
    int pixel = 0; int stride = 3;
    while (itr_dest != itr_dest_end) {
        *itr_dest++ = 255-50 * pixel ; // r
        *itr_dest++ = 255-50 * pixel ; // g
        *itr_dest++ = 255-10 * pixel ; // b
        if (channels == RGBA) {
            *itr_dest++ = 100;  //  a:半透明
        }
        pixel = ++pixel % stride;
    }
    // 上左端に目印をつける
    itr_dest = iterator_t(image);
    for(int i = 0 ; i < width / 3; i++){
        *itr_dest++ = 50;  // cyan
        *itr_dest++ = 255;
        *itr_dest++ = 255;
        if (channels == RGBA) {
            *itr_dest++ = 100;
        }
    }
    return image;
}

libpng1.5.4をOSXでビルドする

zlibをビルドする

http://zlib.net/からzlib source code, version 1.2.5をダウンロード、適当なディレクトに展開、そこに移動する
あとは、configure,make,make installを実行するだけです。

./configure
make
make install

libz.aやlibz1.2.5.dylibが作成されています。

ソースコードの入手

http://www.libpng.org/pub/png/libpng.html
バージョン1.5.4の表のSource code:から入手→適当なディレクトに展開し、そこに移動

cd 

次にconfigureを呼び出しますが、"./configure"を走らせようとしても動きません→autogen.shを先に呼び出して回避します。

    ./configure --enable-maintainer-mode
    make maintainer-clean
    ./autogen.sh

ところがautogen.shを走らせようとすると下のエラーがでます。

running libtoolize
./autogen.sh: line 15: libtoolize: command not found
ERROR: autogen.sh failed, autogen is incomplete

libtoolizeがないとのこと。libtoolize→glibtoolizeに書き換えて実行すればうまくいきます。
autogen.sh

   LT=${LIBTOOLIZE-libtoolize}

   LT=${LIBTOOLIZE-glibtoolize}

autogen.shを実行します。

$ ./autogen.sh
running glibtoolize
running aclocal
running autoheader [ignore the warnings]
running automake
configure.ac:39: installing `./config.sub'
configure.ac:22: installing `./missing'
configure.ac:22: installing `./install-sh'
configure.ac:39: installing `./config.guess'
Makefile.am: installing `./depcomp'
running autoconf
autogen complete

あとはconfigureでmakefileを作成します。

$ ./configure
checking for a BSD-compatible install... /usr/bin/install -c
....省略
....
configure: creating ./config.status
config.status: creating Makefile
config.status: creating libpng.pc
config.status: creating libpng-config
config.status: creating config.h
config.status: executing depfiles commands
config.status: executing libtool commands

makeします。

$make
make  all-am
....省略
....
libtool: link: ranlib .libs/libpng15.a
libtool: link: ( cd ".libs" && rm -f "libpng15.la" && ln -s "../libpng15.la" "libpng15.la" )
cp libpng-config libpng15-config
cp libpng.pc libpng15.pc

でlibpng.a、libpng15.dylibが作成されました。
インストールするには、

make install

を実行して完了です。あとはlibpng.aなどを持ち運んで利用することもできます。

Xcodeで利用する

static libraryを利用するには、libz.a, libpng.aへのライブラリパスを指定して、
TARGET>Build Settings>Search Paths>Library Search Paths
ライブラリを追加すればOKです。
Build Phases>Link Binary With Libraries>"+">Add Others>libpngとlibzを追加

Cocoaアプリでライブラリを使用する方法

CocoaアプリケーションのプロジェクトにC/C++で作成しているStaticLibraryプロジェクトやCocoaFrameworkを組み込む方法についてです。開発環境はXcode 4です。
まず実行ファイルの出力先を相対パスに設定しておきます。
Xcode>Preferences>Locations>Derived Data>Relative

StaticLibrary用プロジェクトの作成

File>New>New Project>MacOSX>Framework&Library>C/C++Library>Next>ProductNameに名称入力"StaticLibForCocoa", Type:Static>プロジェクトのパスを指定、""を選択>"Create"
//StaticLibForCocoa内にStaticLibForCocoa.xcodeprojが作成される。
プロジェクトにC++クラスを追加します
StaticLib.h

class StaticLib{
public:    
    static void print();  
};

StaticLib.cpp

#include "StaticLib.h"
#include <stdio.h>
void StaticLib::print(){
    printf("Staticlib::print");
}

Cocoaアプリケーションプロジェクトの作成

File>New>New Project>MacOSX>Application>Cocoa Application>Next>ProductNameに名称入力"CocoaLibUse", Type:Static>プロジェクトのパスを指定、""を選択>"Create"
//CocoaLibUse内にCocoaLibUse.xcodeprojが作成される。

CocoaプロジェクトにStaticLibrary用プロジェクトを読み込ませる

File>Add Files To "CocoaLibUse">スタティックライブラリ用プロジェクトStaticLibForCocoa.xcodeprojを選択する>Add
これでCocoaLibUse.xcodeproj内にStaticLibForCocoa.xcodeprojが追加できます。

Staticライブラリ用プロジェクトのターゲットを追加する

Cocoaプロジェクトのビルドと同時にStaticライブラリ用プロジェクトもビルドされるように設定します
Product>Edit Scheme>Build>"+">StaticLibForCocoaを選択>Add
Staticライブラリ側のターゲットを追加することができました。

ライブラリを追加する

リンクするライブラリ一覧にlibStaticLibForCocoa.aを加えます。
CocoaLibUseのターゲットを選択>Build Phases>Link Binary With Libraries>"+">Workspace>"libStaticLibForCocoa.a"を選択>Add
Build Phases>TargetDependencies>"+">StaticLibForCocoaを選択>Add

Staticライブラリのヘッダインクルードパスを設定する

ヘッダStaticLib.hへのパスを通します。
CocoaLibUseのターゲットを選択>Build Settings>Search Paths>Header Search Paths>ターゲットの項目をクリック>"+">Recursiveにチェックを入れる>Pathに"../StaticLibForCocoa"を入力

Staticライブラリを利用する

ファイルをObjective-C++に対応させるために拡張子を.mmにかえます。(CocoaLibUseAppDelegate.m→CocoaLibUseAppDelegate.mmに変更)
さらにCocoaLibUse内のヘッダファイルの拡張子を.hhに変更します。
CocoaLibUseAppDelegate.h→CocoaLibUseAppDelegate.hh
(ライブラリ側のヘッダと".hh"をインルードしているobjective-cのヘッダは全て.hhに変更)
StaticLib.hをimportして、StaticLibクラスを利用します。呼び出し側のコードはC++スタイルで記述します。
CocoaLibUse.mm

#import "CocoaLibUseAppDelegate.hh"
#import "StaticLib.h"

@implementation CocoaLibUseAppDelegate
@synthesize window;
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    StaticLib::print();
}
@end

最後にビルド・実行して

Staticlib::print

がコンソールに表示されれば成功です。
次にカスタムCocoaFrameworkを別プロジェクトから使用する手順です。

CocoaFrameworkプロジェクトの作成

File>New>New Project>MacOSX>Framework&Library>CocoaFramework>Next>ProductNameに名称入力"MyCocoaFramework",プロジェクトのパスを指定、""を選択>"Create"
//MyCocoaFramework内にMyCocoaFramework.xcodeprojが作成される。
プロジェクトにObjective-Cクラスを追加する
MyCocoaFramework.h

@interface MyCocoaFramework : NSObject
+(void)API;
@end

MyCocoaFramework.m

#import "MyCocoaFramework.h"
@implementation MyCocoaFramework
+(void)API
{
    NSLog(@"MyCocoaFramework API was called.");
}
@end

CocoaFrameworkの利用

Cocoaプロジェクトに作成したFrameworkプロジェクトを読み込ませます。
File>Add Files To "CocoaLibUse">スタティックライブラリ用プロジェクトMyCocoaFramework.xcodeprojを選択する>Add
CocoaLibUse.xcodeproj内にMyCocoaFramework.xcodeprojが追加されます。

Staticライブラリ用プロジェクトのターゲット・ライブラリを追加する

先ほどと同様に
Product>Edit Scheme>Build>"+">MyCocoaFrameworkを選択>Add
さらに
CocoaLibUseのターゲットを選択>Build Phases>Link Binary With Libraries>"+">Workspace>"MyCocoaFramework.framework"を選択>Add

Staticライブラリのヘッダインクルードパスを設定する

CocoaLibUseのターゲットを選択>Build Settings>Search Paths>Header Search Paths>ターゲットの項目をクリック>"+">Recursiveにチェックを入れる>Pathに"../MyCocoaFramework"を入力

frameworkを利用する

CocoaLibUseAppDelegateからMyCocoaFrameworkを呼び出してみます。
CocoaLibUseAppDelegate.m

#import "CocoaLibUseAppDelegate.h"
#import "MyCocoaFramework.h"

@implementation CocoaLibUseAppDelegate
@synthesize window;
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
   [MyCocoaFramework API];
}
@end

最後にビルド・実行して

MyCocoaFramework API was called.

がコンソールに表示されれば成功です。