Project

General

Profile

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

examples / src / main / java / org / distorted / examples / save / SaveWorkerThread.java @ 88d9ff62

1
///////////////////////////////////////////////////////////////////////////////////////////////////
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.content.Intent;
24
import android.graphics.Bitmap;
25
import android.net.Uri;
26
import android.widget.Toast;
27

    
28
import java.io.BufferedOutputStream;
29
import java.io.File;
30
import java.io.FileOutputStream;
31
import java.io.IOException;
32
import java.lang.ref.WeakReference;
33
import java.nio.ByteBuffer;
34
import java.util.Vector;
35

    
36
public class SaveWorkerThread extends Thread
37
  {
38
  private static Vector<WorkLoad> mBuffers;
39
  private static SaveWorkerThread mThis=null;
40
  private static volatile boolean mPaused;
41
  private static WeakReference<Activity> mWeakAct;
42

    
43
  private static class WorkLoad
44
    {
45
    ByteBuffer buffer;
46
    int width;
47
    int height;
48
    String filename;
49

    
50
    WorkLoad(ByteBuffer buf, int w, int h, String name)
51
      {
52
      buffer   = buf;
53
      width    = w;
54
      height   = h;
55
      filename = name;
56
      }
57
    }
58

    
59
///////////////////////////////////////////////////////////////////////////////////////////////////
60

    
61
  public SaveWorkerThread()
62
    {
63
    }
64

    
65
///////////////////////////////////////////////////////////////////////////////////////////////////
66

    
67
  static void startSending(Activity act)
68
    {
69
    mWeakAct = new WeakReference(act);
70

    
71
    mPaused = false;
72

    
73
    if( mThis==null )
74
      {
75
      mBuffers = new Vector<>();
76
      mThis = new SaveWorkerThread();
77
      mThis.start();
78
      }
79
    else
80
      {
81
      synchronized(mThis)
82
        {
83
        mThis.notify();
84
        }
85
      }
86
    }
87

    
88
///////////////////////////////////////////////////////////////////////////////////////////////////
89

    
90
  static void stopSending()
91
    {
92
    mPaused = true;
93
    }
94

    
95
///////////////////////////////////////////////////////////////////////////////////////////////////
96

    
97
  public void run()
98
    {
99
    WorkLoad load;
100

    
101
    while(true)
102
      {
103
      if( mBuffers.size()>0 )
104
        {
105
        load = mBuffers.remove(0);
106
        process(load);
107
        }
108

    
109
      if( mPaused )
110
        {
111
        synchronized(mThis)
112
          {
113
          try  { mThis.wait(); }
114
          catch(InterruptedException ex) { }
115
          }
116
        }
117
      }
118
    }
119

    
120
///////////////////////////////////////////////////////////////////////////////////////////////////
121

    
122
  static void newBuffer(ByteBuffer buffer, int width, int height, String filename)
123
    {
124
    WorkLoad load = new WorkLoad(buffer,width,height,filename);
125
    mBuffers.add(load);
126
    }
127

    
128
///////////////////////////////////////////////////////////////////////////////////////////////////
129

    
130
  private void process(WorkLoad load)
131
    {
132
    ByteBuffer buf = load.buffer;
133
    int width  = load.width;
134
    int height = load.height;
135
    final String filename = load.filename;
136

    
137
    byte[] tmp1 = new byte[width*4];
138
    byte[] tmp2 = new byte[width*4];
139

    
140
    for(int i=0; i<height/2; i++)
141
      {
142
      buf.position((         i)*width*4);  // GL uses a coordinate system from mathematics; i.e.
143
      buf.get(tmp1);                       // (0,0) is in the lower-left corner. 2D stuff has
144
      buf.position((height-1-i)*width*4);  // the origin on the upper-left corner; we have to flip
145
      buf.get(tmp2);                       // out bitmap upside down!
146

    
147
      buf.position((         i)*width*4);
148
      buf.put(tmp2);
149
      buf.position((height-1-i)*width*4);
150
      buf.put(tmp1);
151
      }
152

    
153
    buf.rewind();
154
    BufferedOutputStream bos =null;
155
    final Activity act = mWeakAct.get();
156

    
157
    try
158
      {
159
      bos = new BufferedOutputStream(new FileOutputStream(filename));
160
      Bitmap bmp = Bitmap.createBitmap( width, height, Bitmap.Config.ARGB_8888);
161
      bmp.copyPixelsFromBuffer(buf);
162
      bmp.compress(Bitmap.CompressFormat.PNG, 90, bos);
163
      bmp.recycle();
164

    
165
      act.runOnUiThread(new Runnable()
166
        {
167
        public void run()
168
          {
169
          Toast.makeText(act,
170
              "Saving to \n\n"+filename+"\n\nsuccessful" ,
171
              Toast.LENGTH_LONG).show();
172
          }
173
        });
174
      }
175
    catch(final Exception ex)
176
      {
177
      act.runOnUiThread(new Runnable()
178
        {
179
        public void run()
180
          {
181
          Toast.makeText(act,
182
              "Saving to \n\n"+filename+"\n\n failed: "+"\n\n"+ex.getMessage() ,
183
              Toast.LENGTH_LONG).show();
184
          }
185
        });
186
      }
187
    finally
188
      {
189
      if(bos!=null)
190
        {
191
        try { bos.close(); }
192
        catch(IOException io) {}
193
        }
194
      }
195

    
196
    Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
197
    File f = new File(filename);
198
    Uri contentUri = Uri.fromFile(f);
199
    mediaScanIntent.setData(contentUri);
200
    act.sendBroadcast(mediaScanIntent);
201
    }
202
  }
(4-4/4)