title: Hangs at "compressToJpeg"
body: <p><strong>See all 3 edits below</strong></p>
  
  <p><strong>Update: Changed 'read()' to 'readFully()' and got some things working. 'decodeByteArray()' no longer returns null. The jpeg written to the card is actually a full image. The image is still not being drawn to my view. I will keep working and post another question if need be.</strong></p>
  
  <p>I am writing a video streaming client program that takes in images from a DataInputStream. </p>
  
  <p>Because the server calls compressToJpeg() on these images, I figured I could simply take the byte array from my DataInputStream, decode it, and draw the Bitmap from decodeByteArray() to my SurfaceView. Unfortunately, that method only leaves me with decodeByteArray() returning null.</p>
  
  <p>So I added an intermediate step. I created a compressFrame() method which simply takes the byte array from the stream, creates a new YuvImage instance, and uses that to call compressToJpeg(). When run, however, this method <em>hangs on compressToJpeg</em> and <em>closes my client activity</em>. There is no FC popup, and I get no errors in my log.</p>
  
  <p>I have provided the run() of the thread calling the problem method, the method itself, and the log printed before the app closes.</p>
  
  <p><strong>EDIT:</strong> I've also added the ReceiverUtils.getFrame() just in case.</p>
  
  <pre><code>@Override
  public void run() {
  
      String fromServer = null;
      int jpgSize;
      byte[] buffer;
      byte[] jpgData;
      Bitmap image;
      ByteArrayOutputStream jpgBaos = null;
  
      while(isItOK &amp;&amp; (receiver.textIn != null)){
          if(!holder.getSurface().isValid()){
              continue;
          }
  
          ReceiverUtils.init(holder);
  
          //Receive 'ready' flag from camcorder
          fromServer = ReceiverUtils.receiveText(receiver);
  
          while((fromServer != null)){
  
              Log.e("From server: ", fromServer); //logging here because of null pointers when done in Utils
  
              if(fromServer.startsWith("ANDROID_JPG_READY")){
  
                  //Obtain size for byte array
                  jpgSize = Integer.parseInt(fromServer.substring(18));
                  Log.e("JPG SIZE", String.valueOf(jpgSize));
  
                  //Create byte array of size jpgSize
                  buffer = new byte[jpgSize];
                  Log.e("BUFFER SIZE", String.valueOf(buffer.length));
  
                  //Send flag and receive image data from camcorder
                  ReceiverUtils.sendText(receiver, "ANDROID_JPG_SEND");
                  jpgData = ReceiverUtils.receiveData(receiver, buffer);
  
                  //Compress jpgData and write result to jpgBaos
                  jpgBaos = ReceiverUtils.compressFrame(imgRect, jpgData);
  
                  //Decode jpgData into Bitmap
                  image = ReceiverUtils.getFrame(jpgBaos.toByteArray(), jpgSize);
                  //image = ReceiverUtils.getFrame(jpgData, jpgSize);
  
                  //Set buffer and jpgData to null since we aren't using them
                  buffer = null;
                  jpgData = null;
  
                  //Draw Bitmap to canvas
                  ReceiverUtils.draw(image, holder, imgRect);
                  //break; (testing one run-through)
              }
  
              //Receive 'ready' flag from camcorder
              fromServer = ReceiverUtils.receiveText(receiver);
              if(isItOK == false){
                  break;
              }
          }
          //break; (testing one run-through)
      }
      }
  </code></pre>
  
  <p>This is the ReceiverUtils.compressFrame() called in the previous snippet.</p>
  
  <pre><code>/*----------------------------------------
   * compressFrame(Rect imgRect, byte[] input): Creates new instance of YuvImage used to compress ARGB 
   * byte array data to jpeg. Returns ByteArrayOutputStream with data.    
   */
  
      public static ByteArrayOutputStream compressFrame(Rect imgRect, byte[] input){
          boolean success = false;
  
          ByteArrayOutputStream baos = new ByteArrayOutputStream();
  
          YuvImage yuvImage = new YuvImage(input, ImageFormat.NV21, 
                    imgRect.width(), imgRect.height(), null);
          Log.e("HEY", "HEY");
          success = yuvImage.compressToJpeg(imgRect, 80, baos);
          Log.e("Compression Success:", String.valueOf(success));
  
          return baos;
      }
  </code></pre>
  
  <p>Finally, this is the output I'm getting from my LogCat. (Beware some obviously hastily written debug logs.)</p>
  
  <pre><code>07-03 15:01:19.754: E/From server:(1634): ANDROID_JPG_READY_26907
  07-03 15:01:19.754: E/JPG SIZE(1634): 26907
  07-03 15:01:19.764: E/BUFFER SIZE(1634): 26907
  07-03 15:01:19.764: E/To server:(1634): ANDROID_JPG_SEND
  07-03 15:01:19.834: E/jpgIn(1634): Data received successfully.
  07-03 15:01:19.834: E/HEY(1634): HEY
  07-03 15:01:19.844: D/skia(1634): onFlyCompress
  </code></pre>
  
  <p><strong>EDIT: ReceiverUtils.getFrame()</strong></p>
  
  <pre><code>/*---------------------------------------
   * getFrame(byte[] jpgData, int jpgSize): Decodes a byte array into a Bitmap and 
   * returns the Bitmap.
   */
      public static Bitmap getFrame(byte[] jpgData, int jpgSize){
          Bitmap res = null;
  
          res = BitmapFactory.decodeByteArray(jpgData, 0, jpgSize);
          Log.e("Decode success", String.valueOf(!(res == null)));            
  
          return res;
      }
  </code></pre>
  
  <p><strong>EDIT 2: Code before adding compression</strong>  </p>
  
  <pre><code>//Compress jpgData and write result to jpgBaos
  //jpgBaos = ReceiverUtils.compressFrame(imgRect, jpgData);
  
  //Decode jpgData into Bitmap
  //image = ReceiverUtils.getFrame(jpgBaos.toByteArray(), jpgSize);
  image = ReceiverUtils.getFrame(jpgData, jpgSize);
  </code></pre>
  
  <p><strong>EDIT 3: Image after saved to SD Card</strong></p>
  
  <p>The image that Android holds in 'jpgData' in the first code snippet is not the entire image. I can't post it due to being a new user. I added a 'writeToSD' method to test. I assume that the reason it cannot be decoded is because the majority of the image is just blank space, and only a portion of the image is there.</p>