⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 kdu_show.cpp

📁 该源码是JPEG2000的c++源代码,希望对研究JPEG2000标准以及编解码的朋友们有用.
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/******************************************************************************//*                        CKdu_showApp::paint_region                          *//******************************************************************************/void  CKdu_showApp::paint_region(CDC *dc, kdu_dims region){  kdu_dims region_on_buffer = region;  region_on_buffer.pos += view_dims.pos; // Convert to absolute region  region_on_buffer &= buffer_dims; // Intersect with buffer region  region_on_buffer.pos -= buffer_dims.pos; // Make relative to buffer region  if (region_on_buffer.size != region.size)    { /* Need to erase the region first and then modify it to reflect the         region we are about to actually paint. */      dc->BitBlt(region.pos.x,region.pos.y,region.size.x,region.size.y,                 NULL,0,0,WHITENESS);      region = region_on_buffer;      region.pos += buffer_dims.pos; // Convert to absolute region      region.pos -= view_dims.pos; // Make relative to client region.    }  if (!region_on_buffer)    return;  assert(region.size == region_on_buffer.size);  BITMAPINFO info;  memset(&info,0,sizeof(info));  info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);  info.bmiHeader.biWidth = buffer_extent.x;  info.bmiHeader.biHeight = -region.size.y;  info.bmiHeader.biPlanes = 1;  info.bmiHeader.biBitCount = 24;  info.bmiHeader.biCompression = BI_RGB;  kdu_byte *start = buffer +    (region_on_buffer.pos.y*buffer_extent.x + region_on_buffer.pos.x)*3;  int success =    SetDIBitsToDevice(dc->GetSafeHdc(),region.pos.x,region.pos.y,                      region.size.x,region.size.y,0,0,0,region.size.y,                      start,&info,DIB_RGB_COLORS);  if (!success)    { // This should not be necessary, except that there appears to be a nasty      // bug in the Windows OS or MFC.  After a window has been automatically      // resized (required sometimes after rotation or zooming operations to      // make sure the image fits inside the window), the framework sometimes      // gets itself into an inexplicable (and certainly undocumented) funk,      // where attempts to paint to a region which includes the last line of      // the window sometimes cause the entire paint operation to fail.  I      // have tried just about every version of the painting functions,      // defering painting operations thru the windows message loop and all      // sorts of things.  To create the problem yourself (let me know if you      // are able to fix it) try viewing an image which is wider than it is      // tall.  Rotate the image thru 360 degrees so that the window is forced      // to shrink in the horizontal direction.  Then try scrolling to the      // right (scrolling to the left seems not to be so problematic).  My      // only conclusion at this point is that it is a Microsoft bug which I      // can do nothing about.  The current work-around, simply does not update      // the last line of the viewing window, which is not ideal.  Manually      // resizing the window horizontally can get the framework out of this      // difficulty.  Windows NT has also been observed to be a lot more      // robust to this problem than Windows 95.      success =        SetDIBitsToDevice(dc->GetSafeHdc(),region.pos.x,region.pos.y,                          region.size.x,region.size.y-1,0,0,0,region.size.y-1,                          start,&info,DIB_RGB_COLORS);    }}/******************************************************************************//*                 CKdu_showApp::display_quality_layer_status                 *//******************************************************************************/void  CKdu_showApp::display_quality_layer_status(){  if (!codestream)    return;  char string[128];  if (max_display_layers >= codestream.get_max_tile_layers())    sprintf(string,"All quality layers in use.");  else    sprintf(string,"Using %d of %d quality layers.",            max_display_layers,codestream.get_max_tile_layers());  frame->SetMessageText(string);}/******************************************************************************//*                            CKdu_showApp::OnIdle                            *//******************************************************************************/BOOL CKdu_showApp::OnIdle(LONG lCount)   /* Note: this function implements a very simple heuristic for scheduling     regions for processing.  It is intended primarily to demonstrate     capabilities of the underlying framework -- in particular the     `kd_region_decompressor' object and the rest of the Kakadu JPEG2000     platform on which it is built. */{  if (in_idle || !codestream)    return FALSE; // Don't need to be called from recursive loop again.  in_idle = true;  if (!processing)    { // Decide on a region to process.      if (valid_dims.area() < (buffer_dims.area()>>2))        region_in_process = buffer_dims; // No point skirting round `valid_dims'      else        { /* The new region should share a boundary with `valid_dims' so that             they can be added together to form a new rectangular valid region.             Of the four possible regions of this form, pick the one whose             intersection with the current view is largest. */          kdu_coords valid_min = valid_dims.pos;          kdu_coords valid_lim = valid_min + valid_dims.size;          kdu_coords buffer_min = buffer_dims.pos;          kdu_coords buffer_lim = buffer_min + buffer_dims.size;          int needed_left = valid_min.x - buffer_min.x;          int needed_right = buffer_lim.x - valid_lim.x;          int needed_above = valid_min.y - buffer_min.y;          int needed_below = buffer_lim.y - valid_lim.y;          assert((needed_left >= 0) && (needed_right >= 0) &&                 (needed_above >= 0) && (needed_below >= 0));          kdu_dims region_left = valid_dims;          region_left.pos.x = buffer_min.x; region_left.size.x = needed_left;          kdu_dims region_right = valid_dims;          region_right.pos.x = valid_lim.x; region_right.size.x = needed_right;          kdu_dims region_above = valid_dims;          region_above.pos.y = buffer_min.y; region_above.size.y = needed_above;          kdu_dims region_below = valid_dims;          region_below.pos.y = valid_lim.y; region_below.size.y = needed_below;          region_in_process = region_left;          if (((region_in_process & view_dims).area() <               (region_right & view_dims).area()) || !region_in_process)            region_in_process = region_right;          if (((region_in_process & view_dims).area() <               (region_above & view_dims).area()) || !region_in_process)            region_in_process = region_above;          if (((region_in_process & view_dims).area() <               (region_below & view_dims).area()) || !region_in_process)            region_in_process = region_below;        }      if (!(!region_in_process))        {          decompressor.start(codestream,(single_component<0)?(&channels):NULL,                             single_component,discard_levels,max_display_layers,                             region_in_process,expansion);          incomplete_region = region_in_process;          processing = true;        }    }  if (processing)    { // Process some more data.      kdu_dims new_region;      if ((!decompressor.process(buffer,buffer_extent.x,buffer_dims,                                 incomplete_region,8192,new_region)) ||          !incomplete_region)        {          processing = false;          if (!decompressor.finish())            { // Code-stream failure.  Must destroy it.              close_file();            }          else            valid_dims = combine_regions(valid_dims,region_in_process);        }      // In any event, paint any newly decompressed region right away.      new_region &= view_dims; // No point in painting invisible regions.      if (!(!new_region))        {          new_region.pos -= view_dims.pos; // Make relative to view region.          CDC *dc = child->GetDC();          paint_region(dc,new_region);          child->ReleaseDC(dc);        }    }  in_idle = false;  if (valid_dims != buffer_dims)    return TRUE;  display_quality_layer_status(); // All processing done, keep status up to date  return CWinApp::OnIdle(lCount); // Give low-level idle processing a go.}/******************************************************************************//*                          CKdu_showApp::OnAppAbout                          *//******************************************************************************/void CKdu_showApp::OnAppAbout(){  CAboutDlg aboutDlg;  aboutDlg.DoModal();}/******************************************************************************//*                          CKdu_showApp::OnFileClose                         *//******************************************************************************/void CKdu_showApp::OnFileClose() {  if (codestream.exists())    close_file();	}/******************************************************************************//*                       CKdu_showApp::OnUpdateFileClose                      *//******************************************************************************/void CKdu_showApp::OnUpdateFileClose(CCmdUI* pCmdUI) {  pCmdUI->Enable(codestream.exists());}/******************************************************************************//*                          CKdu_showApp::OnFileOpen                          *//******************************************************************************/void CKdu_showApp::OnFileOpen() {  char filename[1024];  OPENFILENAME ofn; memset(&ofn,0,sizeof(ofn)); ofn.lStructSize = sizeof(ofn);  ofn.hwndOwner = m_pMainWnd->GetSafeHwnd();  ofn.lpstrFilter =    "JP2 compatible file (*.jp2, *.jpx)\0*.jp2;*.jpx\0"    "JPEG2000 unwrapped code-stream (*.j2c)\0*.j2c\0"    "Arbitrary name (*.*)\0*.*\0\0";  ofn.nFilterIndex = 3;  ofn.lpstrFile = filename; filename[0] = '\0';  ofn.nMaxFile = 1023;  ofn.lpstrTitle = "Open JPEG2000 Compressed Image";  ofn.Flags = OFN_FILEMUSTEXIST;  if (!GetOpenFileName(&ofn))    return;  open_file(filename);}/******************************************************************************//*                        CKdu_showApp::OnFileProperties                      *//******************************************************************************/void CKdu_showApp::OnFileProperties() {  if (!codestream)    return;  if (processing)    {      processing = false;      if (!decompressor.finish())        {          close_file();          return;        }    }  // Make sure we have all tile information.  if (!tiles_loaded)    {      try { // We may be parsing the code-stream for the first time          max_discard_levels = -1;          codestream.apply_input_restrictions(0,total_components,0,0,NULL);          kdu_dims valid_tiles; codestream.get_valid_tiles(valid_tiles);          kdu_coords idx;          for (idx.y=0; idx.y < valid_tiles.size.y; idx.y++)            for (idx.x=0; idx.x < valid_tiles.size.x; idx.x++)              {                kdu_tile tile = codestream.open_tile(valid_tiles.pos+idx);                tile.close();              }          tiles_loaded = true;        }      catch (int)        {          close_file();          return;        }    }  // Textualize the properties into an `ostrstream' object.  std::ostrstream string_buf;  kdu_params *root = codestream.access_siz();  string_buf << "<<<<< Main Header >>>>>\n";  root->textualize_attributes(string_buf,-1,-1);  codestream.apply_input_restrictions(0,total_components,0,0,NULL);  codestream.change_appearance(false,false,false);  kdu_dims valid_tiles; codestream.get_valid_tiles(valid_tiles);  kdu_coords idx;  for (idx.y=0; idx.y < valid_tiles.size.y; idx.y++)    for (idx.x=0; idx.x < valid_tiles.size.x; idx.x++)      {        kdu_dims tile_dims;        codestream.get_tile_dims(valid_tiles.pos+idx,-1,tile_dims);        int tnum = idx.x + idx.y*valid_tiles.size.x;        string_buf << "<<<<< Tile " << tnum << " >>>>>"                 << " Canvas coordinates: "                 << "y = " << tile_dims.pos.y                 << "; x = " << tile_dims.pos.x                 << "; height = " << tile_dims.size.y                 << "; width = " << tile_dims.size.x << "\n";      root->textualize_attributes(string_buf,tnum,tnum);    }  // Display the properties.  CPropertiesDlg properties(codestream,&string_buf);  properties.DoModal();}/******************************************************************************//*                     CKdu_showApp::OnUpdateFileProperties                   *//******************************************************************************/void CKdu_showApp::OnUpdateFileProperties(CCmdUI* pCmdUI){  pCmdUI->Enable(codestream.exists());}/******************************************************************************//*                          CKdu_showApp::OnViewHflip                         *//******************************************************************************/void CKdu_showApp::OnViewHflip(){  if (!codestream)    return;  hflip = !hflip;  calculate_view_centre();  view_centre_x = 1.0F - view_centre_x;  initialize_regions();}/******************************************************************************//*                       CKdu_showApp::OnUpdateViewHflip                      *//******************************************************************************/void CKdu_showApp::OnUpdateViewHflip(CCmdUI* pCmdUI) {  pCmdUI->Enable(codestream.exists());}/******************************************************************************//*                          CKdu_showApp::OnViewVflip                         *//******************************************************************************/void CKdu_showApp::OnViewVflip() {  if (!codestream)    return;  vflip = !vflip;  calculate_view_centre();  view_centre_y = 1.0F - view_centre_y;  initialize_regions();}/******************************************************************************//*                       CKdu_showApp::OnUpdateViewVflip                      *//****

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -