Project

General

Profile

Download (5.95 KB) Statistics
| Branch: | Revision:

examples / src / main / java / org / distorted / examples / save / SaveWorkerThread.java @ e4237c21

1 e4237c21 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2016 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Distorted.                                                               //
5
//                                                                                               //
6
// Distorted is free software: you can redistribute it and/or modify                             //
7
// it under the terms of the GNU General Public License as published by                          //
8
// the Free Software Foundation, either version 2 of the License, or                             //
9
// (at your option) any later version.                                                           //
10
//                                                                                               //
11
// Distorted is distributed in the hope that it will be useful,                                  //
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
14
// GNU General Public License for more details.                                                  //
15
//                                                                                               //
16
// You should have received a copy of the GNU General Public License                             //
17
// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
18
///////////////////////////////////////////////////////////////////////////////////////////////////
19
20
package org.distorted.examples.save;
21
22
import android.app.Activity;
23
import android.graphics.Bitmap;
24
import android.widget.Toast;
25
26
import java.io.BufferedOutputStream;
27
import java.io.FileOutputStream;
28
import java.io.IOException;
29
import java.lang.ref.WeakReference;
30
import java.nio.ByteBuffer;
31
import java.util.Vector;
32
33
public class SaveWorkerThread extends Thread
34
  {
35
  private static Vector<WorkLoad> mBuffers;
36
  private static SaveWorkerThread mThis=null;
37
  private static volatile boolean mPaused;
38
  private static WeakReference<Activity> mWeakAct;
39
40
  private static class WorkLoad
41
    {
42
    ByteBuffer buffer;
43
    int width;
44
    int height;
45
    String filename;
46
47
    WorkLoad(ByteBuffer buf, int w, int h, String name)
48
      {
49
      buffer   = buf;
50
      width    = w;
51
      height   = h;
52
      filename = name;
53
      }
54
    }
55
56
///////////////////////////////////////////////////////////////////////////////////////////////////
57
58
  public SaveWorkerThread()
59
    {
60
    }
61
62
///////////////////////////////////////////////////////////////////////////////////////////////////
63
64
  static void startSending(Activity act)
65
    {
66
    mWeakAct = new WeakReference(act);
67
68
    mPaused = false;
69
70
    if( mThis==null )
71
      {
72
      mBuffers = new Vector<>();
73
      mThis = new SaveWorkerThread();
74
      mThis.start();
75
      }
76
    else
77
      {
78
      synchronized(mThis)
79
        {
80
        mThis.notify();
81
        }
82
      }
83
    }
84
85
///////////////////////////////////////////////////////////////////////////////////////////////////
86
87
  static void stopSending()
88
    {
89
    mPaused = true;
90
    }
91
92
///////////////////////////////////////////////////////////////////////////////////////////////////
93
94
  public void run()
95
    {
96
    WorkLoad load;
97
98
    while(true)
99
      {
100
      if( mBuffers.size()>0 )
101
        {
102
        load = mBuffers.remove(0);
103
        process(load);
104
        }
105
106
      if( mPaused )
107
        {
108
        synchronized(mThis)
109
          {
110
          try  { mThis.wait(); }
111
          catch(InterruptedException ex) { }
112
          }
113
        }
114
      }
115
    }
116
117
///////////////////////////////////////////////////////////////////////////////////////////////////
118
119
  static void newBuffer(ByteBuffer buffer, int width, int height, String filename)
120
    {
121
    WorkLoad load = new WorkLoad(buffer,width,height,filename);
122
    mBuffers.add(load);
123
    }
124
125
///////////////////////////////////////////////////////////////////////////////////////////////////
126
127
  private void process(WorkLoad load)
128
    {
129
    ByteBuffer buf = load.buffer;
130
    int width  = load.width;
131
    int height = load.height;
132
    final String filename = load.filename;
133
134
    byte[] tmp1 = new byte[width*4];
135
    byte[] tmp2 = new byte[width*4];
136
137
    for(int i=0; i<height/2; i++)
138
      {
139
      buf.position((         i)*width*4);  // GL uses a coordinate system from mathematics; i.e.
140
      buf.get(tmp1);                       // (0,0) is in the lower-left corner. 2D stuff has
141
      buf.position((height-1-i)*width*4);  // the origin on the upper-left corner; we have to flip
142
      buf.get(tmp2);                       // out bitmap upside down!
143
144
      buf.position((         i)*width*4);
145
      buf.put(tmp2);
146
      buf.position((height-1-i)*width*4);
147
      buf.put(tmp1);
148
      }
149
150
    buf.rewind();
151
    BufferedOutputStream bos =null;
152
    final Activity act = mWeakAct.get();
153
154
    try
155
      {
156
      bos = new BufferedOutputStream(new FileOutputStream(filename));
157
      Bitmap bmp = Bitmap.createBitmap( width, height, Bitmap.Config.ARGB_8888);
158
      bmp.copyPixelsFromBuffer(buf);
159
      bmp.compress(Bitmap.CompressFormat.PNG, 90, bos);
160
      bmp.recycle();
161
162
      act.runOnUiThread(new Runnable()
163
        {
164
        public void run()
165
          {
166
          Toast.makeText(act,
167
              "Saving to \n\n"+filename+"\n\nsuccessful" ,
168
              Toast.LENGTH_LONG).show();
169
          }
170
        });
171
      }
172
    catch(final Exception ex)
173
      {
174
      act.runOnUiThread(new Runnable()
175
        {
176
        public void run()
177
          {
178
          Toast.makeText(act,
179
              "Saving to \n\n"+filename+"\n\n failed: "+"\n\n"+ex.getMessage() ,
180
              Toast.LENGTH_LONG).show();
181
          }
182
        });
183
      }
184
    finally
185
      {
186
      if(bos!=null)
187
        {
188
        try { bos.close(); }
189
        catch(IOException io) {}
190
        }
191
      }
192
    }
193
  }