/**************************************************************************** * name: hack_htmlsrc (PRIVATE) * purpose: Do really nasty things to a stream of HTML that just got * pulled over from a server. * inputs: * - none (global HTMainText is assumed to contain current * HText object) * returns: * - HTMainText->htmlSrc (char *) * remarks: * This is ugly but it gets the job done. * The job is this: * - Filter out repeated instances of <PLAINTEXT>. * - Discover if <PLAINTEXT> has been improperly applied * to the head of an HTML document (we discover HTML documents * by checking to see if a <TITLE> element is on the next line). * - Same as above but for <HEAD> and <HTML>. * We advance the character pointer HTMainText->htmlSrc by the * appropriate remark to make adjustments, and keep the original * head of the allocated block of text in HTMainText->htmlSrcHead. ****************************************************************************/ static char *hack_htmlsrc (void) { if (!HTMainText) return NULL; if (!HTMainText->htmlSrc) { HTMainText->htmlSrcHead = NULL; return NULL; } if(get_pref_boolean(eFRAME_HACK)) frame_hack(); /* Keep pointer to real head of htmlSrc memory block. */ HTMainText->htmlSrcHead = HTMainText->htmlSrc; if (HTMainText->htmlSrc && HTMainText->srclen > 30) { if (!strncmp (HTMainText->htmlSrc, "<plaintext>", 11) || !strncmp (HTMainText->htmlSrc, "<PLAINTEXT>", 11)) { if (!strncmp (HTMainText->htmlSrc + 11, "<plaintext>", 11) || !strncmp (HTMainText->htmlSrc + 11, "<PLAINTEXT>", 11)) { HTMainText->htmlSrc += 11; } else if (!strncmp (HTMainText->htmlSrc + 11, "\n<plaintext>", 12) || !strncmp (HTMainText->htmlSrc + 11, "\n<PLAINTEXT>", 12)) { HTMainText->htmlSrc += 12; } else if (!strncmp (HTMainText->htmlSrc + 11, "\n<title>", 8) || !strncmp (HTMainText->htmlSrc + 11, "\n<TITLE>", 8)) { HTMainText->htmlSrc += 12; } else if (!strncmp (HTMainText->htmlSrc + 11, "\n<HEAD>", 7) || !strncmp (HTMainText->htmlSrc + 11, "\n<head>", 7) || !strncmp (HTMainText->htmlSrc + 11, "\n<HTML>", 7) || !strncmp (HTMainText->htmlSrc + 11, "\n<html>", 7) || !strncmp (HTMainText->htmlSrc + 11, "\n<BASE", 6) || !strncmp (HTMainText->htmlSrc + 11, "\n<base", 6)) { HTMainText->htmlSrc += 12; } } if (!strncmp (HTMainText->htmlSrc, "<TITLE>Document</TITLE>\n<PLAINTEXT>", 35)) { if (!strncmp (HTMainText->htmlSrc + 35, "\n<title>", 8) || !strncmp (HTMainText->htmlSrc + 35, "\n<TITLE>", 8)) { HTMainText->htmlSrc += 36; } } } return HTMainText->htmlSrc; }
/* We've just init'd a new history list widget; look at the window's history and load 'er up. */ static void mo_load_history_list (mo_window *win, Widget list) { mo_node *node; for (node = win->history; node != NULL; node = node->next) { XmString xmstr = XmxMakeXmstrFromString (get_pref_boolean(eDISPLAY_URLS_NOT_TITLES) ? node->url : node->title); XmListAddItemUnselected (list, xmstr, 0); XmStringFree (xmstr); } XmListSetBottomPos (list, 0); if (win->current_node) XmListSelectPos (win->history_list, win->current_node->position, False); return; }
/* Called from mo_record_visit to insert an mo_node into the history list of an mo_window. */ mo_status mo_add_node_to_history (mo_window *win, mo_node *node) { /* If there is no current node, this is our first time through. */ if (win->history == NULL) { win->history = node; node->previous = NULL; node->next = NULL; node->position = 1; win->current_node = node; } else { /* Node becomes end of history list. */ /* Point back at current node. */ node->previous = win->current_node; /* Point forward to nothing. */ node->next = NULL; node->position = node->previous->position + 1; /* Kill descendents of current node, since we'll never be able to go forward to them again. */ mo_kill_node_descendents (win, win->current_node); /* Current node points forward to this. */ win->current_node->next = node; /* Current node now becomes new node. */ win->current_node = node; } if (win->history_list) { XmString xmstr = XmxMakeXmstrFromString( get_pref_boolean(eDISPLAY_URLS_NOT_TITLES) ? node->url : node->title); XmListAddItemUnselected (win->history_list, xmstr, node->position); XmStringFree (xmstr); } return mo_succeed; }
unsigned char * ReadPNG(FILE *infile,int *width, int *height, XColor *colrs) { unsigned char *pixmap; unsigned char *p; png_byte *q; png_struct *png_ptr; png_info *info_ptr; double screen_gamma; png_byte *png_pixels=NULL, **row_pointers=NULL; int i, j; unsigned int packets; png_color std_color_cube[216]; /* first check to see if its a valid PNG file. If not, return. */ /* we assume that infile is a valid filepointer */ { int ret; png_byte buf[8]; ret = fread(buf, 1, 8, infile); if(ret != 8) return 0; ret = png_check_sig(buf, 8); if(!ret) return(0); } /* OK, it is a valid PNG file, so let's rewind it, and start decoding it */ rewind(infile); /* allocate the structures */ png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if(!png_ptr) return 0; info_ptr = png_create_info_struct(png_ptr); if(!info_ptr) { png_destroy_read_struct(&png_ptr, NULL, NULL); return 0; } /* Establish the setjmp return context for png_error to use. */ if (setjmp(png_jmpbuf(png_ptr))) { #ifndef DISABLE_TRACE if (srcTrace) { fprintf(stderr, "\n!!!libpng read error!!!\n"); } #endif png_destroy_read_struct(&png_ptr, &info_ptr, NULL); if(png_pixels != NULL) free((char *)png_pixels); if(row_pointers != NULL) free((png_byte **)row_pointers); png_destroy_read_struct(&png_ptr, &info_ptr, NULL); return 0; } /* set up the input control */ png_init_io(png_ptr, infile); /* read the file information */ png_read_info(png_ptr, info_ptr); /* setup other stuff using the fields of png_info. */ *width = (int)png_get_image_width(png_ptr, info_ptr); *height = (int)png_get_image_height(png_ptr, info_ptr); #ifndef DISABLE_TRACE if (srcTrace) { fprintf(stderr,"\n\nBEFORE\nheight = %d\n", (int)png_get_image_width(png_ptr, info_ptr)); fprintf(stderr,"width = %d\n", (int)png_get_image_height(png_ptr, info_ptr)); fprintf(stderr,"bit depth = %d\n", png_get_bit_depth(png_ptr, info_ptr)); fprintf(stderr,"color type = %d\n", png_get_color_type(png_ptr, info_ptr)); fprintf(stderr,"compression type = %d\n", png_get_compression_type(png_ptr, info_ptr)); fprintf(stderr,"filter type = %d\n", png_get_filter_type(png_ptr, info_ptr)); fprintf(stderr,"interlace type = %d\n", png_get_interlace_type(png_ptr, info_ptr)); fprintf(stderr,"num colors = %d\n", png_get_palette_max(png_ptr, info_ptr)); fprintf(stderr,"rowbytes = %d\n", png_get_rowbytes(png_ptr, info_ptr)); } #endif #if 0 /* This handles alpha and transparency by replacing it with a background value. */ /* its #if'ed out for now cause I don't have anything to test it with */ { png_color_16 my_background; if (png_get_valid(png_ptr, info_ptr) & PNG_INFO_bKGD) png_set_background(png_ptr, &(info_ptr->background), PNG_GAMMA_FILE, 1, 1.0); else png_set_background(png_ptr, &my_background, PNG_GAMMA_SCREEN, 0, 1.0); } #endif /* strip pixels in 16-bit images down to 8 bits */ if (png_get_bit_depth(png_ptr, info_ptr) == 16) png_set_strip_16(png_ptr); /* If it is a color image then check if it has a palette. If not then dither the image to 256 colors, and make up a palette */ if (png_get_color_type(png_ptr, info_ptr)==PNG_COLOR_TYPE_RGB || png_get_color_type(png_ptr, info_ptr)==PNG_COLOR_TYPE_RGB_ALPHA) { if(! (png_get_valid(png_ptr, info_ptr, PNG_INFO_PLTE)) ) { #ifndef DISABLE_TRACE if (srcTrace) { fprintf(stderr,"dithering (RGB->palette)...\n"); } #endif /* if there is is no valid palette, then we need to make one up */ for(i=0;i<216;i++) { /* 255.0/5 = 51 */ std_color_cube[i].red=(i%6)*51; std_color_cube[i].green=((i/6)%6)*51; std_color_cube[i].blue=(i/36)*51; } /* this should probably be dithering to Rdata.colors_per_inlined_image colors */ png_set_quantize(png_ptr, std_color_cube, 216, 216, NULL, 1); } else { #ifndef DISABLE_TRACE if (srcTrace) { fprintf(stderr,"dithering (RGB->file supplied palette)...\n"); } #endif png_colorp palette; int num_palette; png_get_PLTE(png_ptr, info_ptr, palette, &num_palette); png_uint_16p hist; png_get_hIST(png_ptr, info_ptr, &hist); png_set_quantize(png_ptr, palette, num_palette, get_pref_int(eCOLORS_PER_INLINED_IMAGE), hist, 1); } } /* PNG files pack pixels of bit depths 1, 2, and 4 into bytes as small as they can. This expands pixels to 1 pixel per byte, and if a transparency value is supplied, an alpha channel is built.*/ if (png_get_bit_depth(png_ptr, info_ptr) < 8) png_set_packing(png_ptr); /* have libpng handle the gamma conversion */ if (get_pref_boolean(eUSE_SCREEN_GAMMA)) { /*SWP*/ if (png_get_bit_depth(png_ptr, info_ptr) != 16) { /* temporary .. glennrp */ screen_gamma=(double)(get_pref_float(eSCREEN_GAMMA)); #ifndef DISABLE_TRACE if (srcTrace) { fprintf(stderr,"screen gamma=%f\n",screen_gamma); } #endif if (png_get_valid(png_ptr, info_ptr, PNG_INFO_gAMA)) { double gamma; png_get_gAMA(png_ptr, info_ptr, &gamma); #ifndef DISABLE_TRACE if (srcTrace) { printf("setting gamma=%f\n",gamma); } #endif png_set_gamma(png_ptr, screen_gamma, gamma); } else { #ifndef DISABLE_TRACE if (srcTrace) { fprintf(stderr,"setting gamma=%f\n",0.45); } #endif png_set_gamma(png_ptr, screen_gamma, (double)0.45); } } } if (png_get_interlace_type(png_ptr, info_ptr)) png_set_interlace_handling(png_ptr); png_read_update_info(png_ptr, info_ptr); #ifndef DISABLE_TRACE if (srcTrace) { fprintf(stderr,"\n\nAFTER\nheight = %d\n", (int)png_get_image_width(png_ptr, info_ptr)); fprintf(stderr,"width = %d\n", (int)png_get_image_height(png_ptr, info_ptr)); fprintf(stderr,"bit depth = %d\n", png_get_bit_depth(png_ptr, info_ptr)); fprintf(stderr,"color type = %d\n", png_get_color_type(png_ptr, info_ptr)); fprintf(stderr,"compression type = %d\n", png_get_compression_type(png_ptr, info_ptr)); fprintf(stderr,"filter type = %d\n", png_get_filter_type(png_ptr, info_ptr)); fprintf(stderr,"interlace type = %d\n", png_get_interlace_type(png_ptr, info_ptr)); fprintf(stderr,"num colors = %d\n", png_get_palette_max(png_ptr, info_ptr)); fprintf(stderr,"rowbytes = %d\n", png_get_rowbytes(png_ptr, info_ptr)); } #endif /* allocate the pixel grid which we will need to send to png_read_image(). */ png_pixels = (png_byte *)malloc(png_get_rowbytes(png_ptr, info_ptr) * (*height) * sizeof(png_byte)); row_pointers = (png_byte **) malloc((*height) * sizeof(png_byte *)); for (i=0; i < *height; i++) row_pointers[i]=png_pixels+(png_get_rowbytes(png_ptr, info_ptr)*i); /* FINALLY - read the darn thing. */ png_read_image(png_ptr, row_pointers); /* now that we have the (transformed to 8-bit RGB) image, we have to copy the resulting palette to our colormap. */ if (png_get_color_type(png_ptr, info_ptr) & PNG_COLOR_MASK_COLOR) { if (png_get_valid(png_ptr, info_ptr, PNG_INFO_PLTE)) { png_colorp palette; int num_palette = png_get_palette_max(png_ptr, info_ptr); for (i=0; i < num_palette; i++) { png_get_PLTE(png_ptr, info_ptr, &palette, i); colrs[i].red = palette->red << 8; colrs[i].green = palette->green << 8; colrs[i].blue = palette->blue << 8; colrs[i].pixel = i; colrs[i].flags = DoRed|DoGreen|DoBlue; } } else { for (i=0; i < 216; i++) { colrs[i].red = std_color_cube[i].red << 8; colrs[i].green = std_color_cube[i].green << 8; colrs[i].blue = std_color_cube[i].blue << 8; colrs[i].pixel = i; colrs[i].flags = DoRed|DoGreen|DoBlue; } } } else { /* grayscale image */ for(i=0; i < 256; i++ ) { colrs[i].red = i << 8; colrs[i].green = i << 8; colrs[i].blue = i << 8; colrs[i].pixel = i; colrs[i].flags = DoRed|DoGreen|DoBlue; } } /* Now copy the pixel data from png_pixels to pixmap */ pixmap = (png_byte *)malloc((*width) * (*height) * sizeof(png_byte)); p = pixmap; q = png_pixels; /* if there is an alpha channel, we have to get rid of it in the pixmap, since I don't do anything with it yet */ if (png_get_color_type(png_ptr, info_ptr) & PNG_COLOR_MASK_ALPHA) { #ifndef DISABLE_TRACE if (srcTrace) { fprintf(stderr,"Getting rid of alpha channel\n"); } #endif for(i=0; i<*height; i++) { q = row_pointers[i]; for(j=0; j<*width; j++) { *p++ = *q++; /*palette index*/ q++; /* skip the alpha pixel */ } } free((char *)png_pixels); } else { #ifndef DISABLE_TRACE if (srcTrace) { fprintf(stderr,"No alpha channel\n"); } #endif for(i=0; i<*height; i++) { q = row_pointers[i]; for(j=0; j<*width; j++) { *p++ = *q++; /*palette index*/ } } free((char *)png_pixels); } free((png_byte **)row_pointers); /* clean up after the read, and free any memory allocated */ /* free the structure */ png_destroy_read_struct(&png_ptr, &info_ptr, NULL); return pixmap; }